--- uae/src/sd-uss/sound.c 2018/04/24 17:17:21 1.1.1.9 +++ uae/src/sd-uss/sound.c 2018/04/24 17:19:12 1.1.1.10 @@ -13,6 +13,7 @@ #include "memory.h" #include "events.h" #include "custom.h" +#include "newcpu.h" #include "gensound.h" #include "sounddep/sound.h" #include "threaddep/thread.h" @@ -31,7 +32,7 @@ static smp_comm_pipe to_sound_pipe; static uae_sem_t sound_comm_sem; static int sound_fd; -static int have_sound = 0; +static int have_sound = 0, have_thread = 0; static int dont_block; static unsigned long formats; @@ -50,20 +51,27 @@ static int exact_log2 (int v) void finish_sound_buffers (void) { - dont_block = currprefs.m68k_speed == -1; - write_comm_pipe_int (&to_sound_pipe, 2, 1); - uae_sem_wait (&sound_comm_sem); + dont_block = currprefs.m68k_speed == -1 && (!regs.stopped || active_fs_packets > 0); + if (!dont_block) { + write (sound_fd, sndbuffer[which_buffer], sndbufsize); + } else { + write_comm_pipe_int (&to_sound_pipe, 2, 1); + uae_sem_wait (&sound_comm_sem); + } sndbufpt = sndbuf_base = sndbuffer[which_buffer ^= 1]; } void close_sound (void) { + sync_with_sound = 0; if (have_sound) close (sound_fd); - write_comm_pipe_int (&to_sound_pipe, 1, 1); - uae_sem_wait (&sound_comm_sem); - uae_sem_destroy (&sound_comm_sem); + if (have_thread) { + write_comm_pipe_int (&to_sound_pipe, 1, 1); + uae_sem_wait (&sound_comm_sem); + uae_sem_destroy (&sound_comm_sem); + } } /* Try to determine whether sound is available. This is only for GUI purposes. */ @@ -100,6 +108,8 @@ static void open_sound (void) int rate; int dspbits; + sync_with_sound = 0; + sound_fd = open ("/dev/dsp", O_WRONLY); have_sound = !(sound_fd < 0); if (! have_sound) { @@ -115,13 +125,9 @@ static void open_sound (void) if (currprefs.sound_maxbsiz < 128 || currprefs.sound_maxbsiz > 16384) { fprintf (stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz); - currprefs.sound_maxbsiz = 8192; + currprefs.sound_maxbsiz = 1024; } - tmp = 0x00040000 + exact_log2 (currprefs.sound_maxbsiz); - ioctl (sound_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); - ioctl (sound_fd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize); - dspbits = 16; ioctl (sound_fd, SNDCTL_DSP_SAMPLESIZE, &dspbits); ioctl (sound_fd, SOUND_PCM_READ_BITS, &dspbits); @@ -142,6 +148,17 @@ static void open_sound (void) goto out_err; } + tmp = 1 << exact_log2 (currprefs.sound_maxbsiz); + while (tmp * 1000 / (rate * 2 * (currprefs.sound_stereo ? 2 : 1)) < 6) + tmp *= 2; + if (tmp != currprefs.sound_maxbsiz) { + fprintf (stderr, "Increasing sound buffer size to sane minimum of %d bytes.\n", + tmp); + } + tmp = 0x00040000 + exact_log2 (tmp); + ioctl (sound_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); + ioctl (sound_fd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize); + obtainedfreq = rate; if (!(formats & AFMT_S16_NE)) @@ -154,6 +171,7 @@ static void open_sound (void) rate, sndbufsize, sndbufsize * 1000 / (rate * 2 * (currprefs.sound_stereo ? 2 : 1))); sndbufpt = sndbuf_base = sndbuffer[which_buffer = 0]; + sync_with_sound = 1; return; out_err: @@ -164,6 +182,7 @@ static void open_sound (void) static void *sound_thread (void *dummy) { + uae_u16 *base; for (;;) { int cmd = read_comm_pipe_int_blocking (&to_sound_pipe); int n; @@ -178,18 +197,19 @@ static void *sound_thread (void *dummy) return 0; case 2: /* If trying for maximum CPU speed, don't block the main - thread, instead set the blocking_on_sound variable. If + thread, instead set the delaying_for_sound variable. If not trying for maximum CPU speed, synchronize here by delaying the sem_post until after the write. */ - blocking_on_sound = dont_block; + delaying_for_sound = dont_block; + base = sndbuf_base; if (dont_block) uae_sem_post (&sound_comm_sem); - write (sound_fd, sndbuffer[which_buffer], sndbufsize); + write (sound_fd, sndbuf_base, sndbufsize); if (!dont_block) uae_sem_post (&sound_comm_sem); - blocking_on_sound = 0; + delaying_for_sound = 0; break; } } @@ -204,6 +224,7 @@ static void init_sound_thread (void) init_comm_pipe (&to_sound_pipe, 20, 1); uae_sem_init (&sound_comm_sem, 0, 0); uae_start_thread (sound_thread, NULL, &tid); + have_thread = 1; } int init_sound (void)