From 4fa31d14cf53dd54b182508df31b5524b1f24cb6 Mon Sep 17 00:00:00 2001 From: mannol Date: Thu, 9 Apr 2015 02:43:13 +0200 Subject: [PATCH] Make it possible to decode mono audio with stereo decoder --- toxav/av_test.c | 26 +++++++++++--------- toxav/codec.c | 64 ++++++++++++++++++++++++++++++++---------------- toxav/codec.h | 3 +++ toxav/toxav.c | 15 ++++++++---- toxcore/logger.c | 12 ++++----- 5 files changed, 76 insertions(+), 44 deletions(-) diff --git a/toxav/av_test.c b/toxav/av_test.c index a04aff7c..007a1a10 100644 --- a/toxav/av_test.c +++ b/toxav/av_test.c @@ -141,28 +141,30 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number, int32_t processed = 0, queued = 16; alGetSourcei(adout, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(adout, AL_BUFFERS_QUEUED, &queued); - + if(processed) { uint32_t bufids[processed]; alSourceUnqueueBuffers(adout, processed, bufids); alDeleteBuffers(processed - 1, bufids + 1); -// bufid = bufids[0]; + bufid = bufids[0]; } -// else if(queued < 16) +// else if(queued < 16) { alGenBuffers(1, &bufid); +// } // else // return; - + alBufferData(bufid, channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, - pcm, sample_count * 2, sampling_rate); + pcm, sample_count * 2 * channels, sampling_rate); alSourceQueueBuffers(adout, 1, &bufid); - + int32_t state; alGetSourcei(adout, AL_SOURCE_STATE, &state); - - if(state != AL_PLAYING) + if(state != AL_PLAYING) { + printf("Here\n"); alSourcePlay(adout); + } } void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) { @@ -260,7 +262,8 @@ void* iterate_toxav (void * data) printf("\rToxAV interval: %d ", rc); fflush(stdout); - cvWaitKey(rc); +// cvWaitKey(rc); + c_sleep(rc/2); } data_cast->sig = 1; @@ -319,7 +322,7 @@ ALCdevice* open_audio_device(const char* audio_out_dev_name) alcMakeContextCurrent(out_ctx); alGenSources((uint32_t)1, &adout); - alSourcei(adout, AL_LOOPING, AL_FALSE); + alSourcei(adout, AL_LOOPING, AL_FALSE); alSourcePlay(adout); return rc; @@ -730,7 +733,7 @@ int main (int argc, char** argv) { /* Call */ TOXAV_ERR_CALL rc; - toxav_call(AliceAV, 0, 48, 0, &rc); + toxav_call(AliceAV, 0, 8, 0, &rc); if (rc != TOXAV_ERR_CALL_OK) { printf("toxav_call failed: %d\n", rc); @@ -785,7 +788,6 @@ int main (int argc, char** argv) int64_t count = sf_read_short(af_handle, PCM, frame_size); if (count > 0) { -// t_toxav_receive_audio_frame_cb(AliceAV, 0, PCM, count, af_info.channels, af_info.samplerate, NULL); TOXAV_ERR_SEND_FRAME rc; if (toxav_send_audio_frame(AliceAV, 0, PCM, count, af_info.channels, af_info.samplerate, &rc) == false) { printf("Error sending frame of size %ld: %d\n", count, rc); diff --git a/toxav/codec.c b/toxav/codec.c index cd26d1e3..be69ee70 100644 --- a/toxav/codec.c +++ b/toxav/codec.c @@ -38,7 +38,7 @@ #include "rtp.h" #include "codec.h" -#define DEFAULT_JBUF 6 +#define DEFAULT_JBUF 3 /* Good quality encode. */ #define MAX_DECODE_TIME_US 0 @@ -342,39 +342,59 @@ void cs_do(CSession *cs) (cs->last_packet_sampling_rate * cs->last_packet_frame_duration / 1000) * cs->last_packet_channel_count, 1); } else { - /* Get values from packet and decode. - * It also checks for validity of an opus packet - */ + /* Get values from packet and decode. */ + /* NOTE: This didn't work very well rc = convert_bw_to_sampling_rate(opus_packet_get_bandwidth(msg->data)); if (rc != -1) { cs->last_packet_sampling_rate = rc; - cs->last_packet_channel_count = opus_packet_get_nb_channels(msg->data); - - cs->last_packet_frame_duration = - ( opus_packet_get_samples_per_frame(msg->data, cs->last_packet_sampling_rate) * 1000 ) - / cs->last_packet_sampling_rate; - - /* TODO FIXME WARNING calculate properly according to propper channel count */ - cs->last_packet_frame_duration /= cs->last_packet_channel_count; } else { LOGGER_WARNING("Failed to load packet values!"); rtp_free_msg(NULL, msg); continue; - } + }*/ - rc = opus_decode(cs->audio_decoder, msg->data, msg->length, tmp, 5760, 0); + + /* Pick up sampling rate from packet */ + memcpy(&cs->last_packet_sampling_rate, msg->data, 4); + cs->last_packet_sampling_rate = ntohl(cs->last_packet_sampling_rate); + + cs->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4); + rc = opus_decode(cs->audio_decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0); rtp_free_msg(NULL, msg); } if (rc < 0) { LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); } else if (cs->acb.first) { - /* Play */ - LOGGER_DEBUG("Playing audio frame size: %d; channels: %d; srate: %d; duration %d", rc, - cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->last_packet_frame_duration); - cs->acb.first(cs->av, cs->friend_id, tmp, rc, - cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); + /* Extract channels */ + int16_t left[rc/2]; + int16_t right[rc/2]; + int i = 0; + for (; i < rc/2; i ++) { + left[i] = tmp[i * 2]; + right[i] = tmp[(i * 2) + 1]; + } + + if (memcmp(left, right, sizeof(int16_t)) == 0) { + cs->last_packet_channel_count = 1; + cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; + + LOGGER_DEBUG("Playing mono audio frame size: %d; srate: %d; duration %d", rc, + cs->last_packet_sampling_rate, cs->last_packet_frame_duration); + + cs->acb.first(cs->av, cs->friend_id, right, rc / 2, + cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); + } else { + cs->last_packet_channel_count = 2; + cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; + + LOGGER_DEBUG("Playing stereo audio frame size: %d; channels: %d; srate: %d; duration %d", rc, + cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->last_packet_frame_duration); + + cs->acb.first(cs->av, cs->friend_id, tmp, rc, + cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); + } } LOGGED_LOCK(cs->queue_mutex); @@ -438,7 +458,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size) */ int status; - cs->audio_decoder = opus_decoder_create(48000, 1, &status ); /* NOTE: Must be mono */ + cs->audio_decoder = opus_decoder_create(48000, 2, &status ); /* NOTE: Must be stereo */ if ( status != OPUS_OK ) { LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); @@ -482,7 +502,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size) goto FAILURE; cs->linfts = current_time_monotonic(); - cs->lcfd = 10; + cs->lcfd = 60; /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* Initialize encoders with default values */ @@ -579,6 +599,8 @@ const uint8_t *cs_iterate_split_video_frame(CSession *cs, uint16_t *size) return cs->split_video_frame; } + + int cs_reconfigure_video_encoder(CSession* cs, int32_t bitrate, uint16_t width, uint16_t height) { vpx_codec_enc_cfg_t cfg = *cs->v_encoder[0].config.enc; diff --git a/toxav/codec.h b/toxav/codec.h index 93b08cd2..4e2b995b 100644 --- a/toxav/codec.h +++ b/toxav/codec.h @@ -42,6 +42,9 @@ #define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } +#define PACKED_AUDIO_SIZE(x) (x + 5) +#define UNPACKED_AUDIO_SIZE(x) (x - 5) + typedef struct CSession_s { /* VIDEO diff --git a/toxav/toxav.c b/toxav/toxav.c index 0f16fde2..12f8b561 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -223,7 +223,7 @@ void toxav_iterate(ToxAV* av) if (i->last_self_capabilities & msi_CapRAudio) /* Receiving audio */ rc = MIN(i->cs->last_packet_frame_duration, rc); if (i->last_self_capabilities & msi_CapRVideo) /* Receiving video */ - rc = MIN(i->cs->lcfd, rc); + rc = MIN(i->cs->lcfd, rc); /* TODO handle on/off */ uint32_t fid = i->friend_id; @@ -712,9 +712,11 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc goto END; } - LOGGER_DEBUG("Sending audio frame size: %d; channels: %d; srate: %d", sample_count, channels, sampling_rate); - uint8_t dest[sample_count * channels * sizeof(int16_t)]; - int vrc = opus_encode(call->cs->audio_encoder, pcm, sample_count, dest, sizeof (dest)); + uint8_t dest[sample_count * channels + sizeof(sampling_rate)]; /* This is more than enough always */ + + sampling_rate = htonl(sampling_rate); + memcpy(dest, &sampling_rate, sizeof(sampling_rate)); + int vrc = opus_encode(call->cs->audio_encoder, pcm, sample_count, dest + sizeof(sampling_rate), sizeof(dest) - sizeof(sampling_rate)); if (vrc < 0) { LOGGER_WARNING("Failed to encode frame"); @@ -723,7 +725,10 @@ bool toxav_send_audio_frame(ToxAV* av, uint32_t friend_number, const int16_t* pc goto END; } - if (rtp_send_msg(call->rtps[audio_index], dest, vrc) != 0) { + LOGGER_DEBUG("Sending encoded audio frame size: %d; channels: %d; srate: %d", vrc, channels, + ntohl(sampling_rate)); + + if (rtp_send_msg(call->rtps[audio_index], dest, vrc + sizeof(sampling_rate)) != 0) { LOGGER_WARNING("Failed to send audio packet"); rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; } diff --git a/toxcore/logger.c b/toxcore/logger.c index e8aef7e0..fc6a989a 100644 --- a/toxcore/logger.c +++ b/toxcore/logger.c @@ -200,12 +200,12 @@ void logger_write (Logger *log, LOG_LEVEL level, const char *file, int line, con #endif static const char *logger_format = - "%s " /* Logger id string */ - "%-16s" /* Time string of format: %m:%d %H:%M:%S */ - "%u " /* Thread id */ - "%-5s " /* Logger lever string */ - "%-20s " /* File:line string */ - "- %s" /* Output message */ + "%s " /* Logger id string */ + "%-16s" /* Time string of format: %m:%d %H:%M:%S */ + "%-12u " /* Thread id */ + "%-5s " /* Logger lever string */ + "%-20s " /* File:line string */ + "- %s" /* Output message */ WIN_CR "\n"; /* Every new print new line */