diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-22 01:51:52 +0200 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-22 01:51:52 +0200 |
commit | 226260b78d77f0f4a1dc8c60627a8d65af3537dd (patch) | |
tree | 52fe5b01116aead725619da98f3b04b9a39ee97e | |
parent | c09fb835986c7412119767449a976fa1e61f6b0d (diff) |
windows specific
-rw-r--r-- | sound_detector/main.cpp | 55 | ||||
-rw-r--r-- | sound_detector/wingetopt.c | 77 | ||||
-rw-r--r-- | sound_detector/wingetopt.h | 28 |
3 files changed, 158 insertions, 2 deletions
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 <unistd.h> +#else +#include "wingetopt.h" #endif #include <cstdint> @@ -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 <dev number> -o <path> -p <sec> -P <sec> -m <sec> -s <float percents> -S <float percents>\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 <dev number> -o <path> -p <sec> -P <sec> -m <sec> -s <float percents> -S <float percents>\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 <dev number> -o <path> -p <sec> -P <sec> -m <sec> -s <float percents> -S <float percents>\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 <dev number> -o <path> -p <sec> -P <sec> -m <sec> -s <float percents> -S <float percents>\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) diff --git a/sound_detector/wingetopt.c b/sound_detector/wingetopt.c new file mode 100644 index 0000000..a2ce064 --- /dev/null +++ b/sound_detector/wingetopt.c @@ -0,0 +1,77 @@ +/* +POSIX getopt for Windows + +AT&T Public License + +Code given out at the 1985 UNIFORUM conference in Dallas. +*/ + +//#ifndef __GNUC__ + +#include "wingetopt.h" +#include <stdio.h> +#include <string.h> + +#define EOF (-1) +#define ERR(s, c) if(opterr){\ + char errbuf[2];\ + errbuf[0] = c; errbuf[1] = '\n';\ + fputs(argv[0], stderr);\ + fputs(s, stderr);\ + fputc(c, stderr);} + //(void) write(2, argv[0], (unsigned)strlen(argv[0]));\ + //(void) write(2, s, (unsigned)strlen(s));\ + //(void) write(2, errbuf, 2);} + +int opterr = 1; +int optind = 1; +int optopt; +char *optarg; + +int +getopt(argc, argv, opts) +int argc; +char **argv, *opts; +{ + static int sp = 1; + register int c; + register char *cp; + + if(sp == 1) + if(optind >= argc || + argv[optind][0] != '-' || argv[optind][1] == '\0') + return(EOF); + else if(strcmp(argv[optind], "--") == NULL) { + optind++; + return(EOF); + } + optopt = c = argv[optind][sp]; + if(c == ':' || (cp=strchr(opts, c)) == NULL) { + ERR(": illegal option -- ", c); + if(argv[optind][++sp] == '\0') { + optind++; + sp = 1; + } + return('?'); + } + if(*++cp == ':') { + if(argv[optind][sp+1] != '\0') + optarg = &argv[optind++][sp+1]; + else if(++optind >= argc) { + ERR(": option requires an argument -- ", c); + sp = 1; + return('?'); + } else + optarg = argv[optind++]; + sp = 1; + } else { + if(argv[optind][++sp] == '\0') { + sp = 1; + optind++; + } + optarg = NULL; + } + return(c); +} + +//#endif /* __GNUC__ */ diff --git a/sound_detector/wingetopt.h b/sound_detector/wingetopt.h new file mode 100644 index 0000000..b3969ad --- /dev/null +++ b/sound_detector/wingetopt.h @@ -0,0 +1,28 @@ +/* +POSIX getopt for Windows + +AT&T Public License + +Code given out at the 1985 UNIFORUM conference in Dallas. +*/ + + +#ifndef _WINGETOPT_H_ +#define _WINGETOPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int opterr; +extern int optind; +extern int optopt; +extern char *optarg; +extern int getopt(int argc, char **argv, char *opts); + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H_ */ + |