Question

I'm trying to create a loop for reading in stereo wave files in R, but I'm unsure if I should use for.loop or while.loop. I'm calculating the RMS for both channels.

Here's the action for one sound file:

foo=readWave("mysound.wav")
L=foo@left
R=foo@right
rms(L)
rms(R)

Now, I have directories full of 2 minute sound files. I want to take each of those files, isolate the channels, and calculate the RMS. I THINK this is how it's done:

mydir=list.files("directory", recursive=TRUE) 
for (i in 1:length(mydir)) {
    foo=readWave(mydir[i])
    L=foo@left
    R=foo@right
    rms(L)
    rms(R)
    write(combine, file="test.txt", append=true, sep="\t")  
}

This loop returns the error message that my first sound files doesn't exist. As per the suggestion below, I've also tried to read in the files by:

wav_files <- lapply(mydir, readWave)
Error in FUN(c("DASBR2_20131112$224708.wav", "DASBR2_20131112$224910.wav",  : 
   File 'DASBR2_20131112$224708.wav' does not exist.

This also returns that my file does not exist. Perhaps there is a better way to read in the wave files? Can lapply or for.loop handle waves?

When I type mydir into the console, R produces the following output:

> mydir
   [1] "DASBR2_20131112$224708.wav" "DASBR2_20131112$224910.wav"
   [3] "DASBR2_20131112$225110.wav" "DASBR2_20131112$225310.wav"
   [5] "DASBR2_20131112$225446.wav" "DASBR2_20131112$225648.wav"
   ...

This is what I expect, as these are the names of my sound files. Thoughts?

Was it helpful?

Solution 2

Here is how I did this:

fnam=file.path("directory path")
filist=list.files(fnam, recursive=TRUE, pattern="wav")
filist1=paste(fnam, "/", filist, sep="")
nfiles=length(filist1)
test_rms=c("Full File Path", "RMS-L","RMS-R")
for (i in 1:nfiles){
     inname=filist1[i]
     ywave=readWave(inname)
     L=ywave@left
     R=ywave@right
     test_rms = rbind(test_rms, c(inname, rms(L), rms(R)))
 }

The code for RMS can be replaced with whatever process you need to preform. I will say that the code failed to run through my entire directory, as I had may sub-directories. At least two deep from the path I specified. This code went one level in, and read everything in that directory, even wav files in further sub-directories. I think this script just can handle two directories out.

OTHER TIPS

I think you might just need to get the full path to the files from the current directory.

mydir <- list.files("directory", recursive=TRUE, full.names=TRUE)

Alternatively, you could change directories after the list.files but before reading them.

setwd("directory")

My first thought is to use lapply to read in the files. Something along the lines of this:

wav_files <- lapply(mydir, readWave)

Then I would go through the resulting list of Wave objects using lapply to accomplish the remaining parts of the task.

Something like this could work for extracting channels and using the rms function:

right_rms <- lapply(wave_files, function(x)rms(x@right)) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top