summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/sdl/pcm-sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/hosted/sdl/pcm-sdl.c')
-rw-r--r--firmware/target/hosted/sdl/pcm-sdl.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/firmware/target/hosted/sdl/pcm-sdl.c b/firmware/target/hosted/sdl/pcm-sdl.c
index 7780083b99..dfdd90f29b 100644
--- a/firmware/target/hosted/sdl/pcm-sdl.c
+++ b/firmware/target/hosted/sdl/pcm-sdl.c
@@ -30,6 +30,7 @@
30#include "sound.h" 30#include "sound.h"
31#include "audiohw.h" 31#include "audiohw.h"
32#include "system.h" 32#include "system.h"
33#include "panic.h"
33 34
34#ifdef HAVE_RECORDING 35#ifdef HAVE_RECORDING
35#include "audiohw.h" 36#include "audiohw.h"
@@ -39,6 +40,7 @@
39#endif 40#endif
40 41
41#include "pcm.h" 42#include "pcm.h"
43#include "pcm-internal.h"
42#include "pcm_sampr.h" 44#include "pcm_sampr.h"
43 45
44/*#define LOGF_ENABLE*/ 46/*#define LOGF_ENABLE*/
@@ -71,15 +73,19 @@ static struct pcm_udata
71 73
72static SDL_AudioSpec obtained; 74static SDL_AudioSpec obtained;
73static SDL_AudioCVT cvt; 75static SDL_AudioCVT cvt;
76static int audio_locked = 0;
77static SDL_mutex *audio_lock;
74 78
75void pcm_play_lock(void) 79void pcm_play_lock(void)
76{ 80{
77 SDL_LockAudio(); 81 if (++audio_locked == 1)
82 SDL_LockMutex(audio_lock);
78} 83}
79 84
80void pcm_play_unlock(void) 85void pcm_play_unlock(void)
81{ 86{
82 SDL_UnlockAudio(); 87 if (--audio_locked == 0)
88 SDL_UnlockMutex(audio_lock);
83} 89}
84 90
85static void pcm_dma_apply_settings_nolock(void) 91static void pcm_dma_apply_settings_nolock(void)
@@ -227,14 +233,19 @@ static void write_to_soundcard(struct pcm_udata *udata)
227static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len) 233static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
228{ 234{
229 logf("sdl_audio_callback: len %d, pcm %d\n", len, pcm_data_size); 235 logf("sdl_audio_callback: len %d, pcm %d\n", len, pcm_data_size);
236
237 bool new_buffer = false;
230 udata->stream = stream; 238 udata->stream = stream;
231 239
240 SDL_LockMutex(audio_lock);
241
232 /* Write what we have in the PCM buffer */ 242 /* Write what we have in the PCM buffer */
233 if (pcm_data_size > 0) 243 if (pcm_data_size > 0)
234 goto start; 244 goto start;
235 245
236 /* Audio card wants more? Get some more then. */ 246 /* Audio card wants more? Get some more then. */
237 while (len > 0) { 247 while (len > 0) {
248 new_buffer = true;
238 pcm_play_get_more_callback((void **)&pcm_data, &pcm_data_size); 249 pcm_play_get_more_callback((void **)&pcm_data, &pcm_data_size);
239 start: 250 start:
240 if (pcm_data_size != 0) { 251 if (pcm_data_size != 0) {
@@ -246,6 +257,28 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
246 udata->num_in *= pcm_sample_bytes; 257 udata->num_in *= pcm_sample_bytes;
247 udata->num_out *= pcm_sample_bytes; 258 udata->num_out *= pcm_sample_bytes;
248 259
260
261 if (new_buffer)
262 {
263 new_buffer = false;
264 pcm_play_dma_started_callback();
265
266 if ((size_t)len > udata->num_out)
267 {
268 int delay = pcm_data_size*250 / pcm_sampr - 1;
269
270 if (delay > 0)
271 {
272 SDL_UnlockMutex(audio_lock);
273 SDL_Delay(delay);
274 SDL_LockMutex(audio_lock);
275
276 if (!pcm_is_playing())
277 break;
278 }
279 }
280 }
281
249 pcm_data += udata->num_in; 282 pcm_data += udata->num_in;
250 pcm_data_size -= udata->num_in; 283 pcm_data_size -= udata->num_in;
251 udata->stream += udata->num_out; 284 udata->stream += udata->num_out;
@@ -255,6 +288,8 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
255 break; 288 break;
256 } 289 }
257 } 290 }
291
292 SDL_UnlockMutex(audio_lock);
258} 293}
259 294
260const void * pcm_play_dma_get_peak_buffer(int *count) 295const void * pcm_play_dma_get_peak_buffer(int *count)
@@ -320,6 +355,14 @@ void pcm_play_dma_init(void)
320 return; 355 return;
321 } 356 }
322 357
358 audio_lock = SDL_CreateMutex();
359
360 if (!audio_lock)
361 {
362 panicf("Could not create audio_lock\n");
363 return;
364 }
365
323 SDL_AudioSpec wanted_spec; 366 SDL_AudioSpec wanted_spec;
324#ifdef DEBUG 367#ifdef DEBUG
325 udata.debug = NULL; 368 udata.debug = NULL;