mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
2 channel audio can now be sent to groupchats.
Some cleanups and added comments.
This commit is contained in:
parent
a8f670bd68
commit
8c0225b27f
|
@ -158,35 +158,37 @@ typedef struct {
|
||||||
|
|
||||||
static void kill_group_av(Group_AV *group_av)
|
static void kill_group_av(Group_AV *group_av)
|
||||||
{
|
{
|
||||||
opus_encoder_destroy(group_av->audio_encoder);
|
if (group_av->audio_encoder) {
|
||||||
|
opus_encoder_destroy(group_av->audio_encoder);
|
||||||
|
}
|
||||||
|
|
||||||
free(group_av);
|
free(group_av);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Group_AV *new_group_av(Group_Chats *g_c, unsigned int audio_channels, unsigned int audio_sample_rate,
|
static int recreate_encoder(Group_AV *group_av)
|
||||||
unsigned int audio_bitrate, void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int, uint8_t,
|
|
||||||
unsigned int, void *), void *userdata)
|
|
||||||
{
|
{
|
||||||
if (!g_c)
|
if (group_av->audio_encoder) {
|
||||||
return NULL;
|
opus_encoder_destroy(group_av->audio_encoder);
|
||||||
|
group_av->audio_encoder = NULL;
|
||||||
Group_AV *group_av = calloc(1, sizeof(Group_AV));
|
}
|
||||||
|
|
||||||
int rc = OPUS_OK;
|
int rc = OPUS_OK;
|
||||||
group_av->audio_encoder = opus_encoder_create(audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &rc);
|
group_av->audio_encoder = opus_encoder_create(group_av->audio_sample_rate, group_av->audio_channels,
|
||||||
|
OPUS_APPLICATION_AUDIO, &rc);
|
||||||
|
|
||||||
if ( rc != OPUS_OK ) {
|
if ( rc != OPUS_OK ) {
|
||||||
LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc));
|
LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc));
|
||||||
free(group_av);
|
group_av->audio_encoder = NULL;
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_BITRATE(audio_bitrate));
|
rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_BITRATE(group_av->audio_bitrate));
|
||||||
|
|
||||||
if ( rc != OPUS_OK ) {
|
if ( rc != OPUS_OK ) {
|
||||||
LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc));
|
LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc));
|
||||||
opus_encoder_destroy(group_av->audio_encoder);
|
opus_encoder_destroy(group_av->audio_encoder);
|
||||||
free(group_av);
|
group_av->audio_encoder = NULL;
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_COMPLEXITY(10));
|
rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_COMPLEXITY(10));
|
||||||
|
@ -194,17 +196,29 @@ static Group_AV *new_group_av(Group_Chats *g_c, unsigned int audio_channels, uns
|
||||||
if ( rc != OPUS_OK ) {
|
if ( rc != OPUS_OK ) {
|
||||||
LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc));
|
LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc));
|
||||||
opus_encoder_destroy(group_av->audio_encoder);
|
opus_encoder_destroy(group_av->audio_encoder);
|
||||||
free(group_av);
|
group_av->audio_encoder = NULL;
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
group_av->audio_channels = audio_channels;
|
return 0;
|
||||||
group_av->audio_sample_rate = audio_sample_rate;
|
}
|
||||||
group_av->audio_bitrate = audio_bitrate;
|
|
||||||
|
static Group_AV *new_group_av(Group_Chats *g_c, void (*audio_callback)(Messenger *, int, int, const int16_t *,
|
||||||
|
unsigned int, uint8_t, unsigned int, void *), void *userdata)
|
||||||
|
{
|
||||||
|
if (!g_c)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Group_AV *group_av = calloc(1, sizeof(Group_AV));
|
||||||
|
|
||||||
|
if (!group_av)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
group_av->g_c = g_c;
|
group_av->g_c = g_c;
|
||||||
|
|
||||||
group_av->audio_data = audio_callback;
|
group_av->audio_data = audio_callback;
|
||||||
group_av->userdata = userdata;
|
group_av->userdata = userdata;
|
||||||
|
|
||||||
return group_av;
|
return group_av;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,6 +262,8 @@ static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, int g
|
||||||
int16_t *out_audio = NULL;
|
int16_t *out_audio = NULL;
|
||||||
unsigned int out_audio_samples = 0;
|
unsigned int out_audio_samples = 0;
|
||||||
|
|
||||||
|
unsigned int sample_rate = 48000;
|
||||||
|
|
||||||
if (success == 1) {
|
if (success == 1) {
|
||||||
int channels = opus_packet_get_nb_channels(pk->data);
|
int channels = opus_packet_get_nb_channels(pk->data);
|
||||||
|
|
||||||
|
@ -268,7 +284,7 @@ static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, int g
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
peer_av->audio_decoder = opus_decoder_create(group_av->audio_sample_rate, channels, &rc);
|
peer_av->audio_decoder = opus_decoder_create(sample_rate, 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));
|
||||||
|
@ -320,7 +336,7 @@ static int decode_audio_packet(Group_AV *group_av, Group_Peer_AV *peer_av, int g
|
||||||
|
|
||||||
if (group_av->audio_data)
|
if (group_av->audio_data)
|
||||||
group_av->audio_data(group_av->g_c->m, groupnumber, friendgroupnumber, out_audio, out_audio_samples,
|
group_av->audio_data(group_av->g_c->m, groupnumber, friendgroupnumber, out_audio, out_audio_samples,
|
||||||
peer_av->decoder_channels, group_av->audio_sample_rate, group_av->userdata);
|
peer_av->decoder_channels, sample_rate, group_av->userdata);
|
||||||
|
|
||||||
free(out_audio);
|
free(out_audio);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -371,7 +387,7 @@ static int groupchat_enable_av(Group_Chats *g_c, int groupnumber, void (*audio_c
|
||||||
if (groupnumber == -1)
|
if (groupnumber == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
Group_AV *group_av = new_group_av(g_c, 1, 48000, 64000, audio_callback, userdata); //TODO: Use variables instead.
|
Group_AV *group_av = new_group_av(g_c, audio_callback, userdata);
|
||||||
|
|
||||||
if (group_av == NULL)
|
if (group_av == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -465,12 +481,27 @@ static int send_audio_packet(Group_Chats *g_c, int groupnumber, uint8_t *packet,
|
||||||
int group_send_audio(Group_Chats *g_c, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
int group_send_audio(Group_Chats *g_c, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
||||||
unsigned int sample_rate)
|
unsigned int sample_rate)
|
||||||
{
|
{
|
||||||
//TODO use channels and sample_rate arguments.
|
|
||||||
Group_AV *group_av = group_get_object(g_c, groupnumber);
|
Group_AV *group_av = group_get_object(g_c, groupnumber);
|
||||||
|
|
||||||
if (!group_av)
|
if (!group_av)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (channels != 1 && channels != 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
//TODO: allow different sample rates
|
||||||
|
if (sample_rate != 48000)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!group_av->audio_encoder || group_av->audio_channels != channels || group_av->audio_sample_rate != sample_rate) {
|
||||||
|
group_av->audio_channels = channels;
|
||||||
|
group_av->audio_sample_rate = sample_rate;
|
||||||
|
group_av->audio_bitrate = 64000; //TODO: add way of adjusting bitrate
|
||||||
|
|
||||||
|
if (recreate_encoder(group_av) == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t encoded[1024];
|
uint8_t encoded[1024];
|
||||||
int32_t size = opus_encode(group_av->audio_encoder, pcm, samples, encoded, sizeof(encoded));
|
int32_t size = opus_encode(group_av->audio_encoder, pcm, samples, encoded, sizeof(encoded));
|
||||||
|
|
||||||
|
|
|
@ -1160,6 +1160,8 @@ end:
|
||||||
*
|
*
|
||||||
* Audio data callback format:
|
* Audio data callback format:
|
||||||
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
||||||
|
*
|
||||||
|
* Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
|
||||||
*/
|
*/
|
||||||
int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int,
|
int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int,
|
||||||
uint8_t, unsigned int, void *), void *userdata)
|
uint8_t, unsigned int, void *), void *userdata)
|
||||||
|
@ -1175,6 +1177,8 @@ int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Messenger *, int, in
|
||||||
*
|
*
|
||||||
* Audio data callback format (same as the one for toxav_add_av_groupchat()):
|
* Audio data callback format (same as the one for toxav_add_av_groupchat()):
|
||||||
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
||||||
|
*
|
||||||
|
* Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
|
||||||
*/
|
*/
|
||||||
int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length,
|
int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length,
|
||||||
void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *),
|
void (*audio_callback)(Messenger *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *),
|
||||||
|
@ -1188,6 +1192,14 @@ int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data,
|
||||||
*
|
*
|
||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
* return -1 on failure.
|
* return -1 on failure.
|
||||||
|
*
|
||||||
|
* Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
|
||||||
|
*
|
||||||
|
* Valid number of samples are ((sample rate) * (audio length (Valid ones are: 2.5, 5, 10, 20, 40 or 60 ms)) / 1000)
|
||||||
|
* Valid number of channels are 1 or 2.
|
||||||
|
* Valid sample rates are 8000, 12000, 16000, 24000, or 48000.
|
||||||
|
*
|
||||||
|
* Recommended values are: samples = 960, channels = 1, sample_rate = 48000
|
||||||
*/
|
*/
|
||||||
int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
||||||
unsigned int sample_rate)
|
unsigned int sample_rate)
|
||||||
|
|
|
@ -390,6 +390,8 @@ int toxav_has_activity ( ToxAv *av, int32_t call_index, int16_t *PCM, uint16_t f
|
||||||
*
|
*
|
||||||
* Audio data callback format:
|
* Audio data callback format:
|
||||||
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
||||||
|
*
|
||||||
|
* Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
|
||||||
*/
|
*/
|
||||||
int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Tox *, int, int, const int16_t *, unsigned int, uint8_t,
|
int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Tox *, int, int, const int16_t *, unsigned int, uint8_t,
|
||||||
unsigned int, void *), void *userdata);
|
unsigned int, void *), void *userdata);
|
||||||
|
@ -401,6 +403,8 @@ int toxav_add_av_groupchat(Tox *tox, void (*audio_callback)(Tox *, int, int, con
|
||||||
*
|
*
|
||||||
* Audio data callback format (same as the one for toxav_add_av_groupchat()):
|
* Audio data callback format (same as the one for toxav_add_av_groupchat()):
|
||||||
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
* audio_callback(Tox *tox, int groupnumber, int peernumber, const int16_t *pcm, unsigned int samples, uint8_t channels, unsigned int sample_rate, void *userdata)
|
||||||
|
*
|
||||||
|
* Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
|
||||||
*/
|
*/
|
||||||
int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length,
|
int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length,
|
||||||
void (*audio_callback)(Tox *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), void *userdata);
|
void (*audio_callback)(Tox *, int, int, const int16_t *, unsigned int, uint8_t, unsigned int, void *), void *userdata);
|
||||||
|
@ -409,6 +413,16 @@ int toxav_join_av_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *data,
|
||||||
*
|
*
|
||||||
* return 0 on success.
|
* return 0 on success.
|
||||||
* return -1 on failure.
|
* return -1 on failure.
|
||||||
|
*
|
||||||
|
* Note that total size of pcm in bytes is equal to (samples * channels * sizeof(int16_t)).
|
||||||
|
*
|
||||||
|
* Valid number of samples are ((sample rate) * (audio length (Valid ones are: 2.5, 5, 10, 20, 40 or 60 ms)) / 1000)
|
||||||
|
* Valid number of channels are 1 or 2.
|
||||||
|
* Valid sample rates are 8000, 12000, 16000, 24000, or 48000.
|
||||||
|
*
|
||||||
|
* Recommended values are: samples = 960, channels = 1, sample_rate = 48000
|
||||||
|
*
|
||||||
|
* TODO: currently the only supported sample rate is 48000.
|
||||||
*/
|
*/
|
||||||
int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
int toxav_group_send_audio(Tox *tox, int groupnumber, const int16_t *pcm, unsigned int samples, uint8_t channels,
|
||||||
unsigned int sample_rate);
|
unsigned int sample_rate);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user