-2

I have raw 16bit 48khz pcm data. I need to strip all data which is out of the range of human hearing.

For now I'm just doing a sum of all samples and then dividing by the sample count to calculate peak sound level, but I need to reduce false positives.

I have big peak level all the time, speaking and other sounds which I can hear increasing levels just a little, so I need to implement some filtering. I am not familiar with sound processing at all, so currently I am not using any filtering because I do not understand how to create it. My current code looks like this:

for(size_t i = 0; i < buffer.size(); i++)
level += abs(buffer[i]);
level /= buffer.size();

How can I implement this kind of filtering using C++?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
sss123next
  • 295
  • 1
  • 3
  • 13
  • "out of human hearing"? What is it? – Roman R. Feb 21 '13 at 17:16
  • sounds which humans does not hearing, sorry for my bad english, it's not my primary language – sss123next Feb 21 '13 at 17:20
  • 1
    1) What are you really trying to do? 2) There are sounds some people can hear but others can't, so you need to be more specific. 3) The code you show does not calculate peak level - it calculates mean (average) level. 4) Why filter out sounds that can't be heard anyway? It won't reduce the amount of data or anything (although it may improve compressibility, or avoid aliasing and other issues with further processing. Again, being more specific about what you want to do would be helpful). – twalberg Feb 21 '13 at 17:23
  • 1
    You should start with some book on digital audio, your current code does not make much sense - to start with. With zero background a book is way better source of information than Q&A format. – Roman R. Feb 21 '13 at 17:25
  • Your raw data probably doesn't contain much (if anything) that a person with good hearing can't hear. The typically-quoted range of human hearing is 20Hz to 20 KHz. In theory 48KHz sampling allows up to 24 KHz to be recorded, but the faster sampling mostly just simplifies design of the anti-aliasing filter. – Jerry Coffin Feb 21 '13 at 17:44
  • yes, i know nothing about sound currently, i want to write small program which will write sound files when some sounds exists in room, some kind of monitoring system, i write most of it without any problems, but sound is problem because i do not understanding it currently., code above detect speech e.t.c but most of time i see big sound level, so idea is to strip out all what i can't hear and keep average lower – sss123next Feb 21 '13 at 17:47
  • Given that this question has good answers, I'll let it stay open, but next time just edit your original question with follow-on details like you have here. – Brad Larson Feb 22 '13 at 03:17

2 Answers2

1

Use a band pass filter.

A band-pass filter is a device that passes frequencies within a certain range and rejects (attenuates) frequencies outside that range.

This sounds like exactly the sort of filter you are looking for.

I had a quick google search and found this thread that discusses implementation in C++.

1

It sounds like you want to do something (maybe start recording) if the sound level goes above a certain threshold. This is sometimes called a "gate". It also sounds like you are having trouble with false positives. This is sometimes handled with a "side-chain" applied to the gate.

The general principle of a gate is create an envelope of your signal, and then monitor the envelope to discover when it goes above a certain threshold. If it is above the threshold, your gate is "on", if not, your gate is "off". If you treat your signal before creating the envelope in some way to make it more or less sensitive to various parts of your signal/noise the treatment is called a "side-chain".

You will have to discover the details on your own because there is too much for a Q&A website, but maybe this is enough of a start:

float[] buffer; //defined elsewhere
float HOLD = .9999 ; //there are precise ways to compute this, but experimentation might work fine
float THRESH = .7 ; //or whatever
float env = 0; //we initialize to 0, but in real code be sure to save this between runs
for(size_t i = 0; i < buffer.size(); i++) {
     // side-chain, if used, goes here
     float b = buffer[i];
     // create envelope:
     float tmp = abs(b); // you could also do buffer[i] * buffer[i]
     env = env * HOLD + tmp * (1-HOLD);
     // threshold detection
     if( env > THRESH ) {
        //gate is "on"
     } else {
        //gate is "off"
     }
}

The side-chain might consist of filters like an eq. Here is a tutorial on designing audio eq: http://blog.bjornroche.com/2012/08/basic-audio-eqs.html

Bjorn Roche
  • 11,279
  • 6
  • 36
  • 58
  • thx, very useful, currently i writing this http://sss.chaoslab.ru/git/?p=misc.git;a=blob;f=sound_detector/main.cpp;h=2e576c8dc3566338089bc1ca2ecfc43a83679aaf;hb=c09fb835986c7412119767449a976fa1e61f6b0d, it working, but have false positives, i will try what you proposing – sss123next Feb 21 '13 at 19:13