From 3d475abf2b8856d474ce5b13ad8a0611e181b5ac Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sat, 4 Oct 2008 00:16:19 +0000 Subject: [PATCH] Hook up sound output in the LLE plugin. Some AX games actually produce some icky scratchy "sound" sometimes :D git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@761 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugin_DSP_HLE/Src/Debugger/Debugger.h | 20 +++ Source/Plugins/Plugin_DSP_HLE/Src/Globals.h | 20 --- .../Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj | 14 +- .../Plugins/Plugin_DSP_LLE/Src/DisAsmDlg.cpp | 2 +- Source/Plugins/Plugin_DSP_LLE/Src/Mixer.cpp | 157 ++++++++++++++++++ Source/Plugins/Plugin_DSP_LLE/Src/Mixer.h | 30 ++++ .../Plugin_DSP_LLE/Src/gdsp_memory.cpp | 14 +- Source/Plugins/Plugin_DSP_LLE/Src/main.cpp | 22 ++- 8 files changed, 243 insertions(+), 36 deletions(-) create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Mixer.cpp create mode 100644 Source/Plugins/Plugin_DSP_LLE/Src/Mixer.h diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h index 8e048d3383..ab4c379d93 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Debugger/Debugger.h @@ -23,6 +23,26 @@ #define __CDebugger_h__ +// --------------------------------------------------------------------------------------- +// wx stuff, I'm not sure if we use all these +#ifndef WX_PRECOMP + #include + #include +#else + #include +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +// ------------ + #include "../Globals.h" class CPBView; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h index 0ba54fd114..908a6664fb 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h @@ -2,26 +2,6 @@ #define _GLOBALS_H -// --------------------------------------------------------------------------------------- -// wx stuff, I'm not sure if we use all these -#ifndef WX_PRECOMP - #include - #include -#else - #include -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include -// ------------ - #include "Common.h" #include "pluginspecs_dsp.h" diff --git a/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj b/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj index 91788bd053..5864a44d85 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj +++ b/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj @@ -1,7 +1,7 @@ + + + + + + diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/DisAsmDlg.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/DisAsmDlg.cpp index 104982bc40..84e5645a3d 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/DisAsmDlg.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/DisAsmDlg.cpp @@ -60,7 +60,7 @@ LRESULT CDisAsmDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPar m_DisAsmListViewCtrl.AddColumn(_T("BP"), ColumnBP); m_DisAsmListViewCtrl.AddColumn(_T("Function"), ColumnFunction); m_DisAsmListViewCtrl.AddColumn(_T("Address"), ColumnAddress); - m_DisAsmListViewCtrl.AddColumn(_T("Menmomic"), ColumnMenmomic); + m_DisAsmListViewCtrl.AddColumn(_T("Mnenmomic"), ColumnMenmomic); m_DisAsmListViewCtrl.AddColumn(_T("Opcode"), ColumnOpcode); m_DisAsmListViewCtrl.AddColumn(_T("Ext"), ColumnExt); m_DisAsmListViewCtrl.AddColumn(_T("Parameter"), ColumnParameter); diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Mixer.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/Mixer.cpp new file mode 100644 index 0000000000..448ee1090e --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Mixer.cpp @@ -0,0 +1,157 @@ +// 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" +#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; + } + sample_queue.push(DataL); + sample_queue.push(DataR); + queue_size += 2; + } + push_sync.Leave(); +} diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/Mixer.h b/Source/Plugins/Plugin_DSP_LLE/Src/Mixer.h new file mode 100644 index 0000000000..a3340845c6 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE/Src/Mixer.h @@ -0,0 +1,30 @@ +// 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/Src/gdsp_memory.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/gdsp_memory.cpp index c6fcf002b6..e5a9829b7f 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/gdsp_memory.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/gdsp_memory.cpp @@ -82,8 +82,8 @@ uint16 dsp_dmem_read(uint16 addr) switch (addr >> 12) { - case 0x1: // 1xxx COEF - val = g_dsp.coef[addr & DSP_DROM_MASK]; + case 0x0: // 0xxx DRAM + val = g_dsp.dram[addr & DSP_DRAM_MASK]; val = dsp_swap16(val); break; @@ -93,13 +93,13 @@ uint16 dsp_dmem_read(uint16 addr) val = dsp_swap16(val); break; - case 0xf: // Fxxx HW regs - val = gdsp_ifx_read(addr); + case 0x1: // 1xxx COEF + val = g_dsp.coef[addr & DSP_DROM_MASK]; + val = dsp_swap16(val); break; - case 0x0: // 0xxx DRAM - val = g_dsp.dram[addr & DSP_DRAM_MASK]; - val = dsp_swap16(val); + case 0xf: // Fxxx HW regs + val = gdsp_ifx_read(addr); break; default: // error diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp index 4bc344f836..f54c874737 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp @@ -18,6 +18,7 @@ #include "Common.h" #include "Globals.h" #include "CommonTypes.h" +#include "Mixer.h" #include "gdsp_interpreter.h" #include "gdsp_interface.h" @@ -203,10 +204,6 @@ void dspi_req_dsp_irq() } -void Mixer(short* buffer, int numSamples, int bits, int rate, int channels) -{} - - void DSP_Initialize(DSPInitialize _dspInitialize) { bool bCanWork = true; @@ -376,12 +373,23 @@ void DSP_Update(int cycles) #endif } + void DSP_SendAIBuffer(unsigned int address, int sample_rate) { - // uint32 Size = _Size * 16 * 2; // 16bit per sample, two channels + short samples[16] = {0}; // interleaved stereo + if (address) { + for (int i = 0; i < 16; i++) { + samples[i] = Memory_Read_U16(address + i * 2); + } + } + Mixer_PushSamples(samples, 32 / 4, sample_rate); - g_LastDMAAddress = address; - g_LastDMASize = 32; + static int counter = 0; + counter++; +#ifdef _WIN32 + if ((counter & 255) == 0) + DSound::DSound_UpdateSound(); +#endif }