diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2018-01-02 12:26:02 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2018-01-02 12:26:02 +0300 |
commit | cbc1ef0dc330ceaff4d208e600b9d94ceb3dcddb (patch) | |
tree | d9ab77b203c2d8263221295a93d906ef0976f821 | |
parent | deac6d7a827d93e9ec68274b16f54a20d9eefb5e (diff) |
started opus encoding implamantationsound_detector
-rw-r--r-- | sound_detector/Makefile | 2 | ||||
-rw-r--r-- | sound_detector/main.cpp | 73 |
2 files changed, 52 insertions, 23 deletions
diff --git a/sound_detector/Makefile b/sound_detector/Makefile index c38b514..dc0049b 100644 --- a/sound_detector/Makefile +++ b/sound_detector/Makefile @@ -1,6 +1,6 @@ all: g++ -c main.cpp -std=gnu++11 -o main.o - g++ -o sound_detector main.o -lboost_system -lboost_date_time -lboost_thread -lboost_random-mt -lboost_filesystem -lportaudio -lvorbis -lvorbisenc -logg -Wl,-O1 -s + g++ -o sound_detector main.o -lboost_system -lboost_date_time -lboost_thread -lboost_random-mt -lboost_filesystem -lportaudio -lvorbis -lvorbisenc -logg -lopus -Wl,-O1 -s clean: rm *.o diff --git a/sound_detector/main.cpp b/sound_detector/main.cpp index 6bffcb6..e212d7d 100644 --- a/sound_detector/main.cpp +++ b/sound_detector/main.cpp @@ -32,7 +32,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -//#include <complex.h> //c++ #include <limits> @@ -43,7 +42,12 @@ //portaudio #include <portaudio.h> +//vorbis #include <vorbis/vorbisenc.h> + +//opus +#include <opus/opus.h> + //boost #include <boost/thread.hpp> #include <boost/bind.hpp> @@ -68,6 +72,14 @@ boost::mutex lock; std::vector<int16_t> buffer; +struct detector_params +{ + std::string out_dir; + double sample_rate; +}; + +detector_params sd_params; + struct vorbis_params { ogg_stream_state os; @@ -79,7 +91,7 @@ struct vorbis_params vorbis_block vb; }; -void encode_start(vorbis_params &vparams) +void vorbis_encode_start(vorbis_params &vparams) { vorbis_info_init(&(vparams.vi)); if(vorbis_encode_init_vbr(&(vparams.vi), 1, rate,.0)) @@ -107,7 +119,7 @@ void encode_start(vorbis_params &vparams) } } -void encode_data(vorbis_params &vparams) +void vorbis_encode_data(vorbis_params &vparams) { float **b = vorbis_analysis_buffer(&(vparams.vd), buffer.size()); for(size_t i = 0; i < buffer.size(); i++) @@ -136,7 +148,7 @@ void encode_data(vorbis_params &vparams) } } -void encode_end(vorbis_params &vparams) +void vorbis_encode_end(vorbis_params &vparams) { vorbis_analysis_wrote(&(vparams.vd),0); ogg_stream_clear(&(vparams.os)); @@ -146,6 +158,23 @@ void encode_end(vorbis_params &vparams) vorbis_info_clear(&(vparams.vi)); } +struct opus_params +{ + OpusEncoder *encoder; +}; + +void opus_encode_start(opus_params &op) +{ + if(op.encoder) + free(op.encoder); + int encoder_error = 0; + op.encoder = opus_encoder_create(sd_params.sample_rate, 1, OPUS_APPLICATION_AUDIO, &encoder_error); + opus_encoder_ctl(op.encoder, OPUS_SET_BITRATE(24000)); + opus_encoder_ctl(op.encoder, OPUS_SET_COMPLEXITY(10)); + opus_encoder_ctl(op.encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + +} + std::string time_str() { boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); @@ -156,7 +185,6 @@ std::string time_str() #endif } -std::string out_dir; void handle_data() @@ -182,13 +210,13 @@ void handle_data() { if(debug) printf("write started\n"); - boost::filesystem::path p(out_dir); + boost::filesystem::path p(sd_params.out_dir); p += "/"; p += time_str(); p += ".ogg"; file = fopen(p.string().c_str(), "wb"); - encode_start(vparams); - encode_data(vparams); + vorbis_encode_start(vparams); + vorbis_encode_data(vparams); sound_detected = true; } else @@ -207,7 +235,7 @@ void handle_data() for(size_t i = 0; i < buffer.size(); i++) level += abs(buffer[i]); level /= buffer.size(); - encode_data(vparams); + vorbis_encode_data(vparams); if(debug) printf("level detected %f, level lower than %f required to stop\n", ((float)level/(float)INT16_MAX)*100, stop_thresold_percent); lock.unlock(); @@ -216,7 +244,7 @@ void handle_data() if(debug) printf("write stopped\n"); fclose(file); - encode_end(vparams); + vorbis_encode_end(vparams); sound_detected = false; } } @@ -323,7 +351,7 @@ int main(int argc, char **argv) stop_thresold_percent = strtof(optarg, NULL); break; case 'o': - out_dir = optarg; + sd_params.out_dir = optarg; break; case 'd': device = atoi(optarg); @@ -348,17 +376,17 @@ int main(int argc, char **argv) printf("ERROR: device number is required\n"); return 1; } - if(out_dir.empty()) + if(sd_params.out_dir.empty()) { printf("ERROR: output directory is required\n"); return 1; } - if(!boost::filesystem::exists(out_dir)) + if(!boost::filesystem::exists(sd_params.out_dir)) { printf("ERROR: output directory does not exists\n"); return 1; } - if(!boost::filesystem::is_directory(out_dir)) + if(!boost::filesystem::is_directory(sd_params.out_dir)) { printf("ERROR: output directory is not directory %%) \n"); return 1; @@ -366,16 +394,17 @@ int main(int argc, char **argv) thresold = (int)(((float)INT16_MAX/100.0)*thresold_percent); stop_thresold = (int)(((float)INT16_MAX/100.0)*stop_thresold_percent); PaStream *stream; - PaStreamParameters params; - memset(¶ms, 0, sizeof(PaStreamParameters)); - params.channelCount = 1; - params.sampleFormat = paInt16 | paNonInterleaved; - params.device = device; + PaStreamParameters pa_params; + memset(&pa_params, 0, sizeof(PaStreamParameters)); + pa_params.channelCount = 1; + pa_params.sampleFormat = paInt16 | paNonInterleaved; + pa_params.device = device; const PaDeviceInfo *info = Pa_GetDeviceInfo(device); - params.suggestedLatency = info->defaultHighInputLatency; + pa_params.suggestedLatency = info->defaultHighInputLatency; + sd_params.sample_rate = get_lowest_rate(&pa_params); if(debug) - printf("choosen device latency %f, choosen rate %f\n", info->defaultHighInputLatency, get_lowest_rate(¶ms)); - err = Pa_OpenStream(&stream, ¶ms, NULL, get_lowest_rate(¶ms), paFramesPerBufferUnspecified, paClipOff, stream_callback, NULL); + printf("choosen device latency %f, choosen rate %f\n", info->defaultHighInputLatency, sd_params.sample_rate); + err = Pa_OpenStream(&stream, &pa_params, NULL, sd_params.sample_rate, paFramesPerBufferUnspecified, paClipOff, stream_callback, NULL); if(err != paNoError) printf("PortAudio error: %s\n", Pa_GetErrorText(err)); #ifndef WIN32 |