Make it possible to change channels/sample rate of the decoder

This commit is contained in:
mannol 2015-03-23 23:38:04 +01:00
parent 995bddbc26
commit 96ca88a0d6
4 changed files with 75 additions and 6 deletions

View File

@ -26,6 +26,8 @@
#define c_sleep(x) usleep(1000*x) #define c_sleep(x) usleep(1000*x)
#endif #endif
#define MIN(a,b) (((a)<(b))?(a):(b))
/* Enable/disable tests */ /* Enable/disable tests */
#define TEST_REGULAR_AV 0 #define TEST_REGULAR_AV 0
#define TEST_REGULAR_A 0 #define TEST_REGULAR_A 0
@ -156,12 +158,15 @@ void iterate(Tox* Bsn, ToxAV* AliceAV, ToxAV* BobAV)
toxav_iteration(AliceAV); toxav_iteration(AliceAV);
toxav_iteration(BobAV); toxav_iteration(BobAV);
c_sleep(toxav_iteration_interval(AliceAV)); int mina = MIN(tox_do_interval(toxav_get_tox(AliceAV)), toxav_iteration_interval(AliceAV));
int minb = MIN(tox_do_interval(toxav_get_tox(BobAV)), toxav_iteration_interval(BobAV));
c_sleep(MIN(mina, minb));
} }
int device_read_frame(ALCdevice* device, int32_t frame_dur, int16_t* PCM, size_t max_size) int device_read_frame(ALCdevice* device, int32_t frame_dur, int16_t* PCM, size_t max_size)
{ {
int f_size = (48000 * frame_dur / 1000); int f_size = (8000 * frame_dur / 1000);
if (max_size < f_size) if (max_size < f_size)
return -1; return -1;
@ -645,7 +650,7 @@ int main (int argc, char** argv)
int frame_size = device_read_frame(in_device, 20, PCM, sizeof(PCM)); int frame_size = device_read_frame(in_device, 20, PCM, sizeof(PCM));
if (frame_size > 0) { if (frame_size > 0) {
TOXAV_ERR_SEND_FRAME rc; TOXAV_ERR_SEND_FRAME rc;
if (toxav_send_audio_frame(AliceAV, 0, PCM, frame_size, 2, 48000, &rc) == false) { if (toxav_send_audio_frame(AliceAV, 0, PCM, frame_size, 2, 8000, &rc) == false) {
printf("Error sending frame of size %d: %d\n", frame_size, rc); printf("Error sending frame of size %d: %d\n", frame_size, rc);
exit (1); exit (1);
} }

View File

@ -237,6 +237,61 @@ static int convert_bw_to_sampling_rate(int bw)
} }
int cs_set_receiving_audio_bitrate(CSSession *cs, int32_t rate)
{
if (cs->audio_decoder == NULL)
return -1;
int rc = opus_decoder_ctl(cs->audio_decoder, OPUS_SET_BITRATE(rate));
if ( rc != OPUS_OK ) {
LOGGER_ERROR("Error while setting decoder ctl: %s", opus_strerror(rc));
return -1;
}
LOGGER_DEBUG("Set new decoder bitrate to: %d", rate);
return 0;
}
int cs_set_receiving_audio_sampling_rate(CSSession* cs, int32_t rate)
{
/* TODO Find a better way? */
if (cs->audio_decoder == NULL)
return -1;
if (cs->decoder_sample_rate == rate)
return 0;
int channels = cs->decoder_channels;
cs_disable_audio_receiving(cs);
cs->decoder_sample_rate = rate;
cs->decoder_channels = channels;
LOGGER_DEBUG("Set new encoder sampling rate: %d", rate);
return cs_enable_audio_receiving(cs);
}
int cs_set_receiving_audio_channels(CSSession* cs, int32_t count)
{
/* TODO Find a better way? */
if (cs->audio_decoder == NULL)
return -1;
if (cs->decoder_channels == count)
return 0;
int srate = cs->decoder_sample_rate;
cs_disable_audio_receiving(cs);
cs->decoder_channels = count;
cs->decoder_sample_rate = srate;
LOGGER_DEBUG("Set new encoder channel count: %d", count);
return cs_enable_audio_receiving(cs);
}
/* PUBLIC */ /* PUBLIC */
@ -284,6 +339,9 @@ void cs_do(CSSession *cs)
continue; continue;
} }
cs_set_receiving_audio_sampling_rate(cs, cs->last_packet_sampling_rate);
cs_set_receiving_audio_channels(cs, cs->last_pack_channels);
LOGGER_DEBUG("Decoding packet of length: %d", msg->length); LOGGER_DEBUG("Decoding packet of length: %d", msg->length);
rc = opus_decode(cs->audio_decoder, msg->data, msg->length, tmp, fsize, 0); rc = opus_decode(cs->audio_decoder, msg->data, msg->length, tmp, fsize, 0);
rtp_free_msg(NULL, msg); rtp_free_msg(NULL, msg);
@ -353,6 +411,8 @@ CSSession *cs_new(uint32_t peer_video_frame_piece_size)
cs->peer_video_frame_piece_size = peer_video_frame_piece_size; cs->peer_video_frame_piece_size = peer_video_frame_piece_size;
cs->decoder_sample_rate = 48000;
cs->decoder_channels = 2;
return cs; return cs;
} }
@ -676,6 +736,8 @@ void cs_disable_audio_receiving(CSSession* cs)
* To avoid unecessary checking we set this to 500 * To avoid unecessary checking we set this to 500
*/ */
cs->last_packet_frame_duration = 500; cs->last_packet_frame_duration = 500;
cs->decoder_sample_rate = 48000;
cs->decoder_channels = 2;
} }
} }
@ -723,7 +785,7 @@ int cs_enable_audio_receiving(CSSession* cs)
return 0; return 0;
int rc; int rc;
cs->audio_decoder = opus_decoder_create(48000, 2, &rc ); cs->audio_decoder = opus_decoder_create(cs->decoder_sample_rate, cs->decoder_channels, &rc );
if ( rc != OPUS_OK ) { if ( rc != OPUS_OK ) {
LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc)); LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc));
@ -742,6 +804,7 @@ int cs_enable_audio_receiving(CSSession* cs)
* To avoid unecessary checking we set this to 500 * To avoid unecessary checking we set this to 500
*/ */
cs->last_packet_frame_duration = 500; cs->last_packet_frame_duration = 500;
return 0; return 0;
} }

View File

@ -112,6 +112,8 @@ typedef struct CSSession_s {
/* audio decoding */ /* audio decoding */
OpusDecoder *audio_decoder; OpusDecoder *audio_decoder;
int32_t decoder_channels;
int32_t decoder_sample_rate;
int32_t last_pack_channels; int32_t last_pack_channels;
int32_t last_packet_sampling_rate; int32_t last_packet_sampling_rate;
int32_t last_packet_frame_duration; int32_t last_packet_frame_duration;

View File

@ -650,7 +650,6 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc
} }
{ /* Encode and send */ { /* Encode and send */
/* TODO redundant? */
cs_set_sending_audio_channels(call->cs, channels); cs_set_sending_audio_channels(call->cs, channels);
cs_set_sending_audio_sampling_rate(call->cs, sampling_rate); cs_set_sending_audio_sampling_rate(call->cs, sampling_rate);