mirror of
https://github.com/dborth/vbagx.git
synced 2024-11-25 20:16:53 +01:00
update audio core to match VBA-M (BUG: static added to GBA sound!)
This commit is contained in:
parent
ad6f2134fc
commit
5dcdb7e86a
@ -13,6 +13,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
extern int ConfigRequested;
|
extern int ConfigRequested;
|
||||||
|
|
||||||
/** Locals **/
|
/** Locals **/
|
||||||
@ -31,7 +33,7 @@ static int IsPlaying = 0;
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* MIXER_GetSamples
|
* MIXER_GetSamples
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int MIXER_GetSamples( u8 *dstbuffer, int maxlen )
|
static int MIXER_GetSamples(u8 *dstbuffer, int maxlen)
|
||||||
{
|
{
|
||||||
u32 *src = (u32 *)mixerdata;
|
u32 *src = (u32 *)mixerdata;
|
||||||
u32 *dst = (u32 *)dstbuffer;
|
u32 *dst = (u32 *)dstbuffer;
|
||||||
@ -55,61 +57,17 @@ static int MIXER_GetSamples( u8 *dstbuffer, int maxlen )
|
|||||||
|
|
||||||
static void AudioPlayer()
|
static void AudioPlayer()
|
||||||
{
|
{
|
||||||
if ( !ConfigRequested )
|
if (IsPlaying)
|
||||||
{
|
{
|
||||||
int len = MIXER_GetSamples(soundbuffer[whichab], 3200);
|
int len = MIXER_GetSamples(soundbuffer[whichab], 3200);
|
||||||
DCFlushRange(soundbuffer[whichab],len);
|
|
||||||
AUDIO_InitDMA((u32)soundbuffer[whichab],len);
|
AUDIO_InitDMA((u32)soundbuffer[whichab],len);
|
||||||
AUDIO_StartDMA();
|
DCFlushRange(soundbuffer[whichab],len);
|
||||||
whichab ^= 1;
|
whichab ^= 1;
|
||||||
IsPlaying = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
IsPlaying = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* MIXER_AddSamples
|
|
||||||
*
|
|
||||||
* Upsample from 11025 to 48000
|
|
||||||
* 11025 == 15052
|
|
||||||
* 22050 == 30106
|
|
||||||
* 44100 == 60211
|
|
||||||
*
|
|
||||||
* Audio officianados should look away now !
|
|
||||||
****************************************************************************/
|
|
||||||
void MIXER_AddSamples( u8 *sampledata, int len )
|
|
||||||
{
|
|
||||||
u32 *src = (u32 *)sampledata;
|
|
||||||
u32 *dst = (u32 *)mixerdata;
|
|
||||||
u32 intlen = (3200 >> 2);
|
|
||||||
u32 fixofs = 0;
|
|
||||||
u32 fixinc;
|
|
||||||
|
|
||||||
if ( !len )
|
|
||||||
fixinc = 30106;
|
|
||||||
else
|
|
||||||
fixinc = 60211;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Do simple linear interpolate, and swap channels from L-R to R-L
|
|
||||||
dst[head++] = SWAP(src[fixofs >> 16]);
|
|
||||||
head &= MIXERMASK;
|
|
||||||
fixofs += fixinc;
|
|
||||||
}
|
|
||||||
while( --intlen );
|
|
||||||
|
|
||||||
// Restart Sound Processing if stopped
|
|
||||||
if (IsPlaying == 0)
|
|
||||||
{
|
|
||||||
ConfigRequested = 0;
|
|
||||||
AudioPlayer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* MIXER_GetSamples
|
* InitialiseSound
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
void InitialiseSound()
|
void InitialiseSound()
|
||||||
@ -122,21 +80,72 @@ void InitialiseSound()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* MIXER_GetSamples
|
* SoundDriver
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
void ResetAudio()
|
SoundWii::SoundWii()
|
||||||
{
|
{
|
||||||
memset(soundbuffer, 0, 3840*2);
|
memset(soundbuffer, 0, 3840*2);
|
||||||
memset(mixerdata, 0, MIXBUFFSIZE);
|
memset(mixerdata, 0, MIXBUFFSIZE);
|
||||||
|
AudioPlayer();
|
||||||
|
AUDIO_StartDMA();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* MIXER_GetSamples
|
* SoundWii::write
|
||||||
***************************************************************************/
|
*
|
||||||
|
* Upsample from 11025 to 48000
|
||||||
|
* 11025 == 15052
|
||||||
|
* 22050 == 30106
|
||||||
|
* 44100 == 60211
|
||||||
|
*
|
||||||
|
* Audio officianados should look away now !
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
void StopAudio()
|
void SoundWii::write(u16 * finalWave, int length)
|
||||||
|
{
|
||||||
|
u32 *src = (u32 *)finalWave;
|
||||||
|
u32 *dst = (u32 *)mixerdata;
|
||||||
|
u32 intlen = (3200 >> 2);
|
||||||
|
u32 fixofs = 0;
|
||||||
|
u32 fixinc;
|
||||||
|
|
||||||
|
if (length < 2940) // length = 1468 - GBA
|
||||||
|
fixinc = 30106;
|
||||||
|
else // length = 2940 - GB
|
||||||
|
fixinc = 60211;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Do simple linear interpolate, and swap channels from L-R to R-L
|
||||||
|
dst[head++] = SWAP(src[fixofs >> 16]);
|
||||||
|
head &= MIXERMASK;
|
||||||
|
fixofs += fixinc;
|
||||||
|
}
|
||||||
|
while( --intlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundWii::init(long sampleRate)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundWii::~SoundWii()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundWii::pause()
|
||||||
{
|
{
|
||||||
AUDIO_StopDMA();
|
AUDIO_StopDMA();
|
||||||
IsPlaying = 0;
|
IsPlaying = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundWii::resume()
|
||||||
|
{
|
||||||
|
AUDIO_StartDMA();
|
||||||
|
IsPlaying = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundWii::reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -11,9 +11,21 @@
|
|||||||
#ifndef __AUDIOMIXER__
|
#ifndef __AUDIOMIXER__
|
||||||
#define __AUDIOMIXER__
|
#define __AUDIOMIXER__
|
||||||
|
|
||||||
void MIXER_AddSamples( u8 *sampledata, int len );
|
#include "common/SoundDriver.h"
|
||||||
void StopAudio();
|
|
||||||
void ResetAudio();
|
|
||||||
void InitialiseSound();
|
void InitialiseSound();
|
||||||
|
|
||||||
|
class SoundWii: public SoundDriver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundWii();
|
||||||
|
virtual ~SoundWii();
|
||||||
|
|
||||||
|
virtual bool init(long sampleRate);
|
||||||
|
virtual void pause();
|
||||||
|
virtual void reset();
|
||||||
|
virtual void resume();
|
||||||
|
virtual void write(u16 * finalWave, int length);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <ogcsys.h>
|
#include <ogcsys.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
@ -331,7 +330,6 @@ u32 GetJoy(int pad)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
StopAudio();
|
|
||||||
ConfigRequested = 1;
|
ConfigRequested = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "gba/Sound.h"
|
||||||
|
|
||||||
#include "vba.h"
|
#include "vba.h"
|
||||||
#include "vbasupport.h"
|
#include "vbasupport.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
@ -246,6 +248,7 @@ int main(int argc, char *argv[])
|
|||||||
LWP_SuspendThread (devicethread);
|
LWP_SuspendThread (devicethread);
|
||||||
|
|
||||||
ResetVideo_Emu();
|
ResetVideo_Emu();
|
||||||
|
soundResume();
|
||||||
|
|
||||||
while (emulating) // emulation loop
|
while (emulating) // emulation loop
|
||||||
{
|
{
|
||||||
@ -259,6 +262,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if(ConfigRequested)
|
if(ConfigRequested)
|
||||||
{
|
{
|
||||||
|
soundPause();
|
||||||
ResetVideo_Menu (); // change to menu video mode
|
ResetVideo_Menu (); // change to menu video mode
|
||||||
|
|
||||||
if (GCSettings.AutoSave == 1)
|
if (GCSettings.AutoSave == 1)
|
||||||
@ -277,7 +281,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// save zoom level
|
// save zoom level
|
||||||
SavePrefs(SILENT);
|
SavePrefs(SILENT);
|
||||||
|
|
||||||
ConfigRequested = 0;
|
ConfigRequested = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -444,15 +444,10 @@ bool SaveBatteryOrState(int method, int action, bool silent)
|
|||||||
* Sound
|
* Sound
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void systemWriteDataToSoundBuffer()
|
SoundDriver * systemSoundInit()
|
||||||
{
|
{
|
||||||
MIXER_AddSamples((u8 *)soundFinalWave, (cartridgeType == 1));
|
soundShutdown();
|
||||||
}
|
return new SoundWii();
|
||||||
|
|
||||||
bool systemSoundInit()
|
|
||||||
{
|
|
||||||
ResetAudio();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool systemCanChangeSoundQuality()
|
bool systemCanChangeSoundQuality()
|
||||||
@ -460,10 +455,13 @@ bool systemCanChangeSoundQuality()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void systemSoundPause() {}
|
void systemOnWriteDataToSoundBuffer(const u16 * finalWave, int length)
|
||||||
void systemSoundResume() {}
|
{
|
||||||
void systemSoundReset() {}
|
}
|
||||||
void systemSoundShutdown() {}
|
|
||||||
|
void systemOnSoundShutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* systemReadJoypads
|
* systemReadJoypads
|
||||||
@ -773,8 +771,7 @@ bool LoadVBAROM(int method)
|
|||||||
hAspect = 70;
|
hAspect = 70;
|
||||||
vAspect = 46;
|
vAspect = 46;
|
||||||
srcPitch = 484;
|
srcPitch = 484;
|
||||||
soundQuality = 2;
|
soundSetSampleRate(44100 / 2);
|
||||||
soundBufferLen = 736 * 2;
|
|
||||||
cpuSaveType = 0;
|
cpuSaveType = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -807,8 +804,7 @@ bool LoadVBAROM(int method)
|
|||||||
hAspect = 60;
|
hAspect = 60;
|
||||||
vAspect = 46;
|
vAspect = 46;
|
||||||
srcPitch = 324;
|
srcPitch = 324;
|
||||||
soundQuality = 1;
|
soundSetSampleRate(44100);
|
||||||
soundBufferLen = 1470 * 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,7 +829,6 @@ bool LoadVBAROM(int method)
|
|||||||
LoadPatch(method);
|
LoadPatch(method);
|
||||||
|
|
||||||
gbSoundReset();
|
gbSoundReset();
|
||||||
gbSoundSetQuality(soundQuality);
|
|
||||||
gbSoundSetDeclicking(true);
|
gbSoundSetDeclicking(true);
|
||||||
gbReset();
|
gbReset();
|
||||||
}
|
}
|
||||||
@ -851,7 +846,6 @@ bool LoadVBAROM(int method)
|
|||||||
doMirroring(mirroringEnable);
|
doMirroring(mirroringEnable);
|
||||||
|
|
||||||
soundReset();
|
soundReset();
|
||||||
soundSetQuality(soundQuality);
|
|
||||||
CPUInit("BIOS.GBA", 1);
|
CPUInit("BIOS.GBA", 1);
|
||||||
LoadPatch(method);
|
LoadPatch(method);
|
||||||
CPUReset();
|
CPUReset();
|
||||||
|
@ -51,12 +51,9 @@ extern u32 systemReadJoypad(int);
|
|||||||
extern u32 systemGetClock();
|
extern u32 systemGetClock();
|
||||||
extern void systemMessage(int, const char *, ...);
|
extern void systemMessage(int, const char *, ...);
|
||||||
extern void systemSetTitle(const char *);
|
extern void systemSetTitle(const char *);
|
||||||
extern void systemWriteDataToSoundBuffer();
|
extern SoundDriver * systemSoundInit();
|
||||||
extern void systemSoundShutdown();
|
extern void systemOnWriteDataToSoundBuffer(const u16 * finalWave, int length);
|
||||||
extern void systemSoundPause();
|
extern void systemOnSoundShutdown();
|
||||||
extern void systemSoundResume();
|
|
||||||
extern void systemSoundReset();
|
|
||||||
extern bool systemSoundInit();
|
|
||||||
extern void systemScreenMessage(const char *);
|
extern void systemScreenMessage(const char *);
|
||||||
extern void systemUpdateMotionSensor();
|
extern void systemUpdateMotionSensor();
|
||||||
extern int systemGetSensorX();
|
extern int systemGetSensorX();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "../apu/Effects_Buffer.h"
|
#include "../apu/Effects_Buffer.h"
|
||||||
|
|
||||||
extern int gbHardware;
|
extern int gbHardware;
|
||||||
|
extern long soundSampleRate; // current sound quality
|
||||||
|
|
||||||
gb_effects_config_t gb_effects_config = { false, 0.20f, 0.15f, false };
|
gb_effects_config_t gb_effects_config = { false, 0.20f, 0.15f, false };
|
||||||
|
|
||||||
@ -50,22 +51,6 @@ static void end_frame( blip_time_t time )
|
|||||||
stereo_buffer->end_frame( 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()
|
static void apply_effects()
|
||||||
{
|
{
|
||||||
prevSoundEnable = soundGetEnable();
|
prevSoundEnable = soundGetEnable();
|
||||||
@ -106,7 +91,7 @@ void gbSoundTick()
|
|||||||
// Run sound hardware to present
|
// Run sound hardware to present
|
||||||
end_frame( SOUND_CLOCK_TICKS * ticks_to_time );
|
end_frame( SOUND_CLOCK_TICKS * ticks_to_time );
|
||||||
|
|
||||||
flush_samples();
|
flush_samples(stereo_buffer);
|
||||||
|
|
||||||
// Update effects config if it was changed
|
// Update effects config if it was changed
|
||||||
if ( memcmp( &gb_effects_config_current, &gb_effects_config,
|
if ( memcmp( &gb_effects_config_current, &gb_effects_config,
|
||||||
@ -141,7 +126,7 @@ static void remake_stereo_buffer()
|
|||||||
stereo_buffer = 0;
|
stereo_buffer = 0;
|
||||||
|
|
||||||
stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
|
stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
|
||||||
if ( stereo_buffer->set_sample_rate( 44100 / soundQuality ) ) { } // TODO: handle out of memory
|
if ( stereo_buffer->set_sample_rate( soundSampleRate ) ) { } // TODO: handle out of memory
|
||||||
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
||||||
|
|
||||||
// APU
|
// APU
|
||||||
@ -231,19 +216,19 @@ void gbSoundReset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbSoundSetQuality(int quality)
|
void gbSoundSetSampleRate( long sampleRate )
|
||||||
{
|
{
|
||||||
if ( soundQuality != quality )
|
if ( soundSampleRate != sampleRate )
|
||||||
{
|
{
|
||||||
if ( systemCanChangeSoundQuality() )
|
if ( systemCanChangeSoundQuality() )
|
||||||
{
|
{
|
||||||
soundShutdown();
|
soundShutdown();
|
||||||
soundQuality = quality;
|
soundSampleRate = sampleRate;
|
||||||
soundInit();
|
soundInit();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
soundQuality = quality;
|
soundSampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
remake_stereo_buffer();
|
remake_stereo_buffer();
|
||||||
@ -380,7 +365,7 @@ static void gbSoundReadGameOld(int version,gzFile gzFile)
|
|||||||
if ( version >= 7 )
|
if ( version >= 7 )
|
||||||
quality = utilReadInt( gzFile );
|
quality = utilReadInt( gzFile );
|
||||||
|
|
||||||
gbSoundSetQuality( quality );
|
gbSoundSetSampleRate( 44100 / quality );
|
||||||
|
|
||||||
// Convert to format Gb_Apu uses
|
// Convert to format Gb_Apu uses
|
||||||
gb_apu_state_t& s = state.apu;
|
gb_apu_state_t& s = state.apu;
|
||||||
|
@ -7,9 +7,7 @@
|
|||||||
|
|
||||||
//// GB sound options
|
//// GB sound options
|
||||||
|
|
||||||
// Sets sample rate to 44100 / quality
|
void gbSoundSetSampleRate( long sampleRate );
|
||||||
void gbSoundSetQuality( int quality );
|
|
||||||
extern int soundQuality; // current sound quality
|
|
||||||
|
|
||||||
// Manages declicking mode. When enabled, clicks are reduced. Note that clicks
|
// Manages declicking mode. When enabled, clicks are reduced. Note that clicks
|
||||||
// are normal for GB and GBC sound hardware.
|
// are normal for GB and GBC sound hardware.
|
||||||
|
@ -1951,9 +1951,9 @@ void CPUSoftwareInterrupt(int comment)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(reg[0].I)
|
if(reg[0].I)
|
||||||
systemSoundPause();
|
soundPause();
|
||||||
else
|
else
|
||||||
systemSoundResume();
|
soundResume();
|
||||||
break;
|
break;
|
||||||
case 0x1F:
|
case 0x1F:
|
||||||
BIOS_MidiKey2Freq();
|
BIOS_MidiKey2Freq();
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include "../apu/Gb_Apu.h"
|
#include "../apu/Gb_Apu.h"
|
||||||
#include "../apu/Multi_Buffer.h"
|
#include "../apu/Multi_Buffer.h"
|
||||||
|
|
||||||
|
#include "../common/SoundDriver.h"
|
||||||
|
|
||||||
#define NR10 0x60
|
#define NR10 0x60
|
||||||
#define NR11 0x62
|
#define NR11 0x62
|
||||||
#define NR12 0x63
|
#define NR12 0x63
|
||||||
@ -32,21 +34,21 @@
|
|||||||
#define NR51 0x81
|
#define NR51 0x81
|
||||||
#define NR52 0x84
|
#define NR52 0x84
|
||||||
|
|
||||||
|
SoundDriver * soundDriver = 0;
|
||||||
|
|
||||||
extern bool stopState; // TODO: silence sound when true
|
extern bool stopState; // TODO: silence sound when true
|
||||||
|
|
||||||
int const SOUND_CLOCK_TICKS_ = 167772; // 1/100 second
|
int const SOUND_CLOCK_TICKS_ = 167772; // 1/100 second
|
||||||
|
|
||||||
u16 soundFinalWave [1470];
|
static u16 soundFinalWave [1600];
|
||||||
int soundBufferLen = sizeof soundFinalWave;
|
long soundSampleRate = 44100;
|
||||||
int soundQuality = 1;
|
|
||||||
bool soundInterpolation = true;
|
bool soundInterpolation = true;
|
||||||
bool soundPaused = true;
|
bool soundPaused = true;
|
||||||
float soundFiltering = 0.5f;
|
float soundFiltering = 0.5f;
|
||||||
float soundVolume = 1.0f;
|
|
||||||
bool soundEcho = false;
|
|
||||||
int SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_;
|
int SOUND_CLOCK_TICKS = SOUND_CLOCK_TICKS_;
|
||||||
int soundTicks = SOUND_CLOCK_TICKS_;
|
int soundTicks = SOUND_CLOCK_TICKS_;
|
||||||
|
|
||||||
|
static float soundVolume = 1.0f;
|
||||||
static int soundEnableFlag = 0x3ff; // emulator channels enabled
|
static int soundEnableFlag = 0x3ff; // emulator channels enabled
|
||||||
static float soundFiltering_ = -1;
|
static float soundFiltering_ = -1;
|
||||||
static float soundVolume_ = -1;
|
static float soundVolume_ = -1;
|
||||||
@ -344,8 +346,14 @@ static void end_frame( blip_time_t time )
|
|||||||
stereo_buffer->end_frame( time );
|
stereo_buffer->end_frame( time );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_samples()
|
void flush_samples(Multi_Buffer * buffer)
|
||||||
{
|
{
|
||||||
|
// We want to write the data frame by frame to support legacy audio drivers
|
||||||
|
// that don't use the length parameter of the write method.
|
||||||
|
// TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the
|
||||||
|
// samples at once to help reducing the audio delay on all platforms.
|
||||||
|
int soundBufferLen = ( soundSampleRate / 60 ) * 4;
|
||||||
|
|
||||||
// soundBufferLen should have a whole number of sample pairs
|
// soundBufferLen should have a whole number of sample pairs
|
||||||
assert( soundBufferLen % (2 * sizeof *soundFinalWave) == 0 );
|
assert( soundBufferLen % (2 * sizeof *soundFinalWave) == 0 );
|
||||||
|
|
||||||
@ -353,13 +361,14 @@ static void flush_samples()
|
|||||||
int const out_buf_size = soundBufferLen / sizeof *soundFinalWave;
|
int const out_buf_size = soundBufferLen / sizeof *soundFinalWave;
|
||||||
|
|
||||||
// Keep filling and writing soundFinalWave until it can't be fully filled
|
// 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)
|
if(soundPaused)
|
||||||
soundResume();
|
soundResume();
|
||||||
|
|
||||||
systemWriteDataToSoundBuffer();
|
soundDriver->write(soundFinalWave, soundBufferLen);
|
||||||
|
systemOnWriteDataToSoundBuffer(soundFinalWave, soundBufferLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +395,7 @@ void psoundTickfn()
|
|||||||
// Run sound hardware to present
|
// Run sound hardware to present
|
||||||
end_frame( SOUND_CLOCK_TICKS );
|
end_frame( SOUND_CLOCK_TICKS );
|
||||||
|
|
||||||
flush_samples();
|
flush_samples(stereo_buffer);
|
||||||
|
|
||||||
if ( soundFiltering_ != soundFiltering )
|
if ( soundFiltering_ != soundFiltering )
|
||||||
apply_filtering();
|
apply_filtering();
|
||||||
@ -442,8 +451,7 @@ static void remake_stereo_buffer()
|
|||||||
stereo_buffer = 0;
|
stereo_buffer = 0;
|
||||||
|
|
||||||
stereo_buffer = new Stereo_Buffer; // TODO: handle out of memory
|
stereo_buffer = new Stereo_Buffer; // TODO: handle out of memory
|
||||||
long const sample_rate = 44100 / soundQuality;
|
stereo_buffer->set_sample_rate( soundSampleRate ); // TODO: handle out of memory
|
||||||
stereo_buffer->set_sample_rate( sample_rate ); // TODO: handle out of memory
|
|
||||||
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
stereo_buffer->clock_rate( gb_apu->clock_rate );
|
||||||
|
|
||||||
// PCM
|
// PCM
|
||||||
@ -464,19 +472,27 @@ static void remake_stereo_buffer()
|
|||||||
|
|
||||||
void soundShutdown()
|
void soundShutdown()
|
||||||
{
|
{
|
||||||
systemSoundShutdown();
|
if (soundDriver)
|
||||||
|
{
|
||||||
|
delete soundDriver;
|
||||||
|
soundDriver = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
systemOnSoundShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundPause()
|
void soundPause()
|
||||||
{
|
{
|
||||||
soundPaused = true;
|
soundPaused = true;
|
||||||
systemSoundPause();
|
if (soundDriver)
|
||||||
|
soundDriver->pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundResume()
|
void soundResume()
|
||||||
{
|
{
|
||||||
soundPaused = false;
|
soundPaused = false;
|
||||||
systemSoundResume();
|
if (soundDriver)
|
||||||
|
soundDriver->resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundSetVolume( float volume )
|
void soundSetVolume( float volume )
|
||||||
@ -502,7 +518,7 @@ int soundGetEnable()
|
|||||||
|
|
||||||
void soundReset()
|
void soundReset()
|
||||||
{
|
{
|
||||||
systemSoundReset();
|
soundDriver->reset();
|
||||||
|
|
||||||
remake_stereo_buffer();
|
remake_stereo_buffer();
|
||||||
reset_apu();
|
reset_apu();
|
||||||
@ -516,26 +532,35 @@ void soundReset()
|
|||||||
|
|
||||||
bool soundInit()
|
bool soundInit()
|
||||||
{
|
{
|
||||||
if ( !systemSoundInit() )
|
soundDriver = systemSoundInit();
|
||||||
|
if ( !soundDriver )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!soundDriver->init(soundSampleRate))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
soundPaused = true;
|
soundPaused = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void soundSetQuality(int quality)
|
long soundGetSampleRate()
|
||||||
{
|
{
|
||||||
if ( soundQuality != quality )
|
return soundSampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void soundSetSampleRate(long sampleRate)
|
||||||
|
{
|
||||||
|
if ( soundSampleRate != sampleRate )
|
||||||
{
|
{
|
||||||
if ( systemCanChangeSoundQuality() )
|
if ( systemCanChangeSoundQuality() )
|
||||||
{
|
{
|
||||||
soundShutdown();
|
soundShutdown();
|
||||||
soundQuality = quality;
|
soundSampleRate = sampleRate;
|
||||||
soundInit();
|
soundInit();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
soundQuality = quality;
|
soundSampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
remake_stereo_buffer();
|
remake_stereo_buffer();
|
||||||
|
@ -33,16 +33,10 @@ extern bool soundPaused; // current paused state
|
|||||||
// Cleans up sound. Afterwards, soundInit() can be called again.
|
// Cleans up sound. Afterwards, soundInit() can be called again.
|
||||||
void soundShutdown();
|
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
|
//// GBA sound options
|
||||||
|
|
||||||
// Sets sample rate to 44100 / quality
|
long soundGetSampleRate();
|
||||||
void soundSetQuality( int quality );
|
void soundSetSampleRate(long sampleRate);
|
||||||
extern int soundQuality; // current sound quality
|
|
||||||
|
|
||||||
// Sound settings
|
// Sound settings
|
||||||
extern bool soundInterpolation; // 1 if PCM should have low-pass filtering
|
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 soundSaveGame( gzFile );
|
||||||
void soundReadGame( gzFile, int version );
|
void soundReadGame( gzFile, int version );
|
||||||
|
|
||||||
|
class Multi_Buffer;
|
||||||
|
|
||||||
|
void flush_samples(Multi_Buffer * buffer);
|
||||||
|
|
||||||
#endif // SOUND_H
|
#endif // SOUND_H
|
||||||
|
Loading…
Reference in New Issue
Block a user