저는 R을 사용하고 있으며 고속 푸리에 변환을 적용하여 많은 음파 (오디오 파일의 1000 개)에서 주파수 (실제 주파수에 가까운 숫자)를 복구하려고합니다. 각 파일에 대해 가장 높은 주파수로 주파수를 식별합니다. 가능한 한 빨리 이러한 피크 주파수를 복구 할 수 있기를 바랍니다. FFT 방법은 최근에 배웠던 한 가지 방법이며이 작업을 위해 잘 작동해야한다고 생각합니다. 그러나 FFT에 의존하지 않는 답변에 대해 열려 있습니다. 필자는 FFT를 적용하고 가장 큰 주파수를 얻는 몇 가지 방법을 시도해 보았습니다. 첫 번째 방법부터 상당한 성능 향상을 보았습니다. 그러나 가능하면 실행 시간을 훨씬 더 단축하고 싶습니다. 여기 FFT에서 신호의 주파수를 효율적으로 추출하십시오.
샘플 데이터이다s.rate<-44100 # sampling frequency
t <- 2 # seconds, for my situation, I've got 1000s of 1 - 5 minute files to go through
ind <- seq(s.rate*t)/s.rate # time indices for each step
# let's add two sin waves together to make the sound wave
f1 <- 600 # Hz: freq of sound wave 1
y <- 100*sin(2*pi*f1*ind) # sine wave 1
f2 <- 1500 # Hz: freq of sound wave 2
z <- 500*sin(2*pi*f2*ind+1) # sine wave 2
s <- y+z # the sound wave: my data isn't this nice, but I think this is an OK example
I는 seewave 패키지에서 fpeaksspec 및 기능을 사용하려고 한 첫 번째 방법은, 작동하는 것으로 보인다. 그러나, 그것은 매우 어렵습니다.
library(seewave)
fpeaks(spec(s, f=s.rate), nmax=1, plot=F) * 1000 # *1000 in order to recover freq in Hz
[1] 1494
# pretty close, quite slow
좀 더 읽기를 수행 한 후, 나는 조금 더 둘러보고 후이 다음 방법에있어서, 상기
spec(s, f=s.rate, plot=F)[which(spec(s, f=s.rate, plot=F)[,2]==max(spec(s, f=s.rate, plot=F)[,2])),1] * 1000 # again need to *1000 to get Hz
x
1494
# pretty close, definitely faster
을 시도, 나는 합리적으로 잘 작동하는이 방법을 발견했다.
library(microbenchmark)
microbenchmark(
WHICH.MOD = which(Mod(fft(s))==max(abs(Mod(fft(s))))) * s.rate/length(s),
SPEC.WHICH = spec(s,f=s.rate,plot=F)[which(spec(s,f=s.rate,plot=F)[,2] == max(spec(s,f=s.rate,plot=F)[,2])),1] * 1000, # this is spec from the seewave package
# to recover a number around 1500, you have to multiply by 1000
FPEAKS.SPEC = fpeaks(spec(s,f=s.rate),nmax=1,plot=F)[,1] * 1000, # fpeaks is from the seewave package... again, need to multiply by 1000
times=10)
Unit: milliseconds
expr min lq median uq max neval
WHICH.MOD 10.78 10.81 11.07 11.43 12.33 10
SPEC.WHICH 64.68 65.83 66.66 67.18 78.74 10
FPEAKS.SPEC 100297.52 100648.50 101056.05 101737.56 102927.06 10
좋은 솔루션은 실제 주파수 가장 빠른에 주파수 가까운 (± 10 Hz에서) 복구하는 사람이 될 것입니다 : 여기
which(Mod(fft(s)) == max(abs(Mod(fft(s))))) * s.rate/length(s)
[1] 1500
# recovered the exact frequency, and quickly!
약간의 성능 데이터입니다. 각각 여러 번에게 두 번째 변조, 그냥 침묵이되도록 가끔 신호가 실제로 완전히 사라됩니다 톤을 포함
나는 많은 파일 (몇 GB를)를 가지고
더 많은 상황. 나는 변조되지 않은 음색의 주파수를 확인하고 싶습니다. 나는 그들이 모두 6000 Hz 미만의 어딘가에 있어야한다는 것을 알고 있지만, 그것보다 정확하게는 모른다. (큰 경우) 제가 올바르게 이해한다면, 여기에 OK 접근법이 있습니다. 단지 더 빨리 만드는 문제 일뿐입니다. 필자는 디지털 신호 처리에 대한 이전 경험이 없으므로 프로그래밍 방식으로 접근하는 것이 더 나은 방법에 대한 조언 외에도 수학/방법과 관련된 팁과 포인터에 감사드립니다.
FFT를 사용할 때의 문제점은 입력이 주기적이라고 가정합니다. 이는 대개 신호의 스냅 샷에있는 대부분의 주파수에 해당하지 않습니다. –
@MatthewLundberg 나의 이해는 내가 상대적으로 일정한 주파수 인 톤을 가지고 있는데, 800 ± 50 Hz와 같은 것을 말하며 때로는 변조되지만 시그널의 주된 주파수이다. 이는 정기적 인 것으로 간주되며,이 접근법을 통해 식별 가능해야합니다. 그렇지 않다면 왜 안 되겠습니까? 나는 오해하고있다? – Jota
주기적으로 말하면, FFT는 주어진 신호가 연속적으로 재생되고 양방향으로 무한대로 재생된다고 생각합니다. 이는 몇 가지 주파수를 제외하고 모두 에지 효과를 가져옵니다. 이 엣지 효과는 결과를 채색 할 수도 그렇지 않을 수도 있습니다. –