diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-04-11 02:07:54 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-04-11 02:07:54 +0200 |
commit | b2d88a4544a81a217db18b60d91a44d85821db3d (patch) | |
tree | 29eb1dc55848187b78e91cdb8dc59f6cf2ef89c2 /toxav | |
parent | 4fa31d14cf53dd54b182508df31b5524b1f24cb6 (diff) |
Random fixes
Diffstat (limited to 'toxav')
-rw-r--r-- | toxav/av_test.c | 174 | ||||
-rw-r--r-- | toxav/codec.c | 78 | ||||
-rw-r--r-- | toxav/codec.h | 3 | ||||
-rw-r--r-- | toxav/toxav.c | 14 |
4 files changed, 132 insertions, 137 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c index 007a1a10..dab1f6ef 100644 --- a/toxav/av_test.c +++ b/toxav/av_test.c | |||
@@ -1,14 +1,12 @@ | |||
1 | #include "../toxav/toxav.h" | 1 | #include "../toxav/toxav.h" |
2 | #include "../toxcore/tox.h" | 2 | #include "../toxcore/tox.h" |
3 | 3 | ||
4 | /* For playing audio data */ | 4 | /* Playing audio data */ |
5 | #include <AL/al.h> | 5 | #include <portaudio.h> |
6 | #include <AL/alc.h> | 6 | /* Reading audio */ |
7 | |||
8 | /* Processing wav's */ | ||
9 | #include <sndfile.h> | 7 | #include <sndfile.h> |
10 | 8 | ||
11 | /* For reading and displaying video data */ | 9 | /* Reading and Displaying video data */ |
12 | #include <opencv/cv.h> | 10 | #include <opencv/cv.h> |
13 | #include <opencv/highgui.h> | 11 | #include <opencv/highgui.h> |
14 | #include <opencv/cvwimage.h> | 12 | #include <opencv/cvwimage.h> |
@@ -23,7 +21,6 @@ | |||
23 | #include <errno.h> | 21 | #include <errno.h> |
24 | #include <unistd.h> | 22 | #include <unistd.h> |
25 | 23 | ||
26 | |||
27 | #define c_sleep(x) usleep(1000*x) | 24 | #define c_sleep(x) usleep(1000*x) |
28 | 25 | ||
29 | 26 | ||
@@ -67,7 +64,7 @@ struct toxav_thread_data { | |||
67 | }; | 64 | }; |
68 | 65 | ||
69 | const char* vdout = "AV Test"; | 66 | const char* vdout = "AV Test"; |
70 | uint32_t adout; | 67 | PaStream* adout = NULL; |
71 | 68 | ||
72 | const char* stringify_state(TOXAV_CALL_STATE s) | 69 | const char* stringify_state(TOXAV_CALL_STATE s) |
73 | { | 70 | { |
@@ -137,34 +134,7 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, | |||
137 | uint32_t sampling_rate, | 134 | uint32_t sampling_rate, |
138 | void *user_data) | 135 | void *user_data) |
139 | { | 136 | { |
140 | uint32_t bufid; | 137 | Pa_WriteStream(adout, pcm, sample_count/channels); |
141 | int32_t processed = 0, queued = 16; | ||
142 | alGetSourcei(adout, AL_BUFFERS_PROCESSED, &processed); | ||
143 | alGetSourcei(adout, AL_BUFFERS_QUEUED, &queued); | ||
144 | |||
145 | if(processed) { | ||
146 | uint32_t bufids[processed]; | ||
147 | alSourceUnqueueBuffers(adout, processed, bufids); | ||
148 | alDeleteBuffers(processed - 1, bufids + 1); | ||
149 | bufid = bufids[0]; | ||
150 | } | ||
151 | // else if(queued < 16) { | ||
152 | alGenBuffers(1, &bufid); | ||
153 | // } | ||
154 | // else | ||
155 | // return; | ||
156 | |||
157 | |||
158 | alBufferData(bufid, channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, | ||
159 | pcm, sample_count * 2 * channels, sampling_rate); | ||
160 | alSourceQueueBuffers(adout, 1, &bufid); | ||
161 | |||
162 | int32_t state; | ||
163 | alGetSourcei(adout, AL_SOURCE_STATE, &state); | ||
164 | if(state != AL_PLAYING) { | ||
165 | printf("Here\n"); | ||
166 | alSourcePlay(adout); | ||
167 | } | ||
168 | } | 138 | } |
169 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) | 139 | void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) |
170 | { | 140 | { |
@@ -260,10 +230,8 @@ void* iterate_toxav (void * data) | |||
260 | toxav_iterate(data_cast->BobAV); | 230 | toxav_iterate(data_cast->BobAV); |
261 | int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); | 231 | int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); |
262 | 232 | ||
263 | printf("\rToxAV interval: %d ", rc); | ||
264 | fflush(stdout); | ||
265 | // cvWaitKey(rc); | 233 | // cvWaitKey(rc); |
266 | c_sleep(rc/2); | 234 | c_sleep(10); |
267 | } | 235 | } |
268 | 236 | ||
269 | data_cast->sig = 1; | 237 | data_cast->sig = 1; |
@@ -309,36 +277,13 @@ int send_opencv_img(ToxAV* av, uint32_t friend_number, const IplImage* img) | |||
309 | return rc; | 277 | return rc; |
310 | } | 278 | } |
311 | 279 | ||
312 | ALCdevice* open_audio_device(const char* audio_out_dev_name) | ||
313 | { | ||
314 | ALCdevice* rc; | ||
315 | rc = alcOpenDevice(audio_out_dev_name); | ||
316 | if ( !rc ) { | ||
317 | printf("Failed to open playback device: %s: %d\n", audio_out_dev_name, alGetError()); | ||
318 | exit(1); | ||
319 | } | ||
320 | |||
321 | ALCcontext* out_ctx = alcCreateContext(rc, NULL); | ||
322 | alcMakeContextCurrent(out_ctx); | ||
323 | |||
324 | alGenSources((uint32_t)1, &adout); | ||
325 | alSourcei(adout, AL_LOOPING, AL_FALSE); | ||
326 | alSourcePlay(adout); | ||
327 | |||
328 | return rc; | ||
329 | } | ||
330 | |||
331 | int print_audio_devices() | 280 | int print_audio_devices() |
332 | { | 281 | { |
333 | const char *device; | ||
334 | |||
335 | printf("Default output device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER)); | ||
336 | printf("Output devices:\n"); | ||
337 | |||
338 | int i = 0; | 282 | int i = 0; |
339 | for(device = alcGetString(NULL, ALC_DEVICE_SPECIFIER); *device; | 283 | for (i = 0; i < Pa_GetDeviceCount(); ++i) { |
340 | device += strlen( device ) + 1, ++i) { | 284 | const PaDeviceInfo* info = Pa_GetDeviceInfo(i); |
341 | printf("%d) %s\n", i, device); | 285 | if (info) |
286 | printf("%d) %s\n", i, info->name); | ||
342 | } | 287 | } |
343 | 288 | ||
344 | return 0; | 289 | return 0; |
@@ -361,12 +306,13 @@ int print_help (const char* name) | |||
361 | 306 | ||
362 | int main (int argc, char** argv) | 307 | int main (int argc, char** argv) |
363 | { | 308 | { |
309 | Pa_Initialize(); | ||
364 | struct stat st; | 310 | struct stat st; |
365 | 311 | ||
366 | /* AV files for testing */ | 312 | /* AV files for testing */ |
367 | const char* af_name = NULL; | 313 | const char* af_name = NULL; |
368 | const char* vf_name = NULL; | 314 | const char* vf_name = NULL; |
369 | long audio_out_dev_idx = 0; | 315 | long audio_out_dev_idx = -1; |
370 | 316 | ||
371 | int32_t audio_frame_duration = 20; | 317 | int32_t audio_frame_duration = 20; |
372 | int32_t video_frame_duration = 10; | 318 | int32_t video_frame_duration = 10; |
@@ -440,52 +386,66 @@ int main (int argc, char** argv) | |||
440 | } | 386 | } |
441 | } | 387 | } |
442 | 388 | ||
443 | const char* audio_out_dev_name = NULL; | 389 | if (audio_out_dev_idx < 0) |
390 | audio_out_dev_idx = Pa_GetDefaultOutputDevice(); | ||
444 | 391 | ||
445 | int i = 0; | 392 | const PaDeviceInfo* audio_dev = Pa_GetDeviceInfo(audio_out_dev_idx); |
446 | for(audio_out_dev_name = alcGetString(NULL, ALC_DEVICE_SPECIFIER); i < audio_out_dev_idx; | 393 | if (!audio_dev) { |
447 | audio_out_dev_name += strlen( audio_out_dev_name ) + 1, ++i) | 394 | fprintf(stderr, "Device under index: %ld invalid", audio_out_dev_idx); |
448 | if (!(audio_out_dev_name + strlen( audio_out_dev_name ) + 1)) | 395 | return 1; |
449 | break; | 396 | } |
450 | |||
451 | printf("Using audio device: %s\n", audio_out_dev_name); | ||
452 | printf("Using audio file: %s\n", af_name); | ||
453 | printf("Using video file: %s\n", vf_name); | ||
454 | 397 | ||
455 | if (0) { | 398 | if (0) { |
456 | /* Open audio file */ | 399 | SNDFILE* af_handle; |
457 | SF_INFO af_info; | 400 | SF_INFO af_info; |
458 | SNDFILE* af_handle = sf_open(af_name, SFM_READ, &af_info); | 401 | |
459 | if (af_handle == NULL) | 402 | /* Open audio file */ |
460 | { | 403 | af_handle = sf_open(af_name, SFM_READ, &af_info); |
404 | if (af_handle == NULL) { | ||
461 | printf("Failed to open the file.\n"); | 405 | printf("Failed to open the file.\n"); |
462 | exit(1); | 406 | exit(1); |
463 | } | 407 | } |
464 | ALCdevice* audio_out_device = open_audio_device(audio_out_dev_name); | ||
465 | 408 | ||
409 | int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; | ||
466 | 410 | ||
467 | int16_t PCM[5760]; | 411 | struct PaStreamParameters output; |
412 | output.device = audio_out_dev_idx; /* default output device */ | ||
413 | output.channelCount = af_info.channels; | ||
414 | output.sampleFormat = paInt16; | ||
415 | output.suggestedLatency = audio_dev->defaultHighOutputLatency; | ||
416 | output.hostApiSpecificStreamInfo = NULL; | ||
417 | |||
418 | |||
419 | PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL); | ||
420 | assert(err == paNoError); | ||
421 | |||
422 | err = Pa_StartStream(adout); | ||
423 | assert(err == paNoError); | ||
424 | |||
425 | int16_t PCM[frame_size]; | ||
468 | 426 | ||
469 | time_t start_time = time(NULL); | 427 | time_t start_time = time(NULL); |
470 | time_t expected_time = af_info.frames / af_info.samplerate + 2; | 428 | time_t expected_time = af_info.frames / af_info.samplerate + 2; |
471 | 429 | ||
472 | printf("Sample rate %d\n", af_info.samplerate); | 430 | printf("Sample rate %d\n", af_info.samplerate); |
473 | while ( start_time + expected_time > time(NULL) ) { | 431 | while ( start_time + expected_time > time(NULL) ) { |
474 | int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; | ||
475 | 432 | ||
476 | int64_t count = sf_read_short(af_handle, PCM, frame_size); | 433 | int64_t count = sf_read_short(af_handle, PCM, frame_size); |
477 | if (count > 0) | 434 | if (count > 0) { |
478 | t_toxav_receive_audio_frame_cb(NULL, 0, PCM, count, af_info.channels, af_info.samplerate, NULL); | 435 | t_toxav_receive_audio_frame_cb(NULL, 0, PCM, count, af_info.channels, af_info.samplerate, NULL); |
479 | c_sleep(audio_frame_duration); | 436 | } |
437 | |||
438 | c_sleep(audio_frame_duration / 2); | ||
480 | } | 439 | } |
481 | |||
482 | |||
483 | printf("Played file in: %lu\n", time(NULL) - start_time); | ||
484 | 440 | ||
485 | alcCloseDevice(audio_out_device); | 441 | Pa_Terminate(); |
486 | sf_close(af_handle); | ||
487 | return 0; | 442 | return 0; |
488 | } | 443 | } |
444 | |||
445 | printf("Using audio device: %s\n", audio_dev->name); | ||
446 | printf("Using audio file: %s\n", af_name); | ||
447 | printf("Using video file: %s\n", vf_name); | ||
448 | |||
489 | /* START TOX NETWORK */ | 449 | /* START TOX NETWORK */ |
490 | 450 | ||
491 | Tox *bootstrap; | 451 | Tox *bootstrap; |
@@ -733,7 +693,7 @@ int main (int argc, char** argv) | |||
733 | 693 | ||
734 | { /* Call */ | 694 | { /* Call */ |
735 | TOXAV_ERR_CALL rc; | 695 | TOXAV_ERR_CALL rc; |
736 | toxav_call(AliceAV, 0, 8, 0, &rc); | 696 | toxav_call(AliceAV, 0, 48, 0, &rc); |
737 | 697 | ||
738 | if (rc != TOXAV_ERR_CALL_OK) { | 698 | if (rc != TOXAV_ERR_CALL_OK) { |
739 | printf("toxav_call failed: %d\n", rc); | 699 | printf("toxav_call failed: %d\n", rc); |
@@ -746,7 +706,7 @@ int main (int argc, char** argv) | |||
746 | 706 | ||
747 | { /* Answer */ | 707 | { /* Answer */ |
748 | TOXAV_ERR_ANSWER rc; | 708 | TOXAV_ERR_ANSWER rc; |
749 | toxav_answer(BobAV, 0, 64, 0, &rc); | 709 | toxav_answer(BobAV, 0, 48, 0, &rc); |
750 | 710 | ||
751 | if (rc != TOXAV_ERR_ANSWER_OK) { | 711 | if (rc != TOXAV_ERR_ANSWER_OK) { |
752 | printf("toxav_answer failed: %d\n", rc); | 712 | printf("toxav_answer failed: %d\n", rc); |
@@ -758,12 +718,26 @@ int main (int argc, char** argv) | |||
758 | 718 | ||
759 | /* Open audio file */ | 719 | /* Open audio file */ |
760 | af_handle = sf_open(af_name, SFM_READ, &af_info); | 720 | af_handle = sf_open(af_name, SFM_READ, &af_info); |
761 | if (af_handle == NULL) | 721 | if (af_handle == NULL) { |
762 | { | ||
763 | printf("Failed to open the file.\n"); | 722 | printf("Failed to open the file.\n"); |
764 | exit(1); | 723 | exit(1); |
765 | } | 724 | } |
766 | ALCdevice* audio_out_device = open_audio_device(audio_out_dev_name); | 725 | |
726 | |||
727 | int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; | ||
728 | |||
729 | struct PaStreamParameters output; | ||
730 | output.device = audio_out_dev_idx; | ||
731 | output.channelCount = af_info.channels; | ||
732 | output.sampleFormat = paInt16; | ||
733 | output.suggestedLatency = audio_dev->defaultHighOutputLatency; | ||
734 | output.hostApiSpecificStreamInfo = NULL; | ||
735 | |||
736 | PaError err = Pa_OpenStream(&adout, NULL, &output, af_info.samplerate, frame_size, paNoFlag, NULL, NULL); | ||
737 | assert(err == paNoError); | ||
738 | |||
739 | err = Pa_StartStream(adout); | ||
740 | assert(err == paNoError); | ||
767 | 741 | ||
768 | int16_t PCM[5760]; | 742 | int16_t PCM[5760]; |
769 | 743 | ||
@@ -784,24 +758,22 @@ int main (int argc, char** argv) | |||
784 | 758 | ||
785 | printf("Sample rate %d\n", af_info.samplerate); | 759 | printf("Sample rate %d\n", af_info.samplerate); |
786 | while ( start_time + expected_time > time(NULL) ) { | 760 | while ( start_time + expected_time > time(NULL) ) { |
787 | int frame_size = (af_info.samplerate * audio_frame_duration / 1000) * af_info.channels; | ||
788 | 761 | ||
789 | int64_t count = sf_read_short(af_handle, PCM, frame_size); | 762 | int64_t count = sf_read_short(af_handle, PCM, frame_size); |
790 | if (count > 0) { | 763 | if (count > 0) { |
791 | TOXAV_ERR_SEND_FRAME rc; | 764 | TOXAV_ERR_SEND_FRAME rc; |
792 | if (toxav_send_audio_frame(AliceAV, 0, PCM, count, af_info.channels, af_info.samplerate, &rc) == false) { | 765 | if (toxav_send_audio_frame(AliceAV, 0, PCM, count/af_info.channels, af_info.channels, af_info.samplerate, &rc) == false) { |
793 | printf("Error sending frame of size %ld: %d\n", count, rc); | 766 | printf("Error sending frame of size %ld: %d\n", count, rc); |
794 | exit(1); | 767 | // exit(1); |
795 | } | 768 | } |
796 | } | 769 | } |
797 | iterate_tox(bootstrap, AliceAV, BobAV); | 770 | iterate_tox(bootstrap, AliceAV, BobAV); |
798 | c_sleep(audio_frame_duration); | 771 | c_sleep(30); |
799 | } | 772 | } |
800 | 773 | ||
801 | 774 | ||
802 | printf("Played file in: %lu\n", time(NULL) - start_time); | 775 | printf("Played file in: %lu\n", time(NULL) - start_time); |
803 | 776 | ||
804 | alcCloseDevice(audio_out_device); | ||
805 | sf_close(af_handle); | 777 | sf_close(af_handle); |
806 | 778 | ||
807 | { /* Hangup */ | 779 | { /* Hangup */ |
diff --git a/toxav/codec.c b/toxav/codec.c index be69ee70..d55cc345 100644 --- a/toxav/codec.c +++ b/toxav/codec.c | |||
@@ -175,7 +175,7 @@ static int jbuf_write(JitterBuffer *q, RTPMessage *m) | |||
175 | unsigned int num = sequnum % q->size; | 175 | unsigned int num = sequnum % q->size; |
176 | 176 | ||
177 | if ((uint32_t)(sequnum - q->bottom) > q->size) { | 177 | if ((uint32_t)(sequnum - q->bottom) > q->size) { |
178 | LOGGER_DEBUG("Clearing jitter: %p", q); | 178 | LOGGER_DEBUG("Clearing filled jitter buffer: %p", q); |
179 | 179 | ||
180 | jbuf_clear(q); | 180 | jbuf_clear(q); |
181 | q->bottom = sequnum - q->capacity; | 181 | q->bottom = sequnum - q->capacity; |
@@ -309,6 +309,32 @@ bool create_video_encoder (vpx_codec_ctx_t* dest, int32_t bitrate) | |||
309 | return true; | 309 | return true; |
310 | } | 310 | } |
311 | 311 | ||
312 | bool reconfigure_audio_decoder(CSession* cs, int32_t sampling_rate, int8_t channels) | ||
313 | { | ||
314 | if (sampling_rate != cs->last_decoding_sampling_rate || channels != cs->last_decoding_channel_count) { | ||
315 | if (current_time_monotonic() - cs->last_decoder_reconfiguration < 500) | ||
316 | return false; | ||
317 | |||
318 | int status; | ||
319 | OpusDecoder* new_dec = opus_decoder_create(sampling_rate, channels, &status ); | ||
320 | if ( status != OPUS_OK ) { | ||
321 | LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); | ||
322 | return false; | ||
323 | } | ||
324 | |||
325 | cs->last_decoding_sampling_rate = sampling_rate; | ||
326 | cs->last_decoding_channel_count = channels; | ||
327 | cs->last_decoder_reconfiguration = current_time_monotonic(); | ||
328 | |||
329 | opus_decoder_destroy(cs->audio_decoder); | ||
330 | cs->audio_decoder = new_dec; | ||
331 | |||
332 | LOGGER_DEBUG("Reconfigured audio decoder sr: %d cc: %d", sampling_rate, channels); | ||
333 | } | ||
334 | |||
335 | return true; | ||
336 | } | ||
337 | |||
312 | /* PUBLIC */ | 338 | /* PUBLIC */ |
313 | 339 | ||
314 | void cs_do(CSession *cs) | 340 | void cs_do(CSession *cs) |
@@ -339,7 +365,7 @@ void cs_do(CSession *cs) | |||
339 | if (success == 2) { | 365 | if (success == 2) { |
340 | LOGGER_DEBUG("OPUS correction"); | 366 | LOGGER_DEBUG("OPUS correction"); |
341 | rc = opus_decode(cs->audio_decoder, NULL, 0, tmp, | 367 | rc = opus_decode(cs->audio_decoder, NULL, 0, tmp, |
342 | (cs->last_packet_sampling_rate * cs->last_packet_frame_duration / 1000) * | 368 | (cs->last_packet_sampling_rate * cs->last_packet_frame_duration / 1000) / |
343 | cs->last_packet_channel_count, 1); | 369 | cs->last_packet_channel_count, 1); |
344 | } else { | 370 | } else { |
345 | /* Get values from packet and decode. */ | 371 | /* Get values from packet and decode. */ |
@@ -359,6 +385,17 @@ void cs_do(CSession *cs) | |||
359 | cs->last_packet_sampling_rate = ntohl(cs->last_packet_sampling_rate); | 385 | cs->last_packet_sampling_rate = ntohl(cs->last_packet_sampling_rate); |
360 | 386 | ||
361 | cs->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4); | 387 | cs->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4); |
388 | |||
389 | /* | ||
390 | * NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa, | ||
391 | * it didn't work quite well. | ||
392 | */ | ||
393 | if (!reconfigure_audio_decoder(cs, cs->last_packet_sampling_rate, cs->last_packet_channel_count)) { | ||
394 | LOGGER_WARNING("Failed to reconfigure decoder!"); | ||
395 | rtp_free_msg(NULL, msg); | ||
396 | continue; | ||
397 | } | ||
398 | |||
362 | rc = opus_decode(cs->audio_decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0); | 399 | rc = opus_decode(cs->audio_decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0); |
363 | rtp_free_msg(NULL, msg); | 400 | rtp_free_msg(NULL, msg); |
364 | } | 401 | } |
@@ -366,35 +403,12 @@ void cs_do(CSession *cs) | |||
366 | if (rc < 0) { | 403 | if (rc < 0) { |
367 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); | 404 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); |
368 | } else if (cs->acb.first) { | 405 | } else if (cs->acb.first) { |
406 | cs->last_packet_channel_count = 2; | ||
407 | cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; | ||
369 | 408 | ||
370 | /* Extract channels */ | 409 | cs->acb.first(cs->av, cs->friend_id, tmp, rc * cs->last_packet_channel_count, |
371 | int16_t left[rc/2]; | 410 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); |
372 | int16_t right[rc/2]; | ||
373 | int i = 0; | ||
374 | for (; i < rc/2; i ++) { | ||
375 | left[i] = tmp[i * 2]; | ||
376 | right[i] = tmp[(i * 2) + 1]; | ||
377 | } | ||
378 | 411 | ||
379 | if (memcmp(left, right, sizeof(int16_t)) == 0) { | ||
380 | cs->last_packet_channel_count = 1; | ||
381 | cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; | ||
382 | |||
383 | LOGGER_DEBUG("Playing mono audio frame size: %d; srate: %d; duration %d", rc, | ||
384 | cs->last_packet_sampling_rate, cs->last_packet_frame_duration); | ||
385 | |||
386 | cs->acb.first(cs->av, cs->friend_id, right, rc / 2, | ||
387 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); | ||
388 | } else { | ||
389 | cs->last_packet_channel_count = 2; | ||
390 | cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; | ||
391 | |||
392 | LOGGER_DEBUG("Playing stereo audio frame size: %d; channels: %d; srate: %d; duration %d", rc, | ||
393 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->last_packet_frame_duration); | ||
394 | |||
395 | cs->acb.first(cs->av, cs->friend_id, tmp, rc, | ||
396 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); | ||
397 | } | ||
398 | } | 412 | } |
399 | 413 | ||
400 | LOGGED_LOCK(cs->queue_mutex); | 414 | LOGGED_LOCK(cs->queue_mutex); |
@@ -458,13 +472,17 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size) | |||
458 | */ | 472 | */ |
459 | 473 | ||
460 | int status; | 474 | int status; |
461 | cs->audio_decoder = opus_decoder_create(48000, 2, &status ); /* NOTE: Must be stereo */ | 475 | cs->audio_decoder = opus_decoder_create(48000, 2, &status ); |
462 | 476 | ||
463 | if ( status != OPUS_OK ) { | 477 | if ( status != OPUS_OK ) { |
464 | LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); | 478 | LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); |
465 | goto FAILURE; | 479 | goto FAILURE; |
466 | } | 480 | } |
467 | 481 | ||
482 | cs->last_decoding_channel_count = 2; | ||
483 | cs->last_decoding_sampling_rate = 48000; | ||
484 | cs->last_decoder_reconfiguration = 0; /* Make it possible to reconfigure straight away */ | ||
485 | |||
468 | /* These need to be set in order to properly | 486 | /* These need to be set in order to properly |
469 | * do error correction with opus */ | 487 | * do error correction with opus */ |
470 | cs->last_packet_frame_duration = 120; | 488 | cs->last_packet_frame_duration = 120; |
diff --git a/toxav/codec.h b/toxav/codec.h index 4e2b995b..830dbbf6 100644 --- a/toxav/codec.h +++ b/toxav/codec.h | |||
@@ -93,6 +93,9 @@ typedef struct CSession_s { | |||
93 | int32_t last_packet_channel_count; | 93 | int32_t last_packet_channel_count; |
94 | int32_t last_packet_sampling_rate; | 94 | int32_t last_packet_sampling_rate; |
95 | int32_t last_packet_frame_duration; | 95 | int32_t last_packet_frame_duration; |
96 | int32_t last_decoding_sampling_rate; | ||
97 | int32_t last_decoding_channel_count; | ||
98 | uint64_t last_decoder_reconfiguration; | ||
96 | struct JitterBuffer_s *j_buf; | 99 | struct JitterBuffer_s *j_buf; |
97 | 100 | ||
98 | 101 | ||
diff --git a/toxav/toxav.c b/toxav/toxav.c index 12f8b561..bd788d7d 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c | |||
@@ -237,7 +237,8 @@ void toxav_iterate(ToxAV* av) | |||
237 | } | 237 | } |
238 | LOGGED_UNLOCK(av->mutex); | 238 | LOGGED_UNLOCK(av->mutex); |
239 | 239 | ||
240 | av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa); | 240 | // av->interval = rc < av->dmssa ? 0 : (rc - av->dmssa); |
241 | av->interval = rc < 5 ? 1: rc - 5; | ||
241 | av->dmsst += current_time_monotonic() - start; | 242 | av->dmsst += current_time_monotonic() - start; |
242 | 243 | ||
243 | if (++av->dmssc == 3) { | 244 | if (++av->dmssc == 3) { |
@@ -712,21 +713,22 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc | |||
712 | goto END; | 713 | goto END; |
713 | } | 714 | } |
714 | 715 | ||
715 | uint8_t dest[sample_count * channels + sizeof(sampling_rate)]; /* This is more than enough always */ | 716 | uint8_t dest[sample_count + sizeof(sampling_rate)]; /* This is more than enough always */ |
716 | 717 | ||
717 | sampling_rate = htonl(sampling_rate); | 718 | sampling_rate = htonl(sampling_rate); |
718 | memcpy(dest, &sampling_rate, sizeof(sampling_rate)); | 719 | memcpy(dest, &sampling_rate, sizeof(sampling_rate)); |
719 | int vrc = opus_encode(call->cs->audio_encoder, pcm, sample_count, dest + sizeof(sampling_rate), sizeof(dest) - sizeof(sampling_rate)); | 720 | int vrc = opus_encode(call->cs->audio_encoder, pcm, sample_count, |
721 | dest + sizeof(sampling_rate), sizeof(dest) - sizeof(sampling_rate)); | ||
720 | 722 | ||
721 | if (vrc < 0) { | 723 | if (vrc < 0) { |
722 | LOGGER_WARNING("Failed to encode frame"); | 724 | LOGGER_WARNING("Failed to encode frame %s", opus_strerror(vrc)); |
723 | LOGGED_UNLOCK(call->mutex_audio_sending); | 725 | LOGGED_UNLOCK(call->mutex_audio_sending); |
724 | rc = TOXAV_ERR_SEND_FRAME_INVALID; | 726 | rc = TOXAV_ERR_SEND_FRAME_INVALID; |
725 | goto END; | 727 | goto END; |
726 | } | 728 | } |
727 | 729 | ||
728 | LOGGER_DEBUG("Sending encoded audio frame size: %d; channels: %d; srate: %d", vrc, channels, | 730 | // LOGGER_DEBUG("Sending encoded audio frame size: %d; channels: %d; srate: %d", vrc, channels, |
729 | ntohl(sampling_rate)); | 731 | // ntohl(sampling_rate)); |
730 | 732 | ||
731 | if (rtp_send_msg(call->rtps[audio_index], dest, vrc + sizeof(sampling_rate)) != 0) { | 733 | if (rtp_send_msg(call->rtps[audio_index], dest, vrc + sizeof(sampling_rate)) != 0) { |
732 | LOGGER_WARNING("Failed to send audio packet"); | 734 | LOGGER_WARNING("Failed to send audio packet"); |