diff options
Diffstat (limited to 'sound_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  | 
