Added new GBA sound emulation core (thanks to blargg)

Updated GB sound emulation core

git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@160 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
mudlord 2007-12-05 04:25:47 +00:00
parent cdb46fb21b
commit c973879c24
6 changed files with 502 additions and 1624 deletions

View File

@ -3722,6 +3722,15 @@ void CPULoop(int ticks)
}
}
// we shouldn't be doing sound in stop state, but we loose synchronization
// if sound is disabled, so in stop state, soundTick will just produce
// mute sound
soundTicks -= clockTicks;
if(soundTicks <= 0) {
psoundTickfn();
soundTicks += SOUND_CLOCK_TICKS;
}
if(!stopState) {
if(timer0On) {
timer0Ticks -= clockTicks;
@ -3828,14 +3837,7 @@ void CPULoop(int ticks)
timerOverflow = 0;
// we shouldn't be doing sound in stop state, but we loose synchronization
// if sound is disabled, so in stop state, soundTick will just produce
// mute sound
soundTicks -= clockTicks;
if(soundTicks <= 0) {
psoundTickfn();
soundTicks += SOUND_CLOCK_TICKS;
}
#ifdef PROFILING
profilingTicks -= clockTicks;

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,6 @@
#define FIFOB_L 0xa4
#define FIFOB_H 0xa6
extern void setSoundFn();
extern void (*psoundTickfn)();
extern void soundShutdown();
extern bool soundInit();
@ -68,7 +67,6 @@ extern void soundTimerOverflow(int);
extern void soundSetQuality(int);
extern void setsystemSoundOn(bool value);
extern void setsoundPaused(bool value);
extern void setsoundMasterOn(bool value);
extern void interp_rate();
extern int SOUND_CLOCK_TICKS;

View File

@ -29,125 +29,32 @@
static Gb_Apu* gb_apu;
static Simple_Effects_Buffer* stereo_buffer;
extern u8 soundBuffer[6][735];
extern u16 soundFinalWave[1470];
extern int soundVolume;
#define SOUND_MAGIC 0x60000000
#define SOUND_MAGIC_2 0x30000000
#define NOISE_MAGIC 5
extern int speed;
extern int gbHardware;
extern void soundResume();
extern u8 soundWavePattern[4][32];
extern int soundBufferLen;
extern int soundBufferTotalLen;
extern int soundQuality;
extern bool soundPaused;
extern int soundPlay;
extern int soundTicks;
extern int SOUND_CLOCK_TICKS;
extern u32 soundNextPosition;
extern int soundLevel1;
extern int soundLevel2;
extern int soundBalance;
extern int soundMasterOn;
extern int soundIndex;
extern int soundBufferIndex;
int soundVIN = 0;
extern int soundDebug;
extern int sound1On;
extern int sound1ATL;
int sound1ATLreload;
int freq1low;
int freq1high;
extern int sound1Skip;
extern int sound1Index;
extern int sound1Continue;
extern int sound1EnvelopeVolume;
extern int sound1EnvelopeATL;
extern int sound1EnvelopeUpDown;
extern int sound1EnvelopeATLReload;
extern int sound1SweepATL;
extern int sound1SweepATLReload;
extern int sound1SweepSteps;
extern int sound1SweepUpDown;
extern int sound1SweepStep;
extern u8 *sound1Wave;
extern int sound2On;
extern int sound2ATL;
int sound2ATLreload;
int freq2low;
int freq2high;
extern int sound2Skip;
extern int sound2Index;
extern int sound2Continue;
extern int sound2EnvelopeVolume;
extern int sound2EnvelopeATL;
extern int sound2EnvelopeUpDown;
extern int sound2EnvelopeATLReload;
extern u8 *sound2Wave;
extern int sound3On;
extern int sound3ATL;
int sound3ATLreload;
int freq3low;
int freq3high;
extern int sound3Skip;
extern int sound3Index;
extern int sound3Continue;
extern int sound3OutputLevel;
extern int sound3Last;
extern int sound4On;
extern int sound4Clock;
extern int sound4ATL;
int sound4ATLreload;
int freq4;
extern int sound4Skip;
extern int sound4Index;
extern int sound4ShiftRight;
extern int sound4ShiftSkip;
extern int sound4ShiftIndex;
extern int sound4NSteps;
extern int sound4CountDown;
extern int sound4Continue;
extern int sound4EnvelopeVolume;
extern int sound4EnvelopeATL;
extern int sound4EnvelopeUpDown;
extern int sound4EnvelopeATLReload;
extern int soundEnableFlag;
extern int soundFreqRatio[8];
extern int soundShiftClock[16];
extern s16 soundFilter[4000];
extern s16 soundLeft[5];
extern s16 soundRight[5];
extern int soundEchoIndex;
extern bool soundEcho;
extern bool soundLowPass;
extern bool soundReverse;
extern bool soundOffFlag;
bool gbDigitalSound = false;
static inline blip_time_t ticks_to_time( int ticks )
{
return ticks * 2;
}
int const ticks_to_time = 2 * GB_APU_OVERCLOCK;
static inline blip_time_t blip_time()
{
return ticks_to_time( SOUND_CLOCK_TICKS - soundTicks );
return (SOUND_CLOCK_TICKS - soundTicks) * ticks_to_time;
}
u8 gbSoundRead( u16 address )
@ -175,32 +82,18 @@ void gbSoundEvent(register u16 address, register int data)
gb_apu->write_register( blip_time(), address, data );
}
void gbSoundChannel1()
{
}
void gbSoundChannel2()
{
}
void gbSoundChannel3()
{
}
void gbSoundChannel4()
{
}
static void end_frame( blip_time_t time )
{
gb_apu->end_frame( time );
gb_apu ->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 );
@ -211,8 +104,6 @@ static void flush_samples()
systemWriteDataToSoundBuffer();
}
soundIndex = 0;
soundBufferIndex = 0;
}
}
@ -240,9 +131,11 @@ static void apply_effects()
void gbSoundTick()
{
if(systemSoundOn && gb_apu && stereo_buffer)
if ( systemSoundOn && gb_apu && stereo_buffer )
{
end_frame( ticks_to_time( SOUND_CLOCK_TICKS ) );
// Run sound hardware to present
end_frame( SOUND_CLOCK_TICKS * ticks_to_time );
flush_samples();
// Update effects config if it was changed
@ -254,25 +147,28 @@ void gbSoundTick()
static void remake_stereo_buffer()
{
if ( !gb_apu )
gb_apu = new Gb_Apu;
// Stereo_Buffer
delete stereo_buffer;
stereo_buffer = 0;
stereo_buffer = new Simple_Effects_Buffer;
stereo_buffer->set_sample_rate( 44100 / soundQuality );
stereo_buffer = new Simple_Effects_Buffer; // TODO: handle out of memory
stereo_buffer->set_sample_rate( 44100 / soundQuality ); // TODO: handle out of memory
stereo_buffer->clock_rate( gb_apu->clock_rate );
// APU
static int const chan_types [chan_count] = {
Multi_Buffer::wave_type+1, Multi_Buffer::wave_type+2,
Multi_Buffer::wave_type+3, Multi_Buffer::mixed_type+1
};
stereo_buffer->set_channel_count( chan_count, chan_types );
if ( !gb_apu )
gb_apu = new Gb_Apu;
apply_effects();
gb_apu->reset( gb_apu->mode_cgb );
// Use DMG or CGB sound differences based on type of game
gb_apu->reset( gbHardware & 1 ? gb_apu->mode_dmg : gb_apu->mode_cgb );
}
void gbSoundReset()
@ -280,64 +176,9 @@ void gbSoundReset()
remake_stereo_buffer();
soundPaused = 1;
soundPlay = 0;
SOUND_CLOCK_TICKS = 20000;
soundTicks = SOUND_CLOCK_TICKS;
soundNextPosition = 0;
soundMasterOn = 1;
soundIndex = 0;
soundBufferIndex = 0;
soundLevel1 = 7;
soundLevel2 = 7;
soundVIN = 0;
sound1On = 0;
sound1ATL = 0;
sound1Skip = 0;
sound1Index = 0;
sound1Continue = 0;
sound1EnvelopeVolume = 0;
sound1EnvelopeATL = 0;
sound1EnvelopeUpDown = 0;
sound1EnvelopeATLReload = 0;
sound1SweepATL = 0;
sound1SweepATLReload = 0;
sound1SweepSteps = 0;
sound1SweepUpDown = 0;
sound1SweepStep = 0;
sound1Wave = soundWavePattern[2];
sound2On = 0;
sound2ATL = 0;
sound2Skip = 0;
sound2Index = 0;
sound2Continue = 0;
sound2EnvelopeVolume = 0;
sound2EnvelopeATL = 0;
sound2EnvelopeUpDown = 0;
sound2EnvelopeATLReload = 0;
sound2Wave = soundWavePattern[2];
sound3On = 0;
sound3ATL = 0;
sound3Skip = 0;
sound3Index = 0;
sound3Continue = 0;
sound3OutputLevel = 0;
sound4On = 0;
sound4Clock = 0;
sound4ATL = 0;
sound4Skip = 0;
sound4Index = 0;
sound4ShiftRight = 0x7f;
sound4NSteps = 0;
sound4CountDown = 0;
sound4Continue = 0;
sound4EnvelopeVolume = 0;
sound4EnvelopeATL = 0;
sound4EnvelopeUpDown = 0;
sound4EnvelopeATLReload = 0;
// don't translate
#ifndef FINAL_VERSION
@ -376,23 +217,12 @@ void gbSoundReset()
log("*** Sound Init Complete ***\n");
}
#endif
sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;
int addr = 0xff30;
while(addr < 0xff40) {
gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;
}
memset(soundFinalWave, 0x00, soundBufferLen);
memset(soundFilter, 0, sizeof(soundFilter));
soundEchoIndex = 0;
}
extern bool soundInit();
@ -400,29 +230,35 @@ extern void soundShutdown();
void gbSoundSetQuality(int quality)
{
if(soundQuality != quality && systemCanChangeSoundQuality()) {
if(!soundOffFlag)
if ( soundQuality != quality )
{
if ( systemCanChangeSoundQuality() )
{
if ( !soundOffFlag )
soundShutdown();
soundQuality = quality;
soundNextPosition = 0;
if(!soundOffFlag)
if ( !soundOffFlag )
soundInit();
//SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * 24 * soundQuality;
soundIndex = 0;
soundBufferIndex = 0;
} else {
soundNextPosition = 0;
//SOUND_CLOCK_TICKS = (gbSpeed ? 2 : 1) * 24 * soundQuality;
soundIndex = 0;
soundBufferIndex = 0;
}
else
{
soundQuality = quality;
soundNextPosition = 0;
}
remake_stereo_buffer();
}
}
void gbSoundSaveGame(gzFile gzFile)
{
// TODO: implement
}
void gbSoundReadGame(int version,gzFile gzFile)
{
// TODO: implement
}

View File

@ -63,10 +63,12 @@ extern int SOUND_CLOCK_TICKS;
struct gb_effects_config_t
{
bool enabled; // false = disable all effects
float echo; // 0.0 = none, 1.0 = lots
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
bool surround; // true = put some channels in back
};
// Can be changed at any time, probably from another thread too.
// Sound will notice changes during next 1/100 second.
extern gb_effects_config_t gb_effects_config;

View File

@ -1,11 +1,11 @@
// Gb_Snd_Emu 0.2.0 user configuration file. Don't replace when updating library.
// $package user configuration file. Don't replace when updating library.
#ifndef BLARGG_CONFIG_H
#define BLARGG_CONFIG_H
// Uncomment to have Gb_Apu run at 4x normal clock rate (16777216 Hz), useful in
// a Game Boy Advance emulator.
//#define GB_APU_OVERCLOCK 4
#define GB_APU_OVERCLOCK 4
// Uncomment to enable platform-specific (and possibly non-portable) optimizations.
//#define BLARGG_NONPORTABLE 1