summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2018-01-02 12:26:02 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2018-01-02 12:26:02 +0300
commitcbc1ef0dc330ceaff4d208e600b9d94ceb3dcddb (patch)
treed9ab77b203c2d8263221295a93d906ef0976f821
parentdeac6d7a827d93e9ec68274b16f54a20d9eefb5e (diff)
started opus encoding implamantationsound_detector
-rw-r--r--sound_detector/Makefile2
-rw-r--r--sound_detector/main.cpp73
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(&params, 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(&params));
- err = Pa_OpenStream(&stream, &params, NULL, get_lowest_rate(&params), 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