summaryrefslogtreecommitdiff
path: root/sound_detector/main.cpp
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 /sound_detector/main.cpp
parentc09fb835986c7412119767449a976fa1e61f6b0d (diff)
windows specific
Diffstat (limited to 'sound_detector/main.cpp')
-rw-r--r--sound_detector/main.cpp55
1 files changed, 53 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)