summaryrefslogtreecommitdiff
path: root/toxav/audio.c
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2015-04-21 02:31:12 +0200
committermannol <eniz_vukovic@hotmail.com>2015-04-21 02:31:12 +0200
commit3fd0ee5f0873924b4881b0e33eb1c17ea877ab4a (patch)
tree6a4ee64a3ea7f0191ccfd0205a68411cf0b84063 /toxav/audio.c
parentcbb8fdd4eab3bae4db1179f1fa04cdaa35957aeb (diff)
Final touchups
Diffstat (limited to 'toxav/audio.c')
-rw-r--r--toxav/audio.c383
1 files changed, 383 insertions, 0 deletions
diff --git a/toxav/audio.c b/toxav/audio.c
new file mode 100644
index 00000000..f3e969e9
--- /dev/null
+++ b/toxav/audio.c
@@ -0,0 +1,383 @@
1/** audio.c
2 *
3 * Copyright (C) 2013-2015 Tox project All Rights Reserved.
4 *
5 * This file is part of Tox.
6 *
7 * Tox is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * Tox is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include <stdlib.h>
23
24#include "audio.h"
25#include "rtp.h"
26
27#include "../toxcore/logger.h"
28
29static struct JitterBuffer *jbuf_new(uint32_t capacity);
30static void jbuf_clear(struct JitterBuffer *q);
31static void jbuf_free(struct JitterBuffer *q);
32static int jbuf_write(struct JitterBuffer *q, RTPMessage *m);
33static RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success);
34
35OpusEncoder* create_audio_encoder (int32_t bitrate, int32_t sampling_rate, int32_t channel_count);
36bool reconfigure_audio_decoder(ACSession* ac, int32_t sampling_rate, int8_t channels);
37
38
39
40ACSession* ac_new(ToxAV* av, uint32_t friend_id, toxav_receive_audio_frame_cb *cb, void *cb_data)
41{
42 ACSession *ac = calloc(sizeof(ACSession), 1);
43
44 if (!ac) {
45 LOGGER_WARNING("Allocation failed! Application might misbehave!");
46 return NULL;
47 }
48
49 if (create_recursive_mutex(ac->queue_mutex) != 0) {
50 LOGGER_WARNING("Failed to create recursive mutex!");
51 free(ac);
52 return NULL;
53 }
54
55 int status;
56 ac->decoder = opus_decoder_create(48000, 2, &status );
57
58 if ( status != OPUS_OK ) {
59 LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status));
60 goto BASE_CLEANUP;
61 }
62
63 if ( !(ac->j_buf = jbuf_new(3)) ) {
64 LOGGER_WARNING("Jitter buffer creaton failed!");
65 opus_decoder_destroy(ac->decoder);
66 goto BASE_CLEANUP;
67 }
68
69 /* Initialize encoders with default values */
70 ac->encoder = create_audio_encoder(48000, 48000, 2);
71 if (ac->encoder == NULL)
72 goto DECODER_CLEANUP;
73
74 ac->last_encoding_bitrate = 48000;
75 ac->last_encoding_sampling_rate = 48000;
76 ac->last_encoding_channel_count = 2;
77
78 ac->last_decoding_channel_count = 2;
79 ac->last_decoding_sampling_rate = 48000;
80 ac->last_decoder_reconfiguration = 0; /* Make it possible to reconfigure straight away */
81
82 /* These need to be set in order to properly
83 * do error correction with opus */
84 ac->last_packet_frame_duration = 120;
85 ac->last_packet_sampling_rate = 48000;
86
87 ac->av = av;
88 ac->friend_id = friend_id;
89 ac->acb.first = cb;
90 ac->acb.second = cb_data;
91
92 return ac;
93
94DECODER_CLEANUP:
95 opus_decoder_destroy(ac->decoder);
96 jbuf_free(ac->j_buf);
97BASE_CLEANUP:
98 pthread_mutex_destroy(ac->queue_mutex);
99 free(ac);
100 return NULL;
101}
102void ac_kill(ACSession* ac)
103{
104 if (!ac)
105 return;
106
107 opus_encoder_destroy(ac->encoder);
108 opus_decoder_destroy(ac->decoder);
109 jbuf_free(ac->j_buf);
110
111 pthread_mutex_destroy(ac->queue_mutex);
112
113 LOGGER_DEBUG("Terminated audio handler: %p", ac);
114 free(ac);
115}
116void ac_do(ACSession* ac)
117{
118 if (!ac)
119 return;
120
121 /* Enough space for the maximum frame size (120 ms 48 KHz audio) */
122 int16_t tmp[5760];
123
124 RTPMessage *msg;
125 int rc = 0;
126
127 pthread_mutex_lock(ac->queue_mutex);
128 while ((msg = jbuf_read(ac->j_buf, &rc)) || rc == 2) {
129 pthread_mutex_unlock(ac->queue_mutex);
130
131 if (rc == 2) {
132 LOGGER_DEBUG("OPUS correction");
133 rc = opus_decode(ac->decoder, NULL, 0, tmp,
134 (ac->last_packet_sampling_rate * ac->last_packet_frame_duration / 1000) /
135 ac->last_packet_channel_count, 1);
136 } else {
137 /* Get values from packet and decode. */
138 /* NOTE: This didn't work very well
139 rc = convert_bw_to_sampling_rate(opus_packet_get_bandwidth(msg->data));
140 if (rc != -1) {
141 cs->last_packet_sampling_rate = rc;
142 } else {
143 LOGGER_WARNING("Failed to load packet values!");
144 rtp_free_msg(NULL, msg);
145 continue;
146 }*/
147
148
149 /* Pick up sampling rate from packet */
150 memcpy(&ac->last_packet_sampling_rate, msg->data, 4);
151 ac->last_packet_sampling_rate = ntohl(ac->last_packet_sampling_rate);
152
153 ac->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4);
154
155 /*
156 * NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
157 * it didn't work quite well.
158 */
159 if (!reconfigure_audio_decoder(ac, ac->last_packet_sampling_rate, ac->last_packet_channel_count)) {
160 LOGGER_WARNING("Failed to reconfigure decoder!");
161 rtp_free_msg(NULL, msg);
162 continue;
163 }
164
165 rc = opus_decode(ac->decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0);
166 rtp_free_msg(NULL, msg);
167 }
168
169 if (rc < 0) {
170 LOGGER_WARNING("Decoding error: %s", opus_strerror(rc));
171 } else if (ac->acb.first) {
172 ac->last_packet_frame_duration = (rc * 1000) / ac->last_packet_sampling_rate * ac->last_packet_channel_count;
173
174 ac->acb.first(ac->av, ac->friend_id, tmp, rc * ac->last_packet_channel_count,
175 ac->last_packet_channel_count, ac->last_packet_sampling_rate, ac->acb.second);
176 }
177
178 return;
179 }
180 pthread_mutex_unlock(ac->queue_mutex);
181}
182int ac_reconfigure_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels)
183{
184 if (!ac)
185 return;
186
187 /* Values are checked in toxav.c */
188 if (ac->last_encoding_sampling_rate != sampling_rate || ac->last_encoding_channel_count != channels) {
189 OpusEncoder* new_encoder = create_audio_encoder(bitrate, sampling_rate, channels);
190 if (new_encoder == NULL)
191 return -1;
192
193 opus_encoder_destroy(ac->encoder);
194 ac->encoder = new_encoder;
195 } else if (ac->last_encoding_bitrate == bitrate)
196 return 0; /* Nothing changed */
197 else {
198 int status = opus_encoder_ctl(ac->encoder, OPUS_SET_BITRATE(bitrate));
199
200 if ( status != OPUS_OK ) {
201 LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(status));
202 return -1;
203 }
204 }
205
206 ac->last_encoding_bitrate = bitrate;
207 ac->last_encoding_sampling_rate = sampling_rate;
208 ac->last_encoding_channel_count = channels;
209
210 LOGGER_DEBUG ("Reconfigured audio encoder br: %d sr: %d cc:%d", bitrate, sampling_rate, channels);
211 return 0;
212}
213/* called from rtp */
214void ac_queue_message(void* acp, RTPMessage *msg)
215{
216 if (!acp || !msg)
217 return;
218
219 ACSession* ac = acp;
220
221 pthread_mutex_lock(ac->queue_mutex);
222 int ret = jbuf_write(ac->j_buf, msg);
223 pthread_mutex_unlock(ac->queue_mutex);
224
225 if (ret == -1)
226 rtp_free_msg(NULL, msg);
227}
228
229
230/* JITTER BUFFER WORK */
231struct JitterBuffer {
232 RTPMessage **queue;
233 uint32_t size;
234 uint32_t capacity;
235 uint16_t bottom;
236 uint16_t top;
237};
238
239static struct JitterBuffer *jbuf_new(uint32_t capacity)
240{
241 unsigned int size = 1;
242
243 while (size <= (capacity * 4)) {
244 size *= 2;
245 }
246
247 struct JitterBuffer *q;
248
249 if ( !(q = calloc(sizeof(struct JitterBuffer), 1)) ) return NULL;
250
251 if (!(q->queue = calloc(sizeof(RTPMessage *), size))) {
252 free(q);
253 return NULL;
254 }
255
256 q->size = size;
257 q->capacity = capacity;
258 return q;
259}
260static void jbuf_clear(struct JitterBuffer *q)
261{
262 for (; q->bottom != q->top; ++q->bottom) {
263 if (q->queue[q->bottom % q->size]) {
264 rtp_free_msg(NULL, q->queue[q->bottom % q->size]);
265 q->queue[q->bottom % q->size] = NULL;
266 }
267 }
268}
269static void jbuf_free(struct JitterBuffer *q)
270{
271 if (!q) return;
272
273 jbuf_clear(q);
274 free(q->queue);
275 free(q);
276}
277static int jbuf_write(struct JitterBuffer *q, RTPMessage *m)
278{
279 uint16_t sequnum = m->header->sequnum;
280
281 unsigned int num = sequnum % q->size;
282
283 if ((uint32_t)(sequnum - q->bottom) > q->size) {
284 LOGGER_DEBUG("Clearing filled jitter buffer: %p", q);
285
286 jbuf_clear(q);
287 q->bottom = sequnum - q->capacity;
288 q->queue[num] = m;
289 q->top = sequnum + 1;
290 return 0;
291 }
292
293 if (q->queue[num])
294 return -1;
295
296 q->queue[num] = m;
297
298 if ((sequnum - q->bottom) >= (q->top - q->bottom))
299 q->top = sequnum + 1;
300
301 return 0;
302}
303static RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success)
304{
305 if (q->top == q->bottom) {
306 *success = 0;
307 return NULL;
308 }
309
310 unsigned int num = q->bottom % q->size;
311
312 if (q->queue[num]) {
313 RTPMessage *ret = q->queue[num];
314 q->queue[num] = NULL;
315 ++q->bottom;
316 *success = 1;
317 return ret;
318 }
319
320 if ((uint32_t)(q->top - q->bottom) > q->capacity) {
321 ++q->bottom;
322 *success = 2;
323 return NULL;
324 }
325
326 *success = 0;
327 return NULL;
328}
329OpusEncoder* create_audio_encoder (int32_t bitrate, int32_t sampling_rate, int32_t channel_count)
330{
331 int status = OPUS_OK;
332 OpusEncoder* rc = opus_encoder_create(sampling_rate, channel_count, OPUS_APPLICATION_AUDIO, &status);
333
334 if ( status != OPUS_OK ) {
335 LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(status));
336 return NULL;
337 }
338
339 status = opus_encoder_ctl(rc, OPUS_SET_BITRATE(bitrate));
340
341 if ( status != OPUS_OK ) {
342 LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(status));
343 goto FAILURE;
344 }
345
346 status = opus_encoder_ctl(rc, OPUS_SET_COMPLEXITY(10));
347
348 if ( status != OPUS_OK ) {
349 LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(status));
350 goto FAILURE;
351 }
352
353 return rc;
354
355FAILURE:
356 opus_encoder_destroy(rc);
357 return NULL;
358}
359bool reconfigure_audio_decoder(ACSession* ac, int32_t sampling_rate, int8_t channels)
360{
361 if (sampling_rate != ac->last_decoding_sampling_rate || channels != ac->last_decoding_channel_count) {
362 if (current_time_monotonic() - ac->last_decoder_reconfiguration < 500)
363 return false;
364
365 int status;
366 OpusDecoder* new_dec = opus_decoder_create(sampling_rate, channels, &status );
367 if ( status != OPUS_OK ) {
368 LOGGER_ERROR("Error while starting audio decoder(%d %d): %s", sampling_rate, channels, opus_strerror(status));
369 return false;
370 }
371
372 ac->last_decoding_sampling_rate = sampling_rate;
373 ac->last_decoding_channel_count = channels;
374 ac->last_decoder_reconfiguration = current_time_monotonic();
375
376 opus_decoder_destroy(ac->decoder);
377 ac->decoder = new_dec;
378
379 LOGGER_DEBUG("Reconfigured audio decoder sr: %d cc: %d", sampling_rate, channels);
380 }
381
382 return true;
383} \ No newline at end of file