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.
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