diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.cpp b/Source/Core/AudioCommon/Src/AOSoundStream.cpp index e6402a5186..f584cb6636 100644 --- a/Source/Core/AudioCommon/Src/AOSoundStream.cpp +++ b/Source/Core/AudioCommon/Src/AOSoundStream.cpp @@ -33,7 +33,7 @@ void AOSound::SoundLoop() device = ao_open_live(default_driver, &format, NULL /* no options */); if (!device) { - PanicAlert("DSP_HLE: Error opening AO device.\n"); + PanicAlert("AudioCommon: Error opening AO device.\n"); ao_shutdown(); Stop(); return; diff --git a/Source/Core/AudioCommon/Src/SConscript b/Source/Core/AudioCommon/Src/SConscript new file mode 100644 index 0000000000..2fb00f47b7 --- /dev/null +++ b/Source/Core/AudioCommon/Src/SConscript @@ -0,0 +1,11 @@ +# -*- python -*- + +Import('env') + +files = [ + 'AOSoundStream.cpp', + ] + +env_audiocommon = env.Clone() +env_audiocommon.Append(CXXFLAGS = [ '-fPIC' ]) +env_audiocommon.StaticLibrary('audiocommon', files) diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp index 04096280de..cdabb195e6 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp @@ -43,7 +43,6 @@ PLUGIN_GLOBALS* globals = NULL; DSPInitialize g_dspInitialize; u8* g_pMemory; extern std::vector sMailLog, sMailTime; -std::string gpName; SoundStream *soundStream = NULL; @@ -127,31 +126,12 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle #endif -/* -// Open and close console -void OpenConsole() -{ -#if defined (_WIN32) - Console::Open(155, 100, "Sound Debugging"); // give room for 100 rows - DEBUG_LOG(CONSOLE, "OpenConsole > Console opened\n"); - MoveWindow(Console::GetHwnd(), 0,400, 1280,550, true); // move window, TODO: make this - // adjustable from the debugging window -#endif -} - -void CloseConsole() -{ -#if defined (_WIN32) - FreeConsole(); -#endif -} -*/ - // Exported fuctions -// Create debugging window - We could use use wxWindow win; new CDebugger(win) like nJoy but I don't -// know why it would be better. - There's a lockup problem with ShowModal(), but Show() doesn't work -// because then DLL_PROCESS_DETACH is called immediately after DLL_PROCESS_ATTACH. +// Create debugging window - We could use use wxWindow win; new CDebugger(win) +// like nJoy but I don't know why it would be better. - There's a lockup +// problem with ShowModal(), but Show() doesn't work because then +// DLL_PROCESS_DETACH is called immediately after DLL_PROCESS_ATTACH. void DllDebugger(HWND _hParent, bool Show) { #if defined(HAVE_WX) && HAVE_WX @@ -214,24 +194,11 @@ void DllConfig(HWND _hParent) void Initialize(void *init) { - //Console::Open(80, 5000); - g_dspInitialize = *(DSPInitialize*)init; g_Config.Load(); g_pMemory = g_dspInitialize.pGetMemoryPointer(0); -#if defined(_DEBUG) || defined(DEBUGFAST) - gpName = g_dspInitialize.pName(); // save the game name globally - for (u32 i = 0; i < gpName.length(); ++i) // and fix it - { - fprintf(stderr,"%c", gpName[i]); - std::cout << gpName[i]; - if (gpName[i] == ':') gpName[i] = ' '; - } - fprintf(stderr, "\n"); -#endif - CDSPHandler::CreateInstance(); if (g_Config.sBackend == "DSound") @@ -254,12 +221,6 @@ void Initialize(void *init) return; } -#if defined(WIN32) && defined(_DEBUG) - //int tmpflag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - //tmpflag |= _CRTDBG_DELAY_FREE_MEM_DF; - //_CrtSetDbgFlag(tmpflag); -#endif - if (soundStream) { if (!soundStream->Start()) @@ -328,9 +289,7 @@ void DoState(unsigned char **ptr, int mode) } -//////////////////////////////////////////////////////////////////////////////////////// // Mailbox fuctions -// ¯¯¯¯¯¯¯¯¯¯¯¯ unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox) { if (_CPUMailbox) @@ -395,12 +354,9 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value) PanicAlert("CPU can't write %08x to DSP mailbox", _Value); } } -///////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// // Other DSP fuctions -// ¯¯¯¯¯¯¯¯¯¯¯¯ unsigned short DSP_WriteControlRegister(unsigned short _Value) { return CDSPHandler::GetInstance().WriteControlRegister(_Value); @@ -416,10 +372,11 @@ void DSP_Update(int cycles) CDSPHandler::GetInstance().Update(); } -/* Other Audio will pass through here. The kind of audio that sometimes are used together with pre-drawn - movies. This audio can be disabled further inside Mixer_PushSamples(), the reason that we don't disable - this entire function when Other Audio is disabled is that then we can't turn it back on again once the - game has started. */ +/* Other Audio will pass through here. The kind of audio that sometimes are + used together with pre-drawn movies. This audio can be disabled further + inside Mixer_PushSamples(), the reason that we don't disable this entire + function when Other Audio is disabled is that then we can't turn it back on + again once the game has started. */ void DSP_SendAIBuffer(unsigned int address, int sample_rate) { // TODO: This is not yet fully threadsafe. @@ -453,4 +410,4 @@ void DSP_SendAIBuffer(unsigned int address, int sample_rate) if ((counter & 31) == 0 && soundStream) soundStream->Update(); } -///////////////////////////////////// + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj index ff1aeb5d63..afb77c8424 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj @@ -2,7 +2,7 @@ - - - - diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.cpp deleted file mode 100644 index 7e416ebfbe..0000000000 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include "AOSoundStream.h" - -namespace AOSound -{ - pthread_t thread; - StreamCallback callback; - - char *buffer; - int buf_size; - - ao_device *device; - ao_sample_format format; - int default_driver; - - int bufferSize; - int totalRenderedBytes; - int sampleRate; - volatile int threadData; - int currentPos; - int lastPos; - short realtimeBuffer[1024 * 1024]; - int AOSound_GetSampleRate() - { - return sampleRate; - } - bool WriteDataToBuffer(int dwOffset,char* soundData, int dwSoundBytes) - { - //void* ptr1, * ptr2; - //DWORD numBytes1, numBytes2; - // Obtain memory address of write block. This will be in two parts if the block wraps around. - //HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); - - // If the buffer was lost, restore and retry lock. - /*if (DSERR_BUFFERLOST == hr) - { - dsBuffer->Restore(); - hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); - } - - if (SUCCEEDED(hr)) - { - memcpy(ptr1, soundData, numBytes1); - - if (ptr2 != 0) - { - memcpy(ptr2, soundData + numBytes1, numBytes2); - } - - // Release the data back to DirectSound. - dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2); - return(true); - } - - return(false);*/ - ao_play(device, soundData, dwSoundBytes); - return true; - - } - - void* soundThread(void*) - { - currentPos = 0; - lastPos = 0; - - // Prefill buffer? - //writeDataToBuffer(0,realtimeBuffer,bufferSize); - // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0); - //dsBuffer->Play(0, 0, DSBPLAY_LOOPING); - - while (!threadData) - { - // No blocking inside the csection - //dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0); - int numBytesToRender = 256; - - if (numBytesToRender >= 256) - { - (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2); - - WriteDataToBuffer(0, (char*)realtimeBuffer, numBytesToRender); - //currentPos = ModBufferSize(lastPos + numBytesToRender); - //totalRenderedBytes += numBytesToRender; - - //lastPos = currentPos; - } - - //WaitForSingleObject(soundSyncEvent, MAXWAIT); - } - - //dsBuffer->Stop(); - return(0); //hurra! - } - bool AOSound_StartSound(int _sampleRate, StreamCallback _callback) - { - callback = _callback; - threadData = 0; - sampleRate = _sampleRate; - - //no security attributes, automatic resetting, init state nonset, untitled - //soundSyncEvent = CreateEvent(0, false, false, 0); - ao_initialize(); - default_driver = ao_default_driver_id(); - format.bits = 16; - format.channels = 2; - format.rate = sampleRate; - format.byte_format = AO_FMT_LITTLE; - - //vi vill ha access till DSOUND sÃ¥... - device = ao_open_live(default_driver, &format, NULL /* no options */); - if (device == NULL) { - fprintf(stderr, "DSP_LLE: Error opening AO device.\n"); - return 1; - } - buf_size = format.bits/8 * format.channels * format.rate; - buffer = (char*)calloc(buf_size, sizeof(char)); - pthread_create(&thread, NULL, soundThread, (void *)NULL); - return(true); - } - void AOSound_StopSound() - { - ao_close(device); - ao_shutdown(); - } -} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp new file mode 100644 index 0000000000..3d96992efc --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.cpp @@ -0,0 +1,56 @@ +// 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/ + +#include "Common.h" +#include "IniFile.h" +#include "Config.h" + +CConfig g_Config; + +CConfig::CConfig() +{ + Load(); +} + +void CConfig::Load() +{ + // first load defaults + std::string temp; + + 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", "EnableThrottle", &m_EnableThrottle, true); +#ifdef _WIN32 + file.Get("Config", "Backend", &sBackend, "DSound"); +#else + file.Get("Config", "Backend", &sBackend, "AOSound"); +#endif +} + +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()); + + file.Save(FULL_CONFIG_DIR "DSP.ini"); +} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h similarity index 63% rename from Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.h rename to Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h index dfef628e0c..a255b52c7d 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h @@ -15,21 +15,26 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#ifndef __AOSOUNDSTREAM_H__ -#define __AOSOUNDSTREAM_H__ +#ifndef _PLUGIN_DSP_HLE_CONFIG_H +#define _PLUGIN_DSP_HLE_CONFIG_H -namespace AOSound +#include + +struct CConfig { -typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels); + bool m_EnableHLEAudio; + bool m_EnableDTKMusic; + bool m_EnableThrottle; + std::string sBackend; + + CConfig(); + + void Load(); + + void Save(); +}; -bool AOSound_StartSound(int sampleRate, StreamCallback _callback); -void AOSound_UpdateSound(); -void AOSound_StopSound(); +extern CConfig g_Config; -float AOSound_GetTimer(); -int AOSound_GetCurSample(); -int AOSound_GetSampleRate(); -} +#endif // _PLUGIN_DSP_HLE_CONFIG_H - -#endif //__AOSOUNDSTREAM_H__ diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp new file mode 100644 index 0000000000..8384a867d0 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.cpp @@ -0,0 +1,101 @@ +// 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/ + + +#include "Config.h" +#include "ConfigDlg.h" + +BEGIN_EVENT_TABLE(ConfigDialog, wxDialog) +EVT_BUTTON(wxID_OK, ConfigDialog::SettingsChanged) +EVT_CHECKBOX(ID_ENABLE_HLE_AUDIO, ConfigDialog::SettingsChanged) +EVT_CHECKBOX(ID_ENABLE_DTK_MUSIC, ConfigDialog::SettingsChanged) +EVT_CHECKBOX(ID_ENABLE_THROTTLE, ConfigDialog::SettingsChanged) +END_EVENT_TABLE() + +ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style) +: wxDialog(parent, id, title, position, size, style) +{ + // Load config settings + g_Config.Load(); + + // Center window + CenterOnParent(); + + m_OK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + + // 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.")); + m_BackendSelection->SetToolTip(wxT("Changing this will have no effect while the emulator is running!")); + + // Create sizer and add items to dialog + 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); + sBackend->Add(m_BackendSelection); + sbSettings->Add(sBackend); + + sMain->Add(sbSettings, 0, wxEXPAND|wxALL, 5); + wxBoxSizer *sButtons = new wxBoxSizer(wxHORIZONTAL); + sButtons->Add(150, 0); // Lazy way to make the dialog as wide as we want it + sButtons->Add(m_OK, 0, wxALL, 5); + sMain->Add(sButtons, 0, wxEXPAND); + this->SetSizerAndFit(sMain); +} + +// Add audio output options +void ConfigDialog::AddBackend(const char* backend) +{ + m_BackendSelection->Append(wxString::FromAscii(backend)); + // Update value + m_BackendSelection->SetValue(wxString::FromAscii(g_Config.sBackend.c_str())); +} + +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(); + + if (event.GetId() == wxID_OK) + EndModal(wxID_OK); +} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.h new file mode 100644 index 0000000000..d0fe6e1466 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/ConfigDlg.h @@ -0,0 +1,61 @@ +// 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 __DSP_HLE_CONFIGDIALOG_h__ +#define __DSP_HLE_CONFIGDIALOG_h__ + +#include +#include +#include +#include + +class ConfigDialog : public wxDialog +{ +public: + ConfigDialog(wxWindow *parent, + wxWindowID id = 1, + const wxString &title = wxT("Dolphin DSP-HLE Plugin Settings"), + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE); + virtual ~ConfigDialog(); + void AddBackend(const char *backend); + +private: + DECLARE_EVENT_TABLE(); + + wxButton *m_OK; + wxCheckBox *m_buttonEnableHLEAudio; + wxCheckBox *m_buttonEnableDTKMusic; + wxCheckBox *m_buttonEnableThrottle; + wxArrayString wxArrayBackends; + wxComboBox *m_BackendSelection; + + enum + { + wxID_OK, + ID_ENABLE_HLE_AUDIO, + ID_ENABLE_DTK_MUSIC, + ID_ENABLE_THROTTLE, + ID_BACKEND + }; + + void OnOK(wxCommandEvent& event); + void SettingsChanged(wxCommandEvent& event); +}; + +#endif //__DSP_HLE_CONFIGDIALOG_h__ diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.cpp deleted file mode 100644 index 823003e17b..0000000000 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.cpp +++ /dev/null @@ -1,280 +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/ - -#include "stdafx.h" - -#include -#include - -#include "DSoundStream.h" - -namespace DSound -{ -#define BUFSIZE 32768 -#define MAXWAIT 70 //ms - -//THE ROCK SOLID SYNCED DSOUND ENGINE :) - - -//våran kritiska sektion och vår syncevent-handle -CRITICAL_SECTION soundCriticalSection; -HANDLE soundSyncEvent; -HANDLE hThread; - -StreamCallback callback; - -//lite mojs -IDirectSound8* ds; -IDirectSoundBuffer* dsBuffer; - -//tja.. behövs -int bufferSize; //i bytes -int totalRenderedBytes; -int sampleRate; - -//med den här synkar vi stängning.. -//0=vi spelar oväsen, 1=stäng tråden NU! 2=japp,tråden är stängd så fortsätt -volatile int threadData; - - -//ser till så X kan delas med 32 -inline int FIX32(int x) -{ - return(x & (~127)); -} - - -int DSound_GetSampleRate() -{ - return(sampleRate); -} - - -//Dags att skapa vår directsound buffert -bool createBuffer() -{ - PCMWAVEFORMAT pcmwf; - DSBUFFERDESC dsbdesc; - - //ljudformatet - memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); - memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); - - pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; - pcmwf.wf.nChannels = 2; - pcmwf.wf.nSamplesPerSec = sampleRate; - pcmwf.wf.nBlockAlign = 4; - pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; - pcmwf.wBitsPerSample = 16; - - //buffer description - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; - dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //ändra för att ställa in bufferstorlek - dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf; - // nu skapar vi bufferjäveln - - if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL))) - { - dsBuffer->SetCurrentPosition(0); - return(true); - } - else - { - // Failed. - dsBuffer = NULL; - return(false); - } -} - - -bool writeDataToBuffer(DWORD dwOffset, // Our own write cursor. - char* soundData, // Start of our data. - DWORD dwSoundBytes) // Size of block to copy. -{ - void* ptr1, * ptr2; - DWORD numBytes1, numBytes2; - // Obtain memory address of write block. This will be in two parts if the block wraps around. - HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); - - // If the buffer was lost, restore and retry lock. - - if (DSERR_BUFFERLOST == hr) - { - dsBuffer->Restore(); - hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); - } - - if (SUCCEEDED(hr)) - { - memcpy(ptr1, soundData, numBytes1); - - if (ptr2 != 0) - { - memcpy(ptr2, soundData + numBytes1, numBytes2); - } - - // Release the data back to DirectSound. - dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2); - return(true); - } /* - else - { - char temp[8]; - sprintf(temp,"%i\n",hr); - OutputDebugString(temp); - }*/ - - return(false); -} - - -inline int ModBufferSize(int x) -{ - return((x + bufferSize) % bufferSize); -} - - -int currentPos; -int lastPos; -short realtimeBuffer[1024 * 1024]; - - -DWORD WINAPI soundThread(void*) -{ - currentPos = 0; - lastPos = 0; - //writeDataToBuffer(0,realtimeBuffer,bufferSize); - // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0); - - dsBuffer->Play(0, 0, DSBPLAY_LOOPING); - - while (!threadData) - { - EnterCriticalSection(&soundCriticalSection); - - dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0); - int numBytesToRender = FIX32(ModBufferSize(currentPos - lastPos)); - - //renderStuff(numBytesToRender/2); - //if (numBytesToRender>bufferSize/2) numBytesToRender=0; - - if (numBytesToRender >= 256) - { - (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2); - - writeDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); - - currentPos = ModBufferSize(lastPos + numBytesToRender); - totalRenderedBytes += numBytesToRender; - - lastPos = currentPos; - } - - LeaveCriticalSection(&soundCriticalSection); - WaitForSingleObject(soundSyncEvent, MAXWAIT); - } - - dsBuffer->Stop(); - - threadData = 2; - return(0); //hurra! -} - - -bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback) -{ - callback = _callback; - threadData = 0; - sampleRate = _sampleRate; - - //no security attributes, automatic resetting, init state nonset, untitled - soundSyncEvent = CreateEvent(0, false, false, 0); - - //vi initierar den........... - InitializeCriticalSection(&soundCriticalSection); - - //vi vill ha access till DSOUND så... - if (FAILED(DirectSoundCreate8(0, &ds, 0))) - { - return(false); - } - - //samarbetsvillig? nää :) - ds->SetCooperativeLevel(window, DSSCL_NORMAL); //DSSCL_PRIORITY? - - //så.. skapa buffern - if (!createBuffer()) - { - return(false); - } - - //rensa den.. ? - DWORD num1; - short* p1; - - dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0); - - memset(p1, 0, num1); - dsBuffer->Unlock(p1, num1, 0, 0); - totalRenderedBytes = -bufferSize; - DWORD h; - hThread = CreateThread(0, 0, soundThread, 0, 0, &h); - SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); - return(true); -} - - -void DSound_UpdateSound() -{ - SetEvent(soundSyncEvent); -} - - -void DSound_StopSound() -{ - EnterCriticalSection(&soundCriticalSection); - threadData = 1; - //kick the thread if it's waiting - SetEvent(soundSyncEvent); - LeaveCriticalSection(&soundCriticalSection); - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - - dsBuffer->Release(); - ds->Release(); - - CloseHandle(soundSyncEvent); -} - - -int DSound_GetCurSample() -{ - EnterCriticalSection(&soundCriticalSection); - int playCursor; - dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0); - playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes; - LeaveCriticalSection(&soundCriticalSection); - return(playCursor); -} - - -float DSound_GetTimer() -{ - return((float)DSound_GetCurSample() * (1.0f / (4.0f * 44100.0f))); -} -} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.h deleted file mode 100644 index 99e3a9d7c6..0000000000 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.h +++ /dev/null @@ -1,35 +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 __SOUNDSTREAM_H__ -#define __SOUNDSTREAM_H__ - -namespace DSound -{ -typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels); - -bool DSound_StartSound(HWND window, int sampleRate, StreamCallback _callback); -void DSound_UpdateSound(); -void DSound_StopSound(); - -float DSound_GetTimer(); -int DSound_GetCurSample(); -int DSound_GetSampleRate(); -} - - -#endif //__SOUNDSTREAM_H__ diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript b/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript index 0a935fa938..fa21ad37db 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript @@ -10,10 +10,10 @@ if not env['HAVE_AO']: Return() files = [ - "AOSoundStream.cpp", # "DisAsmDlg.cpp", + "Config.cpp", + "ConfigDlg.cpp", "disassemble.cpp", -# "DSoundStream.cpp", "gdsp_aram.cpp", "gdsp_ext_op.cpp", "gdsp_interface.cpp", diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp index 74129d76f2..6418e8d359 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp @@ -16,9 +16,6 @@ // http://code.google.com/p/dolphin-emu/ -// ======================================================================================= -// Includes -// -------------- #include "Common.h" // Common #include "WaveFile.h" #include "CommonTypes.h" @@ -28,15 +25,22 @@ #include "gdsp_interpreter.h" #include "gdsp_interface.h" #include "disassemble.h" +#include "Config.h" + +#if defined(HAVE_WX) && HAVE_WX +#include "ConfigDlg.h" +#endif + +#include "AOSoundStream.h" +#include "DSoundStream.h" +#include "NullSoundStream.h" + #ifdef _WIN32 #include "DisAsmDlg.h" - #include "DSoundStream.h" #include "Logging/Logging.h" // For Logging HINSTANCE g_hInstance = NULL; - HANDLE g_hDSPThread = NULL; - CRITICAL_SECTION g_CriticalSection; CDisAsmDlg g_Dialog; #else #define WINAPI @@ -46,19 +50,16 @@ #include #include #include "AOSoundStream.h" - pthread_t g_hDSPThread = NULL; #endif #include "ChunkFile.h" -// ============== - -// ======================================================================================= -// Global declarations and definitions -// -------------- PLUGIN_GLOBALS* globals = NULL; DSPInitialize g_dspInitialize; + +SoundStream *soundStream = NULL; + #define GDSP_MBOX_CPU 0 #define GDSP_MBOX_DSP 1 @@ -73,7 +74,6 @@ bool bCanWork = false; // Set this if you want to log audio. search for log_ai in this file to see the filename. static bool log_ai = false; WaveFileWriter g_wave_writer; -// ============== #ifdef _WIN32 @@ -124,8 +124,24 @@ void DllAbout(HWND _hParent) {} + void DllConfig(HWND _hParent) -{} +{ +#if defined(HAVE_WX) && HAVE_WX + // (shuffle2) TODO: reparent dlg with DolphinApp + ConfigDialog dlg(NULL); + + // Add avaliable output options + if (DSound::isValid()) + dlg.AddBackend("DSound"); + if (AOSound::isValid()) + dlg.AddBackend("AOSound"); + dlg.AddBackend("NullSound"); + + // Show the window + dlg.ShowModal(); +#endif +} void DoState(unsigned char **ptr, int mode) { @@ -138,23 +154,12 @@ void DllDebugger(HWND _hParent, bool Show) #if defined (_DEBUG) || defined (DEBUGFAST) g_Dialog.Create(NULL); //_hParent); g_Dialog.ShowWindow(SW_SHOW); - // MoveWindow(g_Dialog.m_hWnd, 450,0, 780,530, true); - - // Open the console window - // Console::Open(155, 100, "Sound Debugging"); // give room for 100 rows - // Console::Print("DllDebugger > Console opened\n"); - // Todo: Make this adjustable from the Debugging window - // MoveWindow(Console::GetHwnd(), 0,400, 1280,500, true); - #else - MessageBox(0, "Can't open debugging window in the Release build of this plugin.", "DSP LLE", 0); #endif #endif } -// ======================================================================================= // Regular thread -// -------------- #ifdef _WIN32 DWORD WINAPI dsp_thread(LPVOID lpParameter) #else @@ -170,12 +175,8 @@ void* dsp_thread(void* lpParameter) } } } -// ============== - -// ======================================================================================= // Debug thread -// -------------- #ifdef _WIN32 DWORD WINAPI dsp_thread_debug(LPVOID lpParameter) #else @@ -183,10 +184,6 @@ void* dsp_thread_debug(void* lpParameter) #endif { - //if (g_hDSPThread) - //{ - // return NULL; // enable this to disable the plugin - //} #ifdef _WIN32 while (1) @@ -205,7 +202,6 @@ void* dsp_thread_debug(void* lpParameter) #endif return NULL; } -// ============== void DSP_DebugBreak() @@ -236,26 +232,21 @@ void Initialize(void *init) if (!gdsp_load_rom((char *)DSP_ROM_FILE)) { - bCanWork = false; - PanicAlert("No DSP ROM"); - ERROR_LOG(DSPHLE, "Cannot load DSP ROM\n"); + bCanWork = false; + PanicAlert("Cannot load DSP ROM"); } - + if (!gdsp_load_coef((char *)DSP_COEF_FILE)) { - bCanWork = false; - PanicAlert("No DSP COEF"); - ERROR_LOG(DSPHLE, "Cannot load DSP COEF\n"); + 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... +// 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) @@ -264,50 +255,69 @@ void Initialize(void *init) gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t); fclose(t); } -// -------------- -#ifdef _WIN32 -#if defined(_DEBUG) || defined(DEBUGFAST) - g_hDSPThread = CreateThread(NULL, 0, dsp_thread_debug, 0, 0, NULL); -#else - g_hDSPThread = CreateThread(NULL, 0, dsp_thread, 0, 0, NULL); -#endif // DEBUG -#else -#if _DEBUG - pthread_create(&g_hDSPThread, NULL, dsp_thread_debug, (void *)NULL); -#else - pthread_create(&g_hDSPThread, NULL, dsp_thread, (void *)NULL); -#endif // DEBUG -#endif // WIN32 - + 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); + } + 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.SetSkipSilence(false); } - -#ifdef _WIN32 - InitializeCriticalSection(&g_CriticalSection); - DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer); -#else - AOSound::AOSound_StartSound(48000, Mixer); -#endif } void DSP_StopSoundStream() { -#ifdef _WIN32 - if (g_hDSPThread != NULL) - { - TerminateThread(g_hDSPThread, 0); - } -#else - // Isn't pthread_cancel kind of evil? - pthread_cancel(g_hDSPThread); -#endif + if (!soundStream) + PanicAlert("Can't stop non running SoundStream!"); + soundStream->Stop(); + delete soundStream; + soundStream = NULL; } void Shutdown(void) { + // Check that soundstream already is stopped. + if (soundStream) + PanicAlert("SoundStream alive in DSP::Shutdown!"); + + // Stop the sound recording if (log_ai) g_wave_writer.Stop(); } @@ -382,10 +392,8 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail) DEBUG_LOG(DSPHLE, "Write CPU Mail: 0x%08x (pc=0x%04x)\n", uAddress, errpc); - // --------------------------------------------------------------------------------------- - // I couldn't find any better way to detect the AX mails so this had to do. Please feel free - // to change it. - // -------------- + // I couldn't find any better way to detect the AX mails so this had to + // do. Please feel free to change it. if ((errpc == 0x0054 || errpc == 0x0055) && m_addressPBs == 0) { DEBUG_LOG(DSPHLE, "AXTask ======== 0x%08x (pc=0x%04x)", uAddress, errpc); @@ -401,10 +409,6 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail) void DSP_Update(int cycles) { - if (g_hDSPThread) - { - return; - } #ifdef _WIN32 if (g_Dialog.CanDoStep()) {