Make it possible to decode mono audio with stereo decoder

This commit is contained in:
mannol 2015-04-09 02:43:13 +02:00
parent 9c003c9dd2
commit 4fa31d14cf
5 changed files with 76 additions and 44 deletions

View File

@ -141,28 +141,30 @@ void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
int32_t processed = 0, queued = 16; int32_t processed = 0, queued = 16;
alGetSourcei(adout, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(adout, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(adout, AL_BUFFERS_QUEUED, &queued); alGetSourcei(adout, AL_BUFFERS_QUEUED, &queued);
if(processed) { if(processed) {
uint32_t bufids[processed]; uint32_t bufids[processed];
alSourceUnqueueBuffers(adout, processed, bufids); alSourceUnqueueBuffers(adout, processed, bufids);
alDeleteBuffers(processed - 1, bufids + 1); alDeleteBuffers(processed - 1, bufids + 1);
// bufid = bufids[0]; bufid = bufids[0];
} }
// else if(queued < 16) // else if(queued < 16) {
alGenBuffers(1, &bufid); alGenBuffers(1, &bufid);
// }
// else // else
// return; // return;
alBufferData(bufid, channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, 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); alSourceQueueBuffers(adout, 1, &bufid);
int32_t state; int32_t state;
alGetSourcei(adout, AL_SOURCE_STATE, &state); alGetSourcei(adout, AL_SOURCE_STATE, &state);
if(state != AL_PLAYING) {
if(state != AL_PLAYING) printf("Here\n");
alSourcePlay(adout); alSourcePlay(adout);
}
} }
void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) 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); printf("\rToxAV interval: %d ", rc);
fflush(stdout); fflush(stdout);
cvWaitKey(rc); // cvWaitKey(rc);
c_sleep(rc/2);
} }
data_cast->sig = 1; data_cast->sig = 1;
@ -319,7 +322,7 @@ ALCdevice* open_audio_device(const char* audio_out_dev_name)
alcMakeContextCurrent(out_ctx); alcMakeContextCurrent(out_ctx);
alGenSources((uint32_t)1, &adout); alGenSources((uint32_t)1, &adout);
alSourcei(adout, AL_LOOPING, AL_FALSE); alSourcei(adout, AL_LOOPING, AL_FALSE);
alSourcePlay(adout); alSourcePlay(adout);
return rc; return rc;
@ -730,7 +733,7 @@ int main (int argc, char** argv)
{ /* Call */ { /* Call */
TOXAV_ERR_CALL rc; TOXAV_ERR_CALL rc;
toxav_call(AliceAV, 0, 48, 0, &rc); toxav_call(AliceAV, 0, 8, 0, &rc);
if (rc != TOXAV_ERR_CALL_OK) { if (rc != TOXAV_ERR_CALL_OK) {
printf("toxav_call failed: %d\n", rc); 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); int64_t count = sf_read_short(af_handle, PCM, frame_size);
if (count > 0) { 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; TOXAV_ERR_SEND_FRAME rc;
if (toxav_send_audio_frame(AliceAV, 0, PCM, count, af_info.channels, af_info.samplerate, &rc) == false) { 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); printf("Error sending frame of size %ld: %d\n", count, rc);

View File

@ -38,7 +38,7 @@
#include "rtp.h" #include "rtp.h"
#include "codec.h" #include "codec.h"
#define DEFAULT_JBUF 6 #define DEFAULT_JBUF 3
/* Good quality encode. */ /* Good quality encode. */
#define MAX_DECODE_TIME_US 0 #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_sampling_rate * cs->last_packet_frame_duration / 1000) *
cs->last_packet_channel_count, 1); cs->last_packet_channel_count, 1);
} else { } else {
/* Get values from packet and decode. /* Get values from packet and decode. */
* It also checks for validity of an opus packet /* NOTE: This didn't work very well
*/
rc = convert_bw_to_sampling_rate(opus_packet_get_bandwidth(msg->data)); rc = convert_bw_to_sampling_rate(opus_packet_get_bandwidth(msg->data));
if (rc != -1) { if (rc != -1) {
cs->last_packet_sampling_rate = rc; 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 { } else {
LOGGER_WARNING("Failed to load packet values!"); LOGGER_WARNING("Failed to load packet values!");
rtp_free_msg(NULL, msg); rtp_free_msg(NULL, msg);
continue; 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); rtp_free_msg(NULL, msg);
} }
if (rc < 0) { if (rc < 0) {
LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); LOGGER_WARNING("Decoding error: %s", opus_strerror(rc));
} else if (cs->acb.first) { } 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, /* Extract channels */
cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); 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); LOGGED_LOCK(cs->queue_mutex);
@ -438,7 +458,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size)
*/ */
int status; 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 ) { if ( status != OPUS_OK ) {
LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); 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; goto FAILURE;
cs->linfts = current_time_monotonic(); cs->linfts = current_time_monotonic();
cs->lcfd = 10; cs->lcfd = 60;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Initialize encoders with default values */ /* 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; return cs->split_video_frame;
} }
int cs_reconfigure_video_encoder(CSession* cs, int32_t bitrate, uint16_t width, uint16_t height) 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; vpx_codec_enc_cfg_t cfg = *cs->v_encoder[0].config.enc;

View File

@ -42,6 +42,9 @@
#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } #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 { typedef struct CSession_s {
/* VIDEO /* VIDEO

View File

@ -223,7 +223,7 @@ void toxav_iterate(ToxAV* av)
if (i->last_self_capabilities & msi_CapRAudio) /* Receiving audio */ if (i->last_self_capabilities & msi_CapRAudio) /* Receiving audio */
rc = MIN(i->cs->last_packet_frame_duration, rc); rc = MIN(i->cs->last_packet_frame_duration, rc);
if (i->last_self_capabilities & msi_CapRVideo) /* Receiving video */ 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; 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; 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(sampling_rate)]; /* This is more than enough always */
uint8_t dest[sample_count * channels * sizeof(int16_t)];
int vrc = opus_encode(call->cs->audio_encoder, pcm, sample_count, dest, sizeof (dest)); 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) { if (vrc < 0) {
LOGGER_WARNING("Failed to encode frame"); 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; 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"); LOGGER_WARNING("Failed to send audio packet");
rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED; rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
} }

View File

@ -200,12 +200,12 @@ void logger_write (Logger *log, LOG_LEVEL level, const char *file, int line, con
#endif #endif
static const char *logger_format = static const char *logger_format =
"%s " /* Logger id string */ "%s " /* Logger id string */
"%-16s" /* Time string of format: %m:%d %H:%M:%S */ "%-16s" /* Time string of format: %m:%d %H:%M:%S */
"%u " /* Thread id */ "%-12u " /* Thread id */
"%-5s " /* Logger lever string */ "%-5s " /* Logger lever string */
"%-20s " /* File:line string */ "%-20s " /* File:line string */
"- %s" /* Output message */ "- %s" /* Output message */
WIN_CR "\n"; /* Every new print new line */ WIN_CR "\n"; /* Every new print new line */