summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-18 23:48:36 +0200
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-18 23:48:36 +0200
commit908fc2b63dca73ba642bacaf8bb7a038b8df3880 (patch)
tree2b93e1030cb26325cdda2d732688e4ab3136d75c
parent3ab3d03b8b603f210d878d352b56442eec14f6af (diff)
sound detector (like "motion")
-rw-r--r--sound_detector/main.cpp235
-rw-r--r--sound_detector/sound_detector.project105
2 files changed, 340 insertions, 0 deletions
diff --git a/sound_detector/main.cpp b/sound_detector/main.cpp
new file mode 100644
index 0000000..068964c
--- /dev/null
+++ b/sound_detector/main.cpp
@@ -0,0 +1,235 @@
+
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#include <cstdint>
+
+//c
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+//c++
+#include <vector>
+#include <fstream>
+
+//portaudio
+#include <portaudio.h>
+
+//ffmpeg
+
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libswresample/swresample.h>
+
+//boost
+#include <boost/thread.hpp>
+#include <boost/bind.hpp>
+
+//FILE *file = NULL;
+//int max_len = 1024*1024*32, len = 0;
+
+
+const unsigned int pecapture = 3, postcapture = 7, min_length = 1, thresold_percent = 5;
+unsigned rate = 0, current_file = 0;
+
+bool sound_detected = false;
+
+//std::ofstream file;
+FILE *file = NULL;
+
+boost::mutex lock;
+
+
+std::vector<int16_t> buffer;
+
+
+
+
+void handle_data()
+{
+ while(true)
+ {
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ printf("buffer contain %u, required %d\n", buffer.size(), rate*3);
+ if(!sound_detected)
+ {
+ if(buffer.size() > rate * 3)
+ {
+ int thresold = (int)((float)INT16_MAX/100.0*(float)thresold_percent), noise = 0;
+ lock.lock();
+ for(size_t i = 0; i < buffer.size(); i++)
+ {
+ if(buffer[i] > thresold)
+ noise++;
+ }
+ printf("noise detected %d, noise required %d\n", noise, ((min_length * rate) / 10));
+ if(noise > ((min_length * rate) /10)) //need to do some research
+ {
+ printf("write started\n");
+ char filename[128];
+ snprintf(filename, 127, "./file%d.pcm", current_file);
+ //file.open(filename);
+ file = fopen(filename, "wb");
+ ++current_file;
+ for(size_t i = 0; i < buffer.size(); i++)
+ {
+ fwrite(&buffer[i], sizeof(int16_t), 1, file);
+/* const char *test = reinterpret_cast<char*>(&buffer[i]);
+ file.write(test, sizeof(test)); */
+// file.put((char)buffer[i]<<8);
+// file.put((char)buffer[i]);
+ }
+ sound_detected = true;
+ }
+ buffer.clear();
+ lock.unlock();
+ }
+ }
+ else
+ {
+ if(buffer.size() > (rate * ((postcapture > 3)?postcapture:3)))
+ {
+ int thresold = (int)((float)INT16_MAX/100.0*(float)thresold_percent), silence = 0;
+ lock.lock();
+ for(size_t i = 0; i < buffer.size(); i++)
+ {
+ //file.put(buffer[i]);
+ //file<<buffer[i];
+ fwrite(&buffer[i], sizeof(int16_t), 1, file);
+/* const char *test = reinterpret_cast<char*>(&buffer[i]);
+ file.write(test, sizeof(test)); */
+// file.put((char)buffer[i]<<8);
+// file.put((char)buffer[i]);
+ if(buffer[i] < thresold)
+ silence++;
+ else
+ silence = 0;
+ }
+ printf("silence detected %d, silence required %d\n", silence, (postcapture * rate));
+ buffer.clear();
+ lock.unlock();
+ if(silence > (rate * postcapture))
+ {
+ printf("write stopped\n");
+ //file.close();
+ fclose(file);
+ sound_detected = false;
+ }
+ }
+ }
+ }
+}
+
+
+int stream_callback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
+{
+ int16_t *buf = (int16_t*)input;
+ lock.lock();
+ buffer.insert(buffer.end(), buf, buf + frameCount);
+ lock.unlock();
+ //debug
+/* for(unsigned long i = 0; i < frameCount; i++)
+ {
+ if(buf[i] > (int)((float)INT16_MAX/100.0*(float)thresold_percent))
+ printf("%d ", buf[i]);
+ } */
+ return paContinue;
+ //debug end
+}
+
+double get_lowest_rate(const PaStreamParameters *inputParameters)
+{
+ static double standardSampleRates[] = {
+ 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
+ 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated list */
+ };
+ for(int i=0; standardSampleRates[i] > 0; i++)
+ {
+ if(Pa_IsFormatSupported(inputParameters, NULL, standardSampleRates[i]) == paFormatIsSupported)
+ {
+ rate = standardSampleRates[i];
+ return rate;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ PaError err = Pa_Initialize();
+ if(err != paNoError)
+ {
+ printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+ return 1;
+ }
+ int opt = -1, device = -1;
+ char out_dir[1024] = {0};
+ if(argc == 1)
+ {
+ printf("usage:\n%s -h -l -d <dev number> -o <path>\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", argv[0]);
+ return 0;
+ }
+ while((opt = getopt(argc, argv, "hld:o:")) != -1)
+ {
+ switch(opt)
+ {
+ break;
+ case 'l':
+ for(PaDeviceIndex i =0, end = Pa_GetDeviceCount(); i < end; i++)
+ {
+ const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
+ printf("%d. %s, input channels %d, output channels %d, default sample rate %f, lowest input latency %f, highest input latency %f\n",
+ i, info->name, info->maxInputChannels, info->maxOutputChannels, info->defaultSampleRate, info->defaultLowInputLatency, info->defaultHighInputLatency);
+ }
+ break;
+ case 'o':
+ strcpy(out_dir, optarg);
+ break;
+ case 'd':
+ device = atoi(optarg);
+ break;
+ case 'h':
+ default:
+ printf("usage:\n%s -h -l -d <dev number> -o <path>\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", argv[0]);
+ break;
+ };
+ }
+ if(device == -1)
+ {
+ printf("ERROR: device number is required\n");
+ return 1;
+ }
+ if(!out_dir[0])
+ {
+ printf("ERROR: output directory is required\n");
+ return 1;
+ }
+ PaStream *stream;
+ PaStreamParameters params;
+ memset(&params, 0, sizeof(PaStreamParameters));
+ params.channelCount = 1;
+ params.sampleFormat = paInt16;
+ params.device = device;
+ const PaDeviceInfo *info = Pa_GetDeviceInfo(device);
+ params.suggestedLatency = info->defaultHighInputLatency;
+ 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));
+//debug
+ //file = fopen("./data_dump", "wb");
+
+//end debug
+ new boost::thread(boost::bind(handle_data));
+ Pa_StartStream(stream);
+ while(true)
+ sleep(1);
+
+ err = Pa_Terminate();
+ if(err != paNoError)
+ {
+ printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+ return 1;
+ }
+ return 0;
+}
diff --git a/sound_detector/sound_detector.project b/sound_detector/sound_detector.project
new file mode 100644
index 0000000..b14f4ac
--- /dev/null
+++ b/sound_detector/sound_detector.project
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CodeLite_Project Name="sound_detector" InternalType="Console">
+ <Plugins>
+ <Plugin Name="qmake">
+ <![CDATA[00010001N0005Debug000000000000]]>
+ </Plugin>
+ </Plugins>
+ <Description/>
+ <Dependencies/>
+ <VirtualDirectory Name="src">
+ <File Name="main.cpp"/>
+ </VirtualDirectory>
+ <Settings Type="Executable">
+ <GlobalSettings>
+ <Compiler Options="" C_Options="">
+ <IncludePath Value="."/>
+ </Compiler>
+ <Linker Options="">
+ <LibraryPath Value="."/>
+ </Linker>
+ <ResourceCompiler Options=""/>
+ </GlobalSettings>
+ <Configuration Name="Debug" CompilerType="gnu g++" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
+ <Compiler Options="-g;-Wall;-O0;-std=gnu++0x" C_Options="-g;-Wall;-O0;-std=gnu99" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" UseDifferentPCHFlags="no" PCHFlags="">
+ <IncludePath Value="."/>
+ </Compiler>
+ <Linker Options="" Required="yes">
+ <Library Value="portaudio"/>
+ <Library Value="avcodec"/>
+ <Library Value="avformat"/>
+ <Library Value="swresample"/>
+ <Library Value="boost_thread"/>
+ <Library Value="boost_system"/>
+ </Linker>
+ <ResourceCompiler Options="" Required="no"/>
+ <General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="-d4 -o." UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
+ <Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
+ <![CDATA[]]>
+ </Environment>
+ <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
+ <PostConnectCommands/>
+ <StartupCommands/>
+ </Debugger>
+ <PreBuild/>
+ <PostBuild/>
+ <CustomBuild Enabled="no">
+ <RebuildCommand/>
+ <CleanCommand/>
+ <BuildCommand/>
+ <PreprocessFileCommand/>
+ <SingleFileCommand/>
+ <MakefileGenerationCommand/>
+ <ThirdPartyToolName>None</ThirdPartyToolName>
+ <WorkingDirectory/>
+ </CustomBuild>
+ <AdditionalRules>
+ <CustomPostBuild/>
+ <CustomPreBuild/>
+ </AdditionalRules>
+ <Completion EnableCpp11="no">
+ <ClangCmpFlagsC/>
+ <ClangCmpFlags/>
+ <ClangPP/>
+ <SearchPaths/>
+ </Completion>
+ </Configuration>
+ <Configuration Name="Release" CompilerType="gnu g++" DebuggerType="GNU gdb debugger" Type="" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
+ <Compiler Options="-O2;-Wall" C_Options="-O2;-Wall" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" UseDifferentPCHFlags="no" PCHFlags="">
+ <IncludePath Value="."/>
+ </Compiler>
+ <Linker Options="" Required="yes"/>
+ <ResourceCompiler Options="" Required="no"/>
+ <General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Release" Command="./$(ProjectName)" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
+ <Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
+ <![CDATA[]]>
+ </Environment>
+ <Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
+ <PostConnectCommands/>
+ <StartupCommands/>
+ </Debugger>
+ <PreBuild/>
+ <PostBuild/>
+ <CustomBuild Enabled="no">
+ <RebuildCommand/>
+ <CleanCommand/>
+ <BuildCommand/>
+ <PreprocessFileCommand/>
+ <SingleFileCommand/>
+ <MakefileGenerationCommand/>
+ <ThirdPartyToolName>None</ThirdPartyToolName>
+ <WorkingDirectory/>
+ </CustomBuild>
+ <AdditionalRules>
+ <CustomPostBuild/>
+ <CustomPreBuild/>
+ </AdditionalRules>
+ <Completion EnableCpp11="no">
+ <ClangCmpFlagsC/>
+ <ClangCmpFlags/>
+ <ClangPP/>
+ <SearchPaths/>
+ </Completion>
+ </Configuration>
+ </Settings>
+</CodeLite_Project>