From 09a0525aace673be75cfed0ff03af41429cc5dff Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Sun, 27 Dec 2015 22:13:00 -0500 Subject: [PATCH 1/3] Enable audio volume in SDL This is useful for keeping the volume of SS/B2 separate from that of the host machine. For example, you can mute a game in SS, while still playing music on your host. --- BasiliskII/src/SDL/audio_sdl.cpp | 35 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/BasiliskII/src/SDL/audio_sdl.cpp b/BasiliskII/src/SDL/audio_sdl.cpp index 81fff018..3f418a14 100644 --- a/BasiliskII/src/SDL/audio_sdl.cpp +++ b/BasiliskII/src/SDL/audio_sdl.cpp @@ -45,6 +45,9 @@ static int audio_channel_count_index = 0; // Global variables static SDL_sem *audio_irq_done_sem = NULL; // Signal from interrupt to streaming thread: data block read static uint8 silence_byte; // Byte value to use to fill sound buffers with silence +static uint8 *audio_mix_buf = NULL; +static int audio_volume = SDL_MIX_MAXVOLUME; +static bool audio_mute = false; // Prototypes static void stream_func(void *arg, uint8 *stream, int stream_len); @@ -107,6 +110,7 @@ static bool open_sdl_audio(void) // Sound buffer size = 4096 frames audio_frames_per_block = audio_spec.samples; + audio_mix_buf = (uint8*)malloc(audio_spec.size); return true; } @@ -156,6 +160,7 @@ static void close_audio(void) { // Close audio device SDL_CloseAudio(); + free(audio_mix_buf); audio_open = false; } @@ -195,7 +200,6 @@ void audio_exit_stream() static void stream_func(void *arg, uint8 *stream, int stream_len) { if (AudioStatus.num_sources) { - // Trigger audio interrupt to get new buffer D(bug("stream: triggering irq\n")); SetInterruptFlag(INTFLAG_AUDIO); @@ -206,7 +210,7 @@ static void stream_func(void *arg, uint8 *stream, int stream_len) // Get size of audio data uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); - if (apple_stream_info) { + if (apple_stream_info && !audio_mute) { int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels; D(bug("stream: work_size %d\n", work_size)); if (work_size > stream_len) @@ -215,10 +219,16 @@ static void stream_func(void *arg, uint8 *stream, int stream_len) goto silence; // Send data to audio device - Mac2Host_memcpy(stream, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - if (work_size != stream_len) - memset((uint8 *)stream + work_size, silence_byte, stream_len - work_size); + Mac2Host_memcpy(audio_mix_buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size); + memset((uint8 *)stream, silence_byte, stream_len); + SDL_MixAudio(stream, audio_mix_buf, work_size, audio_volume); + + // Mac2Host_memcpy(stream, ReadMacInt32(apple_stream_info + scd_buffer), work_size); + // if (work_size != stream_len) + // memset((uint8 *)stream + work_size, silence_byte, stream_len - work_size); + D(bug("stream: data written\n")); + } else goto silence; @@ -293,30 +303,37 @@ bool audio_set_channels(int index) bool audio_get_main_mute(void) { - return false; + return audio_mute; } uint32 audio_get_main_volume(void) { - return 0x01000100; + uint32 chan = (audio_volume * 0x0100 / SDL_MIX_MAXVOLUME); + return (chan << 16) + chan; } bool audio_get_speaker_mute(void) { - return false; + return audio_mute; } uint32 audio_get_speaker_volume(void) { - return 0x01000100; + return audio_get_main_volume(); } void audio_set_main_mute(bool mute) { + audio_mute = mute; } void audio_set_main_volume(uint32 vol) { + // We only have one-channel volume right now. + uint32 avg = ((vol >> 16) + (vol & 0xffff)) / 2; + if (avg > 0x0100) + avg = 0x0100; + audio_volume = avg * SDL_MIX_MAXVOLUME / 0x0100; } void audio_set_speaker_mute(bool mute) From 4fa03d5fb18d8ab01b65cda2bd81d002813372fd Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Sun, 27 Dec 2015 22:39:23 -0500 Subject: [PATCH 2/3] Cleanups: Set to NULL after free, remove commented out code --- BasiliskII/src/SDL/audio_sdl.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/BasiliskII/src/SDL/audio_sdl.cpp b/BasiliskII/src/SDL/audio_sdl.cpp index 3f418a14..b1d1080a 100644 --- a/BasiliskII/src/SDL/audio_sdl.cpp +++ b/BasiliskII/src/SDL/audio_sdl.cpp @@ -161,6 +161,7 @@ static void close_audio(void) // Close audio device SDL_CloseAudio(); free(audio_mix_buf); + audio_mix_buf = NULL; audio_open = false; } @@ -223,10 +224,6 @@ static void stream_func(void *arg, uint8 *stream, int stream_len) memset((uint8 *)stream, silence_byte, stream_len); SDL_MixAudio(stream, audio_mix_buf, work_size, audio_volume); - // Mac2Host_memcpy(stream, ReadMacInt32(apple_stream_info + scd_buffer), work_size); - // if (work_size != stream_len) - // memset((uint8 *)stream + work_size, silence_byte, stream_len - work_size); - D(bug("stream: data written\n")); } else From c2236350f46fecaa0f65f8e5045b06f0919d8d89 Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Sun, 27 Dec 2015 22:42:37 -0500 Subject: [PATCH 3/3] Use constant for max volume --- BasiliskII/src/SDL/audio_sdl.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/BasiliskII/src/SDL/audio_sdl.cpp b/BasiliskII/src/SDL/audio_sdl.cpp index b1d1080a..921beb4c 100644 --- a/BasiliskII/src/SDL/audio_sdl.cpp +++ b/BasiliskII/src/SDL/audio_sdl.cpp @@ -37,6 +37,8 @@ #endif +#define MAC_MAX_VOLUME 0x0100 + // The currently selected audio parameters (indices in audio_sample_rates[] etc. vectors) static int audio_sample_rate_index = 0; static int audio_sample_size_index = 0; @@ -305,7 +307,7 @@ bool audio_get_main_mute(void) uint32 audio_get_main_volume(void) { - uint32 chan = (audio_volume * 0x0100 / SDL_MIX_MAXVOLUME); + uint32 chan = (audio_volume * MAC_MAX_VOLUME / SDL_MIX_MAXVOLUME); return (chan << 16) + chan; } @@ -328,9 +330,9 @@ void audio_set_main_volume(uint32 vol) { // We only have one-channel volume right now. uint32 avg = ((vol >> 16) + (vol & 0xffff)) / 2; - if (avg > 0x0100) - avg = 0x0100; - audio_volume = avg * SDL_MIX_MAXVOLUME / 0x0100; + if (avg > MAC_MAX_VOLUME) + avg = MAC_MAX_VOLUME; + audio_volume = avg * SDL_MIX_MAXVOLUME / MAC_MAX_VOLUME; } void audio_set_speaker_mute(bool mute)