From 226260b78d77f0f4a1dc8c60627a8d65af3537dd Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Fri, 22 Feb 2013 01:51:52 +0200 Subject: windows specific --- sound_detector/main.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'sound_detector/main.cpp') diff --git a/sound_detector/main.cpp b/sound_detector/main.cpp index 2e576c8..0c4b489 100644 --- a/sound_detector/main.cpp +++ b/sound_detector/main.cpp @@ -1,6 +1,8 @@ #ifndef WIN32 #include +#else +#include "wingetopt.h" #endif #include @@ -125,6 +127,40 @@ std::string time_str() char out_dir[1024] = {0}; + +/* + * + + +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 + + * + */ + void handle_data() { vorbis_params vparams; @@ -151,7 +187,7 @@ void handle_data() p += "/"; p += time_str(); p += ".ogg"; - file = fopen(p.c_str(), "wb"); + file = fopen(p.string().c_str(), "wb"); encode_start(vparams); encode_data(vparams); sound_detected = true; @@ -234,7 +270,12 @@ int main(int argc, char **argv) int opt = -1, device = -1; if(argc == 1) { + +#ifndef WIN32 printf("usage:\n%s -h -l -f -v -d -o -p -P -m -s -S \n\t-h\tthis help message\n\t-l\tdevice list\n\t-d\tdevice number from device list\n\t-o\toutput directory\n\t-f\tfork to bakground\n\t-v\tverbose\n\t-P\tpre capture seconds\n\t-p\tpost capture seconds\n\t-m\tminimum capture length\n\t-s\tsound level in float value 5,0%% default\n\t-S minimum sound level to stop recording in float value 5,0%% is default\n", argv[0]); +#else + printf("usage:\n%s -h -l -v -d -o -p -P -m -s -S \n\t-h\tthis help message\n\t-l\tdevice list\n\t-d\tdevice number from device list\n\t-o\toutput directory\n\t-v\tverbose\n\t-P\tpre capture seconds\n\t-p\tpost capture seconds\n\t-m\tminimum capture length\n\t-s\tsound level in float value 5,0%% default\n\t-S minimum sound level to stop recording in float value 5,0%% is default\n", argv[0]); +#endif return 1; } bool _fork = false; @@ -276,12 +317,18 @@ int main(int argc, char **argv) case 'd': device = atoi(optarg); break; +#ifdef WIN32 case 'f': _fork = true; break; +#endif case 'h': default: +#ifndef WIN32 printf("usage:\n%s -h -l -f -v -d -o -p -P -m -s -S \n\t-h\tthis help message\n\t-l\tdevice list\n\t-d\tdevice number from device list\n\t-o\toutput directory\n\t-f\tfork to bakground\n\t-v\tverbose\n\t-P\tpre capture seconds\n\t-p\tpost capture seconds\n\t-m\tminimum capture length\n\t-s\tsound level in float value 5,0%% default\n\t-S minimum sound level to stop recording in float value 5,0%% is default\n", argv[0]); +#else + printf("usage:\n%s -h -l -v -d -o -p -P -m -s -S \n\t-h\tthis help message\n\t-l\tdevice list\n\t-d\tdevice number from device list\n\t-o\toutput directory\n\t-v\tverbose\n\t-P\tpre capture seconds\n\t-p\tpost capture seconds\n\t-m\tminimum capture length\n\t-s\tsound level in float value 5,0%% default\n\t-S minimum sound level to stop recording in float value 5,0%% is default\n", argv[0]); +#endif break; }; } @@ -315,9 +362,12 @@ int main(int argc, char **argv) params.device = device; const PaDeviceInfo *info = Pa_GetDeviceInfo(device); params.suggestedLatency = info->defaultHighInputLatency; + if(debug) + printf("choosen device latency %f, choosen rate %f\n", info->defaultHighInputLatency, get_lowest_rate(¶ms)); err = Pa_OpenStream(&stream, ¶ms, NULL, get_lowest_rate(¶ms), paFramesPerBufferUnspecified, paNoFlag, stream_callback, NULL); if(err != paNoError) printf("PortAudio error: %s\n", Pa_GetErrorText(err)); +#ifndef WIN32 if(_fork) { pid_t pid = fork(); @@ -329,6 +379,7 @@ int main(int argc, char **argv) if(pid > 0) exit(EXIT_SUCCESS); } +#endif //debug //file = fopen("./data_dump", "wb"); @@ -336,7 +387,7 @@ int main(int argc, char **argv) new boost::thread(boost::bind(handle_data)); Pa_StartStream(stream); while(true) - sleep(1); + boost::this_thread::sleep(boost::posix_time::seconds(1)); err = Pa_Terminate(); if(err != paNoError) -- cgit v1.2.3