2011-01-26 29 views
9

Tôi đang đọc luồng sóng thô đến từ micrô.
(Phần này hoạt động như tôi có thể gửi cho loa và nhận được tiếng vang đẹp.)Phát hiện tần số/âm cụ thể từ dữ liệu sóng thô

Để đơn giản cho phép nói rằng tôi muốn phát hiện âm DTMF trong dữ liệu sóng. Trong thực tế, tôi muốn phát hiện bất kỳ tần số nào, không chỉ những tần số trong DTMF. Nhưng tôi luôn biết tần suất mà tôi đang tìm kiếm.

Tôi đã thử chạy nó thông qua FFT, nhưng nó không có vẻ rất hiệu quả nếu tôi muốn độ chính xác cao trong việc phát hiện (nói rằng nó là có cho chỉ 20 ms). Tôi có thể phát hiện nó xuống đến độ chính xác khoảng 200 ms.

Tùy chọn của tôi liên quan đến thuật toán là gì? Có bất kỳ lib .Net nào không?

+0

Tỷ lệ mẫu của bạn là bao nhiêu? – ThomasMcLeod

+0

Mọi thứ tôi muốn, ngay bây giờ là 44,1k (âm thanh nổi 16 bit). Tôi nhận được một mẫu 2k mỗi ~ 20ms. –

+0

Hey tôi có cùng một vấn đề ... bạn có một số mã hoặc độ phân giải? bởi vì câu hỏi là một chút cũ. – Daniloloko

Trả lời

11

Bạn có thể muốn xem Goertzel algorithm nếu bạn đang cố gắng phát hiện các tần số cụ thể như đầu vào DTMF. Có một thư viện C# DTMF generator/detector trên Sourceforge dựa trên thuật toán này.

+0

Cảm ơn lời khuyên. Có vẻ như Goertzel là con đường để đi.Tôi đã nhìn vào mã bạn liên kết, nhưng nó không phải là tài liệu rất tốt nên rất khó để làm cho đầu và đuôi của nó. –

+0

Goertzel có hoạt động ngay cả với tiếng ồn khác (ví dụ như âm nhạc), hay nó đòi hỏi một giai điệu rõ ràng hơn hoặc ít hơn? –

+0

Tôi không thấy lý do tại sao nó sẽ không hoạt động với sự hiện diện của tiếng ồn khác; nó ít nhất cũng không kém hơn bất kỳ thuật toán biến đổi Fourier rời rạc nào khác. –

-2

Spectral Analysis.

Tất cả ứng dụng mà bạn trích xuất tần số từ tín hiệu đi theo phân tích phổ trường.

+0

Đây không phải là câu trả lời hay cho câu hỏi. Nói chung, một liên kết đến Wikipedia không trả lời được câu hỏi. – Gabe

+0

@Gabe Tôi chỉ cho anh ta đúng hướng. Tất cả các thuật toán có suatable. –

+3

Một gợi ý đúng hướng nên là một bình luận, không phải là một câu trả lời. – Gabe

0

Giả sử tần số DTMF điển hình là 200Hz - 1000Hz. Sau đó, bạn phải phát hiện tín hiệu dựa trên chu kỳ từ 4 đến 20. FFT sẽ không đưa bạn đến bất cứ nơi nào tôi đoán, vì bạn sẽ chỉ phát hiện bội số tần số 50Hz: đây là được xây dựng trong tính năng của FFT, tăng số lượng mẫu sẽ không phải là giải quyết vấn đề của bạn. Bạn sẽ phải làm một cái gì đó thông minh hơn.

bắn tốt nhất của bạn là để tuyến tính phù hợp nhất vuông dữ liệu của bạn để

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

cho một omega nhất định (một trong những tần số DTMF). Xem this để biết chi tiết (cụ thể là cách thiết lập mức ý nghĩa thống kê) và liên kết đến nội dung.

+0

Cảm ơn. Sau đó, tôi thấy lý do tại sao FFT không phải là rất hữu ích. Nhìn vào tuyến tính vuông phù hợp nhất để xem nếu tôi có thể tìm thấy một số .Net hoặc sử dụng .dll để kiểm tra. –

+0

Tôi không biết về thuật toán Görtzel trước đây, nó phải là cách nhanh hơn ít nhất vuông phù hợp với một làn sóng sin. –

+0

Tôi không hiểu bạn đang nói gì về FFT. Tần số DTMF từ 697Hz đến 1477Hz, mỗi tần số cách nhau ít nhất 73Hz. Tại 8kHz một FFT 256 điểm sẽ hoạt động tốt. Tất nhiên bằng cách sử dụng FFTs để phát hiện tần số cụ thể là quá mức cần thiết, nhưng nó vẫn hoạt động. – Gabe

1

Tôi thấy điều này như là việc triển khai Goertzel đơn giản. Đã không nhận được nó để làm việc nào (tìm kiếm tần số sai?), Nhưng tôi nghĩ rằng tôi muốn chia sẻ nó anywas. Nó được sao chép từ 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

Giống như mọi thư viện .NET thực hiện việc này, hãy thử TAPIEx ToneDecoder.Net Component. Tôi sử dụng nó để phát hiện DTMF, nhưng nó cũng có thể thực hiện các tông tùy chỉnh.

Tôi biết câu hỏi này cũ, nhưng có thể nó sẽ tiết kiệm cho người khác vài ngày tìm kiếm và thử các mẫu mã và thư viện không hoạt động.

3

Triển khai rất tốt Goertzel là there. C# modify:

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; 
    } 

Hoạt động rất tốt cho tôi.

Các vấn đề liên quan