From 46758ce339be22e6d9027d882f19d40ebcf8cc8a Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Wed, 30 Dec 2009 15:24:12 +0000 Subject: [PATCH] improved audio accuracy (input samplerate is now adjusted according to emulated framerate) --- HISTORY.txt | 15 +++++++++------ source/gx/main.c | 2 +- source/sound/Fir_Resampler.c | 2 +- source/sound/sound.c | 14 ++++++++------ source/sound/sound.h | 2 +- source/system.c | 7 ++++--- source/system.h | 2 +- 7 files changed, 25 insertions(+), 19 deletions(-) diff --git a/HISTORY.txt b/HISTORY.txt index 3517a43..93b2922 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -9,29 +9,32 @@ Genesis Plus GX 1.4.0 (??/??/????) (Eke-Eke) * added an option to boost SN76489 Noise Channel * removed outdated Gens YM2612 core * improved YM2612 core general accuracy (SSG-EG, CSM mode,...) (based upon Nemesis recent tests on real MD) -* improved YM2612 LFO emulation (fixes "Spider-Man & Venom : Separation Anxiety" intro music) +* improved YM2612 LFO emulation accuracy (fixes "Spider-Man & Venom : Separation Anxiety" intro music) * fixed YM2612 context saving/loading. -* added 3-Band EQ for fully configurable sound filtering (credits to Neil C / Etanza Systems) -* removed libsamplerate support, implemented faster/better FIR resampler (thanks to Blargg and AamirM) +* added 3-Band EQ for fully configurable sound filtering (thanks to Neil C) +* implemented faster FIR resampler, dropped libsamplerate support (thanks to Blargg & AamirM) * improved VDP sprite masking emulation: fixes 3D level in Mickey Mania (thanks to Nemesis for his sprite test program) * fixed 2-Cell vertical scrolling when column 0 is shifted. * added support for 2-Cell vertical scrolling in Interlaced 2 mode. -* fixed lightgun autodetection: fixes cursor position in Lethal Enforcers II +* fixed lightgun auto detection: fixes cursor position in Lethal Enforcers II * improved DIVU/DVIS (thanks to Jorge Cwik) & MULU/MULS 68000 instructions timing accuracy * updated Z80 core to last version (fixes interrupt Mode 0 timing and some BIT instructions) * fixed Backup Memory support in some games using serial EEPROM * added Game Genie hardware emulation (Game Genie ROM is now fully supported, see README for more details) * added Action Replay hardware emulation (Action replay ROM is now fully supported, see README for more details) +* added S&K "Lock-On" hardware emulation ("lock" any games to Sonic & Knuckles) +* added Cartridge "hot swap" feature (swap games without reseting the virtual console) * various code cleanup & core optimizations [Gamecube/Wii] * improved audio/video synchronization: fixes video skipping issues in 60Hz modes -* fixed stability issues and some (potential) memory leaks +* fixed stability issues and some potential memory leaks * added internal screenshot feature * improved lightgun cursors * implemented new FONT & GUI engines: use internal IPL FONT, GX hardware & multithreading for fast rendering. -* implemented new interface: incl. IR pointing, ROM snapshots, menu effects, sound effects, BGM... (check the README for more details) +* implemented new interface: incl. IR pointing, game snapshots, menu effects, sound effects, BGM... + (check the README for more details) diff --git a/source/gx/main.c b/source/gx/main.c index 95f339d..a278ad5 100644 --- a/source/gx/main.c +++ b/source/gx/main.c @@ -126,7 +126,7 @@ void reloadrom (int size, char *name) else { system_init (); /* Initialize System */ - audio_init(48000); /* Audio System initialization */ + audio_init(48000,vdp_pal?50.0:(1000000.0/16715.0)); ClearGGCodes (); /* Clear Game Genie patches */ system_reset (); /* System Power ON */ } diff --git a/source/sound/Fir_Resampler.c b/source/sound/Fir_Resampler.c index 79eb43d..73faa5a 100644 --- a/source/sound/Fir_Resampler.c +++ b/source/sound/Fir_Resampler.c @@ -281,7 +281,7 @@ int Fir_Resampler_input_needed( unsigned long output_count ) output_count -= 2; } - long input_extra = input_count - (write_pos - &buffer [(WIDTH - 1) * STEREO]); + long input_extra = input_count - (write_pos - &buffer [WRITE_OFFSET]); if ( input_extra < 0 ) input_extra = 0; return input_extra; diff --git a/source/sound/sound.c b/source/sound/sound.c index 0c28ff4..1f355a2 100644 --- a/source/sound/sound.c +++ b/source/sound/sound.c @@ -61,24 +61,26 @@ static inline void psg_update(int cnt) } /* initialize sound chips emulation */ -void sound_init(int rate) +void sound_init(int rate, double fps) { double vclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 7.0; /* 68000 and YM2612 clock */ double zclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 15.0; /* Z80 and SN76489 clock */ /* cycle-accurate FM & PSG samples */ - m68cycles_per_sample[0] = (int)(((double)m68cycles_per_line * (double)lines_per_frame * (double)vdp_rate / (double)rate) + 0.5); + m68cycles_per_sample[0] = (int)(((double)m68cycles_per_line * (double)lines_per_frame * fps/ (double)rate) + 0.5); m68cycles_per_sample[1] = m68cycles_per_sample[0]; /* YM2612 is emulated at its original frequency (VLCK/144) */ if (config.hq_fm) { + /* "real" ratio is (vclk/144.0)/(rate) but since we need perfect synchronization between video & audio + on the target system, we are not exactly running at the real genesis framerate but the target + framerate (which is calculated so that no video or audio frameskip occur) + */ + Fir_Resampler_time_ratio((double)m68cycles_per_line * (double)lines_per_frame * fps / 144.0 / (double)rate); + m68cycles_per_sample[0] = 144; - /* "real" ratio is (vclk/144.0)/(rate) but this causes scratchy sound in Wii/GCN 50Hz video mode */ - /* since "real" framerate is lower than 50 fps whereas PAL Wii/GCN framerate is higher than 50 fps */ - /* it's better to directly use the ratio between generated & expected numbers of samples per frame */ - Fir_Resampler_time_ratio((double)m68cycles_per_line * (double)lines_per_frame * (double)vdp_rate / 144.0 / (double)rate); } /* initialize sound chips */ diff --git a/source/sound/sound.h b/source/sound/sound.h index a39ae0e..e7a77a9 100644 --- a/source/sound/sound.h +++ b/source/sound/sound.h @@ -25,7 +25,7 @@ #define _SOUND_H_ /* Function prototypes */ -extern void sound_init(int rate); +extern void sound_init(int rate, double fps); extern void sound_update(int fm_len, int psg_len); extern void fm_reset(void); extern void fm_write(unsigned int cpu, unsigned int address, unsigned int data); diff --git a/source/system.c b/source/system.c index 838ec48..19b6796 100644 --- a/source/system.c +++ b/source/system.c @@ -138,7 +138,7 @@ void audio_update (int size) /**************************************************************** * AUDIO System initialization ****************************************************************/ -int audio_init (int rate) +int audio_init (int rate, double fps) { /* Shutdown first */ audio_shutdown(); @@ -151,7 +151,7 @@ int audio_init (int rate) snd.sample_rate = rate; /* Calculate the sound buffer size (for one frame) */ - snd.buffer_size = (rate / vdp_rate) + 32; + snd.buffer_size = (rate / vdp_rate) + 8; #ifndef NGC /* Output buffers */ @@ -182,7 +182,7 @@ int audio_init (int rate) snd.enabled = 1; /* Initialize Sound Chips emulation */ - sound_init(rate); + sound_init(rate,fps); return (0); } @@ -238,6 +238,7 @@ void system_reset (void) if (snd.fm.buffer[0]) memset (snd.fm.buffer[0], 0, SND_SIZE); if (snd.fm.buffer[1]) memset (snd.fm.buffer[1], 0, SND_SIZE); Fir_Resampler_clear(); + llp = rrp = 0; } /**************************************************************** diff --git a/source/system.h b/source/system.h index ddbd2b4..307d7d4 100644 --- a/source/system.h +++ b/source/system.h @@ -87,7 +87,7 @@ extern int32 current_z80; extern uint8 system_hw; /* Function prototypes */ -extern int audio_init (int rate); +extern int audio_init (int rate,double fps); extern void audio_shutdown (void); extern void audio_update (int len); extern void audio_set_equalizer(void);