diff options
Diffstat (limited to 'toxav/audio.c')
-rw-r--r-- | toxav/audio.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/toxav/audio.c b/toxav/audio.c index f3e969e9..dc85452a 100644 --- a/toxav/audio.c +++ b/toxav/audio.c | |||
@@ -83,6 +83,7 @@ ACSession* ac_new(ToxAV* av, uint32_t friend_id, toxav_receive_audio_frame_cb *c | |||
83 | * do error correction with opus */ | 83 | * do error correction with opus */ |
84 | ac->last_packet_frame_duration = 120; | 84 | ac->last_packet_frame_duration = 120; |
85 | ac->last_packet_sampling_rate = 48000; | 85 | ac->last_packet_sampling_rate = 48000; |
86 | ac->last_packet_channel_count = 1; | ||
86 | 87 | ||
87 | ac->av = av; | 88 | ac->av = av; |
88 | ac->friend_id = friend_id; | 89 | ac->friend_id = friend_id; |
@@ -119,7 +120,7 @@ void ac_do(ACSession* ac) | |||
119 | return; | 120 | return; |
120 | 121 | ||
121 | /* Enough space for the maximum frame size (120 ms 48 KHz audio) */ | 122 | /* Enough space for the maximum frame size (120 ms 48 KHz audio) */ |
122 | int16_t tmp[5760]; | 123 | int16_t tmp[5760 * 2]; |
123 | 124 | ||
124 | RTPMessage *msg; | 125 | RTPMessage *msg; |
125 | int rc = 0; | 126 | int rc = 0; |
@@ -130,9 +131,8 @@ void ac_do(ACSession* ac) | |||
130 | 131 | ||
131 | if (rc == 2) { | 132 | if (rc == 2) { |
132 | LOGGER_DEBUG("OPUS correction"); | 133 | LOGGER_DEBUG("OPUS correction"); |
133 | rc = opus_decode(ac->decoder, NULL, 0, tmp, | 134 | int fs = (ac->last_packet_sampling_rate * ac->last_packet_frame_duration) / 1000; |
134 | (ac->last_packet_sampling_rate * ac->last_packet_frame_duration / 1000) / | 135 | rc = opus_decode(ac->decoder, NULL, 0, tmp, fs, 1); |
135 | ac->last_packet_channel_count, 1); | ||
136 | } else { | 136 | } else { |
137 | /* Get values from packet and decode. */ | 137 | /* Get values from packet and decode. */ |
138 | /* NOTE: This didn't work very well | 138 | /* NOTE: This didn't work very well |
@@ -152,10 +152,9 @@ void ac_do(ACSession* ac) | |||
152 | 152 | ||
153 | ac->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4); | 153 | ac->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4); |
154 | 154 | ||
155 | /* | 155 | /** NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa, |
156 | * NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa, | 156 | * it didn't work quite well. |
157 | * it didn't work quite well. | 157 | */ |
158 | */ | ||
159 | if (!reconfigure_audio_decoder(ac, ac->last_packet_sampling_rate, ac->last_packet_channel_count)) { | 158 | if (!reconfigure_audio_decoder(ac, ac->last_packet_sampling_rate, ac->last_packet_channel_count)) { |
160 | LOGGER_WARNING("Failed to reconfigure decoder!"); | 159 | LOGGER_WARNING("Failed to reconfigure decoder!"); |
161 | rtp_free_msg(NULL, msg); | 160 | rtp_free_msg(NULL, msg); |
@@ -169,7 +168,7 @@ void ac_do(ACSession* ac) | |||
169 | if (rc < 0) { | 168 | if (rc < 0) { |
170 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); | 169 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); |
171 | } else if (ac->acb.first) { | 170 | } else if (ac->acb.first) { |
172 | ac->last_packet_frame_duration = (rc * 1000) / ac->last_packet_sampling_rate * ac->last_packet_channel_count; | 171 | ac->last_packet_frame_duration = (rc * 1000) / ac->last_packet_sampling_rate; |
173 | 172 | ||
174 | ac->acb.first(ac->av, ac->friend_id, tmp, rc * ac->last_packet_channel_count, | 173 | 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); | 174 | ac->last_packet_channel_count, ac->last_packet_sampling_rate, ac->acb.second); |
@@ -179,6 +178,37 @@ void ac_do(ACSession* ac) | |||
179 | } | 178 | } |
180 | pthread_mutex_unlock(ac->queue_mutex); | 179 | pthread_mutex_unlock(ac->queue_mutex); |
181 | } | 180 | } |
181 | int ac_queue_message(void* acp, struct RTPMessage_s *msg) | ||
182 | { | ||
183 | if (!acp || !msg) | ||
184 | return -1; | ||
185 | |||
186 | if ((msg->header->marker_payloadt & 0x7f) == rtp_TypeDummyAudio % 128) { | ||
187 | LOGGER_WARNING("Got dummy!"); | ||
188 | rtp_free_msg(NULL, msg); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | if ((msg->header->marker_payloadt & 0x7f) != rtp_TypeAudio % 128) { | ||
193 | LOGGER_WARNING("Invalid payload type!"); | ||
194 | rtp_free_msg(NULL, msg); | ||
195 | return -1; | ||
196 | } | ||
197 | |||
198 | ACSession* ac = acp; | ||
199 | |||
200 | pthread_mutex_lock(ac->queue_mutex); | ||
201 | int rc = jbuf_write(ac->j_buf, msg); | ||
202 | pthread_mutex_unlock(ac->queue_mutex); | ||
203 | |||
204 | if (rc == -1) { | ||
205 | LOGGER_WARNING("Could not queue the message!"); | ||
206 | rtp_free_msg(NULL, msg); | ||
207 | return -1; | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
182 | int ac_reconfigure_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels) | 212 | int ac_reconfigure_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate, uint8_t channels) |
183 | { | 213 | { |
184 | if (!ac) | 214 | if (!ac) |
@@ -210,21 +240,7 @@ int ac_reconfigure_encoder(ACSession* ac, int32_t bitrate, int32_t sampling_rate | |||
210 | LOGGER_DEBUG ("Reconfigured audio encoder br: %d sr: %d cc:%d", bitrate, sampling_rate, channels); | 240 | LOGGER_DEBUG ("Reconfigured audio encoder br: %d sr: %d cc:%d", bitrate, sampling_rate, channels); |
211 | return 0; | 241 | return 0; |
212 | } | 242 | } |
213 | /* called from rtp */ | ||
214 | void 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 | 243 | ||
225 | if (ret == -1) | ||
226 | rtp_free_msg(NULL, msg); | ||
227 | } | ||
228 | 244 | ||
229 | 245 | ||
230 | /* JITTER BUFFER WORK */ | 246 | /* JITTER BUFFER WORK */ |