I am currently working on a project where I would like to read in an audio file, apply a butterworth filter, and then export the filtered audio file while preserving the scale of the amplitude from the original audio file.
I attempted to do this within the seewave and tuneR packages in R using this code:
BD <- readWave(file_name)
short_name <- tools::file_path_sans_ext(file_name)
FBD <- bwfilter(BD, from = 0, to = 250, bandpass = NULL, output = "Wave")
savewav(FBD, f=24000, channel = 1, filename = paste0(short_name,"_filtered250.wav"), rescale=NULL)
I noticed with this code that when viewing the spectrograms and waveforms of the output files compared to the original audio files, that quiet files are getting rescaled significantly (to be much louder than the original file) while loud files are getting rescaled very little. I tested the code without the bwfilter function and found that simply reading the file in and then saving the output with the savewav function from seewave was still causing the same problem. I dug into the rescale argument in savewav and found that NULL normalizes the amplitude to default settings of the package instead of not rescaling at all, and it relies on the normalize function from tuneR.
I then tested with this code to see if I could solve my problem:
BD <- readWave(file_name)
short_name <- tools::file_path_sans_ext(file_name)
normalize(BD, unit = "16", center = TRUE, level = 1, rescale = FALSE, pcm = BD@pcm)
savewav(BD, f=24000, channel = 1, filename=paste0(short_name,"_rescaleNULLnormalizeFALSE.wav"), rescale=NULL)
This attempt also scaled up the amplitude (see image below of original .wav file on left and output audio file on right).
Next, instead of the savewav function, I used this alternate writeWave function:
BD <- readWave(file_name)
short_name <- tools::file_path_sans_ext(file_name)
writeWave(BD, filename=paste0(short_name,"_writeWave.wav"))
This attempt worked and produced audio files that did not rescale amplitude for quiet, moderate, and loud files. However, when I attempted to add back in the bwfilter function, I received warnings on all of my quiet and moderate files, and an error on the loud file.
BD <- readWave(file_name)
short_name <- tools::file_path_sans_ext(file_name)
FBD <- bwfilter(BD, from = 0, to = 250, bandpass = NULL, output = "Wave")
writeWave(FBD, filename=paste0(short_name,"_filter0bpNULLwriteWave.wav"))
The warning messages for all the moderate/quiet files were saying in writeWave...: channels' data will be rounded to integers for writing the wave file The output .wav files from this attempt appear to have filtered correctly and the amplitude does not look like it has been rescaled.
The error message for the large file was in writeWave...:for 16-bit Wave files, data range is supposed to be in [-32768, 32767], see ?normalize The loud audio file had a lot of clipping in it from high wind, but I do not understand why the writeWav function worked for the large file before, but not now when I attempt to filter it.
Any advice on how to tackle this problem or alternate code suggestions would be greatly appreciated!