mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
Attempt to fix a sound problem that could appear in SSBM, Battle Stadium DON and perhaps other games. Please report any side effects.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@785 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
037e3d0442
commit
f4b9a22324
@ -26,6 +26,9 @@
|
|||||||
|
|
||||||
// externals
|
// externals
|
||||||
extern int gUpdFreq;
|
extern int gUpdFreq;
|
||||||
|
extern bool gSSBM;
|
||||||
|
extern bool gSSBMremedy1;
|
||||||
|
extern bool gSSBMremedy2;
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
// Declare events
|
// Declare events
|
||||||
@ -33,6 +36,9 @@ BEGIN_EVENT_TABLE(CDebugger,wxDialog)
|
|||||||
EVT_CLOSE(CDebugger::OnClose)
|
EVT_CLOSE(CDebugger::OnClose)
|
||||||
EVT_BUTTON(ID_UPD,CDebugger::OnUpdate)
|
EVT_BUTTON(ID_UPD,CDebugger::OnUpdate)
|
||||||
EVT_CHECKBOX(IDC_CHECK2,CDebugger::ShowHideConsole)
|
EVT_CHECKBOX(IDC_CHECK2,CDebugger::ShowHideConsole)
|
||||||
|
EVT_CHECKBOX(IDC_CHECK3,CDebugger::SSBM)
|
||||||
|
EVT_CHECKBOX(IDC_CHECK4,CDebugger::SSBMremedy1)
|
||||||
|
EVT_CHECKBOX(IDC_CHECK5,CDebugger::SSBMremedy2)
|
||||||
EVT_RADIOBOX(IDC_RADIO1,CDebugger::ChangeFrequency)
|
EVT_RADIOBOX(IDC_RADIO1,CDebugger::ChangeFrequency)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
@ -132,6 +138,29 @@ SetTitle(wxT("Sound Debugging"));
|
|||||||
m_checkSizer->Add(m_Check[2], 0, 0, 5);
|
m_checkSizer->Add(m_Check[2], 0, 0, 5);
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
||||||
|
// settings checkboxes -----------------------------------------------------
|
||||||
|
m_Label[1] = new wxStaticBox(this, IDG_LABEL2, wxT("Settings"),
|
||||||
|
wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
wxStaticBoxSizer * m_checkSizer2 = new wxStaticBoxSizer (m_Label[1], wxVERTICAL);
|
||||||
|
|
||||||
|
// checkboxes
|
||||||
|
m_Check[3] = new wxCheckBox(this, IDC_CHECK3, wxT("SSBM fix"),
|
||||||
|
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
m_Check[3]->SetValue(gSSBM);
|
||||||
|
m_Check[4] = new wxCheckBox(this, IDC_CHECK4, wxT("SSBM remedy 1"),
|
||||||
|
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
m_Check[4]->SetValue(gSSBMremedy1);
|
||||||
|
m_Check[5] = new wxCheckBox(this, IDC_CHECK5, wxT("SSBM remedy 2"),
|
||||||
|
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
m_Check[5]->SetValue(gSSBMremedy2);
|
||||||
|
|
||||||
|
|
||||||
|
m_checkSizer2->Add(m_Check[3], 0, 0, 5);
|
||||||
|
m_checkSizer2->Add(m_Check[4], 0, 0, 5);
|
||||||
|
m_checkSizer2->Add(m_Check[5], 0, 0, 5);
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
|
||||||
// radio boxes -----------------------------------------------------
|
// radio boxes -----------------------------------------------------
|
||||||
int m_radioBoxNChoices[2];
|
int m_radioBoxNChoices[2];
|
||||||
|
|
||||||
@ -154,12 +183,18 @@ SetTitle(wxT("Sound Debugging"));
|
|||||||
m_Presets = new wxButton(this, ID_PRESETS, wxT("Presets"),
|
m_Presets = new wxButton(this, ID_PRESETS, wxT("Presets"),
|
||||||
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
sLeft = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Current Status"));
|
// right buttons
|
||||||
|
wxBoxSizer* sButtons2;
|
||||||
|
sButtons2 = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
|
sButtons2->AddStretchSpacer(1);
|
||||||
|
sButtons2->Add(m_checkSizer2, 0, 2, 5);
|
||||||
|
sButtons2->AddStretchSpacer(1);
|
||||||
|
|
||||||
|
// left buttons
|
||||||
wxBoxSizer* sButtons;
|
wxBoxSizer* sButtons;
|
||||||
sButtons = new wxBoxSizer(wxVERTICAL);
|
sButtons = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
|
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
|
|
||||||
sButtons->Add(m_Upd, 0, 0, 5);
|
sButtons->Add(m_Upd, 0, 0, 5);
|
||||||
@ -180,13 +215,16 @@ SetTitle(wxT("Sound Debugging"));
|
|||||||
|
|
||||||
sButtons->AddStretchSpacer(1);
|
sButtons->AddStretchSpacer(1);
|
||||||
|
|
||||||
|
// blocks view
|
||||||
|
sLeft = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Current Status"));
|
||||||
sLeft->Add(m_GPRListView, 1, wxEXPAND|wxALL, 5);
|
sLeft->Add(m_GPRListView, 1, wxEXPAND|wxALL, 5);
|
||||||
|
|
||||||
|
|
||||||
|
// add all stuff to the main container
|
||||||
sMain = new wxBoxSizer(wxHORIZONTAL);
|
sMain = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sMain->Add(sLeft, 1, wxEXPAND|wxALL, 5);
|
sMain->Add(sLeft, 1, wxEXPAND|wxALL, 5);
|
||||||
sMain->Add(sButtons, 0, wxEXPAND, 0);
|
sMain->Add(sButtons, 0, wxEXPAND, 0);
|
||||||
|
sMain->Add(sButtons2, 0, wxEXPAND, 0);
|
||||||
|
|
||||||
this->SetSizer(sMain);
|
this->SetSizer(sMain);
|
||||||
sMain->SetSizeHints(this);
|
sMain->SetSizeHints(this);
|
||||||
@ -208,6 +246,38 @@ void CDebugger::OnUpdate(wxCommandEvent& /*event*/)
|
|||||||
this->NotifyUpdate();
|
this->NotifyUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
// Settings
|
||||||
|
// --------------
|
||||||
|
void CDebugger::SSBM(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
if(m_Check[3]->IsChecked() == 1)
|
||||||
|
{gSSBM = true;}
|
||||||
|
else
|
||||||
|
{gSSBM = false;}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebugger::SSBMremedy1(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
if(m_Check[4]->IsChecked() == 1)
|
||||||
|
{gSSBMremedy1 = true;}
|
||||||
|
else
|
||||||
|
{gSSBMremedy1 = false;}
|
||||||
|
}
|
||||||
|
void CDebugger::SSBMremedy2(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
if(m_Check[5]->IsChecked() == 1)
|
||||||
|
{gSSBMremedy2 = true;}
|
||||||
|
else
|
||||||
|
{gSSBMremedy2 = false;}
|
||||||
|
}
|
||||||
|
// =======================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
// Change update frequency
|
||||||
|
// --------------
|
||||||
void CDebugger::ChangeFrequency(wxCommandEvent& event)
|
void CDebugger::ChangeFrequency(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
DoChangeFrequency();
|
DoChangeFrequency();
|
||||||
@ -228,7 +298,13 @@ void CDebugger::DoChangeFrequency()
|
|||||||
gUpdFreq = 30;
|
gUpdFreq = 30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ==============
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
// Show or hide console window
|
||||||
|
// --------------
|
||||||
void CDebugger::ShowHideConsole(wxCommandEvent& event)
|
void CDebugger::ShowHideConsole(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
DoShowHideConsole();
|
DoShowHideConsole();
|
||||||
@ -247,6 +323,8 @@ void CDebugger::DoShowHideConsole()
|
|||||||
CloseConsole();
|
CloseConsole();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ==============
|
||||||
|
|
||||||
|
|
||||||
void CDebugger::NotifyUpdate()
|
void CDebugger::NotifyUpdate()
|
||||||
{
|
{
|
||||||
|
@ -72,6 +72,9 @@ class CDebugger : public wxDialog
|
|||||||
void DoShowHideConsole();
|
void DoShowHideConsole();
|
||||||
void ChangeFrequency(wxCommandEvent& event);
|
void ChangeFrequency(wxCommandEvent& event);
|
||||||
void DoChangeFrequency();
|
void DoChangeFrequency();
|
||||||
|
void SSBM(wxCommandEvent& event);
|
||||||
|
void SSBMremedy1(wxCommandEvent& event);
|
||||||
|
void SSBMremedy2(wxCommandEvent& event);
|
||||||
|
|
||||||
CPBView* m_GPRListView;
|
CPBView* m_GPRListView;
|
||||||
|
|
||||||
@ -91,11 +94,15 @@ class CDebugger : public wxDialog
|
|||||||
IDC_CHECK0 = 2000,
|
IDC_CHECK0 = 2000,
|
||||||
IDC_CHECK1,
|
IDC_CHECK1,
|
||||||
IDC_CHECK2,
|
IDC_CHECK2,
|
||||||
|
IDC_CHECK3,
|
||||||
|
IDC_CHECK4,
|
||||||
|
IDC_CHECK5,
|
||||||
IDC_RADIO0,
|
IDC_RADIO0,
|
||||||
IDC_RADIO1,
|
IDC_RADIO1,
|
||||||
IDC_RADIO2,
|
IDC_RADIO2,
|
||||||
IDC_RADIO3,
|
IDC_RADIO3,
|
||||||
IDG_LABEL1,
|
IDG_LABEL1,
|
||||||
|
IDG_LABEL2,
|
||||||
ID_UPD,
|
ID_UPD,
|
||||||
ID_SELC,
|
ID_SELC,
|
||||||
ID_PRESETS,
|
ID_PRESETS,
|
||||||
|
@ -45,7 +45,9 @@
|
|||||||
float ratioFactor; // a global to get the ratio factor from MixAdd
|
float ratioFactor; // a global to get the ratio factor from MixAdd
|
||||||
int gUpdFreq = 5;
|
int gUpdFreq = 5;
|
||||||
u32 gLastBlock;
|
u32 gLastBlock;
|
||||||
|
extern bool gSSBM;
|
||||||
|
extern bool gSSBMremedy1;
|
||||||
|
extern bool gSSBMremedy2;
|
||||||
|
|
||||||
// Parameter blocks
|
// Parameter blocks
|
||||||
|
|
||||||
@ -96,16 +98,16 @@ bool iupdonce = false;
|
|||||||
std::vector<u16> viupd(15); // the length of the update frequency bar
|
std::vector<u16> viupd(15); // the length of the update frequency bar
|
||||||
int vectorLengthGUI = 8; // length of playback history bar for the GUI version
|
int vectorLengthGUI = 8; // length of playback history bar for the GUI version
|
||||||
int vectorLength = 15; // for console version
|
int vectorLength = 15; // for console version
|
||||||
|
int vectorLength2 = 100; // for console version
|
||||||
|
|
||||||
|
|
||||||
// More stuff
|
// More stuff
|
||||||
|
|
||||||
std::vector< std::vector<int> > vector1(64, std::vector<int>(100,0));
|
// should we worry about the additonal memory these lists require? bool will allocate
|
||||||
|
// very little memory
|
||||||
|
std::vector< std::vector<bool> > vector1(64, std::vector<bool>(vectorLength,0));
|
||||||
|
std::vector< std::vector<bool> > vector2(64, std::vector<bool>(vectorLength2,0));
|
||||||
std::vector<int> numberRunning(64);
|
std::vector<int> numberRunning(64);
|
||||||
std::vector<u16> vector62(vectorLength);
|
|
||||||
std::vector<u16> vector63(vectorLength);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Classes
|
// Classes
|
||||||
@ -114,8 +116,7 @@ extern CDebugger* m_frame;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// I placed this in CUCode_AX because there was some kind of problem to call it otherwise,
|
// I placed this in CUCode_AX because it needs access to private members of that class.
|
||||||
// I'm sure it's simple to fix but I couldn't.
|
|
||||||
void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -123,15 +124,15 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
|||||||
int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS);
|
int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Control how often the screen is updated
|
// Control how often the screen is updated
|
||||||
j++;
|
j++;
|
||||||
l++;
|
l++;
|
||||||
if (j > (200/gUpdFreq))
|
if (j > (200/gUpdFreq))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
// Move all items back - vector1 is a vector1[64][100] vector, I think
|
// Move all items back - Vector1 is a vector1[64][100] vector
|
||||||
|
// --------------
|
||||||
/*
|
/*
|
||||||
Move all items back like this:
|
Move all items back like this:
|
||||||
1 to 2
|
1 to 2
|
||||||
@ -153,6 +154,35 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
|||||||
{
|
{
|
||||||
vector1.at(i).at(vectorLength-1) = PBs[i].running;
|
vector1.at(i).at(vectorLength-1) = PBs[i].running;
|
||||||
}
|
}
|
||||||
|
// ==============
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
// Have a separate set for which ones to show
|
||||||
|
// --------------
|
||||||
|
/*
|
||||||
|
Move all items back like this:
|
||||||
|
1 to 2
|
||||||
|
2 3
|
||||||
|
3 ...
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
for (int j = 1; j < vectorLength2; j++)
|
||||||
|
{
|
||||||
|
vector2.at(i).at(j-1) = vector2.at(i).at(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Save the latest value
|
||||||
|
|
||||||
|
for (int i = 0; i < numberOfPBs; i++)
|
||||||
|
{
|
||||||
|
vector2.at(i).at(vectorLength2-1) = PBs[i].running;
|
||||||
|
}
|
||||||
|
// ==============
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
// Count how many we have running now
|
// Count how many we have running now
|
||||||
@ -160,9 +190,9 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
|||||||
int jj = 0;
|
int jj = 0;
|
||||||
for (int i = 0; i < 64; i++)
|
for (int i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < vectorLength-1; j++)
|
for (int j = 0; j < vectorLength2-1; j++)
|
||||||
{
|
{
|
||||||
if (vector1.at(i).at(j) == 1)
|
if (vector2.at(i).at(j) == 1)
|
||||||
{
|
{
|
||||||
jj++;
|
jj++;
|
||||||
}
|
}
|
||||||
@ -344,7 +374,6 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
// Write global values
|
// Write global values
|
||||||
// ---------------
|
// ---------------
|
||||||
@ -353,6 +382,15 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a)
|
|||||||
// ===============
|
// ===============
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
// Write settings
|
||||||
|
// ---------------
|
||||||
|
sprintf(buffer, "\nSettings: SSBM fix %i | SSBM remedy 1 %i | SSBM remedy 2 %i \n",
|
||||||
|
gSSBM, gSSBMremedy1, gSSBMremedy2);
|
||||||
|
sbuff = sbuff + buffer; strcpy(buffer, "");
|
||||||
|
// ===============
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
// Show update frequency
|
// Show update frequency
|
||||||
// ---------------
|
// ---------------
|
||||||
|
@ -27,14 +27,19 @@
|
|||||||
#include "UCode_AXStructs.h"
|
#include "UCode_AXStructs.h"
|
||||||
#include "UCode_AX.h"
|
#include "UCode_AX.h"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// Externals
|
// Externals
|
||||||
// -----------
|
// -----------
|
||||||
extern float ratioFactor;
|
extern float ratioFactor;
|
||||||
extern u32 gLastBlock;
|
extern u32 gLastBlock;
|
||||||
|
bool gSSBM = true; // used externally
|
||||||
|
bool gSSBMremedy1 = true; // used externally
|
||||||
|
bool gSSBMremedy2 = true; // used externally
|
||||||
extern CDebugger* m_frame;
|
extern CDebugger* m_frame;
|
||||||
// -----------
|
// -----------
|
||||||
|
|
||||||
|
|
||||||
CUCode_AX::CUCode_AX(CMailHandler& _rMailHandler, bool wii)
|
CUCode_AX::CUCode_AX(CMailHandler& _rMailHandler, bool wii)
|
||||||
: IUCode(_rMailHandler)
|
: IUCode(_rMailHandler)
|
||||||
, m_addressPBs(0xFFFFFFFF)
|
, m_addressPBs(0xFFFFFFFF)
|
||||||
@ -150,52 +155,82 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
|
|||||||
AXParamBlock& pb = PBs[i];
|
AXParamBlock& pb = PBs[i];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
|
||||||
// Sequenced music fix - This seems to work allright. I'm not sure which detection method cause
|
|
||||||
// the least side effects, but pred_scale seems to be nice and simple. Please report any side
|
|
||||||
// effects.
|
|
||||||
// ------------
|
|
||||||
if (!pb.running && pb.adpcm_loop_info.pred_scale)
|
|
||||||
/*
|
|
||||||
if (!pb.running &&
|
|
||||||
(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])
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
pb.running = true;
|
|
||||||
}
|
|
||||||
// =============
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
/*
|
/*
|
||||||
Fix a problem introduced with the SSBM fix - Sometimes when a music stream ended sampleEnd
|
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
|
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. However, when you leave the Continue menu there's
|
a strange noise. This should take care of that. - Some games (Monkey Ball 1 and Tales of
|
||||||
some kind of buzing or interference noise in the music. But it goes away, so I guess it's not a
|
Symphonia) also had one odd block with a strange high loopPos and strange num_updates values,
|
||||||
big issue. Please report any side effects.
|
the loopPos limit turns those off also. - Please report any side effects.Please report any
|
||||||
|
side effects.
|
||||||
*/
|
*/
|
||||||
// ------------
|
// ------------
|
||||||
const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo;
|
const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo;
|
||||||
if (sampleEnd > 0x10000000)
|
const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo;
|
||||||
|
if (
|
||||||
|
sampleEnd > 0x10000000 || loopPos > 0x10000000
|
||||||
|
&& gSSBMremedy1
|
||||||
|
)
|
||||||
{
|
{
|
||||||
pb.running = 0;
|
pb.running = 0;
|
||||||
|
|
||||||
// also reset all values if it makes any difference
|
// also reset all values if it makes any difference
|
||||||
pb.audio_addr.cur_addr_hi = 0;
|
pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 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.end_addr_hi = 0;
|
pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0;
|
||||||
pb.audio_addr.end_addr_lo = 0;
|
|
||||||
pb.audio_addr.loop_addr_hi = 0;
|
|
||||||
pb.audio_addr.loop_addr_lo = 0;
|
|
||||||
|
|
||||||
pb.audio_addr.looping = 0;
|
pb.audio_addr.looping = 0;
|
||||||
pb.adpcm_loop_info.pred_scale = 0;
|
pb.adpcm_loop_info.pred_scale = 0;
|
||||||
pb.adpcm_loop_info.yn1 = 0;
|
pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0;
|
||||||
pb.adpcm_loop_info.yn2 = 0;
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// the fact that no settings are reset (except running) after a SSBM type music stream has ended
|
||||||
|
could cause loud garbled sound to be played from several blocks. It could be seen as five or six
|
||||||
|
simultaneous looping blocks that presumable produced garbled music. My guess is that it was sound
|
||||||
|
effects that were placed in previous music blocks and mutated into these looping noise machines.
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
// detect blocks that have recently been running that we should reset
|
||||||
|
pb.running == 0 && pb.audio_addr.looping == 1
|
||||||
|
|
||||||
|
// this prevents us from ruining sequenced music blocks
|
||||||
|
&& !(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])
|
||||||
|
|
||||||
|
&& gSSBMremedy2 // let us turn this fix on and off
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// reset all values, or mostly all
|
||||||
|
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.audio_addr.looping = 0;
|
||||||
|
pb.adpcm_loop_info.pred_scale = 0;
|
||||||
|
pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
/*
|
||||||
|
// Sequenced music fix - Because SSBM type music did no have its pred_scale (or any other parameter
|
||||||
|
except running) turned off after a song was stopped a pred_scale check here had the effect of
|
||||||
|
turning those blocks on immediately after the stopped. Because the pred_scale check caused these
|
||||||
|
effects I'm trying the num_updates check instead. Please report any side effects.
|
||||||
|
*/
|
||||||
|
// ------------
|
||||||
|
//if (!pb.running && pb.adpcm_loop_info.pred_scale)
|
||||||
|
/**/
|
||||||
|
if (!pb.running &&
|
||||||
|
(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])
|
||||||
|
)
|
||||||
|
|
||||||
|
{
|
||||||
|
pb.running = 1;
|
||||||
}
|
}
|
||||||
// =============
|
// =============
|
||||||
|
|
||||||
@ -205,7 +240,6 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
|
|||||||
// Set initial parameters
|
// Set initial parameters
|
||||||
// ------------
|
// ------------
|
||||||
//constants
|
//constants
|
||||||
const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo;
|
|
||||||
const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor);
|
const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor);
|
||||||
|
|
||||||
//variables
|
//variables
|
||||||
@ -236,11 +270,14 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
|
|||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
// Games that use looping to play non-looping music streams. SSBM has info in all pb.adpcm_loop_info
|
// Games that use looping to play non-looping music streams - SSBM has info in all
|
||||||
// parameters but has pb.audio_addr.looping = 0. If we treat these streams like any other looping
|
// pb.adpcm_loop_info parameters but has pb.audio_addr.looping = 0. If we treat these streams
|
||||||
// streams the music works.
|
// like any other looping streams the music works.
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
if(pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2)
|
if(
|
||||||
|
pb.adpcm_loop_info.pred_scale || pb.adpcm_loop_info.yn1 || pb.adpcm_loop_info.yn2
|
||||||
|
&& gSSBM
|
||||||
|
)
|
||||||
{
|
{
|
||||||
pb.audio_addr.looping = 1;
|
pb.audio_addr.looping = 1;
|
||||||
}
|
}
|
||||||
@ -248,22 +285,18 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
|
|||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
// Streaming music and volume - A lot of music in Paper Mario use the exact same settings, namely
|
// Streaming music and volume - The streaming music in Paper Mario use these settings:
|
||||||
// these:
|
|
||||||
// Base settings
|
// Base settings
|
||||||
// is_stream = 1
|
// is_stream = 1
|
||||||
// src_type = 0
|
// src_type = 0
|
||||||
// coef (unknown1) = 1
|
|
||||||
// PBAudioAddr
|
// PBAudioAddr
|
||||||
// audio_addr.looping = 1 (adpcm_loop_info.pred_scale = value, .yn1 = 0, .yn2 = 0)
|
// audio_addr.looping = 1 (adpcm_loop_info.pred_scale = value, .yn1 = 0, .yn2 = 0)
|
||||||
// However. Some of the ingame music and seemingly randomly some other music incorrectly get
|
/*
|
||||||
// volume = 0 for both left and right. There's also an issue of a hanging very similar to the Baten
|
However. Some of the ingame music and seemingly randomly some other music incorrectly get
|
||||||
// hanging. The Baten issue fixed itself when the music stream was allowed to play to the end and
|
volume = 0 for both left and right. This also affects Fire Emblem. But Starfox Assault
|
||||||
// then stop. However, all five music streams that is playing when the gate locks up in Paper Mario
|
that also use is_stream = 1 has no problem wuth the volume, but its settings are somewhat
|
||||||
// is loooping streams... I don't know what may be wrong.
|
different, it uses src_type = 1 and pb.src.ratio_lo (fraction) != 0
|
||||||
// ---------------------------------------------------------------------------------------
|
*/
|
||||||
// A game that may be used as a comparison is Starfox Assault also has is_stream = 1, but it
|
|
||||||
// has src_type = 1, coef (unknown1) = 0 and its pb.src.ratio_lo (fraction) != 0
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
|
|
||||||
|
|
||||||
@ -620,6 +653,9 @@ int CUCode_AX::ReadOutPBs(AXParamBlock* _pPBs, int _num)
|
|||||||
for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
|
for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
|
||||||
{
|
{
|
||||||
pDest[p] = Common::swap16(pSrc[p]);
|
pDest[p] = Common::swap16(pSrc[p]);
|
||||||
|
|
||||||
|
// To avoid a performance drop in the Release build I place this in the debug
|
||||||
|
// build only
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
gLastBlock = blockAddr + p*2 + 2; // save last block location
|
gLastBlock = blockAddr + p*2 + 2; // save last block location
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user