diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp index 94b4c24707..fcc989396e 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Logging/Logging.cpp @@ -141,8 +141,8 @@ int vectorLength2 = 100; // for console version // should we worry about the additonal memory these lists require? bool will allocate // very little memory -std::vector< std::vector > vector1(64, std::vector(vectorLength,0)); -std::vector< std::vector > vector2(64, std::vector(vectorLength2,0)); +std::vector< std::vector > vector1(64, std::vector(vectorLength, 0)); +std::vector< std::vector > vector2(64, std::vector(vectorLength2, 0)); std::vector numberRunning(64); @@ -301,12 +301,12 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a) } else { - Conditions = (numberRunning.at(i) > 0 || PBs[i].audio_addr.looping); + Conditions = numberRunning.at(i) > 0 || PBs[i].audio_addr.looping; } // -------------- - if(Conditions) + if (Conditions) { // AXPB base gcoef[i] = PBs[i].unknown1; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp index b82bc60abe..b9767e1456 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp @@ -28,7 +28,6 @@ #include "UCode_AXStructs.h" #include "UCode_AX.h" - // --------------------------------------------------------------------------------------- // Externals // ----------- @@ -43,7 +42,6 @@ bool gReset = false; // used externally extern CDebugger* m_frame; // ----------- - CUCode_AX::CUCode_AX(CMailHandler& _rMailHandler, bool wii) : IUCode(_rMailHandler) , m_addressPBs(0xFFFFFFFF) @@ -76,7 +74,7 @@ void CUCode_AX::HandleMail(u32 _uMail) } } -s16 CUCode_AX::ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac) +s16 ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac) { PBADPCMInfo &adpcm = pb.adpcm; @@ -158,302 +156,294 @@ u16 ADPCM_Vol(u16 vol, u16 delta, u16 mixer_control) } // ============== +void MixAddVoice(AXParamBlock &pb, int *templbuffer, int *temprbuffer, int _iSize) +{ +#ifdef _WIN32 + ratioFactor = 32000.0f / (float)DSound::DSound_GetSampleRate(); +#else + ratioFactor = 32000.0f / 44100.0f; +#endif + + // get necessary values + const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo; + const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo; + const u32 updaddr = (u32)(pb.updates.data_hi << 16) | pb.updates.data_lo; + const u16 updpar = Memory_Read_U16(updaddr); + const u16 upddata = Memory_Read_U16(updaddr + 2); + + // ======================================================================================= + /* + Fix problems introduced with the SSBM fix - Sometimes when a music stream ended sampleEnd + would become extremely high and the game would play random sound data from ARAM resulting in + a strange noise. This should take care of that. - Some games (Monkey Ball 1 and Tales of + Symphonia and other) also had one odd last block with a strange high loopPos and strange + num_updates values, the loopPos limit turns those off also. - Please report any side effects. + */ + // ------------ + if ( + (sampleEnd > 0x10000000 || loopPos > 0x10000000) + && gSSBMremedy1 + ) + { + pb.running = 0; + + // also reset all values if it makes any difference + pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; + pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; + pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; + + pb.src.cur_addr_frac = 0; pb.src.ratio_hi = 0; pb.src.ratio_lo = 0; + pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0; + + pb.audio_addr.looping = 0; + pb.adpcm_loop_info.pred_scale = 0; + pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; + } + + /* + // the fact that no settings are reset (except running) after a SSBM type music stream or another + looping block (for example in Battle Stadium DON) has ended could cause loud garbled sound to be + played from one or more blocks. Perhaps it was in conjunction with the old sequenced music fix below, + I'm not sure. This was an attempt to prevent that anyway by resetting all. But I'm not sure if this + is needed anymore. Please try to play SSBM without it and see if it works anyway. + */ + if ( + // detect blocks that have recently been running that we should reset + pb.running == 0 && pb.audio_addr.looping == 1 + //pb.running == 0 && pb.adpcm_loop_info.pred_scale + + // this prevents us from ruining sequenced music blocks, may not be needed + /* + && !(pb.updates.num_updates[0] || pb.updates.num_updates[1] || pb.updates.num_updates[2] + || pb.updates.num_updates[3] || pb.updates.num_updates[4]) + */ + && !(updpar || upddata) + + && pb.mixer_control == 0 // only use this in SSBM + + && gSSBMremedy2 // let us turn this fix on and off + ) + { + // reset the detection values + pb.audio_addr.looping = 0; + pb.adpcm_loop_info.pred_scale = 0; + pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; + + //pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; + //pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; + //pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; + + //pb.src.cur_addr_frac = 0; PBs[i].src.ratio_hi = 0; PBs[i].src.ratio_lo = 0; + //pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0; + } + + // ============= + + + // ======================================================================================= + // Reset all values + // ------------ + if (gReset + && (pb.running || pb.audio_addr.looping || pb.adpcm_loop_info.pred_scale) + ) + { + pb.running = 0; + + pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; + pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; + pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; + + pb.src.cur_addr_frac = 0; pb.src.ratio_hi = 0; pb.src.ratio_lo = 0; + pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0; + + pb.audio_addr.looping = 0; + pb.adpcm_loop_info.pred_scale = 0; + pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; + } + // ============= + if (pb.running) + { + // ======================================================================================= + // Set initial parameters + // ------------ + //constants + const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor); + + //variables + u32 samplePos = (pb.audio_addr.cur_addr_hi << 16) | pb.audio_addr.cur_addr_lo; + u32 frac = pb.src.cur_addr_frac; + // ============= + + // ======================================================================================= + // Handle no-src streams - No src streams have pb.src_type == 2 and have pb.src.ratio_hi = 0 + // and pb.src.ratio_lo = 0. We handle that by setting the sampling ratio integer to 1. This + // makes samplePos update in the correct way. I'm unsure how we are actually supposed to + // detect that this setting. Updates did not fix this automatically. + // --------------------------------------------------------------------------------------- + // Stream settings + // src_type = 2 (most other games have src_type = 0) + // ------------ + // Affected games: + // Baten Kaitos - Eternal Wings (2003) + // Baten Kaitos - Origins (2006)? + // Soul Calibur 2: The movie music use src_type 2 but it needs no adjustment, perhaps + // the sound format plays in to, Baten use ADPCM SC2 use PCM16 + // ------------ + if(pb.src_type == 2 && (pb.src.ratio_hi == 0 && pb.src.ratio_lo == 0)) + { + pb.src.ratio_hi = 1; + } + // ============= + + + // ======================================================================================= + // Games that use looping to play non-looping music streams - SSBM has info in all + // pb.adpcm_loop_info parameters but has pb.audio_addr.looping = 0. If we treat these streams + // like any other looping streams the music works. I'm unsure how we are actually supposed to + // detect that these kinds of blocks should be looping. It seems like pb.mixer_control == 0 may + // identify these types of blocks. Updates did not write any looping values. + // -------------- + if( + (pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2) + && pb.mixer_control == 0 + && gSSBM + ) + { + pb.audio_addr.looping = 1; + } + // ============== + + // ======================================================================================= + // Walk through _iSize. _iSize = numSamples. If the game goes slow _iSize will be higher to + // compensate for that. _iSize can be as low as 100 or as high as 2000 some cases. + for (int s = 0; s < _iSize; s++) + { + int sample = 0; + frac += ratio; + u32 newSamplePos = samplePos + (frac >> 16); //whole number of frac + + // ======================================================================================= + // Process sample format + // -------------- + switch (pb.audio_addr.sample_format) + { + case AUDIOFORMAT_PCM8: + pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample + pb.adpcm.yn1 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos)) << 8; + + if (pb.src_type == SRCTYPE_NEAREST) + { + sample = pb.adpcm.yn1; + } + else //linear interpolation + { + sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16; + } + + samplePos = newSamplePos; + break; + + case AUDIOFORMAT_PCM16: + pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample + pb.adpcm.yn1 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8(samplePos * 2) << 8) | (g_dspInitialize.pARAM_Read_U8((samplePos * 2 + 1)))); + if (pb.src_type == SRCTYPE_NEAREST) + sample = pb.adpcm.yn1; + else //linear interpolation + sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16; + + samplePos = newSamplePos; + break; + + case AUDIOFORMAT_ADPCM: + sample = ADPCM_Step(pb, samplePos, newSamplePos, frac); + break; + + default: + break; + } + // ================ + + // ======================================================================================= + // Volume control + frac &= 0xffff; + + int vol = pb.vol_env.cur_volume >> 9; + sample = sample * vol >> 8; + + if (pb.mixer_control & MIXCONTROL_RAMPING) + { + int x = pb.vol_env.cur_volume; + x += pb.vol_env.cur_volume_delta; // I'm not sure about this, can anybody find a game + // that use this? Or how does it work? + if (x < 0) x = 0; + if (x >= 0x7fff) x = 0x7fff; + pb.vol_env.cur_volume = x; // maybe not per sample?? :P + } + + int leftmix = pb.mixer.volume_left >> 5; + int rightmix = pb.mixer.volume_right >> 5; + // =============== + int left = sample * leftmix >> 8; + int right = sample * rightmix >> 8; + //adpcm has to walk from oldSamplePos to samplePos here + templbuffer[s] += left; + temprbuffer[s] += right; + + if (samplePos >= sampleEnd) + { + if (pb.audio_addr.looping == 1) + { + samplePos = loopPos; + if (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM) + ADPCM_Loop(pb); + } + else + { + pb.running = 0; + break; + } + } + } // end of the _iSize loop + // ============ + if (gVolume) // allow us to turn this off in the debugger + { + pb.mixer.volume_left = ADPCM_Vol(pb.mixer.volume_left, pb.mixer.unknown, pb.mixer_control); + pb.mixer.volume_right = ADPCM_Vol(pb.mixer.volume_right, pb.mixer.unknown2, pb.mixer_control); + } + pb.src.cur_addr_frac = (u16)frac; + pb.audio_addr.cur_addr_hi = samplePos >> 16; + pb.audio_addr.cur_addr_lo = (u16)samplePos; + } +} void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) { AXParamBlock PBs[NUMBER_OF_PBS]; + // read out pbs + int numberOfPBs = ReadOutPBs(1, PBs, NUMBER_OF_PBS); + if (_iSize > 1024 * 1024) _iSize = 1024 * 1024; memset(templbuffer, 0, _iSize * sizeof(int)); memset(temprbuffer, 0, _iSize * sizeof(int)); - // read out pbs - int numberOfPBs = ReadOutPBs(1, PBs, NUMBER_OF_PBS); - -#ifdef _WIN32 - ratioFactor = 32000.0f / (float)DSound::DSound_GetSampleRate(); -#else - ratioFactor = 32000.0f / 44100.0f; -#endif - // write logging data to debugger - if(m_frame) + if (m_frame) { CUCode_AX::Logging(_pBuffer, _iSize, 0); } - - + for (int i = 0; i < numberOfPBs; i++) { AXParamBlock& pb = PBs[i]; - - // get necessary values - const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo; - const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo; - const u32 updaddr = (u32)(pb.updates.data_hi << 16) | pb.updates.data_lo; - const u16 updpar = Memory_Read_U16(updaddr); - const u16 upddata = Memory_Read_U16(updaddr + 2); - - - // ======================================================================================= - /* - Fix problems introduced with the SSBM fix - Sometimes when a music stream ended sampleEnd - would become extremely high and the game would play random sound data from ARAM resulting in - a strange noise. This should take care of that. - Some games (Monkey Ball 1 and Tales of - Symphonia and other) also had one odd last block with a strange high loopPos and strange - num_updates values, the loopPos limit turns those off also. - Please report any side effects. - */ - // ------------ - if ( - (sampleEnd > 0x10000000 || loopPos > 0x10000000) - && gSSBMremedy1 - ) - { - pb.running = 0; - - // also reset all values if it makes any difference - pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; - pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; - pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; - - pb.src.cur_addr_frac = 0; PBs[i].src.ratio_hi = 0; PBs[i].src.ratio_lo = 0; - pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0; - - pb.audio_addr.looping = 0; - pb.adpcm_loop_info.pred_scale = 0; - pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; - } - - /* - // the fact that no settings are reset (except running) after a SSBM type music stream or another - looping block (for example in Battle Stadium DON) has ended could cause loud garbled sound to be - played from one or more blocks. Perhaps it was in conjunction with the old sequenced music fix below, - I'm not sure. This was an attempt to prevent that anyway by resetting all. But I'm not sure if this - is needed anymore. Please try to play SSBM without it and see if it works anyway. - */ - if ( - // detect blocks that have recently been running that we should reset - pb.running == 0 && pb.audio_addr.looping == 1 - //pb.running == 0 && pb.adpcm_loop_info.pred_scale - - // this prevents us from ruining sequenced music blocks, may not be needed - /* - && !(pb.updates.num_updates[0] || pb.updates.num_updates[1] || pb.updates.num_updates[2] - || pb.updates.num_updates[3] || pb.updates.num_updates[4]) - */ - && !(updpar || upddata) - - && pb.mixer_control == 0 // only use this in SSBM - - && gSSBMremedy2 // let us turn this fix on and off - ) - { - // reset the detection values - pb.audio_addr.looping = 0; - pb.adpcm_loop_info.pred_scale = 0; - pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; - - //pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; - //pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; - //pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; - - //pb.src.cur_addr_frac = 0; PBs[i].src.ratio_hi = 0; PBs[i].src.ratio_lo = 0; - //pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0; - } - - // ============= - - - // ======================================================================================= - // Reset all values - // ------------ - if (gReset - && (pb.running || pb.audio_addr.looping || pb.adpcm_loop_info.pred_scale) - ) - { - pb.running = 0; - - pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0; - pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0; - pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0; - - pb.src.cur_addr_frac = 0; PBs[i].src.ratio_hi = 0; PBs[i].src.ratio_lo = 0; - pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0; - - pb.audio_addr.looping = 0; - pb.adpcm_loop_info.pred_scale = 0; - pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0; - } - // ============= - - - if (pb.running) - { - // ======================================================================================= - // Set initial parameters - // ------------ - //constants - const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor); - - //variables - u32 samplePos = (pb.audio_addr.cur_addr_hi << 16) | pb.audio_addr.cur_addr_lo; - u32 frac = pb.src.cur_addr_frac; - // ============= - - - - // ======================================================================================= - // Handle no-src streams - No src streams have pb.src_type == 2 and have pb.src.ratio_hi = 0 - // and pb.src.ratio_lo = 0. We handle that by setting the sampling ratio integer to 1. This - // makes samplePos update in the correct way. I'm unsure how we are actually supposed to - // detect that this setting. Updates did not fix this automatically. - // --------------------------------------------------------------------------------------- - // Stream settings - // src_type = 2 (most other games have src_type = 0) - // ------------ - // Affected games: - // Baten Kaitos - Eternal Wings (2003) - // Baten Kaitos - Origins (2006)? - // Soul Calibur 2: The movie music use src_type 2 but it needs no adjustment, perhaps - // the sound format plays in to, Baten use ADPCM SC2 use PCM16 - // ------------ - if(pb.src_type == 2 && (pb.src.ratio_hi == 0 && pb.src.ratio_lo == 0)) - { - pb.src.ratio_hi = 1; - } - // ============= - - - // ======================================================================================= - // Games that use looping to play non-looping music streams - SSBM has info in all - // pb.adpcm_loop_info parameters but has pb.audio_addr.looping = 0. If we treat these streams - // like any other looping streams the music works. I'm unsure how we are actually supposed to - // detect that these kinds of blocks should be looping. It seems like pb.mixer_control == 0 may - // identify these types of blocks. Updates did not write any looping values. - // -------------- - if( - (pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2) - && pb.mixer_control == 0 - && gSSBM - ) - { - pb.audio_addr.looping = 1; - } - // ============== - - - // ======================================================================================= - // Walk through _iSize. _iSize = numSamples. If the game goes slow _iSize will be higher to - // compensate for that. _iSize can be as low as 100 or as high as 2000 some cases. - for (int s = 0; s < _iSize; s++) - { - int sample = 0; - frac += ratio; - u32 newSamplePos = samplePos + (frac >> 16); //whole number of frac - - - // ======================================================================================= - // Process sample format - // -------------- - switch (pb.audio_addr.sample_format) - { - case AUDIOFORMAT_PCM8: - pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample - pb.adpcm.yn1 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos)) << 8; - - if (pb.src_type == SRCTYPE_NEAREST) - { - sample = pb.adpcm.yn1; - } - else //linear interpolation - { - sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16; - } - - samplePos = newSamplePos; - break; - - case AUDIOFORMAT_PCM16: - pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample - pb.adpcm.yn1 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8(samplePos * 2) << 8) | (g_dspInitialize.pARAM_Read_U8((samplePos * 2 + 1)))); - if (pb.src_type == SRCTYPE_NEAREST) - sample = pb.adpcm.yn1; - else //linear interpolation - sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16; - - samplePos = newSamplePos; - break; - - case AUDIOFORMAT_ADPCM: - sample = ADPCM_Step(pb, samplePos, newSamplePos, frac); - break; - - default: - break; - } - // ================ - - - // ======================================================================================= - // Volume control - frac &= 0xffff; - - int vol = pb.vol_env.cur_volume >> 9; - sample = sample * vol >> 8; - - if (pb.mixer_control & MIXCONTROL_RAMPING) - { - int x = pb.vol_env.cur_volume; - x += pb.vol_env.cur_volume_delta; // I'm not sure about this, can anybody find a game - // that use this? Or how does it work? - if (x < 0) x = 0; - if (x >= 0x7fff) x = 0x7fff; - pb.vol_env.cur_volume = x; // maybe not per sample?? :P - } - - int leftmix = pb.mixer.volume_left >> 5; - int rightmix = pb.mixer.volume_right >> 5; - // =============== - - - int left = sample * leftmix >> 8; - int right = sample * rightmix >> 8; - - //adpcm has to walk from oldSamplePos to samplePos here - templbuffer[s] += left; - temprbuffer[s] += right; - - if (samplePos >= sampleEnd) - { - if (pb.audio_addr.looping == 1) - { - samplePos = loopPos; - if (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM) - ADPCM_Loop(pb); - } - else - { - pb.running = 0; - break; - } - } - } // end of the _iSize loop - // ============ - - if (gVolume) // allow us to turn this off in the debugger - { - pb.mixer.volume_left = ADPCM_Vol(pb.mixer.volume_left, pb.mixer.unknown, pb.mixer_control); - pb.mixer.volume_right = ADPCM_Vol(pb.mixer.volume_right, pb.mixer.unknown2, pb.mixer_control); - } - - pb.src.cur_addr_frac = (u16)frac; - pb.audio_addr.cur_addr_hi = samplePos >> 16; - pb.audio_addr.cur_addr_lo = (u16)samplePos; - } + MixAddVoice(pb, templbuffer, temprbuffer, _iSize); } + // write back out pbs + WriteBackPBs(PBs, numberOfPBs); + for (int i = 0; i < _iSize; i++) { // Clamp into 16-bit. Maybe we should add a volume compressor here. @@ -467,9 +457,6 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) *_pBuffer++ = right; } - // write back out pbs - WriteBackPBs(PBs, numberOfPBs); - // write logging data to debugger again after the update if (m_frame) { @@ -477,6 +464,7 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) } } + void CUCode_AX::Update() { // check if we have to sent something diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h index 1ff81e1203..6614f8b034 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h @@ -20,6 +20,11 @@ #include "UCode_AXStructs.h" +enum +{ + NUMBER_OF_PBS = 64 +}; + class CUCode_AX : public IUCode { public: @@ -34,12 +39,6 @@ public: void Logging(short* _pBuffer, int _iSize, int a); private: - - enum - { - NUMBER_OF_PBS = 64 - }; - enum { MAIL_AX_ALIST = 0xBABE0000, @@ -64,7 +63,6 @@ private: void SendMail(u32 _uMail); int ReadOutPBs(int a, AXParamBlock *_pPBs, int _num); void WriteBackPBs(AXParamBlock *_pPBs, int _num); - s16 ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac); }; #endif // _UCODE_AX diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h index 19bea069b6..a2ca4b1d66 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h @@ -29,6 +29,17 @@ struct PBMixer u16 unknown4[6]; }; +struct PBMixerWii +{ + u16 volume_left; + u16 unknown; + u16 volume_right; + u16 unknown2; + + u16 unknown3[12]; + u16 unknown4[8]; +}; + struct PBInitialTimeDelay { u16 on; @@ -51,11 +62,23 @@ struct PBUpdates u16 data_lo; }; -struct PBUnknown +struct PBUpdatesWii +{ + u16 num_updates[3]; + u16 data_hi; // These point to main RAM. Not sure about the structure of the data. + u16 data_lo; +}; + +struct PBDpop { s16 unknown[9]; }; +struct PBDpopWii +{ + s16 unknown[12]; +}; + struct PBVolumeEnvelope { u16 cur_volume; @@ -121,7 +144,7 @@ struct AXParamBlock /* 9 */ PBMixer mixer; /* 27 */ PBInitialTimeDelay initial_time_delay; /* 34 */ PBUpdates updates; -/* 41 */ PBUnknown unknown2; +/* 41 */ PBDpop dpop; /* 50 */ PBVolumeEnvelope vol_env; /* 52 */ PBUnknown2 unknown3; /* 55 */ PBAudioAddr audio_addr; @@ -131,6 +154,43 @@ struct AXParamBlock /* 93 */ u16 unknown_maybe_padding[3]; }; +struct PBLpf +{ + u16 enabled; + u16 yn1; + u16 a0; + u16 b0; +}; + +struct AXParamBlockWii +{ + u16 next_pb_hi; + u16 next_pb_lo; + + u16 this_pb_hi; + u16 this_pb_lo; + + u16 src_type; // Type of sample rate converter (none, ?, linear) + u16 coef_select; + + u16 mixer_control; + u16 running; // 1=RUN 0=STOP + u16 is_stream; // 1 = stream, 0 = one shot + + PBMixerWii mixer; + PBInitialTimeDelay initial_time_delay; + PBUpdatesWii updates; + PBDpopWii dpop; + PBVolumeEnvelope vol_env; + PBUnknown2 unknown3; + PBAudioAddr audio_addr; + PBADPCMInfo adpcm; + PBSampleRateConverter src; + PBADPCMLoopInfo adpcm_loop_info; + PBLpf lpf; + u16 pad[22]; +}; + enum { AUDIOFORMAT_ADPCM = 0, AUDIOFORMAT_PCM8 = 0x19,