library(shiny)
library(shinyFiles)
library(dplyr)
library(rhinolophus)
library(raster)
shinyServer(function(input, output, session) {
data <- reactiveValues(
n_todo = integer(0),
filename = character(0),
species = character(0)
)
roots <- c(root = "/")
shinyDirChoose(
input,
"path",
roots = roots,
filetypes = c("wav", "WAV")
)
observeEvent(
input$path,
{
data$species <- parseDirPath(roots, input$path) %>%
list.files(
pattern = ".*µ.*\\.wav",
ignore.case = TRUE,
recursive = TRUE
) %>%
basename() %>%
gsub(pattern = "µ.*$", replacement = "") %>%
strsplit("_") %>%
unlist() %>%
gsub(pattern = "-[[:digit:]]*", replacement = "") %>%
c(data$species) %>%
unique() %>%
sort()
updateSelectInput(session, "aspect", selected = 1)
updateCheckboxInput(session, "check", value = FALSE)
todo <- list.files(
path = parseDirPath(roots, input$path),
pattern = "\\.wav$",
ignore.case = TRUE,
full.names = TRUE
)
data$n_todo <- length(todo)
if (data$n_todo > 0) {
data$filename <- sample(todo, 1)
} else {
data$filename <- character(0)
}
}
)
sonor <- reactive({
if (length(data$filename) == 0) {
return(NULL)
}
sonogram <- read_wav(
data$filename,
channel = gsub(",.*$", "", input$channel),
te.factor = as.integer(gsub("^.*, TE = ", "", input$channel))
) %>%
wav2spectrogram()
sonogram$f <- sonogram$f / 1000
sonogram$t <- sonogram$t * 1000
updateSliderInput(
session,
"starttime",
value = 0,
max = input$timeinterval * (max(sonogram$t) %/% input$timeinterval),
step = input$timeinterval
)
amplitude_range <- pretty(range(sonogram$S), 10)
updateSliderInput(
session,
"amplitude",
value = c(0, max(amplitude_range)),
min = min(amplitude_range),
max = max(amplitude_range)
)
frequency_range <- pretty(range(sonogram$f), 10)
updateSliderInput(
session,
"frequency",
value = c(0, pmin(140, max(frequency_range))),
min = min(frequency_range),
max = max(frequency_range)
)
raster(
sonogram$S[rev(seq_along(sonogram$f)), ],
xmn = min(sonogram$t),
xmx = max(sonogram$t),
ymn = min(sonogram$f),
ymx = max(sonogram$f)
)
})
observeEvent(
input$step_backward,
updateSliderInput(
session,
"starttime",
value = input$starttime - input$timeinterval
)
)
observeEvent(
input$step_forward,
updateSliderInput(
session,
"starttime",
value = input$starttime + input$timeinterval
)
)
output$sonogram <- renderPlot({
if (is.null(sonor())) {
return(NULL)
}
breaks <- pretty(input$amplitude[1]:input$amplitude[2], 20)
plot(
clamp(sonor(), lower = input$amplitude[1], upper = input$amplitude[2]),
asp = input$aspect,
breaks = breaks,
col = topo.colors(length(breaks)),
xlim = input$starttime + c(0, input$timeinterval),
ylim = input$frequency,
xlab = "time (ms)",
ylab = "frequency (kHz)",
main = sprintf("%s\nremaining: %i files", data$filename, data$n_todo - 1)
)
abline(
h = c(20, 30, 40, 50, 60, 80, 90, 110),
lty = 2,
col = "white",
lwd = 2
)
abline(h = c(18, 21, 27, 35), lty = 3, col = "white", lwd = 2)
})
observeEvent(
input$aspect,
{
updateSliderInput(session, "timeinterval", value = 200 * as.numeric(input$aspect))
}
)
observeEvent(
input$add_species,
{
data$species <- sort(unique(c(data$species, input$new_species)))
}
)
output$species <- renderUI({
lapply(
data$species,
function(species_name){
numericInput(
species_name,
label = species_name,
value = 0,
min = 0,
max = 9,
step = 1,
)
}
) %>%
tagList()
})
observeEvent(
input$move_file,
{
if (length(data$species) == 0) {
return(NULL)
}
species_names <- sapply(
data$species,
function(species_name){
if (input[[species_name]] > 0) {
updateNumericInput(session, species_name, value = 0)
sprintf("%s-%i", species_name, input[[species_name]])
} else {
""
}
}
)
species_names <- paste(species_names[species_names != ""], collapse = "_")
if (nchar(species_names) == 0) {
return(NULL)
}
if (input$check) {
subdir <- sprintf("%s/check", dirname(data$filename))
} else {
subdir <- sprintf("%s/done", dirname(data$filename))
}
if (!file_test("-d", subdir)) {
dir.create(subdir)
}
file.rename(
data$filename,
sprintf(
"%s/%sµ%s%iµ%s",
subdir,
species_names,
gsub(",.*$", "", input$channel) %>%
strtrim(1),
as.integer(gsub("^.*, TE = ", "", input$channel)),
basename(data$filename)
)
)
updateSelectInput(session, "aspect", selected = 1)
todo <- list.files(
path = parseDirPath(roots, input$path),
pattern = "\\.wav$",
ignore.case = TRUE,
full.names = TRUE
)
data$n_todo <- length(todo)
if (data$n_todo > 0) {
data$filename <- sample(todo, 1)
} else {
data$filename <- character(0)
}
updateCheckboxInput(session, "check", value = FALSE)
}
)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.