Coder Social home page Coder Social logo

nonprenom / tones_detector Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 0.0 1.84 MB

A real time frequency finder by reading the PCM input.

C 100.00%
goertzel goertzel-algorithm busy-tone ring-tone fast-fourier-transform digital-signal-processing audio-processing

tones_detector's Introduction

A real time frequency finder by reading the PCM input.

The tones (ring, busy, etc...) is defined by a frequency and a pattern:

Ring: 425 Hz for 3s then silent for 1 second.

Busy: 400 Hz for 500ms then silent for 500ms

while the DTMF is normalized in the phone protocol, the other tones are specific to a country: the frequency change and the pattern

You can query all the patterns and frequencies for all the country on this online database:

https://www.3amsystems.com/World_Tone_Database?q=Israel,Busy_tone

For example, for Israel, the busy tone is: 400Hs – 0.5s on, 0.5s Off

Implementation

For this I used the Goertzel algorithm which is usually used for DTMF detection. It’s not a FFT (Fourier) because it gives only a magnitude for one frequency. It’s much easier to implement (15 lines in C) and specially adapted for embedded compare to an FFT.

Now, that I’m able to detect a frequency over the time, I implemented a pattern detector.

First, to avoid false detections, I’m not searching for [0.5 On, 0.5 Off] but for 4 of them like this:

0.5 off, 0.5 On, 0.5 off, 0.5 On, 0.5 off

Because the pattern is not 100% perfect on real samples (sometimes it’s 0.45 off, 0.52 on, 0.42 off, ...) I’m working on a statistic: how much % the real signal is close to the one I’m looking for.

I then build a definition file for RING and BUSY for all the country we are working with.

With a required magnitude of 95% and after I downloaded all the samples from the DB above, I’m able to detect all the busy tone.

Note: to clean the signal I'm using the average of the last 20 samples.

Note: I integrated this on a real time embedded platform. For this I start the detector inside a thread which take the PCM sample, not from the file like in this code, but from the PCM device.

Whenever a tone is found it call a callback to the main thread.

Below it’s a representation of the results in excel from a record on a real call. In orange it’s the Goertzel magnitude computed, in gray, it’s after I cleaned it and before pattern detection. The session is RING * 6 > DECLINE > BUSY *25

Below are the results

Israel_call_from_the_CP2.pcm

p=13 res=1 [Israel] [Ring tone] pat_size=1100 dur=11000.000 start=0.000 end=11.000

p=13 res=1 [Israel] [Ring tone] pat_size=1100 dur=11000.000 start=11.370 end=22.370

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=23.320 end=25.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=26.320 end=28.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=29.320 end=31.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=32.320 end=34.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=35.320 end=37.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=38.320 end=40.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=41.320 end=43.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=44.320 end=46.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=47.320 end=49.820

p=14 res=1 [Israel] [Busy tone] pat_size=250 dur=2500.000 start=50.320 end=52.820

How to build and run (on Linux here)

gcc detect.c -o detect -lm && rm -f detect.txt && ./detect > detect.csv

It will compute all the PCM samples from the directory "pcm8kMono16ble".

It outputs the results in the terminal and the goertzel + the signal after cleaning in a CSV file. You can import this in Excel.

Just keep one sample at the beginning.

Others

Ffmpeg tools on windows

Convert a wav to a wav 8000 Hz / Mono / 16 bits LE

"c:\Program Files\ffmpeg\bin\ffmpeg.exe" -i sample.wav -ar 8000 -ac 1 -acodec pcm_u8 sample8kMono.wav

Convert all the wav of a directory to PCM 8k Mono 16 bits LE

for %i in (../wav/*) do "c:\Program Files\ffmpeg\bin\ffmpeg.exe" -y > -i ../wav/%i -ar 8000 -ac 1 -f s16le -acodec pcm_s16le %~ni.pcm

Useful links

http://en.wikipedia.org/wiki/Goertzel_algorithm

https://www.embedded.com/the-goertzel-algorithm/

https://github.com/Harvie/Programs/blob/master/c/goertzel/goertzel.c

https://stackoverflow.com/questions/67556935/busy-tone-detection-in-audio-pcm-signal

tones_detector's People

Contributors

nonprenom avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.