--- uae/src/sd-sdl/sound.c 2018/04/24 17:04:46 1.1.1.2 +++ uae/src/sd-sdl/sound.c 2018/04/24 17:20:52 1.1.1.7 @@ -1,19 +1,19 @@ - /* + /* * UAE - The Un*x Amiga Emulator - * + * * Support for Linux/USS sound - * + * * Copyright 1997 Bernd Schmidt */ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "options.h" #include "memory.h" #include "events.h" #include "custom.h" +#include "newcpu.h" #include "gensound.h" #include "sounddep/sound.h" #include "threaddep/thread.h" @@ -23,14 +23,17 @@ int sound_fd; static int have_sound = 0; static unsigned long formats; -uae_u16 sndbuffer[44100]; -uae_u16 *sndbufpt; +uae_u16 sndbuffer[2][44100]; +uae_u16 *sndbufpt, *sndbuf_base, *callback_sndbuf; +int which_buffer; int sndbufsize; static SDL_AudioSpec spec; static smp_comm_pipe to_sound_pipe; static uae_sem_t data_available_sem, callback_done_sem, sound_init_sem; +static int dont_block; + static int in_callback, closing_sound; static void sound_callback (void *userdata, Uint8 *stream, int len) @@ -38,20 +41,31 @@ static void sound_callback (void *userda if (closing_sound) return; in_callback = 1; + delaying_for_sound = 0; + /* Wait for data to finish. */ uae_sem_wait (&data_available_sem); if (! closing_sound) { - memcpy (stream, sndbuffer, sndbufsize); + memcpy (stream, callback_sndbuf, sndbufsize); + /* Notify writer that we're done. */ - uae_sem_post (&callback_done_sem); + if (!dont_block) + uae_sem_post (&callback_done_sem); } in_callback = 0; } void finish_sound_buffer (void) { + dont_block = currprefs.m68k_speed == -1 && (!regs.stopped || active_fs_packets > 0); + callback_sndbuf = sndbuf_base; + + if (dont_block) + delaying_for_sound = 1; uae_sem_post (&data_available_sem); - uae_sem_wait (&callback_done_sem); + if (!dont_block) + uae_sem_wait (&callback_done_sem); + sndbufpt = sndbuf_base = sndbuffer[which_buffer ^= 1]; } /* Try to determine whether sound is available. This is only for GUI purposes. */ @@ -61,7 +75,7 @@ int setup_sound (void) spec.freq = currprefs.sound_freq; spec.format = AUDIO_S16; - spec.channels = currprefs.stereo ? 2 : 1; + spec.channels = 2; size >>= spec.channels - 1; size >>= 1; while (size & (size - 1)) @@ -73,7 +87,7 @@ int setup_sound (void) spec.userdata = 0; if (SDL_OpenAudio (&spec, NULL) < 0) { - write_log (stderr, "Couldn't open audio: %s\n", SDL_GetError()); + write_log ("Couldn't open audio: %s\n", SDL_GetError()); return 0; } sound_available = 1; @@ -83,17 +97,22 @@ int setup_sound (void) static int open_sound (void) { + SDL_AudioSpec obtained; int size = currprefs.sound_maxbsiz; + sync_with_sound = 0; + spec.freq = currprefs.sound_freq; - spec.format = currprefs.sound_bits == 8 ? AUDIO_U8 : AUDIO_S16; - spec.channels = currprefs.stereo ? 2 : 1; + spec.format = AUDIO_S16; + spec.channels = 2; + /* Always interpret buffer size as number of samples, not as actual buffer size. Of course, since 8192 is the default, we'll have to scale that to a sane value (assuming that otherwise 16 bits and stereo would have been enabled and we'd have done the shift by two anyway). */ - size >>= 2; + size >>= spec.channels; + while (size & (size - 1)) size &= size - 1; if (size < 512) @@ -102,27 +121,23 @@ static int open_sound (void) spec.callback = sound_callback; spec.userdata = 0; - if (SDL_OpenAudio (&spec, NULL) < 0) { - write_log (stderr, "Couldn't open audio: %s\n", SDL_GetError()); + if (SDL_OpenAudio (&spec, &obtained) < 0) { + write_log ("Couldn't open audio: %s\n", SDL_GetError()); return 0; } have_sound = 1; - scaled_sample_evtime = (unsigned long)MAXHPOS_PAL * MAXVPOS_PAL * VBLANK_HZ_PAL * CYCLE_UNIT / spec.freq; - scaled_sample_evtime_ok = 1; + obtainedfreq = obtained.freq; + + init_sound_table16 (); + sample_handler = sample16s_handler; - if (spec.format == AUDIO_S16) { - init_sound_table16 (); - sample_handler = currprefs.stereo ? sample16s_handler : sample16_handler; - } else { - init_sound_table8 (); - sample_handler = currprefs.stereo ? sample8s_handler : sample8_handler; - } sound_available = 1; - write_log ("SDL sound driver found and configured for %d bits at %d Hz, buffer is %d samples\n", - currprefs.sound_bits, spec.freq, spec.samples); - sndbufpt = sndbuffer; - sndbufsize = size * currprefs.sound_bits / 8 * spec.channels; + sndbufpt = sndbuf_base = sndbuffer[which_buffer = 0]; + sndbufsize = size * 2 * obtained.channels; + write_log ("SDL sound driver found and configured at %d Hz, buffer is %d samples (%d ms).\n", + obtainedfreq, obtained.samples, obtained.samples * 1000 / obtainedfreq); + sync_with_sound = 1; return 1; } @@ -161,6 +176,8 @@ static void init_sound_thread (void) void close_sound (void) { + sync_with_sound = 0; + if (! have_sound) return;