2011-01-26 2 views
9

마이크에서 오는 원시 웨이브 스트림을 읽습니다.
(이 부분은 스피커로 전송하여 멋진 반향을 얻을 수 있습니다.)원시 웨이브 데이터에서 특정 주파수/톤을 감지하십시오.

간결함을 위해 웨이브 데이터에서 DTMF 톤을 감지하려고한다고 가정 해 보겠습니다. 실제로 DTMF의 주파수뿐만 아니라 모든 주파수를 감지하고 싶습니다. 그러나 나는 항상 내가 원하는 주파수를 알고있다.

FFT를 통해 실행 해 보았지만 높은 정확도의 탐지가 필요하다면 매우 효율적으로 보이지 않습니다 (20 밀리 초 밖에 없습니다). 나는 약 200ms의 정확도로 그것을 탐지 할 수있다.

알고리즘과 관련하여 내 옵션에는 어떤 것이 있습니까? .Net 라이브러리가 있습니까?

+0

샘플 속도는 무엇입니까? – ThomasMcLeod

+0

원하는 제품, 지금은 44,1k (16 비트 스테레오). 나는 ~ 20ms마다 2k 샘플을 받는다. –

+0

이봐, 나는 같은 문제가있다. 코드 나 해상도가 얼마인가? 질문은 조금 오래 되었기 때문에. – Daniloloko

답변

11

DTMF 입력과 같은 특정 주파수를 감지하려는 경우 Goertzel algorithm을 볼 수 있습니다. 이 알고리즘을 기반으로 Sourceforge에는 C# DTMF generator/detector 라이브러리가 있습니다.

+0

팁 주셔서 감사. Goertzel이 갈 길 인 것 같습니다.내가 링크 된 코드를 살펴 봤지만, 너무 잘 문서화되지 않아 머리와 꼬리를 만드는 것이 어렵습니다. –

+0

Goertzel은 다른 소음 (예 : 음악)과 함께 작동합니까? 아니면 다소 클린 톤이 필요합니까? –

+0

다른 노이즈가있는 경우 왜 작동하지 않는지는 알 수 없습니다. 그것은 적어도 다른 이산 푸리에 변환 알고리즘보다 더 나쁘지 않아야합니다. –

-2

Spectral Analysis.

신호에서 주파수를 추출하는 모든 응용 프로그램은 필드 스펙트럼 분석을 사용합니다.

+0

이것은 좋은 질문이 아닙니다. 일반적으로 Wikipedia에 대한 링크는 질문에 대답하지 않습니다. – Gabe

+0

@Gabe 나는 그를 올바른 방향으로 가리킨다. 거기에 모든 알고리즘을 suatable 있습니다. –

+3

올바른 방향의 힌트는 대답이 아닌 주석이어야합니다. – Gabe

0

일반적인 DTMF 주파수는 200Hz - 1000Hz입니다. 그런 다음 4 ~ 20 사이클을 기준으로 신호를 감지해야합니다. FFT는 이 내장 된 FFT의 기능으로 샘플 수를 늘리면 이 아니며이 문제를 해결할 것입니다. 좀 더 똑똑한 것을해야 할 것입니다.

가장 좋은 샷 선형 최소 자승법에 데이터 주어진 오메가합니다 (DTMF 주파수 중 하나)에 대한

h(t) = A cos (omega t) + B sin (omega t) 

이다. 세부 사항 (특히 통계적 유의 수준을 설정하는 방법) 및 해당 문헌에 대한 링크는 this을 참조하십시오.

+0

감사합니다. 그렇다면 FFT가별로 도움이되지 않는 이유를 알았습니다. Linear least-square fit을 살펴보면 .Net 또는 사용 가능한 .dll을 테스트 할 수 있는지 확인할 수 있습니다. –

+0

이전에 Görtzel 알고리즘에 대해 알지 못했지만, 사인파를 피팅하는 것보다 더 빨리해야합니다. –

+0

나는 FFT에 관해 당신이 말하는 것을 이해하지 못합니다. DTMF 주파수는 697Hz ~ 1477Hz이며, 각각 73Hz 이상 떨어져 있습니다. 8kHz에서 256 포인트 FFT가 정상적으로 작동합니다. 물론 특정 주파수를 탐지하기 위해 FFT를 사용하는 것은 잔인한 일이지만 여전히 작동해야합니다. – Gabe

1

나는 이것을 Goertzel의 간단한 구현으로 발견했습니다. 아직 작동하지 않았다면 (잘못된 주파수를 찾으십니까?) 나는 그것을 공유 할 줄 ​​알았습니다. this site에서 복사됩니다.

 public static double CalculateGoertzel(byte[] sample, double frequency, int samplerate) 
     { 
      double Skn, Skn1, Skn2; 
      Skn = Skn1 = Skn2 = 0; 
      for (int i = 0; i < sample.Length; i++) 
      { 
       Skn2 = Skn1; 
       Skn1 = Skn; 
       Skn = 2 * Math.Cos(2 * Math.PI * frequency/samplerate) * Skn1 - Skn2 + sample[i]; 
      } 
      double WNk = Math.Exp(-2 * Math.PI * frequency/samplerate); 
      return 20 * Math.Log10(Math.Abs((Skn - WNk * Skn1))); 
     } 
0

지금까지 수행 한 모든 .NET 라이브러리는 TAPIEx ToneDecoder.Net Component입니다. DTMF를 탐지하는 데 사용하지만 사용자 정의 톤도 사용할 수 있습니다.

나는이 질문이 오래되었다는 것을 알고 있지만 어쩌면 누군가 다른 사람을 구해서 며칠 만 치워서 코드 샘플과 라이브러리가 작동하지 않는 것을 시험 할 수 있습니다.

3

Goertzel의 아주 좋은 구현은 there입니다. C# 수정 :

private double GoertzelFilter(float[] samples, double freq, int start, int end) 
    { 
     double sPrev = 0.0; 
     double sPrev2 = 0.0; 
     int i; 
     double normalizedfreq = freq/SIGNAL_SAMPLE_RATE; 
     double coeff = 2 * Math.Cos(2 * Math.PI * normalizedfreq); 
     for (i = start; i < end; i++) 
     { 
      double s = samples[i] + coeff * sPrev - sPrev2; 
      sPrev2 = sPrev; 
      sPrev = s; 
     } 
     double power = sPrev2 * sPrev2 + sPrev * sPrev - coeff * sPrev * sPrev2; 
     return power; 
    } 

멋진 작품입니다.

관련 문제