diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-20 04:56:24 +0200 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-20 04:56:24 +0200 |
commit | 5708be163744bec8f70ee6cff297b121a5783963 (patch) | |
tree | 6c0a86fe3116243ee1406632e69cae4c36fd8c56 /sound_detector/main.cpp | |
parent | 9ccb9d74f3ff656b218e5d282d1657251349c1d7 (diff) |
modified: main.cpp
modified: sound_detector.project
Diffstat (limited to 'sound_detector/main.cpp')
-rw-r--r-- | sound_detector/main.cpp | 212 |
1 files changed, 126 insertions, 86 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(¶ms, 0, sizeof(PaStreamParameters)); @@ -266,6 +295,17 @@ int main(int argc, char **argv) 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)); + 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"); |