How to extract frequency range from a Wav file?

How to extract a specific frequency range from a .wav file?

  • I'm really new on sound processing, so maybe my question will be trivial. What I want to do is to extract a specific frequency range (let's say 150-400 Hz) from a wav file, using R. In other words, I want to create another wave file (wave2) that contains only the frequency component that I specify (150 to 400 Hz, or what else). I read something on the net, and I discovered out that this can be done with a FFT analysis, and here's come the problems. Suppose I've this code: library(sound) s1 <- Sine(440, 1) s2 <- Sine(880, 1) s3 <- s1 + s2 s3.s <- as.vector(s3$sound) # s3.s is now a vector, with length 44100; # bitrate is 44100 (by default) # so total time of s3 is 1sec. # now I calculate frequencies N <- length(s3.s) # 44100 k <- c(0:(N-1)) Fs <- 44100 # sampling rate T <- N / Fs freq <- k / T x <- fft(s3.s) / N plot(freq[1:22050], x[1:22050], type="l") # we need just the first half of FFT computation The plot we obtain is: Well, there are two peaks. If we want to know to what frequency they correspond, just find: order(Mod(x)[1:22050], decreasing=T)[1:10] [1] 441 881 882 880 883 442 440 879 884 878 First two values are really near to the frequency I've used to create my sound: real computed Freq1: 440 | 441 Freq2: 880 | 881 So, now comes the problem: how to proceed, if I want to delete from my sound the frequencies in the range, say, (1, 500) ? And how to select (and save) only the range (1, 500) ? What I attend, is that my new sound (with deleted frequencies) will be something near to simple Sine(freq=880, duration=1) (I know, it cannot be exactly like so!). Is that possible? I'm pretty sure that fft(DATA, inverse = TRUE) is what I need. But I'm not sure, and however I don't know how to proceed.

  • Answer:

    Maybe I missed the point, but don't you already have your answer? From your post: order(Mod(x)[1:22050], decreasing=T)[1:10] [1] 441 881 882 880 883 442 440 879 884 878 Simply collect all values above 500: junk <- order(Mod(x)[1:22050], decreasing=T)[1:10] (junk1 <- junk[junk > 500]) [1] 881 882 880 883 879 884 878 To generate the new signal simply repeat what you did to build the original signal: junk2 <- Sine(0, 1) for (i in 1:length(junk1)) { junk2 <- junk2 + Sine(junk1[i], 1) } junk2.s <- as.vector(junk2$sound) To keep the values below 500: (junk3 <- junk[junk <= 500]) [1] 441 442 440

Tommaso at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

look at the 'signal' package on cran, one of the filter functions there should do

Stan

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.