summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-22 01:51:52 +0200
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-22 01:51:52 +0200
commit226260b78d77f0f4a1dc8c60627a8d65af3537dd (patch)
tree52fe5b01116aead725619da98f3b04b9a39ee97e
parentc09fb835986c7412119767449a976fa1e61f6b0d (diff)
windows specific
-rw-r--r--sound_detector/main.cpp55
-rw-r--r--sound_detector/wingetopt.c77
-rw-r--r--sound_detector/wingetopt.h28
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(&params));
err = Pa_OpenStream(&stream, &params, NULL, get_lowest_rate(&params), 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_ */
+