I am trying to reprocess audiofiles according to the occurrence (mainly) bat species. The audio-files were analyzed in batch by a neural network and now I want to store file parts in folders per species occurrence to enable an efficient validation.

The current files are 60s long, but the algorythm made use of only 5 seconds at once, so I want to cut these files as well properly.

I already have the following code:
The navigating to filenames should be okay, I think the problem is with the (re)formatting of the audio-files.

library(audio)
library(tuneR)

# This code will process files in folders if ordered as followed
# 1) Country-level
# 2) Location-level
# 3) Type-level

# ----------------------
# Declare folder paths
# ----------------------
# BTO_file_path <- 'D:/Users/jjovdndr/OneDrive - UGent/PhD DigitAf/Papers/Rproj/Paper 2/Fieldwork data/Bats_BTO.csv'
BTO_file_path <- 'D:/Users/jjovdndr/OneDrive - UGent/PhD DigitAf/Papers/Paper 2/Bats_tmp.csv'
# audio_dir <- 'G:/3 - AudioMoth_data'
audio_dir <- 'D:/Users/jjovdndr/OneDrive - UGent/PhD DigitAf/Papers/Paper 2'

# ----------------------
# Prepare the BTO file accordingly
# ----------------------
BTO <- read.csv(BTO_file_path, header = TRUE) %>%
  filter(prob > 0.4999) %>% # Probability at least 50%
  filter(species.group != "bird") %>%
  filter(scientific.name != "Pipistrellus pipistrellus") %>% # Very common species, validation not needed
  mutate(Country = "Belgium") # Initiating country column
BTO$Loc[BTO$Loc == "K"] <- "AudioMoth Keigat" # Corresponding to path name
BTO$Country[BTO$Loc == "Rot"] <- "Germany" # Corresponding to path name
BTO$Loc[BTO$Loc == "Rot"] <- "Baiersbronn" # Corresponding to path name
BTO

# ----------------------
# Make a list for all species
# ----------------------
list_species <- BTO %>%
  group_by(species.group) %>%
  count(scientific.name) %>%
  select(-n) 
list_species


# ----------------------
# Start transferring
# ----------------------
for (i in 1:nrow(list_species)) {
  tmp <- filter(BTO, scientific.name == list_species$scientific.name[i])
  
  # Create target directory
  target_dir <- paste0(audio_dir, '/Species/', list_species$scientific.name[i])
  dir.create(target_dir, showWarnings = FALSE) # Create target directory if it doesn't exist

  for (j in 1:nrow(tmp)) {
    path_of_file <- file.path(audio_dir, tmp$Country[j], tmp$Loc[j], tmp$Type[j], tmp$Filename[j])
    audio_data <- readWave(path_of_file)

    # ---------------------------------------------------
    # If the input files are bigger then 5 seconds:
    # ---------------------------------------------------
    # Calculate start and end times for the 5-second chunk
    start_time <- (tmp$Filepart[j] - 1) * 5
    end_time <- tmp$Filepart[j] * 5
    
    # Extract the 5-second chunk
    chunk <- audio_data[start_time * [email protected]:(end_time * [email protected])]
    # Remove possible missing values (NA) from the chunk
    # chunk <- na.omit(chunk@left)
    # ---------------------------------------------------

    # Save the chunk with a custom name
    output_file <- file.path(target_dir, paste0(tmp$Country[j], '_', tmp$Loc[j], '_', tmp$Type[j], '_', tmp$Filename[j]))
    writeWave(chunk, filename = output_file)
  }
}

The following error is generated:
Error in if ((object@bit == 16) && ((max(sample.data) > 32767) || (min(sample.data) < : missing value where TRUE/FALSE needed

When I enable chunk <- na.omit(chunk@left), the following error is generated:

Error in writeWave(chunk, filename = output_file) : 
  'object' needs to be of class 'Wave' or 'WaveMC'
2.
stop("'object' needs to be of class 'Wave' or 'WaveMC'")
1.
writeWave(chunk, filename = output_file)

The audiofiles are a tad too heavy to submit as well, so I hope it’s possible to see in the code whatever is coded wrongly to format the audiofiles.

Thanks in advance!

New contributor

Jari Vandendriessche is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.