summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-20 04:56:24 +0200
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2013-02-20 04:56:24 +0200
commit5708be163744bec8f70ee6cff297b121a5783963 (patch)
tree6c0a86fe3116243ee1406632e69cae4c36fd8c56
parent9ccb9d74f3ff656b218e5d282d1657251349c1d7 (diff)
modified: main.cpp
modified: sound_detector.project
-rw-r--r--sound_detector/main.cpp212
-rw-r--r--sound_detector/sound_detector.project9
2 files changed, 131 insertions, 90 deletions
diff --git a/sound_detector/main.cpp b/sound_detector/main.cpp
index d35a261..9950b4d 100644
--- a/sound_detector/main.cpp
+++ b/sound_detector/main.cpp
@@ -16,28 +16,20 @@
//portaudio
#include <portaudio.h>
-//ffmpeg
-
-extern "C" {
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libswresample/swresample.h>
-}
-
+#include <vorbis/vorbisenc.h>
//boost
#include <boost/thread.hpp>
#include <boost/bind.hpp>
+#include <boost/date_time.hpp>
+#include <boost/filesystem.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;
+unsigned rate = 0;
bool sound_detected = false;
-//std::ofstream file;
FILE *file = NULL;
boost::mutex lock;
@@ -45,63 +37,99 @@ boost::mutex lock;
std::vector<int16_t> buffer;
+struct vorbis_params
+{
+ ogg_stream_state os;
+ ogg_page og;
+ ogg_packet op;
+ vorbis_info vi;
+ vorbis_comment vc;
+ vorbis_dsp_state vd;
+ vorbis_block vb;
+};
-
-void encode_start()
+void encode_start(vorbis_params &vparams)
{
- AVCodec *codec;
- AVCodecContext *c= NULL;
- avcodec_register_all();
- codec = avcodec_find_encoder(CODEC_ID_VORBIS);
- if (!codec)
+ vorbis_info_init(&(vparams.vi));
+ if(vorbis_encode_init_vbr(&(vparams.vi), 1, rate,.0))
+ printf("failed to init vorbis vbr");
+ if(vorbis_analysis_init(&(vparams.vd), &(vparams.vi)))
+ printf("failed to init vorbis analysis");
+ vorbis_comment_init(&(vparams.vc));
+ vorbis_comment_add_tag(&(vparams.vc), "ENCODER","sound_detector");
+ vorbis_block_init(&(vparams.vd), &(vparams.vb));
+ srand(time(NULL));
+ ogg_stream_init(&(vparams.os),rand());
+ ogg_packet header, header_comm, header_code;
+ vorbis_analysis_headerout(&(vparams.vd), &(vparams.vc), &header,&header_comm,&header_code);
+ ogg_stream_packetin(&(vparams.os),&header);
+ ogg_stream_packetin(&(vparams.os),&header_comm);
+ ogg_stream_packetin(&(vparams.os),&header_code);
+ int eos = 0;
+ while(!eos)
{
- fprintf(stderr, "codec not found\n");
- exit(1);
- }
- c= avcodec_alloc_context3(codec);
- c->channels = 1;
- c->bit_rate = 32000;
- c->sample_rate = 11025;
- c->sample_fmt = AV_SAMPLE_FMT_S16;
- if (avcodec_open2(c, codec, NULL) < 0)
- {
- fprintf(stderr, "could not open codec\n");
- exit(1);
+ int result = ogg_stream_flush(&(vparams.os),&(vparams.og));
+ if(result == 0)
+ break;
+ fwrite(vparams.og.header,1,vparams.og.header_len,file);
+ fwrite(vparams.og.body,1,vparams.og.body_len,file);
}
-
- AVPacket p;
- av_init_packet(&p);
- AVFrame *f = avcodec_alloc_frame();
-
- f->nb_samples = c->frame_size;
- union int_map
- {
- int16_t t16;
- uint8_t t8[2];
- };
- int_map tmp_buf[f->nb_samples /2];
- for(int i = 0; i < (f->nb_samples/2); i++)
- tmp_buf[i].t16 = buffer[i];
- uint8_t tmp_buf2[f->nb_samples];
- for(int i = 0, ii = 0; i < (f->nb_samples/2); i++)
+}
+
+void encode_data(vorbis_params &vparams)
+{
+ float **b = vorbis_analysis_buffer(&(vparams.vd), buffer.size());
+ for(size_t i = 0; i < buffer.size(); i++)
+ b[0][i] = (float)buffer[i]*3.0517578125e-5f;
+ vorbis_analysis_wrote(&(vparams.vd), buffer.size());
+ buffer.clear();
+ int eos = 0;
+ while(vorbis_analysis_blockout(&(vparams.vd), &(vparams.vb)) == 1)
{
- tmp_buf2[ii] = tmp_buf[i].t8[0];
- ii++;
- tmp_buf2[ii] = tmp_buf[i].t8[1];
- ii++;
+ vorbis_analysis(&(vparams.vb), NULL);
+ vorbis_bitrate_addblock(&(vparams.vb));
+ while(vorbis_bitrate_flushpacket(&(vparams.vd), &(vparams.op)))
+ {
+ ogg_stream_packetin(&(vparams.os),&(vparams.op));
+ while(!eos)
+ {
+ int result = ogg_stream_pageout(&(vparams.os), &(vparams.og));
+ if(result == 0)
+ break;
+ fwrite(vparams.og.header,1, vparams.og.header_len, file);
+ fwrite(vparams.og.body,1, vparams.og.body_len, file);
+ if(ogg_page_eos(&(vparams.og)))
+ eos = 1;
+ }
+ }
}
- f->data[0] = tmp_buf2;
- int got_packet = 0;
- avcodec_encode_audio2(c, &p, f, &got_packet);
}
+void encode_end(vorbis_params &vparams)
+{
+ vorbis_analysis_wrote(&(vparams.vd),0);
+ ogg_stream_clear(&(vparams.os));
+ vorbis_block_clear(&(vparams.vb));
+ vorbis_dsp_clear(&(vparams.vd));
+ vorbis_comment_clear(&(vparams.vc));
+ vorbis_info_clear(&(vparams.vi));
+}
+
+std::string time_str()
+{
+ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+ return boost::posix_time::to_simple_string(now);
+}
+
+char out_dir[1024] = {0};
+
void handle_data()
{
+ vorbis_params vparams;
while(true)
{
- encode_start();
boost::this_thread::sleep(boost::posix_time::seconds(1));
- printf("buffer contain %u, required %d\n", buffer.size(), rate*3);
+ //printf("buffer contain %u, required %d\n", buffer.size(), rate*3);
if(!sound_detected)
{
if(buffer.size() > rate * 3)
@@ -113,26 +141,21 @@ void handle_data()
if(buffer[i] > thresold)
noise++;
}
- printf("noise detected %d, noise required %d\n", noise, ((min_length * rate) / 10));
+ //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]);
- }
+ //printf("write started\n");
+ boost::filesystem::path p(out_dir);
+ p += "/";
+ p += time_str();
+ p += ".ogg";
+ file = fopen(p.c_str(), "wb");
+ encode_start(vparams);
+ encode_data(vparams);
sound_detected = true;
}
- buffer.clear();
+ else
+ buffer.clear();
lock.unlock();
}
}
@@ -144,26 +167,19 @@ void handle_data()
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();
+ encode_data(vparams);
+ //printf("silence detected %d, silence required %d\n", silence, (postcapture * rate));
lock.unlock();
if(silence > (rate * postcapture))
{
- printf("write stopped\n");
- //file.close();
+ //printf("write stopped\n");
fclose(file);
+ encode_end(vparams);
sound_detected = false;
}
}
@@ -214,13 +230,13 @@ int main(int argc, char **argv)
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]);
+ printf("usage:\n%s -h -l -d <dev number> -o <path> -f\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 background\n", argv[0]);
return 0;
}
- while((opt = getopt(argc, argv, "hld:o:")) != -1)
+ bool _fork = false;
+ while((opt = getopt(argc, argv, "hlfd:o:")) != -1)
{
switch(opt)
{
@@ -239,6 +255,9 @@ int main(int argc, char **argv)
case 'd':
device = atoi(optarg);
break;
+ case 'f':
+ _fork = true;
+ 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]);
@@ -255,6 +274,16 @@ int main(int argc, char **argv)
printf("ERROR: output directory is required\n");
return 1;
}
+ if(!boost::filesystem::exists(out_dir))
+ {
+ printf("ERROR: output directory does not exists\n");
+ return 1;
+ }
+ if(!boost::filesystem::is_directory(out_dir))
+ {
+ printf("ERROR: output directory is not directory %%) \n");
+ return 1;
+ }
PaStream *stream;
PaStreamParameters params;
memset(&params, 0, sizeof(PaStreamParameters));
@@ -266,6 +295,17 @@ int main(int argc, char **argv)
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));
+ if(_fork)
+ {
+ pid_t pid = fork();
+ if(pid < 0)
+ {
+ std::cerr<<"Failed to fork\n";
+ exit(EXIT_FAILURE);
+ }
+ if(pid > 0)
+ exit(EXIT_SUCCESS);
+ }
//debug
//file = fopen("./data_dump", "wb");
diff --git a/sound_detector/sound_detector.project b/sound_detector/sound_detector.project
index b14f4ac..9967e5c 100644
--- a/sound_detector/sound_detector.project
+++ b/sound_detector/sound_detector.project
@@ -26,11 +26,11 @@
</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"/>
+ <Library Value="boost_date_time"/>
+ <Library Value="boost_filesystem"/>
+ <Library Value="vorbisenc"/>
</Linker>
<ResourceCompiler Options="" Required="no"/>
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="-d4 -o." UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
@@ -72,7 +72,8 @@
<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[]]>
+ <![CDATA[
+ ]]>
</Environment>
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
<PostConnectCommands/>