diff --git a/src/Sound.cpp b/src/Sound.cpp index e806038f..a408a168 100644 --- a/src/Sound.cpp +++ b/src/Sound.cpp @@ -10,6 +10,8 @@ #include "dmg/gb_apu/Gb_Apu.h" #include "dmg/gb_apu/Multi_Buffer.h" +#include "common/SoundDriver.h" + #define NR10 0x60 #define NR11 0x62 #define NR12 0x63 @@ -32,21 +34,21 @@ #define NR51 0x81 #define NR52 0x84 +SoundDriver * soundDriver = 0; + extern bool stopState; // TODO: silence sound when true int const SOUND_CLOCK_TICKS_ = 167772; // 1/100 second -u16 soundFinalWave [1470]; -int soundBufferLen = sizeof soundFinalWave; +static u16 soundFinalWave [1470]; int soundQuality = 1; bool soundInterpolation = true; bool soundPaused = true; float soundFiltering = 0.5f; -float soundVolume = 1.0f; -bool soundEcho = false; int SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_; int soundTicks = SOUND_CLOCK_TICKS_; +static float soundVolume = 1.0f; static int soundEnableFlag = 0x3ff; // emulator channels enabled static float soundFiltering_ = -1; static float soundVolume_ = -1; @@ -344,8 +346,11 @@ static void end_frame( blip_time_t time ) stereo_buffer->end_frame( time ); } -static void flush_samples() +void flush_samples(Multi_Buffer * buffer) { + // get the size in bytes of the sound driver buffer + int soundBufferLen = soundDriver->getBufferLength(); + // soundBufferLen should have a whole number of sample pairs assert( soundBufferLen % (2 * sizeof *soundFinalWave) == 0 ); @@ -353,13 +358,13 @@ static void flush_samples() int const out_buf_size = soundBufferLen / sizeof *soundFinalWave; // Keep filling and writing soundFinalWave until it can't be fully filled - while ( stereo_buffer->samples_avail() >= out_buf_size ) + while ( buffer->samples_avail() >= out_buf_size ) { - stereo_buffer->read_samples( (blip_sample_t*) soundFinalWave, out_buf_size ); + buffer->read_samples( (blip_sample_t*) soundFinalWave, out_buf_size ); if(soundPaused) soundResume(); - systemWriteDataToSoundBuffer(); + soundDriver->write(soundFinalWave, soundBufferLen); } } @@ -386,7 +391,7 @@ void psoundTickfn() // Run sound hardware to present end_frame( SOUND_CLOCK_TICKS ); - flush_samples(); + flush_samples(stereo_buffer); if ( soundFiltering_ != soundFiltering ) apply_filtering(); @@ -464,19 +469,19 @@ static void remake_stereo_buffer() void soundShutdown() { - systemSoundShutdown(); + delete soundDriver; } void soundPause() { soundPaused = true; - systemSoundPause(); + soundDriver->pause(); } void soundResume() { soundPaused = false; - systemSoundResume(); + soundDriver->resume(); } void soundSetVolume( float volume ) @@ -502,7 +507,7 @@ int soundGetEnable() void soundReset() { - systemSoundReset(); + soundDriver->reset(); remake_stereo_buffer(); reset_apu(); @@ -516,7 +521,11 @@ void soundReset() bool soundInit() { - if ( !systemSoundInit() ) + soundDriver = systemSoundInit(); + if ( !soundDriver ) + return false; + + if (!soundDriver->init(soundQuality)) return false; soundPaused = true; diff --git a/src/Sound.h b/src/Sound.h index 94a1319c..8fe9a154 100644 --- a/src/Sound.h +++ b/src/Sound.h @@ -33,16 +33,10 @@ extern bool soundPaused; // current paused state // Cleans up sound. Afterwards, soundInit() can be called again. void soundShutdown(); -// Sound buffering -extern int soundBufferLen; // size of sound buffer in BYTES -extern u16 soundFinalWave[1470];// 16-bit SIGNED stereo sample buffer - - //// GBA sound options // Sets sample rate to 44100 / quality void soundSetQuality( int quality ); -extern int soundQuality; // current sound quality // Sound settings extern bool soundInterpolation; // 1 if PCM should have low-pass filtering @@ -80,4 +74,8 @@ extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() w void soundSaveGame( gzFile ); void soundReadGame( gzFile, int version ); +class Multi_Buffer; + +void flush_samples(Multi_Buffer * buffer); + #endif // SOUND_H diff --git a/src/System.h b/src/System.h index 28d72e36..543f81b9 100644 --- a/src/System.h +++ b/src/System.h @@ -20,6 +20,7 @@ typedef int16_t s16; typedef int32_t s32; typedef int64_t s64; +class SoundDriver; struct EmulatedSystem { // main emulation function @@ -65,12 +66,7 @@ extern u32 systemReadJoypad(int); extern u32 systemGetClock(); extern void systemMessage(int, const char *, ...); extern void systemSetTitle(const char *); -extern void systemWriteDataToSoundBuffer(); -extern void systemSoundShutdown(); -extern void systemSoundPause(); -extern void systemSoundResume(); -extern void systemSoundReset(); -extern bool systemSoundInit(); +extern SoundDriver * systemSoundInit(); extern void systemScreenMessage(const char *); extern void systemUpdateMotionSensor(); extern int systemGetSensorX(); diff --git a/src/agb/GBA.cpp b/src/agb/GBA.cpp index a0a8318b..18515ad5 100644 --- a/src/agb/GBA.cpp +++ b/src/agb/GBA.cpp @@ -1320,7 +1320,7 @@ int CPULoadRom(const char *szFile) elfCleanUp(); return 0; } - } else + } else #endif //NO_DEBUGGER if(!utilLoad(szFile, utilIsGBAImage, @@ -1952,9 +1952,9 @@ void CPUSoftwareInterrupt(int comment) } #endif if(reg[0].I) - systemSoundPause(); + soundPause(); else - systemSoundResume(); + soundResume(); break; case 0x1F: BIOS_MidiKey2Freq(); diff --git a/src/dmg/gbSound.cpp b/src/dmg/gbSound.cpp index c47452e8..83c6b9ac 100644 --- a/src/dmg/gbSound.cpp +++ b/src/dmg/gbSound.cpp @@ -50,22 +50,6 @@ static void end_frame( blip_time_t time ) stereo_buffer->end_frame( time ); } -static void flush_samples() -{ - // number of samples in output buffer - int const out_buf_size = soundBufferLen / sizeof *soundFinalWave; - - // Keep filling and writing soundFinalWave until it can't be fully filled - while ( stereo_buffer->samples_avail() >= out_buf_size ) - { - stereo_buffer->read_samples( (blip_sample_t*) soundFinalWave, out_buf_size ); - if(soundPaused) - soundResume(); - - systemWriteDataToSoundBuffer(); - } -} - static void apply_effects() { prevSoundEnable = soundGetEnable(); @@ -106,13 +90,13 @@ void gbSoundTick() // Run sound hardware to present end_frame( SOUND_CLOCK_TICKS * ticks_to_time ); - flush_samples(); + flush_samples(stereo_buffer); // Update effects config if it was changed if ( memcmp( &gb_effects_config_current, &gb_effects_config, sizeof gb_effects_config ) || soundGetEnable() != prevSoundEnable ) apply_effects(); - + if ( soundVolume_ != soundGetVolume() ) apply_volume(); } @@ -127,7 +111,7 @@ static void reset_apu() mode = Gb_Apu::mode_agb; gb_apu->reset( mode ); gb_apu->reduce_clicks( declicking ); - + if ( stereo_buffer ) stereo_buffer->clear(); @@ -367,7 +351,7 @@ static void gbSoundReadGameOld(int version,gzFile gzFile) state.apu.regs [nr52] = 0x80; // power on return; } - + // Load state utilReadData( gzFile, gbsound_format ); @@ -400,7 +384,7 @@ static void gbSoundReadGameOld(int version,gzFile gzFile) static variable_desc gb_state [] = { LOAD( int, state.version ), // room_for_expansion will be used by later versions - + // APU LOAD( u8 [0x40], state.apu.regs ), // last values written to registers and wave RAM (both banks) LOAD( int, state.apu.frame_time ), // clocks until next frame sequencer action @@ -446,7 +430,7 @@ void gbSoundReadGame( int version, gzFile in ) // Prepare APU and default state reset_apu(); gb_apu->save_state( &state.apu ); - + if ( version > 11 ) utilReadData( in, gb_state ); else diff --git a/src/gtk/system.cpp b/src/gtk/system.cpp index a2cb0bc3..93796f76 100644 --- a/src/gtk/system.cpp +++ b/src/gtk/system.cpp @@ -49,8 +49,6 @@ int RGB_LOW_BITS_MASK; int systemRenderedFrames; int systemFPS; -static SoundDriver * systemSoundDriver = 0; - inline VBA::Window * GUI() { return VBA::Window::poGetInstance(); @@ -156,39 +154,11 @@ void systemGbBorderOn() { } -void systemWriteDataToSoundBuffer() +SoundDriver * systemSoundInit() { - systemSoundDriver->write(soundFinalWave, soundBufferLen); -} + soundShutdown(); -bool systemSoundInit() -{ - systemSoundShutdown(); - - systemSoundDriver = new SoundSDL(); - bool ret = systemSoundDriver->init(soundQuality); - soundBufferLen = systemSoundDriver->getBufferLength(); - return ret; -} - -void systemSoundShutdown() -{ - delete systemSoundDriver; -} - -void systemSoundPause() -{ - systemSoundDriver->pause(); -} - -void systemSoundResume() -{ - systemSoundDriver->resume(); -} - -void systemSoundReset() -{ - systemSoundDriver->reset(); + return new SoundSDL(); } void debuggerMain() diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index b42b3546..b6e9f309 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -605,7 +605,7 @@ void Window::vInitSystem() void Window::vUnInitSystem() { - systemSoundShutdown(); + soundShutdown(); } void Window::vInitSDL() diff --git a/src/sdl/SDL.cpp b/src/sdl/SDL.cpp index e22d6e18..f37a229b 100644 --- a/src/sdl/SDL.cpp +++ b/src/sdl/SDL.cpp @@ -224,8 +224,6 @@ int sdlMirroringEnable = 0; static int ignore_first_resize_event = 0; -static SoundDriver * systemSoundDriver = 0; - /* forward */ void systemConsoleMessage(const char*); @@ -2712,37 +2710,9 @@ int systemGetSensorY() return inputGetSensorY(); } -void systemWriteDataToSoundBuffer() +SoundDriver * systemSoundInit() { - systemSoundDriver->write(soundFinalWave, soundBufferLen); -} + soundShutdown(); -bool systemSoundInit() -{ - systemSoundShutdown(); - - systemSoundDriver = new SoundSDL(); - bool ret = systemSoundDriver->init(soundQuality); - soundBufferLen = systemSoundDriver->getBufferLength(); - return ret; -} - -void systemSoundShutdown() -{ - delete systemSoundDriver; -} - -void systemSoundPause() -{ - systemSoundDriver->pause(); -} - -void systemSoundResume() -{ - systemSoundDriver->resume(); -} - -void systemSoundReset() -{ - systemSoundDriver->reset(); + return new SoundSDL(); } diff --git a/src/sdl/debugger.cpp b/src/sdl/debugger.cpp index 331a9749..30bbb8f6 100644 --- a/src/sdl/debugger.cpp +++ b/src/sdl/debugger.cpp @@ -25,6 +25,7 @@ #include "../agb/GBA.h" #include "../Port.h" +#include "../Sound.h" #include "../armdis.h" #include "../elf.h" #include "exprNode.h" @@ -2643,7 +2644,7 @@ char* strqtok (char* string, const char* ctrl) debuggerRegisters(0, NULL); while(debugger) { - systemSoundPause(); + soundPause(); debuggerDisableBreakpoints(); printf("debugger> "); commandCount = 0;