diff --git a/Frameworks/GME/gme/Vgm_Core.cpp b/Frameworks/GME/gme/Vgm_Core.cpp index 4ed8c7d9c..acd32c447 100644 --- a/Frameworks/GME/gme/Vgm_Core.cpp +++ b/Frameworks/GME/gme/Vgm_Core.cpp @@ -28,6 +28,7 @@ Vgm_Core::Vgm_Core() Vgm_Core::~Vgm_Core() { StopVGM(vgmp); + CloseVGMFile(vgmp); VGMPlay_Deinit(vgmp); } @@ -160,10 +161,47 @@ blargg_err_t Vgm_Core::load_mem_( byte const data [], int size ) vgmp->VGMMaxLoop = 1; set_tempo( 1 ); - + return blargg_ok; } +int Vgm_Core::get_channel_count() +{ + // XXX may support more than this, but 32 bit masks and all... + unsigned i; + UINT32 j; + for (i = 0; i < 32; i++) + { + if (!GetAccurateChipNameByChannel(vgmp, i, &j)) + break; + } + return i; +} + +char* Vgm_Core::get_voice_name(int channel) +{ + UINT32 realChannel; + const char * name = GetAccurateChipNameByChannel(vgmp, channel, &realChannel); + size_t length = strlen(name) + 16; + char * finalName = (char *) malloc(length); + if (finalName) + sprintf(finalName, "%s #%u", name, realChannel); + return finalName; +} + +void Vgm_Core::free_voice_name(char *name) +{ + free(name); +} + +void Vgm_Core::set_mute(int mask) +{ + for (int i = 0; i < 32; i++) + { + SetChannelMute(vgmp, i, (mask >> i) & 1); + } +} + void Vgm_Core::start_track() { PlayVGM(vgmp); @@ -184,4 +222,4 @@ int Vgm_Core::play_( int sample_count, short out [] ) void Vgm_Core::skip_( int count ) { SeekVGM( vgmp, true, count / 2 ); -} \ No newline at end of file +} diff --git a/Frameworks/GME/gme/Vgm_Core.h b/Frameworks/GME/gme/Vgm_Core.h index de8624e78..43a77f855 100644 --- a/Frameworks/GME/gme/Vgm_Core.h +++ b/Frameworks/GME/gme/Vgm_Core.h @@ -38,6 +38,13 @@ public: // Skips the specified number of samples void skip_( int count ); + + int get_channel_count(); + + char* get_voice_name(int channel); + void free_voice_name(char *); + + void set_mute(int mask); // Implementation public: diff --git a/Frameworks/GME/gme/Vgm_Emu.cpp b/Frameworks/GME/gme/Vgm_Emu.cpp index 975401f4f..ec34a5a98 100644 --- a/Frameworks/GME/gme/Vgm_Emu.cpp +++ b/Frameworks/GME/gme/Vgm_Emu.cpp @@ -31,7 +31,21 @@ Vgm_Emu::Vgm_Emu() set_silence_lookahead( 1 ); // tracks should already be trimmed } -Vgm_Emu::~Vgm_Emu() { } +Vgm_Emu::~Vgm_Emu() +{ + // XXX ugly use of deprecated functions to free allocated voice names + const char ** voice_names_ = voice_names(); + if (voice_names_) + { + for (int i = 0; i < 32; ++i) + { + if (voice_names_[i]) + core.free_voice_name((char*)voice_names_[i]); + else break; + } + free((void *)voice_names_); + } +} void Vgm_Emu::unload() { @@ -431,6 +445,7 @@ blargg_err_t Vgm_Emu::set_sample_rate_( int sample_rate ) void Vgm_Emu::mute_voices_( int mask ) { muted_voices = mask; + core.set_mute(mask); } // Emulation @@ -474,6 +489,33 @@ blargg_err_t Vgm_Emu::hash_( Hash_Function& out ) const blargg_err_t Vgm_Emu::load_mem_( const byte* in, int file_size ) { RETURN_ERR( core.load_mem(in, file_size) ); + + int voice_count = core.get_channel_count(); + + set_voice_count( voice_count ); + + char ** voice_names = (char **) calloc( sizeof(char *), voice_count + 1 ); + if (voice_names) + { + int i; + for (i = 0; i < voice_count; i++) + { + voice_names[i] = core.get_voice_name(i); + if (!voice_names[i]) + break; + } + if (i == voice_count) + set_voice_names(voice_names); + else + { + for (i = 0; i < voice_count; i++) + { + if (voice_names[i]) + free(voice_names[i]); + } + free(voice_names); + } + } get_vgm_length( header(), &metadata ); diff --git a/Frameworks/GME/vgmplay/VGMPlay.c b/Frameworks/GME/vgmplay/VGMPlay.c index e0b4c2d17..e8f84d39a 100644 --- a/Frameworks/GME/vgmplay/VGMPlay.c +++ b/Frameworks/GME/vgmplay/VGMPlay.c @@ -3206,8 +3206,8 @@ static void Chips_GeneralActions(VGM_PLAYER* p, UINT8 Mode) ymz280b_set_mute_mask(p->ymz280b[CurCSet], p->ChipOpts[CurCSet].YMZ280B.ChnMute1); else if (CAA->ChipType == 0x10 && CurCSet == 0x00) rf5c164_set_mute_mask(p->rf5c164, p->ChipOpts[CurCSet].RF5C164.ChnMute1); - else if (CAA->ChipType == 0x11) - ; // PWM - nothing to mute + else if (CAA->ChipType == 0x11 && CurCSet == 0x00) + pwm_mute(p->pwm, p->ChipOpts[CurCSet].PWM.ChnMute1); else if (CAA->ChipType == 0x12) ayxx_set_mute_mask(p->ay8910[CurCSet], p->ChipOpts[CurCSet].AY8910.ChnMute1); else if (CAA->ChipType == 0x13) @@ -3217,9 +3217,9 @@ static void Chips_GeneralActions(VGM_PLAYER* p, UINT8 Mode) else if (CAA->ChipType == 0x15) multipcm_set_mute_mask(p->multipcm[CurCSet], p->ChipOpts[CurCSet].MultiPCM.ChnMute1); else if (CAA->ChipType == 0x16) - ; // UPD7759 - nothing to mute + upd7759_mute(p->upd7759[CurCSet], p->ChipOpts[CurCSet].UPD7759.ChnMute1); else if (CAA->ChipType == 0x17) - ; // OKIM6258 - nothing to mute + okim6258_mute(p->okim6258[CurCSet], p->ChipOpts[CurCSet].OKIM6258.ChnMute1); else if (CAA->ChipType == 0x18) okim6295_set_mute_mask(p->okim6295[CurCSet], p->ChipOpts[CurCSet].OKIM6295.ChnMute1); else if (CAA->ChipType == 0x19) @@ -5147,3 +5147,1245 @@ UINT32 FillBuffer(void *_p, WAVE_16BS* Buffer, UINT32 BufferSize) return CurSmpl; } + +// ChanCount is an array of 3, for the 3 mute masks per chip +static void GetChipByChannel(void* vgmp, UINT32 channel, UINT8 *ChipID, UINT8 *ChipType, UINT8 *Channel, UINT8 *ChanCount) +{ + VGM_PLAYER* p = (VGM_PLAYER *)vgmp; + + *ChipType = 0xFF; + + if (p->VGMHead.lngHzPSG) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x00; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzPSG & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x00; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } + + if (p->VGMHead.lngHzYM2413) + { + if (channel < 14) + { + *ChipID = 0x00; + *ChipType = 0x01; + *Channel = channel; + ChanCount[0] = 14; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 14; + + if (p->VGMHead.lngHzYM2413 & 0x40000000) + { + if (channel < 14) + { + *ChipID = 0x01; + *ChipType = 0x01; + *Channel = channel; + ChanCount[0] = 14; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 14; + } + } + + if (p->VGMHead.lngHzYM2612) + { + if (channel < 7) + { + *ChipID = 0x00; + *ChipType = 0x02; + *Channel = channel; + ChanCount[0] = 7; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 7; + + if (p->VGMHead.lngHzYM2612 & 0x40000000) + { + if (channel < 7) + { + *ChipID = 0x01; + *ChipType = 0x02; + *Channel = channel; + ChanCount[0] = 7; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 7; + } + } + + if (p->VGMHead.lngHzYM2151) + { + if (channel < 8) + { + *ChipID = 0x00; + *ChipType = 0x03; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + + if (p->VGMHead.lngHzYM2151 & 0x40000000) + { + if (channel < 8) + { + *ChipID = 0x01; + *ChipType = 0x03; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + } + } + + if (p->VGMHead.lngHzSPCM) + { + if (channel < 16) + { + *ChipID = 0x00; + *ChipType = 0x04; + *Channel = channel; + ChanCount[0] = 16; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 16; + + if (p->VGMHead.lngHzSPCM & 0x40000000) + { + if (channel < 16) + { + *ChipID = 0x01; + *ChipType = 0x04; + *Channel = channel; + ChanCount[0] = 16; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 16; + } + } + + if (p->VGMHead.lngHzRF5C68) + { + if (channel < 8) + { + *ChipID = 0x00; + *ChipType = 0x05; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + } + + if (p->VGMHead.lngHzYM2203) + { + if (channel < 6) + { + *ChipID = 0x00; + *ChipType = 0x06; + *Channel = channel; + ChanCount[0] = 3; + ChanCount[1] = 0; + ChanCount[2] = 3; + } + + channel -= 6; + + if (p->VGMHead.lngHzYM2203 & 0x40000000) + { + if (channel < 6) + { + *ChipID = 0x01; + *ChipType = 0x06; + *Channel = channel; + ChanCount[0] = 3; + ChanCount[1] = 0; + ChanCount[2] = 3; + } + + channel -= 6; + } + } + + if (p->VGMHead.lngHzYM2608) + { + if (channel < 16) + { + *ChipID = 0x00; + *ChipType = 0x07; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 7; + ChanCount[2] = 3; + } + + channel -= 16; + + if (p->VGMHead.lngHzYM2608 & 0x40000000) + { + if (channel < 16) + { + *ChipID = 0x01; + *ChipType = 0x07; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 7; + ChanCount[2] = 3; + } + + channel -= 16; + } + } + + if (p->VGMHead.lngHzYM2610) + { + if (channel < 16) + { + *ChipID = 0x00; + *ChipType = 0x08; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 7; + ChanCount[2] = 3; + } + + channel -= 16; + + if (p->VGMHead.lngHzYM2610 & 0x40000000) + { + if (channel < 16) + { + *ChipID = 0x01; + *ChipType = 0x08; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 7; + ChanCount[2] = 3; + } + + channel -= 16; + } + } + + if (p->VGMHead.lngHzYM3812) + { + if (channel < 14) + { + *ChipID = 0x00; + *ChipType = 0x09; + *Channel = channel; + ChanCount[0] = 14; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 14; + + if (p->VGMHead.lngHzYM3812 & 0x40000000) + { + if (channel < 14) + { + *ChipID = 0x01; + *ChipType = 0x09; + *Channel = channel; + ChanCount[0] = 14; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 14; + } + } + + if (p->VGMHead.lngHzYM3526) + { + if (channel < 15) + { + *ChipID = 0x00; + *ChipType = 0x0A; + *Channel = channel; + ChanCount[0] = 15; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 15; + + if (p->VGMHead.lngHzYM3526 & 0x40000000) + { + if (channel < 15) + { + *ChipID = 0x01; + *ChipType = 0x0B; + *Channel = channel; + ChanCount[0] = 15; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 15; + } + } + + if (p->VGMHead.lngHzY8950) + { + if (channel < 15) + { + *ChipID = 0x00; + *ChipType = 0x0B; + *Channel = channel; + ChanCount[0] = 15; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 15; + + if (p->VGMHead.lngHzY8950 & 0x40000000) + { + if (channel < 15) + { + *ChipID = 0x01; + *ChipType = 0x0B; + *Channel = channel; + ChanCount[0] = 15; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 15; + } + } + + if (p->VGMHead.lngHzYMF262) + { + if (channel < 23) + { + *ChipID = 0x00; + *ChipType = 0x0C; + *Channel = channel; + ChanCount[0] = 23; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 23; + + if (p->VGMHead.lngHzYMF262 & 0x40000000) + { + if (channel < 23) + { + *ChipID = 0x00; + *ChipType = 0x0C; + *Channel = channel; + ChanCount[0] = 23; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 23; + } + } + + if (p->VGMHead.lngHzYMF278B) + { + if (channel < 47) + { + *ChipID = 0x00; + *ChipType = 0x0D; + *Channel = channel; + ChanCount[0] = 23; + ChanCount[1] = 24; + ChanCount[2] = 0; + } + + channel -= 47; + + if (p->VGMHead.lngHzYMF278B & 0x40000000) + { + if (channel < 47) + { + *ChipID = 0x01; + *ChipType = 0x0D; + *Channel = channel; + ChanCount[0] = 23; + ChanCount[1] = 24; + ChanCount[2] = 0; + } + + channel -= 47; + } + } + + if (p->VGMHead.lngHzYMF271) + { + if (channel < 12) + { + *ChipID = 0x00; + *ChipType = 0x0E; + *Channel = channel; + ChanCount[0] = 12; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 12; + + if (p->VGMHead.lngHzYMF271 & 0x40000000) + { + if (channel < 12) + { + *ChipID = 0x01; + *ChipType = 0x0E; + *Channel = channel; + ChanCount[0] = 12; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 12; + } + } + + if (p->VGMHead.lngHzYMZ280B) + { + if (channel < 8) + { + *ChipID = 0x00; + *ChipType = 0x0F; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + + if (p->VGMHead.lngHzYMZ280B & 0x40000000) + { + if (channel < 8) + { + *ChipID = 0x01; + *ChipType = 0x0F; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + } + } + + if (p->VGMHead.lngHzRF5C164) + { + if (channel < 8) + { + *ChipID = 0x00; + *ChipType = 0x10; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + } + + if (p->VGMHead.lngHzPWM) + { + if (channel < 1) + { + *ChipID = 0x00; + *ChipType = 0x11; + *Channel = channel; + ChanCount[0] = 1; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel--; + } + + if (p->VGMHead.lngHzAY8910) + { + if (channel < 3) + { + *ChipID = 0x00; + *ChipType = 0x12; + *Channel = channel; + ChanCount[0] = 3; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 3; + + if (p->VGMHead.lngHzAY8910 & 0x40000000) + { + if (channel < 3) + { + *ChipID = 0x01; + *ChipType = 0x12; + *Channel = channel; + ChanCount[0] = 3; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 3; + } + } + + if (p->VGMHead.lngHzGBDMG) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x13; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzGBDMG & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x13; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } + + if (p->VGMHead.lngHzNESAPU) + { + if (channel < 6) + { + *ChipID = 0x00; + *ChipType = 0x14; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + + if (p->VGMHead.lngHzNESAPU & 0x40000000) + { + if (channel < 6) + { + *ChipID = 0x01; + *ChipType = 0x14; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + } + } + + if (p->VGMHead.lngHzMultiPCM) + { + if (channel < 28) + { + *ChipID = 0x00; + *ChipType = 0x15; + *Channel = channel; + ChanCount[0] = 28; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 28; + + if (p->VGMHead.lngHzMultiPCM & 0x40000000) + { + if (channel < 28) + { + *ChipID = 0x01; + *ChipType = 0x15; + *Channel = channel; + ChanCount[0] = 28; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 28; + } + } + + if (p->VGMHead.lngHzUPD7759) + { + if (channel < 1) + { + *ChipID = 0x00; + *ChipType = 0x16; + *Channel = channel; + ChanCount[0] = 1; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel--; + + if (p->VGMHead.lngHzUPD7759 & 0x40000000) + { + if (channel < 1) + { + *ChipID = 0x01; + *ChipType = 0x16; + *Channel = channel; + ChanCount[0] = 1; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel--; + } + } + + if (p->VGMHead.lngHzOKIM6258) + { + if (channel < 1) + { + *ChipID = 0x00; + *ChipType = 0x17; + *Channel = channel; + ChanCount[0] = 1; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel--; + + if (p->VGMHead.lngHzOKIM6258 & 0x40000000) + { + if (channel < 1) + { + *ChipID = 0x01; + *ChipType = 0x17; + *Channel = channel; + ChanCount[0] = 1; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel--; + } + } + + if (p->VGMHead.lngHzOKIM6295) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x18; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzOKIM6295 & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x18; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } + + if (p->VGMHead.lngHzK051649) + { + if (channel < 5) + { + *ChipID = 0x00; + *ChipType = 0x19; + *Channel = channel; + ChanCount[0] = 5; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 5; + + if (p->VGMHead.lngHzK051649 & 0x40000000) + { + if (channel < 5) + { + *ChipID = 0x01; + *ChipType = 0x19; + *Channel = channel; + ChanCount[0] = 5; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 5; + } + } + + if (p->VGMHead.lngHzK054539) + { + if (channel < 8) + { + *ChipID = 0x00; + *ChipType = 0x1A; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + + if (p->VGMHead.lngHzK054539 & 0x40000000) + { + if (channel < 8) + { + *ChipID = 0x01; + *ChipType = 0x1A; + *Channel = channel; + ChanCount[0] = 8; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 8; + } + } + + if (p->VGMHead.lngHzHuC6280) + { + if (channel < 6) + { + *ChipID = 0x00; + *ChipType = 0x1B; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + + if (p->VGMHead.lngHzHuC6280 & 0x40000000) + { + if (channel < 6) + { + *ChipID = 0x01; + *ChipType = 0x1B; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + } + } + + if (p->VGMHead.lngHzC140) + { + if (channel < 24) + { + *ChipID = 0x00; + *ChipType = 0x1C; + *Channel = channel; + ChanCount[0] = 24; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 24; + + if (p->VGMHead.lngHzC140 & 0x40000000) + { + if (channel < 24) + { + *ChipID = 0x01; + *ChipType = 0x1C; + *Channel = channel; + ChanCount[0] = 24; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 24; + } + } + + if (p->VGMHead.lngHzK053260) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x1D; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzK053260 & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x1D; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } + + if (p->VGMHead.lngHzPokey) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x1E; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzPokey & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x1E; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } + + if (p->VGMHead.lngHzQSound) + { + if (channel < 16) + { + *ChipID = 0x00; + *ChipType = 0x1F; + *Channel = channel; + ChanCount[0] = 16; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 16; + + if (p->VGMHead.lngHzQSound & 0x40000000) + { + if (channel < 16) + { + *ChipID = 0x01; + *ChipType = 0x1F; + *Channel = channel; + ChanCount[0] = 16; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 16; + } + } + + if (p->VGMHead.lngHzSCSP) + { + if (channel < 32) + { + *ChipID = 0x00; + *ChipType = 0x20; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + + if (p->VGMHead.lngHzSCSP & 0x40000000) + { + if (channel < 32) + { + *ChipID = 0x01; + *ChipType = 0x20; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + } + } + + if (p->VGMHead.lngHzWSwan) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x21; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzWSwan & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x21; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } + + if (p->VGMHead.lngHzVSU) + { + if (channel < 6) + { + *ChipID = 0x00; + *ChipType = 0x22; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + + if (p->VGMHead.lngHzVSU & 0x40000000) + { + if (channel < 6) + { + *ChipID = 0x01; + *ChipType = 0x22; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + } + } + + if (p->VGMHead.lngHzSAA1099) + { + if (channel < 6) + { + *ChipID = 0x00; + *ChipType = 0x23; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + + if (p->VGMHead.lngHzSAA1099 & 0x40000000) + { + if (channel < 6) + { + *ChipID = 0x01; + *ChipType = 0x23; + *Channel = channel; + ChanCount[0] = 6; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 6; + } + } + + if (p->VGMHead.lngHzES5503) + { + if (channel < 32) + { + *ChipID = 0x00; + *ChipType = 0x24; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + + if (p->VGMHead.lngHzES5503 & 0x40000000) + { + if (channel < 32) + { + *ChipID = 0x01; + *ChipType = 0x24; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + } + } + + if (p->VGMHead.lngHzES5506) + { + if (channel < 32) + { + *ChipID = 0x00; + *ChipType = 0x25; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + + if (p->VGMHead.lngHzES5506 & 0x40000000) + { + if (channel < 32) + { + *ChipID = 0x01; + *ChipType = 0x25; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + } + } + + if (p->VGMHead.lngHzX1_010) + { + if (channel < 16) + { + *ChipID = 0x00; + *ChipType = 0x26; + *Channel = channel; + ChanCount[0] = 16; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 16; + + if (p->VGMHead.lngHzX1_010 & 0x40000000) + { + if (channel < 16) + { + *ChipID = 0x01; + *ChipType = 0x26; + *Channel = channel; + ChanCount[0] = 16; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 16; + } + } + + if (p->VGMHead.lngHzC352) + { + if (channel < 32) + { + *ChipID = 0x00; + *ChipType = 0x27; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + + if (p->VGMHead.lngHzC352 & 0x40000000) + { + if (channel < 32) + { + *ChipID = 0x01; + *ChipType = 0x27; + *Channel = channel; + ChanCount[0] = 32; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 32; + } + } + + if (p->VGMHead.lngHzGA20) + { + if (channel < 4) + { + *ChipID = 0x00; + *ChipType = 0x28; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + + if (p->VGMHead.lngHzGA20 & 0x40000000) + { + if (channel < 4) + { + *ChipID = 0x01; + *ChipType = 0x28; + *Channel = channel; + ChanCount[0] = 4; + ChanCount[1] = 0; + ChanCount[2] = 0; + } + + channel -= 4; + } + } +} + +const char* GetAccurateChipNameByChannel(void* vgmp, UINT32 channel, UINT32 *realChannel) +{ + UINT8 ChipID, ChipType, SubType, Channel, ChanCount[3]; + GetChipByChannel(vgmp, channel, &ChipID, &ChipType, &Channel, ChanCount); + if (ChipType == 0xFF) + return NULL; + *realChannel = Channel; + GetChipClock(vgmp, ChipType, &SubType); + return GetAccurateChipName(ChipType, SubType); +} + +void SetChannelMute(void* vgmp, UINT32 channel, UINT8 mute) +{ + VGM_PLAYER *p = (VGM_PLAYER *)vgmp; + + UINT8 ChipID, ChipType, Channel, ChanCount[3]; + + CHIP_OPTS *opts; + + UINT8 FieldNumber; + + UINT32 *ChnMutes; + + GetChipByChannel(vgmp, channel, &ChipID, &ChipType, &Channel, ChanCount); + + if (ChipType == 0xFF) + return; + + opts = (CHIP_OPTS *)(&p->ChipOpts[ChipID]) + ChipType; + + ChnMutes = (UINT32 *)(&opts->ChnMute1); + + for (FieldNumber = 0; FieldNumber < 3; FieldNumber++) + { + if (Channel < ChanCount[FieldNumber]) + { + if (mute) + ChnMutes[FieldNumber] |= 1 << Channel; + else + ChnMutes[FieldNumber] &= ~(1 << Channel); + break; + } + + Channel -= ChanCount[FieldNumber]; + } + + Chips_GeneralActions(p, 0x10); +} diff --git a/Frameworks/GME/vgmplay/VGMPlay_Intf.h b/Frameworks/GME/vgmplay/VGMPlay_Intf.h index 033b4a138..938257c0c 100644 --- a/Frameworks/GME/vgmplay/VGMPlay_Intf.h +++ b/Frameworks/GME/vgmplay/VGMPlay_Intf.h @@ -49,6 +49,10 @@ UINT32 CalcSampleMSecExt(void* vgmp, UINT64 Value, UINT8 Mode, VGM_HEADER* FileH const char* GetChipName(UINT8 ChipID); const char* GetAccurateChipName(UINT8 ChipID, UINT8 SubType); UINT32 GetChipClock(void* vgmp, UINT8 ChipID, UINT8* RetSubType); + +const char* GetAccurateChipNameByChannel(void* vgmp, UINT32 channel, UINT32 *realChannel); + +void SetChannelMute(void* vgmp, UINT32 channel, UINT8 mute); #ifndef NO_WCHAR_FILENAMES UINT32 GetGZFileLengthW(const wchar_t* FileName); diff --git a/Frameworks/GME/vgmplay/chips/okim6258.c b/Frameworks/GME/vgmplay/chips/okim6258.c index c6a27a4d8..c79fc2d49 100644 --- a/Frameworks/GME/vgmplay/chips/okim6258.c +++ b/Frameworks/GME/vgmplay/chips/okim6258.c @@ -72,6 +72,8 @@ struct _okim6258_state UINT8 Iternal10Bit; UINT8 DCRemoval; + + UINT8 mute; }; /* step size index shift table */ @@ -171,6 +173,7 @@ void okim6258_update(void *param, stream_sample_t **outputs, int samples) //stream_sample_t *buffer = outputs[0]; stream_sample_t *bufL = outputs[0]; stream_sample_t *bufR = outputs[1]; + int mute = chip->mute; //memset(outputs[0], 0, samples * sizeof(*outputs[0])); @@ -231,8 +234,16 @@ void okim6258_update(void *param, stream_sample_t **outputs, int samples) nibble_shift ^= 4; //*buffer++ = sample; - *bufL++ = (chip->pan & 0x02) ? 0x00 : sample; - *bufR++ = (chip->pan & 0x01) ? 0x00 : sample; + if (mute) + { + *bufL++ = 0; + *bufR++ = 0; + } + else + { + *bufL++ = (chip->pan & 0x02) ? 0x00 : sample; + *bufR++ = (chip->pan & 0x01) ? 0x00 : sample; + } samples--; } @@ -252,6 +263,12 @@ void okim6258_update(void *param, stream_sample_t **outputs, int samples) } +void okim6258_mute(void *ptr, int mute) +{ + okim6258_state *chip = (okim6258_state *)ptr; + chip->mute = mute; +} + /********************************************************************************************** diff --git a/Frameworks/GME/vgmplay/chips/okim6258.h b/Frameworks/GME/vgmplay/chips/okim6258.h index 154ef4a23..5de57fdd1 100644 --- a/Frameworks/GME/vgmplay/chips/okim6258.h +++ b/Frameworks/GME/vgmplay/chips/okim6258.h @@ -36,6 +36,8 @@ void okim6258_set_divider(void *chip, int val); void okim6258_set_clock(void *chip, int val); int okim6258_get_vclk(void *chip); +void okim6258_mute(void *chip, int mute); + //READ8_DEVICE_HANDLER( okim6258_status_r ); //WRITE8_DEVICE_HANDLER( okim6258_data_w ); //WRITE8_DEVICE_HANDLER( okim6258_ctrl_w ); diff --git a/Frameworks/GME/vgmplay/chips/pwm.c b/Frameworks/GME/vgmplay/chips/pwm.c index 26491efcd..1ca81682d 100644 --- a/Frameworks/GME/vgmplay/chips/pwm.c +++ b/Frameworks/GME/vgmplay/chips/pwm.c @@ -87,6 +87,8 @@ typedef struct _pwm_chip #endif int clock; + + unsigned char Mute; } pwm_chip; #if CHILLY_WILLY_SCALE // TODO: Fix Chilly Willy's new scaling algorithm. @@ -327,6 +329,9 @@ void PWM_Update(pwm_chip* chip, int **buf, int length) tmpOutL = PWM_Update_Scale(chip, (int)chip->PWM_Out_L); tmpOutR = PWM_Update_Scale(chip, (int)chip->PWM_Out_R); + tmpOutL = chip->Mute ? 0 : tmpOutL; + tmpOutR = chip->Mute ? 0 : tmpOutR; + for (i = 0; i < length; i ++) { buf[0][i] = tmpOutL; @@ -342,6 +347,12 @@ void pwm_update(void *_info, stream_sample_t **outputs, int samples) PWM_Update(chip, outputs, samples); } +void pwm_mute(void *_info, UINT8 Mute) +{ + pwm_chip *chip = (pwm_chip *)_info; + chip->Mute = Mute; +} + int device_start_pwm(void **_info, int clock, int CHIP_SAMPLING_MODE, int CHIP_SAMPLE_RATE) { /* allocate memory for the chip */ diff --git a/Frameworks/GME/vgmplay/chips/pwm.h b/Frameworks/GME/vgmplay/chips/pwm.h index 864467b25..7d5ccc56a 100644 --- a/Frameworks/GME/vgmplay/chips/pwm.h +++ b/Frameworks/GME/vgmplay/chips/pwm.h @@ -58,4 +58,6 @@ int device_start_pwm(void **chip, int clock, int CHIP_SAMPLING_MODE, int CHIP_SA void device_stop_pwm(void *chip); void device_reset_pwm(void *chip); +void pwm_mute(void *chip, UINT8 Mute); + void pwm_chn_w(void *chip, UINT8 Channel, UINT16 data); diff --git a/Frameworks/GME/vgmplay/chips/upd7759.c b/Frameworks/GME/vgmplay/chips/upd7759.c index 23e32223c..9b6e80289 100644 --- a/Frameworks/GME/vgmplay/chips/upd7759.c +++ b/Frameworks/GME/vgmplay/chips/upd7759.c @@ -204,6 +204,8 @@ struct _upd7759_state UINT8 data_buf[0x40]; UINT8 dbuf_pos_read; UINT8 dbuf_pos_write; + + UINT8 mute; }; @@ -511,14 +513,23 @@ void upd7759_update(void *param, stream_sample_t **outputs, int samples) UINT32 pos = chip->pos; stream_sample_t *buffer = outputs[0]; stream_sample_t *buffer2 = outputs[1]; + int mute = chip->mute; /* loop until done */ if (chip->state != STATE_IDLE) while (samples != 0) { /* store the current sample */ - *buffer++ = sample << 7; - *buffer2++ = sample << 7; + if (mute) + { + *buffer++ = 0; + *buffer2++ = 0; + } + else + { + *buffer++ = sample << 7; + *buffer2++ = sample << 7; + } samples--; /* advance by the number of clocks/output sample */ @@ -586,6 +597,11 @@ void upd7759_update(void *param, stream_sample_t **outputs, int samples) chip->pos = pos; } +void upd7759_mute(void *ptr, int mute) +{ + upd7759_state *chip = (upd7759_state *)ptr; + chip->mute = mute; +} /************************************************************ diff --git a/Frameworks/GME/vgmplay/chips/upd7759.h b/Frameworks/GME/vgmplay/chips/upd7759.h index e2604a4db..c436ce230 100644 --- a/Frameworks/GME/vgmplay/chips/upd7759.h +++ b/Frameworks/GME/vgmplay/chips/upd7759.h @@ -21,6 +21,8 @@ void device_reset_upd7759(void *chip); int device_start_upd7759(void **chip, int clock); void device_stop_upd7759(void *chip); +void upd7759_mute(void *chip, int mute); + //void upd7759_set_bank_base(running_device *device, offs_t base); //void upd7759_reset_w(running_device *device, UINT8 data);