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
Other answers
look at the 'signal' package on cran, one of the filter functions there should do
Stan
Related Q & A:
- How to get a specific data after post method?Best solution by Stack Overflow
- how elasticsearch exclude a specific value?Best solution by Stack Overflow
- How to extract a specific text from an image?Best solution by Stack Overflow
- How long are a verse, a chorus and a bridge?Best solution by songu.com
- How to put a video file on to a disc?Best solution by wikihow.com
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
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.