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.
This commit is contained in:
Dave Vasilevsky 2015-12-27 22:13:00 -05:00
parent db375713bb
commit 09a0525aac

View File

@ -45,6 +45,9 @@ static int audio_channel_count_index = 0;
// Global variables // Global variables
static SDL_sem *audio_irq_done_sem = NULL; // Signal from interrupt to streaming thread: data block read 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 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 // Prototypes
static void stream_func(void *arg, uint8 *stream, int stream_len); 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 // Sound buffer size = 4096 frames
audio_frames_per_block = audio_spec.samples; audio_frames_per_block = audio_spec.samples;
audio_mix_buf = (uint8*)malloc(audio_spec.size);
return true; return true;
} }
@ -156,6 +160,7 @@ static void close_audio(void)
{ {
// Close audio device // Close audio device
SDL_CloseAudio(); SDL_CloseAudio();
free(audio_mix_buf);
audio_open = false; audio_open = false;
} }
@ -195,7 +200,6 @@ void audio_exit_stream()
static void stream_func(void *arg, uint8 *stream, int stream_len) static void stream_func(void *arg, uint8 *stream, int stream_len)
{ {
if (AudioStatus.num_sources) { if (AudioStatus.num_sources) {
// Trigger audio interrupt to get new buffer // Trigger audio interrupt to get new buffer
D(bug("stream: triggering irq\n")); D(bug("stream: triggering irq\n"));
SetInterruptFlag(INTFLAG_AUDIO); SetInterruptFlag(INTFLAG_AUDIO);
@ -206,7 +210,7 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
// Get size of audio data // Get size of audio data
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo); 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; int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
D(bug("stream: work_size %d\n", work_size)); D(bug("stream: work_size %d\n", work_size));
if (work_size > stream_len) if (work_size > stream_len)
@ -215,10 +219,16 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
goto silence; goto silence;
// Send data to audio device // Send data to audio device
Mac2Host_memcpy(stream, ReadMacInt32(apple_stream_info + scd_buffer), work_size); Mac2Host_memcpy(audio_mix_buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
if (work_size != stream_len) memset((uint8 *)stream, silence_byte, stream_len);
memset((uint8 *)stream + work_size, silence_byte, stream_len - work_size); 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")); D(bug("stream: data written\n"));
} else } else
goto silence; goto silence;
@ -293,30 +303,37 @@ bool audio_set_channels(int index)
bool audio_get_main_mute(void) bool audio_get_main_mute(void)
{ {
return false; return audio_mute;
} }
uint32 audio_get_main_volume(void) 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) bool audio_get_speaker_mute(void)
{ {
return false; return audio_mute;
} }
uint32 audio_get_speaker_volume(void) uint32 audio_get_speaker_volume(void)
{ {
return 0x01000100; return audio_get_main_volume();
} }
void audio_set_main_mute(bool mute) void audio_set_main_mute(bool mute)
{ {
audio_mute = mute;
} }
void audio_set_main_volume(uint32 vol) 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) void audio_set_speaker_mute(bool mute)