diff --git a/Source/Core/AudioCommon/AudioCommon.vcproj b/Source/Core/AudioCommon/AudioCommon.vcproj index 13bb8daed3..a0fb3ed7eb 100644 --- a/Source/Core/AudioCommon/AudioCommon.vcproj +++ b/Source/Core/AudioCommon/AudioCommon.vcproj @@ -433,6 +433,14 @@ RelativePath=".\Src\SoundStream.h" > + + + + diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.cpp b/Source/Core/AudioCommon/Src/AOSoundStream.cpp index f584cb6636..fdc507f5ee 100644 --- a/Source/Core/AudioCommon/Src/AOSoundStream.cpp +++ b/Source/Core/AudioCommon/Src/AOSoundStream.cpp @@ -18,16 +18,18 @@ #include #include "AOSoundStream.h" +#include "Mixer.h" #if defined(HAVE_AO) && HAVE_AO void AOSound::SoundLoop() { + uint_32 numBytesToRender = 256; ao_initialize(); default_driver = ao_default_driver_id(); format.bits = 16; format.channels = 2; - format.rate = sampleRate; + format.rate = m_mixer->GetSampleRate(); format.byte_format = AO_FMT_LITTLE; device = ao_open_live(default_driver, &format, NULL /* no options */); @@ -43,14 +45,21 @@ void AOSound::SoundLoop() while (!threadData) { - soundCriticalSection->Enter(); + soundCriticalSection.Enter(); - uint_32 numBytesToRender = 256; - (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, sampleRate, 2); + m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2); ao_play(device, (char*)realtimeBuffer, numBytesToRender); - soundCriticalSection->Leave(); - soundSyncEvent->Wait(); + + soundCriticalSection.Leave(); + + if (! threadData) + soundSyncEvent.Wait(); } + + ao_close(device); + device = NULL; + ao_shutdown(); + } void *soundThread(void *args) @@ -63,34 +72,28 @@ bool AOSound::Start() { memset(realtimeBuffer, 0, sizeof(realtimeBuffer)); - soundSyncEvent = new Common::Event(); - soundSyncEvent->Init(); - - soundCriticalSection = new Common::CriticalSection(1); - + soundSyncEvent.Init(); + thread = new Common::Thread(soundThread, (void *)this); return true; } void AOSound::Update() { - soundSyncEvent->Set(); + soundSyncEvent.Set(); } void AOSound::Stop() { - soundCriticalSection->Enter(); + soundCriticalSection.Enter(); threadData = 1; - soundSyncEvent->Set(); - soundCriticalSection->Leave(); - soundSyncEvent->Shutdown(); - delete soundCriticalSection; - delete thread; - delete soundSyncEvent; + soundSyncEvent.Set(); + soundCriticalSection.Leave(); + + delete thread; + thread = NULL; + soundSyncEvent.Shutdown(); - ao_close(device); - device = NULL; - ao_shutdown(); } #endif diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.h b/Source/Core/AudioCommon/Src/AOSoundStream.h index 2456e6c8fb..99aa327dab 100644 --- a/Source/Core/AudioCommon/Src/AOSoundStream.h +++ b/Source/Core/AudioCommon/Src/AOSoundStream.h @@ -30,8 +30,8 @@ class AOSound : public SoundStream { #if defined(HAVE_AO) && HAVE_AO Common::Thread *thread; - Common::CriticalSection *soundCriticalSection; - Common::Event *soundSyncEvent; + Common::CriticalSection soundCriticalSection; + Common::Event soundSyncEvent; int buf_size; @@ -42,9 +42,8 @@ class AOSound : public SoundStream short realtimeBuffer[1024 * 1024]; public: - AOSound(int _sampleRate, StreamCallback _callback) : - SoundStream(_sampleRate, _callback) {} - + AOSound(CMixer *mixer) : SoundStream(mixer) {} + virtual ~AOSound() {} virtual bool Start(); @@ -63,14 +62,10 @@ public: virtual void Update(); - virtual int GetSampleRate() { - return sampleRate; - } - #else public: - AOSound(int _sampleRate, StreamCallback _callback) : - SoundStream(_sampleRate, _callback) {} + AOSound(CMixer *mixer) : + SoundStream(mixer) {} #endif }; diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp new file mode 100644 index 0000000000..e8f60bc175 --- /dev/null +++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp @@ -0,0 +1,51 @@ +#include "AudioCommon.h" +#include "Mixer.h" +#include "AOSoundStream.h" +#include "DSoundStream.h" +#include "NullSoundStream.h" + + +namespace AudioCommon { + +SoundStream *InitSoundStream(std::string backend, CMixer *mixer) { + + if (!mixer) { + mixer = new CMixer(); + } + + if (backend == "DSound") { + if (DSound::isValid()) + soundStream = new DSound(mixer, g_dspInitialize.hWnd); + } + else if (backend == "AOSound") { + if (AOSound::isValid()) + soundStream = new AOSound(mixer); + } + else if (backend == "NullSound") { + soundStream = new NullSound(mixer); + } + else { + PanicAlert("Cannot recognize backend %s", backend.c_str()); + return NULL; + } + + if (soundStream) { + if (!soundStream->Start()) { + PanicAlert("Could not initialize backend %s, falling back to NULL", + backend.c_str()); + delete soundStream; + soundStream = new NullSound(mixer); + soundStream->Start(); + } + } + else { + PanicAlert("Sound backend %s is not valid, falling back to NULL", + backend.c_str()); + delete soundStream; + soundStream = new NullSound(mixer); + soundStream->Start(); + } + return soundStream; +} + +} // Namespace diff --git a/Source/Core/AudioCommon/Src/AudioCommon.h b/Source/Core/AudioCommon/Src/AudioCommon.h new file mode 100644 index 0000000000..f834941a28 --- /dev/null +++ b/Source/Core/AudioCommon/Src/AudioCommon.h @@ -0,0 +1,18 @@ +#ifndef _AUDIO_COMMON_H +#define _AUDIO_COMMON_H + +#include "Common.h" +#include "pluginspecs_dsp.h" +#include "SoundStream.h" + +class CMixer; + +extern DSPInitialize g_dspInitialize; +extern SoundStream *soundStream; + +namespace AudioCommon { + + SoundStream *InitSoundStream(std::string backend, CMixer *mixer = NULL); +} // Namespace + +#endif // AUDIO_COMMON diff --git a/Source/Core/AudioCommon/Src/DSoundStream.cpp b/Source/Core/AudioCommon/Src/DSoundStream.cpp index 26bbc9d11f..82f7bcdc15 100644 --- a/Source/Core/AudioCommon/Src/DSoundStream.cpp +++ b/Source/Core/AudioCommon/Src/DSoundStream.cpp @@ -19,7 +19,7 @@ #include #include "DSoundStream.h" -extern bool log_ai; +//extern bool log_ai; bool DSound::CreateBuffer() { @@ -114,7 +114,7 @@ void DSound::SoundLoop() { if (numBytesToRender > sizeof(realtimeBuffer)) PanicAlert("soundThread: too big render call"); - (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, sampleRate, 2); + m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2); WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); currentPos = ModBufferSize(lastPos + numBytesToRender); totalRenderedBytes += numBytesToRender; diff --git a/Source/Core/AudioCommon/Src/DSoundStream.h b/Source/Core/AudioCommon/Src/DSoundStream.h index e81fc8e233..3a62e633ba 100644 --- a/Source/Core/AudioCommon/Src/DSoundStream.h +++ b/Source/Core/AudioCommon/Src/DSoundStream.h @@ -64,12 +64,10 @@ class DSound : public SoundStream DWORD dwSoundBytes); public: - DSound(int _sampleRate, StreamCallback _callback) : - SoundStream(_sampleRate, _callback) {} - - DSound(int _sampleRate, StreamCallback _callback, void *_hWnd) : - SoundStream(_sampleRate, _callback), hWnd(_hWnd) {} - + DSound(CMixer *mixer, void *hWnd = NULL) : SoundStream(mixer) {} + + DSound(CMixer *mixer) : SoundStream(mixer) {} + virtual ~DSound() {} virtual bool Start(); @@ -81,8 +79,8 @@ public: #else public: - DSound(int _sampleRate, StreamCallback _callback, void *hWnd = NULL) : - SoundStream(_sampleRate, _callback) {} + DSound(CMixer *mixer, void *hWnd = NULL) : + SoundStream(mixer) {} #endif }; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.cpp b/Source/Core/AudioCommon/Src/Mixer.cpp similarity index 66% rename from Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.cpp rename to Source/Core/AudioCommon/Src/Mixer.cpp index 27e1bda607..46a0fc1141 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.cpp +++ b/Source/Core/AudioCommon/Src/Mixer.cpp @@ -21,87 +21,51 @@ #include "Thread.h" // Common -#include "../Config.h" // Local -#include "../Globals.h" -#include "../DSPHandler.h" -#include "../Debugger/File.h" -#include "../main.h" - #include "Mixer.h" #include "FixedSizeQueue.h" +#include "AudioCommon.h" -namespace { - -Common::CriticalSection push_sync; - -// On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so... -const int queue_minlength = 1024 * 4; -const int queue_maxlength = 1024 * 28; - -FixedSizeQueue sample_queue; - -} // namespace - -volatile bool mixer_HLEready = false; -volatile int queue_size = 0; - -void Mixer(short *buffer, int numSamples, int bits, int rate, int channels) +void CMixer::Mix(short *samples, int numSamples) { // silence - memset(buffer, 0, numSamples * 2 * sizeof(short)); + memset(samples, 0, numSamples * 2 * sizeof(short)); if (g_dspInitialize.pEmulatorState) { if (*g_dspInitialize.pEmulatorState != 0) return; } - // first get the DTK Music - if (g_Config.m_EnableDTKMusic) - { - g_dspInitialize.pGetAudioStreaming(buffer, numSamples); - } - - Mixer_MixUCode(buffer, numSamples, bits, rate, channels); - + Premix(samples, numSamples); + push_sync.Enter(); int count = 0; - while (queue_size > queue_minlength && count < numSamples * 2) { - int x = buffer[count]; + while (m_queueSize > queue_minlength && count < numSamples * 2) { + int x = samples[count]; x += sample_queue.front(); if (x > 32767) x = 32767; if (x < -32767) x = -32767; - buffer[count++] = x; + samples[count++] = x; sample_queue.pop(); - x = buffer[count]; + x = samples[count]; x += sample_queue.front(); if (x > 32767) x = 32767; if (x < -32767) x = -32767; - buffer[count++] = x; + samples[count++] = x; sample_queue.pop(); - queue_size-=2; + m_queueSize-=2; } push_sync.Leave(); } -void Mixer_MixUCode(short *buffer, int numSamples, int bits, int rate, - int channels) { - //if this was called directly from the HLE, and not by timeout - if (g_Config.m_EnableHLEAudio && mixer_HLEready) - { - IUCode* pUCode = CDSPHandler::GetInstance().GetUCode(); - if (pUCode != NULL) - pUCode->MixAdd(buffer, numSamples); - } -} -void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) +void CMixer::PushSamples(short *samples, int num_stereo_samples) { if (!soundStream) return; - if (queue_size == 0) + if (m_queueSize == 0) { - queue_size = queue_minlength; + m_queueSize = queue_minlength; for (int i = 0; i < queue_minlength; i++) sample_queue.push((s16)0); } @@ -116,12 +80,11 @@ void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) #endif // Write Other Audio - if (g_Config.m_EnableThrottle) - { + if (m_throttle) { /* This is only needed for non-AX sound, currently directly streamed and DTK sound. For AX we call SoundStream::Update in AXTask() for example. */ - while (queue_size > queue_maxlength / 2) { + while (m_queueSize > queue_maxlength / 2) { // Urgh. if (g_dspInitialize.pEmulatorState) { if (*g_dspInitialize.pEmulatorState != 0) @@ -129,25 +92,22 @@ void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) } soundStream->Update(); Common::SleepCurrentThread(0); - } - - //convert into config option? - const int mode = 2; + } push_sync.Enter(); while (num_stereo_samples) { - acc += sample_rate; + acc += m_sampleRate; while (num_stereo_samples && (acc >= 48000)) { PV4l=PV3l; PV3l=PV2l; PV2l=PV1l; - PV1l=*(buffer++); //32bit processing + PV1l=*(samples++); //32bit processing PV4r=PV3r; PV3r=PV2r; PV2r=PV1r; - PV1r=*(buffer++); //32bit processing + PV1r=*(samples++); //32bit processing num_stereo_samples--; acc-=48000; } @@ -156,12 +116,12 @@ void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) s32 DataL = PV1l; s32 DataR = PV1r; - if (mode == 1) //linear + if (m_mode == 1) //linear { DataL = PV1l + ((PV2l - PV1l)*acc)/48000; DataR = PV1r + ((PV2r - PV1r)*acc)/48000; } - else if (mode == 2) //cubic + else if (m_mode == 2) //cubic { s32 a0l = PV1l - PV2l - PV4l + PV3l; s32 a0r = PV1r - PV2r - PV4r + PV3r; @@ -192,7 +152,7 @@ void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) if (r > 32767) r = 32767; sample_queue.push(l); sample_queue.push(r); - queue_size += 2; + m_queueSize += 2; } push_sync.Leave(); } diff --git a/Source/Core/AudioCommon/Src/Mixer.h b/Source/Core/AudioCommon/Src/Mixer.h new file mode 100644 index 0000000000..52c4655e9e --- /dev/null +++ b/Source/Core/AudioCommon/Src/Mixer.h @@ -0,0 +1,67 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _MIXER_H +#define _MIXER_H + +#include "FixedSizeQueue.h" + +// On real hardware, this fifo is much, much smaller. But timing is also +// tighter than under Windows, so... +#define queue_minlength 1024 * 4 +#define queue_maxlength 1024 * 28 + +class CMixer { + +public: + CMixer() : m_sampleRate(48000),m_bits(16),m_channels(2), m_mode(2), m_HLEready(false) {} + + // Called from audio threads + void Mix(short *sample, int numSamples); + + // Called from main thread + void PushSamples(short* samples, int num_stereo_samples); + + virtual void Premix(short *samples, int numSamples) {} + + int GetSampleRate() {return m_sampleRate;} + + void SetThrottle(bool use) { m_throttle = use;} + + // FIXME do we need this + bool IsHLEReady() { return m_HLEready;} + void SetHLEReady(bool ready) { m_HLEready = ready;} + ////// + +protected: + int m_sampleRate; + int m_bits; + int m_channels; + + int m_mode; + bool m_HLEready; + int m_queueSize; + + bool m_throttle; +private: + Common::CriticalSection push_sync; + FixedSizeQueue sample_queue; + +}; + +#endif + diff --git a/Source/Core/AudioCommon/Src/NullSoundStream.h b/Source/Core/AudioCommon/Src/NullSoundStream.h index bd6728b1ae..3a129b2cf0 100644 --- a/Source/Core/AudioCommon/Src/NullSoundStream.h +++ b/Source/Core/AudioCommon/Src/NullSoundStream.h @@ -23,8 +23,7 @@ class NullSound : public SoundStream { public: - NullSound(int _sampleRate, StreamCallback _callback) : - SoundStream(_sampleRate, _callback) {} + NullSound(CMixer *mixer) : SoundStream(mixer) {} virtual ~NullSound() {} @@ -35,7 +34,8 @@ public: virtual bool Start() { return true; } virtual void Update() { - (*callback)(NULL, 256 >> 2, 16, sampleRate, 2); + m_mixer->Mix(NULL, 256 >> 2); + //(*callback)(NULL, 256 >> 2, 16, sampleRate, 2); } }; diff --git a/Source/Core/AudioCommon/Src/SConscript b/Source/Core/AudioCommon/Src/SConscript index 1d973c66ac..4979919b46 100644 --- a/Source/Core/AudioCommon/Src/SConscript +++ b/Source/Core/AudioCommon/Src/SConscript @@ -5,6 +5,8 @@ Import('env') files = [ 'AOSoundStream.cpp', 'WaveFile.cpp', + 'Mixer.cpp', + 'AudioCommon.cpp', ] env_audiocommon = env.Clone() diff --git a/Source/Core/AudioCommon/Src/SoundStream.h b/Source/Core/AudioCommon/Src/SoundStream.h index 44ffdd43b8..afa1605fd8 100644 --- a/Source/Core/AudioCommon/Src/SoundStream.h +++ b/Source/Core/AudioCommon/Src/SoundStream.h @@ -19,32 +19,27 @@ #define __SOUNDSTREAM_H__ #include "Common.h" - -typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels); +#include "Mixer.h" class SoundStream { protected: - int sampleRate; - StreamCallback callback; + CMixer *m_mixer; // We set this to shut down the sound thread. // 0=keep playing, 1=stop playing NOW. volatile int threadData; public: - SoundStream(int _sampleRate, StreamCallback _callback) : - sampleRate(_sampleRate), callback(_callback), threadData(0) {} - virtual ~SoundStream() {} + SoundStream(CMixer *mixer) : m_mixer(mixer), threadData(0) {} + virtual ~SoundStream() { delete m_mixer;} - static bool isValid() { return false; } - virtual bool usesMixer() const { return false; } - virtual bool Start() { return false; } - virtual void SoundLoop() {} - virtual void Stop() {} - virtual void Update() {} - - virtual int GetSampleRate() const { return sampleRate; } + static bool isValid() { return false; } + virtual CMixer *GetMixer() const { return m_mixer; } + virtual bool Start() { return false; } + virtual void SoundLoop() {} + virtual void Stop() {} + virtual void Update() {} }; #endif diff --git a/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj b/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj index 80e032999b..96bc3972b4 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj +++ b/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj @@ -548,18 +548,6 @@ - - - - - - @@ -748,6 +736,14 @@ RelativePath=".\Src\DSPHandler.h" > + + + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp new file mode 100644 index 0000000000..7df54e8771 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.cpp @@ -0,0 +1,25 @@ +#include "Config.h" // Local +#include "Globals.h" +#include "DSPHandler.h" +#include "HLEMixer.h" + +void HLEMixer::MixUCode(short *samples, int numSamples) { + //if this was called directly from the HLE, and not by timeout + if (g_Config.m_EnableHLEAudio && IsHLEReady()) { + IUCode* pUCode = CDSPHandler::GetInstance().GetUCode(); + if (pUCode != NULL) + pUCode->MixAdd(samples, numSamples); + } +} + +void HLEMixer::Premix(short *samples, int numSamples) { + + // first get the DTK Music + if (g_Config.m_EnableDTKMusic) { + g_dspInitialize.pGetAudioStreaming(samples, numSamples); + } + + MixUCode(samples, numSamples); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.h b/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.h new file mode 100644 index 0000000000..ddbcfc317f --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/HLEMixer.h @@ -0,0 +1,16 @@ +#ifndef HLEMIXER_H +#define HLEMIXER_H +#include "AudioCommon.h" +#include "Mixer.h" + +class HLEMixer : public CMixer +{ +public: + void MixUCode(short *samples, int numSamples); + + virtual void Premix(short *samples, int numSamples); +}; + +#endif // HLEMIXER_H + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.h b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.h deleted file mode 100644 index 49603919f8..0000000000 --- a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _MIXER_H -#define _MIXER_H - -extern volatile bool mixer_HLEready; - -// Called from audio threads -void Mixer(short* buffer, int numSamples, int bits, int rate, int channels); - -void Mixer_MixUCode(short *buffer, int numSamples, int bits, int rate, int channels); - -// Called from main thread -void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate); - -#endif - diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/SConscript b/Source/Plugins/Plugin_DSP_HLE/Src/SConscript index 6cfa257bf4..59c9359e18 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/SConscript +++ b/Source/Plugins/Plugin_DSP_HLE/Src/SConscript @@ -8,11 +8,10 @@ name = "Plugin_DSP_HLE" files = [ 'DSPHandler.cpp', 'MailHandler.cpp', + 'HLEMixer.cpp', 'main.cpp', 'Config.cpp', 'Globals.cpp', -# 'PCHW/AOSoundStream.cpp', - 'PCHW/Mixer.cpp', 'Debugger/File.cpp', 'UCodes/UCode_AX.cpp', 'UCodes/UCode_AXWii.cpp', 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 4a9f81eaa4..08e0d3a99d 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp @@ -25,7 +25,7 @@ extern CDebugger* m_frame; #include #include "../Globals.h" -#include "../PCHW/Mixer.h" +#include "Mixer.h" #include "../MailHandler.h" #include "UCodes.h" @@ -513,7 +513,7 @@ bool CUCode_AX::AXTask(u32& _uMail) m_addressPBs = Memory_Read_U32(uAddress); uAddress += 4; - mixer_HLEready = true; + soundStream->GetMixer()->SetHLEReady(true); SaveLog("%08x : AXLIST PB address: %08x", uAddress, m_addressPBs); SaveLog("Update the SoundThread to be in sync"); diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXWii.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXWii.cpp index 4a5aed0bff..dca9c0f7eb 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXWii.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXWii.cpp @@ -23,8 +23,8 @@ extern CDebugger * m_frame; #endif -#include "../PCHW/Mixer.h" #include "../MailHandler.h" +#include "Mixer.h" #include "UCodes.h" #include "UCode_AXStructs.h" @@ -324,7 +324,7 @@ bool CUCode_AXWii::AXTask(u32& _uMail) case 0x0004: // PBs are here now m_addressPBs = Memory_Read_U32(uAddress); lCUCode_AX->m_addressPBs = m_addressPBs; // for the sake of logging - mixer_HLEready = true; + soundStream->GetMixer()->SetHLEReady(true); SaveLog("%08x : AXLIST PB address: %08x", uAddress, m_addressPBs); soundStream->Update(); uAddress += 4; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h index 25e0a90621..6732167ec7 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h @@ -21,7 +21,7 @@ #include "UCode_AX_ADPCM.h" #include "UCode_AX.h" #include "../main.h" - +#include "Mixer.h" // ---------------------------------------------------- // Externals @@ -107,7 +107,7 @@ inline void WriteBackPBsWii(u32 pbs_address, ParamBlockType& _pPBs, int _num) template inline void MixAddVoice(ParamBlockType &pb, int *templbuffer, int *temprbuffer, int _iSize, bool Wii) { - ratioFactor = 32000.0f / (float)soundStream->GetSampleRate(); + ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate(); DoVoiceHacks(pb, Wii); @@ -115,7 +115,6 @@ inline void MixAddVoice(ParamBlockType &pb, int *templbuffer, int *temprbuffer, if (pb.running) { - // ======================================================================================= // Read initial parameters // ------------ //constants diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp index b713b8cbe5..02edf4088a 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp @@ -24,7 +24,7 @@ #include "../MailHandler.h" #include "../main.h" -#include "../PCHW/Mixer.h" +#include "Mixer.h" CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler) @@ -157,8 +157,7 @@ void CUCode_Zelda::ExecuteList() tmp[2] = Read32(); // We're ready to mix - mixer_HLEready = true; - + soundStream->GetMixer()->SetHLEReady(true); DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync"); soundStream->Update(); //do it in this thread to avoid sync problems diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp index cdabb195e6..96edccaf75 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp @@ -28,16 +28,17 @@ CDebugger* m_frame = NULL; #include "ChunkFile.h" #include "WaveFile.h" -#include "PCHW/Mixer.h" +#include "HLEMixer.h" #include "DSPHandler.h" #include "Config.h" #include "Setup.h" #include "StringUtil.h" - +#include "AudioCommon.h" #include "AOSoundStream.h" #include "DSoundStream.h" #include "NullSoundStream.h" + // Declarations and definitions PLUGIN_GLOBALS* globals = NULL; DSPInitialize g_dspInitialize; @@ -192,6 +193,7 @@ void DllConfig(HWND _hParent) #endif } + void Initialize(void *init) { g_dspInitialize = *(DSPInitialize*)init; @@ -201,45 +203,9 @@ void Initialize(void *init) CDSPHandler::CreateInstance(); - if (g_Config.sBackend == "DSound") - { - if (DSound::isValid()) - soundStream = new DSound(48000, Mixer, g_dspInitialize.hWnd); - } - else if (g_Config.sBackend == "AOSound") - { - if (AOSound::isValid()) - soundStream = new AOSound(48000, Mixer); - } - else if (g_Config.sBackend == "NullSound") - { - soundStream = new NullSound(48000, Mixer_MixUCode); - } - else - { - PanicAlert("Cannot recognize backend %s", g_Config.sBackend.c_str()); - return; - } - - if (soundStream) - { - if (!soundStream->Start()) - { - PanicAlert("Could not initialize backend %s, falling back to NULL", - g_Config.sBackend.c_str()); - delete soundStream; - soundStream = new NullSound(48000, Mixer); - soundStream->Start(); - } - } - else - { - PanicAlert("Sound backend %s is not valid, falling back to NULL", - g_Config.sBackend.c_str()); - delete soundStream; - soundStream = new NullSound(48000, Mixer); - soundStream->Start(); - } + soundStream = AudioCommon::InitSoundStream(g_Config.sBackend, + new HLEMixer()); + soundStream->GetMixer()->SetThrottle(g_Config.m_EnableThrottle); // Start the sound recording if (log_ai) @@ -251,15 +217,20 @@ void Initialize(void *init) void DSP_StopSoundStream() { + // fprintf(stderr, "in dsp stop\n"); if (!soundStream) PanicAlert("Can't stop non running SoundStream!"); soundStream->Stop(); delete soundStream; soundStream = NULL; + // fprintf(stderr, "in dsp stop end\n"); + } void Shutdown() { + // FIXME: called before stop is finished???? + // fprintf(stderr, "in dsp shutdown\n"); // Check that soundstream already is stopped. if (soundStream) PanicAlert("SoundStream alive in DSP::Shutdown!"); @@ -384,7 +355,7 @@ void DSP_SendAIBuffer(unsigned int address, int sample_rate) return; } - if (soundStream->usesMixer()) + if (soundStream->GetMixer()) { short samples[16] = {0}; // interleaved stereo if (address) @@ -398,7 +369,7 @@ void DSP_SendAIBuffer(unsigned int address, int sample_rate) if (log_ai) g_wave_writer.AddStereoSamples(samples, 8); } - Mixer_PushSamples(samples, 32 / 4, sample_rate); + soundStream->GetMixer()->PushSamples(samples, 32 / 4); } // SoundStream is updated only when necessary (there is no 70 ms limit diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp index 3d96992efc..03619703eb 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp @@ -33,8 +33,7 @@ void CConfig::Load() IniFile file; file.Load(FULL_CONFIG_DIR "DSP.ini"); - file.Get("Config", "EnableHLEAudio", &m_EnableHLEAudio, true); // Sound Settings - file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true); + file.Get("Config", "EnableHLEAudio", &m_EnableHLEAudio, false); file.Get("Config", "EnableThrottle", &m_EnableThrottle, true); #ifdef _WIN32 file.Get("Config", "Backend", &sBackend, "DSound"); @@ -48,7 +47,6 @@ void CConfig::Save() IniFile file; file.Load(FULL_CONFIG_DIR "DSP.ini"); file.Set("Config", "EnableHLEAudio", m_EnableHLEAudio); // Sound Settings - file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic); file.Set("Config", "EnableThrottle", m_EnableThrottle); file.Set("Config", "Backend", sBackend.c_str()); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp index 8384a867d0..0a6ff609bf 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp @@ -39,19 +39,16 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl // Create items m_buttonEnableHLEAudio = new wxCheckBox(this, ID_ENABLE_HLE_AUDIO, wxT("Enable HLE Audio"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); - m_buttonEnableDTKMusic = new wxCheckBox(this, ID_ENABLE_DTK_MUSIC, wxT("Enable DTK Music"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_buttonEnableThrottle = new wxCheckBox(this, ID_ENABLE_THROTTLE, wxT("Enable Other Audio (Throttle)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxStaticText *BackendText = new wxStaticText(this, wxID_ANY, wxT("Audio Backend"), wxDefaultPosition, wxDefaultSize, 0); m_BackendSelection = new wxComboBox(this, ID_BACKEND, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayBackends, wxCB_READONLY, wxDefaultValidator); // Update values m_buttonEnableHLEAudio->SetValue(g_Config.m_EnableHLEAudio ? true : false); - m_buttonEnableDTKMusic->SetValue(g_Config.m_EnableDTKMusic ? true : false); m_buttonEnableThrottle->SetValue(g_Config.m_EnableThrottle ? true : false); // Add tooltips m_buttonEnableHLEAudio->SetToolTip(wxT("This is the most common sound type")); - m_buttonEnableDTKMusic->SetToolTip(wxT("This is sometimes used to play music tracks from the disc")); m_buttonEnableThrottle->SetToolTip(wxT("This is sometimes used together with pre-rendered movies.\n" "Disabling this also disables the speed throttle which this causes,\n" "meaning that there will be no upper limit on your FPS.")); @@ -61,7 +58,6 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl wxBoxSizer *sMain = new wxBoxSizer(wxVERTICAL); wxStaticBoxSizer *sbSettings = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Sound Settings")); sbSettings->Add(m_buttonEnableHLEAudio, 0, wxALL, 5); - sbSettings->Add(m_buttonEnableDTKMusic, 0, wxALL, 5); sbSettings->Add(m_buttonEnableThrottle, 0, wxALL, 5); wxBoxSizer *sBackend = new wxBoxSizer(wxHORIZONTAL); sBackend->Add(BackendText, 0, wxALIGN_CENTRE_VERTICAL|wxALL, 5); @@ -91,7 +87,6 @@ ConfigDialog::~ConfigDialog() void ConfigDialog::SettingsChanged(wxCommandEvent& event) { g_Config.m_EnableHLEAudio = m_buttonEnableHLEAudio->GetValue(); - g_Config.m_EnableDTKMusic = m_buttonEnableDTKMusic->GetValue(); g_Config.m_EnableThrottle = m_buttonEnableThrottle->GetValue(); g_Config.sBackend = m_BackendSelection->GetValue().mb_str(); g_Config.Save(); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h index 0b40229f84..8c1152f69d 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h @@ -18,15 +18,14 @@ #ifndef _GLOBALS_H #define _GLOBALS_H -#include "pluginspecs_dsp.h" -#include "Common.h" +#include "AudioCommon.h" #include #define WITH_DSP_ON_THREAD 1 #define DUMP_DSP_IMEM 0 #define PROFILE 1 -extern DSPInitialize g_dspInitialize; + void DSP_DebugBreak(); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp index b94a06ca24..970712fa0f 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp @@ -23,10 +23,9 @@ extern u32 m_addressPBs; -// ======================================================================================= -// Get the parameter block location - Example SSBM: We get the addr 8049cf00, first we -// always get 0 and go to AXLIST_STUDIOADDR, then we end up at AXLIST_PBADDR. -// -------------- +// Get the parameter block location - Example SSBM: We get the addr 8049cf00, +// first we always get 0 and go to AXLIST_STUDIOADDR, then we end up at +// AXLIST_PBADDR. bool AXTask(u32& _uMail) { u32 uAddress = _uMail; @@ -37,15 +36,12 @@ bool AXTask(u32& _uMail) while (bExecuteList) { - // --------------------------------------------------------------------------------------- // SSBM: We get the addr 8049cf00, first we always get 0 u16 iCommand = Memory_Read_U16(uAddress); uAddress += 2; - // --------------------------------------------------------------------------------------- switch (iCommand) { - // --------------------------------------------------------------------------------------- // ? case 0: // AXLIST_STUDIOADDR: //00 { @@ -53,10 +49,8 @@ bool AXTask(u32& _uMail) DEBUG_LOG(DSPHLE, "AXLIST AXLIST_SBUFFER: %08x", uAddress); } break; - // --------------------------------------------------------------------------------------- - // --------------------------------------------------------------------------------------- case 2: // AXLIST_PBADDR: // 02 { m_addressPBs = Memory_Read_U32(uAddress); @@ -66,7 +60,6 @@ bool AXTask(u32& _uMail) } break; - // --------------------------------------------------------------------------------------- case 7: // AXLIST_SBUFFER: // 7 { // Hopefully this is where in main ram to write. @@ -79,11 +72,9 @@ bool AXTask(u32& _uMail) default: { - // --------------------------------------------------------------------------------------- // Stop the execution of this TaskList DEBUG_LOG(DSPHLE, "AXLIST default: %08x", uAddress); bExecuteList = false; - // --------------------------------------------------------------------------------------- } break; } // end of switch @@ -95,6 +86,6 @@ bool AXTask(u32& _uMail) // now resume return true; } -// ======================================================================================= + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp index 9cebc6df5e..dd6d144216 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp @@ -16,82 +16,65 @@ // http://code.google.com/p/dolphin-emu/ -#ifdef _WIN32 - -// ======================================================================================= -// Includes -// -------------- #include #include #include // So that we can test if std::string == abc -#include #include "Common.h" #include "UCode_AXStructs.h" // they are only in a virtual dir called UCodes AX -// ===================== -// ======================================================================================= -// Declarations and definitions -// -------------- - -// ---------------------------------- // Settings -// -------------- #define NUMBER_OF_PBS 64 // Todo: move this to a logging class -// ----------------------------------- // Externals -// -------------- extern u32 m_addressPBs; float ratioFactor; int globaliSize; short globalpBuffer; u32 gLastBlock; -// -------------- -// ----------------------------------- + // Vectors and other things -// -------------- std::vector gloopPos(64); std::vector gsampleEnd(64); std::vector gsamplePos(64); - std::vector gratio(64); - std::vector gratiohi(64); - std::vector gratiolo(64); - std::vector gfrac(64); - std::vector gcoef(64); +std::vector gratio(64); +std::vector gratiohi(64); +std::vector gratiolo(64); +std::vector gfrac(64); +std::vector gcoef(64); // PBSampleRateConverter mixer - std::vector gvolume_left(64); - std::vector gvolume_right(64); - std::vector gmixer_control(64); - std::vector gcur_volume(64); - std::vector gcur_volume_delta(64); +std::vector gvolume_left(64); +std::vector gvolume_right(64); +std::vector gmixer_control(64); +std::vector gcur_volume(64); +std::vector gcur_volume_delta(64); - std::vector gaudioFormat(64); - std::vector glooping(64); - std::vector gsrc_type(64); - std::vector gis_stream(64); +std::vector gaudioFormat(64); +std::vector glooping(64); +std::vector gsrc_type(64); +std::vector gis_stream(64); // loop std::vector gloop1(64); - std::vector gloop2(64); - std::vector gloop3(64); - std::vector gadloop1(64); - std::vector gadloop2(64); - std::vector gadloop3(64); +std::vector gloop2(64); +std::vector gloop3(64); +std::vector gadloop1(64); +std::vector gadloop2(64); +std::vector gadloop3(64); // updates - std::vector gupdates1(64); - std::vector gupdates2(64); - std::vector gupdates3(64); - std::vector gupdates4(64); - std::vector gupdates5(64); - std::vector gupdates_addr(64); +std::vector gupdates1(64); +std::vector gupdates2(64); +std::vector gupdates3(64); +std::vector gupdates4(64); +std::vector gupdates5(64); +std::vector gupdates_addr(64); // Other things std::vector Jump(64); // this is 1 or 0 @@ -101,7 +84,7 @@ std::vector numberRunning(64); int j = 0; int k = 0; -__int64 l = 0; +s64 l = 0; int iupd = 0; bool iupdonce = false; std::vector viupd(15); // the length of the update frequency bar @@ -112,18 +95,11 @@ std::vector vector62(vectorLength); std::vector vector63(vectorLength); int ReadOutPBs(AXParamBlock * _pPBs, int _num); -// ===================== -// ======================================================================================= // Main logging function -// -------------- void Logging() { - // --------------------------------------------------------------------------------------- - - - // --------------------------------------------------------------------------------------- // Control how often the screen is updated j++; l++; @@ -151,16 +127,13 @@ void Logging() } // ================= - // --------------------------------------------------------------------------------------- // Enter the latest value for (int i = 0; i < numberOfPBs; i++) { vector1.at(i).at(vectorLength-1) = PBs[i].running; } - // ----------------- - // --------------------------------------------------------------------------------------- // Count how many blocks we have running now int jj = 0; for (int i = 0; i < 64; i++) @@ -174,27 +147,22 @@ void Logging() numberRunning.at(i) = jj; } } - // -------------- - // --------------------------------------------------------------------------------------- // Write the first row char buffer [1000] = ""; std::string sbuff; //sbuff = sbuff + " Nr | | frac ratio | old new \n"; // 5 sbuff = sbuff + " Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n"; - // -------------- - // --------------------------------------------------------------------------------------- + // Read out values for all blocks for (int i = 0; i < numberOfPBs; i++) { if (numberRunning.at(i) > 0) { - // ======================================================================================= // Write the playback bar - // ------------- for (int j = 0; j < vectorLength; j++) { if(vector1.at(i).at(j) == 0) @@ -207,16 +175,13 @@ void Logging() sbuff = sbuff + buffer; strcpy(buffer, ""); } } - // ============== - // ================================================================================================ int sampleJump; int loopJump; //if (PBs[i].running && PBs[i].adpcm_loop_info.yn1 && PBs[i].mixer.volume_left) if (true) { - // --------------------------------------------------------------------------------------- // AXPB base //int running = pb.running; gcoef[i] = PBs[i].unknown1; @@ -271,13 +236,11 @@ void Logging() musicLength[i] = gsampleEnd[i] - gloopPos[i]; } - // ================================================================================================ - // ======================================================================================= + // PRESETS - // --------------------------------------------------------------------------------------- /* /" Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n"; "---------------|00 12341234/12341234 12341234 | 00000 00000 00000 0000 00000 | 0[000 00000 00000] 0 | 00000 00000[0 00000] | @@ -289,7 +252,6 @@ void Logging() gfrac[i], gratio[i], gratiohi[i], gratiolo[i], gupdates1[i], gupdates2[i], gupdates3[i], gupdates4[i], gupdates5[i] ); - // ======================================================================================= // write a new line sbuff = sbuff + buffer; strcpy(buffer, ""); @@ -301,16 +263,12 @@ void Logging() } // end of big loop - for (int i = 0; i < numberOfPBs; i++) - // ======================================================================================= // Write global values sprintf(buffer, "\nParameter blocks span from %08x | to %08x | distance %i %i\n", m_addressPBs, gLastBlock, (gLastBlock-m_addressPBs), (gLastBlock-m_addressPBs) / 192); sbuff = sbuff + buffer; strcpy(buffer, ""); - // ============== - // ======================================================================================= // Show update frequency - // --------------- sbuff = sbuff + "\n"; if(!iupdonce) { @@ -358,10 +316,8 @@ void Logging() // ================ - // ======================================================================================= // Print - // --------------- - // Console::ClearScreen(); + INFO_LOG(DSPHLE, "%s", sbuff.c_str()); sbuff.clear(); strcpy(buffer, ""); // --------------- @@ -370,13 +326,9 @@ void Logging() // --------------- } - // --------------------------------------------------------------------------------------- - } -// ======================================================================================= -#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h index 4b483d7152..ce074b4fbb 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h @@ -15,9 +15,9 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ - -#ifdef _WIN32 +#ifndef LOGGING_H +#define LOGGING_H void Logging(); -#endif \ No newline at end of file +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp index d5669e6d5a..97c089dacd 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp @@ -33,10 +33,6 @@ u32 m_addressPBs = 0; extern u32 gLastBlock; - - -#ifdef _WIN32 - int m = 0; int n = 0; #ifdef LOG2 @@ -56,20 +52,18 @@ int ReadOutPBs(AXParamBlock * _pPBs, int _num) //FIXME if (n > 20 && logall) {Console::ClearScreen();} for (int i = 0; i < _num; i++) { - // --------------------------------------------------------------------------------------- // Check if there is something here. const short * pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr); // ------------- if (pSrc != NULL) // only read non-blank blocks { - // --------------------------------------------------------------------------------------- + // Create a shortcut that let us update struct members short * pDest = (short *) & _pPBs[i]; if (n > 20 && logall) {DEBUG_LOG(DSPHLE, "%c%i:", 223, i);} // logging - // -------------- // Here we update the PB. We do it by going through all 192 / 2 = 96 u16 values for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) { @@ -88,10 +82,8 @@ int ReadOutPBs(AXParamBlock * _pPBs, int _num) } if(n > 20 && logall) {DEBUG_LOG(DSPHLE, "\n");} // logging - // -------------- // Here we update the block address to the starting point of the next PB blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo; - // -------------- // save some values count++; gLastBlock = paraAddr; // blockAddr @@ -109,6 +101,3 @@ int ReadOutPBs(AXParamBlock * _pPBs, int _num) // return the number of readed PBs return count; } -// ======================================================================================= - -#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h index f4cc2d0ec6..ea1fdabc2a 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h @@ -14,8 +14,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#ifdef _WIN32 - #ifndef UCODE_AX_STRUCTS #define UCODE_AX_STRUCTS @@ -142,5 +140,4 @@ enum { #endif -#endif // win32 diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.cpp deleted file mode 100644 index 363571e752..0000000000 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -// This queue solution is temporary. I'll implement something more efficient later. - -#include - -#include "Thread.h" -#include "Mixer.h" -#include "FixedSizeQueue.h" - -#ifdef _WIN32 -#include "DSoundStream.h" -#else -#include -#endif - -namespace { -Common::CriticalSection push_sync; - -// On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so... -const int queue_minlength = 1024 * 4; -const int queue_maxlength = 1024 * 28; - -FixedSizeQueue sample_queue; - -} // namespace - -volatile bool mixer_HLEready = false; -volatile int queue_size = 0; - -void Mixer(short *buffer, int numSamples, int bits, int rate, int channels) -{ - // silence - memset(buffer, 0, numSamples * 2 * sizeof(short)); - - push_sync.Enter(); - int count = 0; - while (queue_size > queue_minlength && count < numSamples * 2) { - int x = buffer[count]; - x += sample_queue.front(); - if (x > 32767) x = 32767; - if (x < -32767) x = -32767; - buffer[count++] = x; - sample_queue.pop(); - x = buffer[count]; - x += sample_queue.front(); - if (x > 32767) x = 32767; - if (x < -32767) x = -32767; - buffer[count++] = x; - sample_queue.pop(); - queue_size-=2; - } - push_sync.Leave(); -} - -void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) { -// static FILE *f; -// if (!f) -// f = fopen("d:\\hello.raw", "wb"); -// fwrite(buffer, num_stereo_samples * 4, 1, f); - if (queue_size == 0) - { - queue_size = queue_minlength; - for (int i = 0; i < queue_minlength; i++) - sample_queue.push((s16)0); - } - - static int PV1l=0,PV2l=0,PV3l=0,PV4l=0; - static int PV1r=0,PV2r=0,PV3r=0,PV4r=0; - static int acc=0; - -#ifdef _WIN32 - if (!GetAsyncKeyState(VK_TAB)) { - while (queue_size > queue_maxlength / 2) { - DSound::DSound_UpdateSound(); - Sleep(0); - } - } else { - return; - } -#else - while (queue_size > queue_maxlength) { - sleep(0); - } -#endif - //convert into config option? - const int mode = 2; - - push_sync.Enter(); - while (num_stereo_samples) - { - acc += sample_rate; - while (num_stereo_samples && (acc >= 48000)) - { - PV4l=PV3l; - PV3l=PV2l; - PV2l=PV1l; - PV1l=*(buffer++); //32bit processing - PV4r=PV3r; - PV3r=PV2r; - PV2r=PV1r; - PV1r=*(buffer++); //32bit processing - num_stereo_samples--; - acc-=48000; - } - - // defaults to nearest - s32 DataL = PV1l; - s32 DataR = PV1r; - - if (mode == 1) //linear - { - DataL = PV1l + ((PV2l - PV1l)*acc)/48000; - DataR = PV1r + ((PV2r - PV1r)*acc)/48000; - } - else if (mode == 2) //cubic - { - s32 a0l = PV1l - PV2l - PV4l + PV3l; - s32 a0r = PV1r - PV2r - PV4r + PV3r; - s32 a1l = PV4l - PV3l - a0l; - s32 a1r = PV4r - PV3r - a0r; - s32 a2l = PV1l - PV4l; - s32 a2r = PV1r - PV4r; - s32 a3l = PV2l; - s32 a3r = PV2r; - - s32 t0l = ((a0l )*acc)/48000; - s32 t0r = ((a0r )*acc)/48000; - s32 t1l = ((t0l+a1l)*acc)/48000; - s32 t1r = ((t0r+a1r)*acc)/48000; - s32 t2l = ((t1l+a2l)*acc)/48000; - s32 t2r = ((t1r+a2r)*acc)/48000; - s32 t3l = ((t2l+a3l)); - s32 t3r = ((t2r+a3r)); - - DataL = t3l; - DataR = t3r; - } - - int l = DataL, r = DataR; - if (l < -32767) l = -32767; - if (r < -32767) r = -32767; - if (l > 32767) l = 32767; - if (r > 32767) r = 32767; - sample_queue.push(l); - sample_queue.push(r); - } - push_sync.Leave(); -} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.h deleted file mode 100644 index 3c5095ab70..0000000000 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2003-2008 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _MIXER_H -#define _MIXER_H - -extern volatile bool mixer_HLEready; - -// Called from audio threads -void Mixer(short* buffer, int numSamples, int bits, int rate, int channels); - -// Called from main thread -void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate); - -#endif - diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript b/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript index ab1ef604e5..96a5040193 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript @@ -25,7 +25,6 @@ files = [ "HLE_Functions.cpp", "HLE_Helper.cpp", "main.cpp", - "Mixer.cpp", "opcodes.cpp", # "RegisterDlg.cpp", # "RegSettings.cpp", diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp index 3a3c1e001f..f2df660cc8 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp @@ -417,7 +417,7 @@ void Hacks() } } */ - if (g_dsp.pc == 0x468) + /* if (g_dsp.pc == 0x468) { int numSamples = g_dsp.r[25] / 2; uint16 bufferAddr = g_dsp.r[27]; @@ -429,7 +429,7 @@ void Hacks() { samples[i] = dsp_dmem_read(bufferAddr+i); } - Mixer_PushSamples(samples, numSamples / 2, 32000); //sample_rate); + PushSamples(samples, numSamples / 2, 32000); //sample_rate); g_wave_writer.AddStereoSamples(samples, numSamples/2); // 2 channels @@ -439,5 +439,5 @@ void Hacks() g_wave_writer.Stop(); exit(1); } - } + }*/ } diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp index 6418e8d359..f22586637d 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp @@ -31,27 +31,20 @@ #include "ConfigDlg.h" #endif +#include "AudioCommon.h" #include "AOSoundStream.h" #include "DSoundStream.h" #include "NullSoundStream.h" +#include "Logging/Logging.h" // For Logging #ifdef _WIN32 #include "DisAsmDlg.h" - #include "Logging/Logging.h" // For Logging HINSTANCE g_hInstance = NULL; CDisAsmDlg g_Dialog; -#else - #define WINAPI - #define LPVOID void* - #include - #include - #include - #include - #include "AOSoundStream.h" #endif - +#include "Thread.h" #include "ChunkFile.h" PLUGIN_GLOBALS* globals = NULL; @@ -159,7 +152,7 @@ void DllDebugger(HWND _hParent, bool Show) } -// Regular thread +/*// Regular thread #ifdef _WIN32 DWORD WINAPI dsp_thread(LPVOID lpParameter) #else @@ -203,7 +196,7 @@ void* dsp_thread_debug(void* lpParameter) return NULL; } - +*/ void DSP_DebugBreak() { #ifdef _WIN32 @@ -230,24 +223,22 @@ void Initialize(void *init) g_dsp.irq_request = dspi_req_dsp_irq; gdsp_reset(); - if (!gdsp_load_rom((char *)DSP_ROM_FILE)) - { + if (!gdsp_load_rom((char *)DSP_ROM_FILE)) { bCanWork = false; PanicAlert("Cannot load DSP ROM"); } - if (!gdsp_load_coef((char *)DSP_COEF_FILE)) - { + if (!gdsp_load_coef((char *)DSP_COEF_FILE)) { bCanWork = false; PanicAlert("Cannot load DSP COEF"); } - - if(!bCanWork) - return; // TODO: Don't let it work - -// First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in -// Globals.h. Then make the disassembled file here. Dump UCode to file... - + + if(!bCanWork) + return; // TODO: Don't let it work + + /*/ First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in + // Globals.h. Then make the disassembled file here. Dump UCode to file... + FILE* t = fopen("C:\\_\\DSP_UC_09CD143F.txt", "wb"); if (t != NULL) { @@ -255,49 +246,15 @@ void Initialize(void *init) gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t); fclose(t); } - - if (g_Config.sBackend == "DSound") + */ + + soundStream = AudioCommon::InitSoundStream(g_Config.sBackend); + + soundStream->GetMixer()->SetThrottle(g_Config.m_EnableThrottle); + // Start the sound recording + if (log_ai) { - if (DSound::isValid()) - soundStream = new DSound(48000, Mixer, g_dspInitialize.hWnd); - } - else if (g_Config.sBackend == "AOSound") - { - if (AOSound::isValid()) - soundStream = new AOSound(48000, Mixer); - } - else if (g_Config.sBackend == "NullSound") - { - soundStream = new NullSound(48000, Mixer); - } - else - { - PanicAlert("Cannot recognize backend %s", g_Config.sBackend.c_str()); - return; - } - - if (soundStream) - { - if (!soundStream->Start()) - { - PanicAlert("Could not initialize backend %s, falling back to NULL", - g_Config.sBackend.c_str()); - delete soundStream; - soundStream = new NullSound(48000, Mixer); - soundStream->Start(); - } - } - else - { - PanicAlert("Sound backend %s is not valid, falling back to NULL", - g_Config.sBackend.c_str()); - delete soundStream; - soundStream = new NullSound(48000, Mixer); - soundStream->Start(); - } - - if (log_ai) { - g_wave_writer.Start("C:\\_\\ai_log.wav"); + g_wave_writer.Start("ai_log.wav"); g_wave_writer.SetSkipSilence(false); } } @@ -418,25 +375,39 @@ void DSP_Update(int cycles) } + void DSP_SendAIBuffer(unsigned int address, int sample_rate) { - short samples[16] = {0}; // interleaved stereo - if (address) { - for (int i = 0; i < 16; i++) { - samples[i] = Memory_Read_U16(address + i * 2); - } - if (log_ai) - g_wave_writer.AddStereoSamples(samples, 8); + // TODO: This is not yet fully threadsafe. + if (!soundStream) { + return; } - Mixer_PushSamples(samples, 32 / 4, sample_rate); + if (soundStream->GetMixer()) + { + short samples[16] = {0}; // interleaved stereo + if (address) + { + for (int i = 0; i < 16; i++) + { + samples[i] = Memory_Read_U16(address + i * 2); + } + + // Write the audio to a file + if (log_ai) + g_wave_writer.AddStereoSamples(samples, 8); + } + soundStream->GetMixer()->PushSamples(samples, 32 / 4); + } + + // SoundStream is updated only when necessary (there is no 70 ms limit + // so each sample now triggers the sound stream) + + // TODO: think about this. static int counter = 0; counter++; -#ifdef _WIN32 - if ((counter & 255) == 0) - DSound::DSound_UpdateSound(); -#endif + if ((counter & 31) == 0 && soundStream) + soundStream->Update(); } -