Some clean up

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2743 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
nakeee 2009-03-23 20:55:32 +00:00
parent 34c05f8e87
commit 7f66eaa694
13 changed files with 350 additions and 604 deletions

View File

@ -33,7 +33,7 @@ void AOSound::SoundLoop()
device = ao_open_live(default_driver, &format, NULL /* no options */); device = ao_open_live(default_driver, &format, NULL /* no options */);
if (!device) if (!device)
{ {
PanicAlert("DSP_HLE: Error opening AO device.\n"); PanicAlert("AudioCommon: Error opening AO device.\n");
ao_shutdown(); ao_shutdown();
Stop(); Stop();
return; return;

View File

@ -0,0 +1,11 @@
# -*- python -*-
Import('env')
files = [
'AOSoundStream.cpp',
]
env_audiocommon = env.Clone()
env_audiocommon.Append(CXXFLAGS = [ '-fPIC' ])
env_audiocommon.StaticLibrary('audiocommon', files)

View File

@ -43,7 +43,6 @@ PLUGIN_GLOBALS* globals = NULL;
DSPInitialize g_dspInitialize; DSPInitialize g_dspInitialize;
u8* g_pMemory; u8* g_pMemory;
extern std::vector<std::string> sMailLog, sMailTime; extern std::vector<std::string> sMailLog, sMailTime;
std::string gpName;
SoundStream *soundStream = NULL; SoundStream *soundStream = NULL;
@ -127,31 +126,12 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
#endif #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 // Exported fuctions
// Create debugging window - We could use use wxWindow win; new CDebugger(win) like nJoy but I don't // Create debugging window - We could use use wxWindow win; new CDebugger(win)
// know why it would be better. - There's a lockup problem with ShowModal(), but Show() doesn't work // like nJoy but I don't know why it would be better. - There's a lockup
// because then DLL_PROCESS_DETACH is called immediately after DLL_PROCESS_ATTACH. // 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) void DllDebugger(HWND _hParent, bool Show)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
@ -214,24 +194,11 @@ void DllConfig(HWND _hParent)
void Initialize(void *init) void Initialize(void *init)
{ {
//Console::Open(80, 5000);
g_dspInitialize = *(DSPInitialize*)init; g_dspInitialize = *(DSPInitialize*)init;
g_Config.Load(); g_Config.Load();
g_pMemory = g_dspInitialize.pGetMemoryPointer(0); 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(); CDSPHandler::CreateInstance();
if (g_Config.sBackend == "DSound") if (g_Config.sBackend == "DSound")
@ -254,12 +221,6 @@ void Initialize(void *init)
return; 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)
{ {
if (!soundStream->Start()) if (!soundStream->Start())
@ -328,9 +289,7 @@ void DoState(unsigned char **ptr, int mode)
} }
////////////////////////////////////////////////////////////////////////////////////////
// Mailbox fuctions // Mailbox fuctions
// ¯¯¯¯¯¯¯¯¯¯¯¯
unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox) unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox)
{ {
if (_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); PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
} }
} }
/////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// Other DSP fuctions // Other DSP fuctions
// ¯¯¯¯¯¯¯¯¯¯¯¯
unsigned short DSP_WriteControlRegister(unsigned short _Value) unsigned short DSP_WriteControlRegister(unsigned short _Value)
{ {
return CDSPHandler::GetInstance().WriteControlRegister(_Value); return CDSPHandler::GetInstance().WriteControlRegister(_Value);
@ -416,10 +372,11 @@ void DSP_Update(int cycles)
CDSPHandler::GetInstance().Update(); CDSPHandler::GetInstance().Update();
} }
/* Other Audio will pass through here. The kind of audio that sometimes are used together with pre-drawn /* Other Audio will pass through here. The kind of audio that sometimes are
movies. This audio can be disabled further inside Mixer_PushSamples(), the reason that we don't disable used together with pre-drawn movies. This audio can be disabled further
this entire function when Other Audio is disabled is that then we can't turn it back on again once the inside Mixer_PushSamples(), the reason that we don't disable this entire
game has started. */ 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) void DSP_SendAIBuffer(unsigned int address, int sample_rate)
{ {
// TODO: This is not yet fully threadsafe. // 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) if ((counter & 31) == 0 && soundStream)
soundStream->Update(); soundStream->Update();
} }
/////////////////////////////////////

View File

@ -2,7 +2,7 @@
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9.00"
Name="Plugin_DSP_LLE" Name="Plugin_DSP_LLE-testing"
ProjectGUID="{C60D0E7A-ED05-4C67-9EE7-3A6C0D7801C8}" ProjectGUID="{C60D0E7A-ED05-4C67-9EE7-3A6C0D7801C8}"
RootNamespace="Plugin_DSP_LLE" RootNamespace="Plugin_DSP_LLE"
Keyword="Win32Proj" Keyword="Win32Proj"
@ -771,14 +771,6 @@
> >
</File> </File>
</Filter> </Filter>
<File
RelativePath=".\Src\DSoundStream.cpp"
>
</File>
<File
RelativePath=".\Src\DSoundStream.h"
>
</File>
<File <File
RelativePath=".\Src\Globals.cpp" RelativePath=".\Src\Globals.cpp"
> >

View File

@ -1,126 +0,0 @@
#include <ao/ao.h>
#include <pthread.h>
#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*)&currentPos, 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();
}
}

View File

@ -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");
}

View File

@ -15,21 +15,26 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef __AOSOUNDSTREAM_H__ #ifndef _PLUGIN_DSP_HLE_CONFIG_H
#define __AOSOUNDSTREAM_H__ #define _PLUGIN_DSP_HLE_CONFIG_H
namespace AOSound #include <string>
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); extern CConfig g_Config;
void AOSound_UpdateSound();
void AOSound_StopSound();
float AOSound_GetTimer(); #endif // _PLUGIN_DSP_HLE_CONFIG_H
int AOSound_GetCurSample();
int AOSound_GetSampleRate();
}
#endif //__AOSOUNDSTREAM_H__

View File

@ -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);
}

View File

@ -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 <wx/wx.h>
#include <wx/dialog.h>
#include <wx/button.h>
#include <wx/statbox.h>
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__

View File

@ -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 <mmsystem.h>
#include <dsound.h>
#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*)&currentPos, 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)));
}
}

View File

@ -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__

View File

@ -10,10 +10,10 @@ if not env['HAVE_AO']:
Return() Return()
files = [ files = [
"AOSoundStream.cpp",
# "DisAsmDlg.cpp", # "DisAsmDlg.cpp",
"Config.cpp",
"ConfigDlg.cpp",
"disassemble.cpp", "disassemble.cpp",
# "DSoundStream.cpp",
"gdsp_aram.cpp", "gdsp_aram.cpp",
"gdsp_ext_op.cpp", "gdsp_ext_op.cpp",
"gdsp_interface.cpp", "gdsp_interface.cpp",

View File

@ -16,9 +16,6 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// =======================================================================================
// Includes
// --------------
#include "Common.h" // Common #include "Common.h" // Common
#include "WaveFile.h" #include "WaveFile.h"
#include "CommonTypes.h" #include "CommonTypes.h"
@ -28,15 +25,22 @@
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "disassemble.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 #ifdef _WIN32
#include "DisAsmDlg.h" #include "DisAsmDlg.h"
#include "DSoundStream.h"
#include "Logging/Logging.h" // For Logging #include "Logging/Logging.h" // For Logging
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
HANDLE g_hDSPThread = NULL;
CRITICAL_SECTION g_CriticalSection;
CDisAsmDlg g_Dialog; CDisAsmDlg g_Dialog;
#else #else
#define WINAPI #define WINAPI
@ -46,19 +50,16 @@
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "AOSoundStream.h" #include "AOSoundStream.h"
pthread_t g_hDSPThread = NULL;
#endif #endif
#include "ChunkFile.h" #include "ChunkFile.h"
// ==============
// =======================================================================================
// Global declarations and definitions
// --------------
PLUGIN_GLOBALS* globals = NULL; PLUGIN_GLOBALS* globals = NULL;
DSPInitialize g_dspInitialize; DSPInitialize g_dspInitialize;
SoundStream *soundStream = NULL;
#define GDSP_MBOX_CPU 0 #define GDSP_MBOX_CPU 0
#define GDSP_MBOX_DSP 1 #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. // Set this if you want to log audio. search for log_ai in this file to see the filename.
static bool log_ai = false; static bool log_ai = false;
WaveFileWriter g_wave_writer; WaveFileWriter g_wave_writer;
// ==============
#ifdef _WIN32 #ifdef _WIN32
@ -124,8 +124,24 @@ void DllAbout(HWND _hParent)
{} {}
void DllConfig(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) { void DoState(unsigned char **ptr, int mode) {
@ -138,23 +154,12 @@ void DllDebugger(HWND _hParent, bool Show)
#if defined (_DEBUG) || defined (DEBUGFAST) #if defined (_DEBUG) || defined (DEBUGFAST)
g_Dialog.Create(NULL); //_hParent); g_Dialog.Create(NULL); //_hParent);
g_Dialog.ShowWindow(SW_SHOW); 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
#endif #endif
} }
// =======================================================================================
// Regular thread // Regular thread
// --------------
#ifdef _WIN32 #ifdef _WIN32
DWORD WINAPI dsp_thread(LPVOID lpParameter) DWORD WINAPI dsp_thread(LPVOID lpParameter)
#else #else
@ -170,12 +175,8 @@ void* dsp_thread(void* lpParameter)
} }
} }
} }
// ==============
// =======================================================================================
// Debug thread // Debug thread
// --------------
#ifdef _WIN32 #ifdef _WIN32
DWORD WINAPI dsp_thread_debug(LPVOID lpParameter) DWORD WINAPI dsp_thread_debug(LPVOID lpParameter)
#else #else
@ -183,10 +184,6 @@ void* dsp_thread_debug(void* lpParameter)
#endif #endif
{ {
//if (g_hDSPThread)
//{
// return NULL; // enable this to disable the plugin
//}
#ifdef _WIN32 #ifdef _WIN32
while (1) while (1)
@ -205,7 +202,6 @@ void* dsp_thread_debug(void* lpParameter)
#endif #endif
return NULL; return NULL;
} }
// ==============
void DSP_DebugBreak() void DSP_DebugBreak()
@ -236,26 +232,21 @@ void Initialize(void *init)
if (!gdsp_load_rom((char *)DSP_ROM_FILE)) if (!gdsp_load_rom((char *)DSP_ROM_FILE))
{ {
bCanWork = false; bCanWork = false;
PanicAlert("No DSP ROM"); PanicAlert("Cannot load DSP ROM");
ERROR_LOG(DSPHLE, "Cannot load DSP ROM\n");
} }
if (!gdsp_load_coef((char *)DSP_COEF_FILE)) if (!gdsp_load_coef((char *)DSP_COEF_FILE))
{ {
bCanWork = false; bCanWork = false;
PanicAlert("No DSP COEF"); PanicAlert("Cannot load DSP COEF");
ERROR_LOG(DSPHLE, "Cannot load DSP COEF\n");
} }
if(!bCanWork) if(!bCanWork)
return; // TODO: Don't let it work return; // TODO: Don't let it work
// --------------------------------------------------------------------------------------- // First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in
// First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in Globals.h. Then // Globals.h. Then make the disassembled file here. Dump UCode to file...
// make the disassembled file here.
// --------------
// Dump UCode to file...
FILE* t = fopen("C:\\_\\DSP_UC_09CD143F.txt", "wb"); FILE* t = fopen("C:\\_\\DSP_UC_09CD143F.txt", "wb");
if (t != NULL) if (t != NULL)
@ -264,50 +255,69 @@ void Initialize(void *init)
gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t); gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t);
fclose(t); fclose(t);
} }
// --------------
#ifdef _WIN32 if (g_Config.sBackend == "DSound")
#if defined(_DEBUG) || defined(DEBUGFAST) {
g_hDSPThread = CreateThread(NULL, 0, dsp_thread_debug, 0, 0, NULL); if (DSound::isValid())
#else soundStream = new DSound(48000, Mixer, g_dspInitialize.hWnd);
g_hDSPThread = CreateThread(NULL, 0, dsp_thread, 0, 0, NULL); }
#endif // DEBUG else if (g_Config.sBackend == "AOSound")
#else {
#if _DEBUG if (AOSound::isValid())
pthread_create(&g_hDSPThread, NULL, dsp_thread_debug, (void *)NULL); soundStream = new AOSound(48000, Mixer);
#else }
pthread_create(&g_hDSPThread, NULL, dsp_thread, (void *)NULL); else if (g_Config.sBackend == "NullSound")
#endif // DEBUG {
#endif // WIN32 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) { if (log_ai) {
g_wave_writer.Start("C:\\_\\ai_log.wav"); g_wave_writer.Start("C:\\_\\ai_log.wav");
g_wave_writer.SetSkipSilence(false); 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() void DSP_StopSoundStream()
{ {
#ifdef _WIN32 if (!soundStream)
if (g_hDSPThread != NULL) PanicAlert("Can't stop non running SoundStream!");
{ soundStream->Stop();
TerminateThread(g_hDSPThread, 0); delete soundStream;
} soundStream = NULL;
#else
// Isn't pthread_cancel kind of evil?
pthread_cancel(g_hDSPThread);
#endif
} }
void Shutdown(void) void Shutdown(void)
{ {
// Check that soundstream already is stopped.
if (soundStream)
PanicAlert("SoundStream alive in DSP::Shutdown!");
// Stop the sound recording
if (log_ai) if (log_ai)
g_wave_writer.Stop(); 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); 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
// I couldn't find any better way to detect the AX mails so this had to do. Please feel free // do. Please feel free to change it.
// to change it.
// --------------
if ((errpc == 0x0054 || errpc == 0x0055) && m_addressPBs == 0) if ((errpc == 0x0054 || errpc == 0x0055) && m_addressPBs == 0)
{ {
DEBUG_LOG(DSPHLE, "AXTask ======== 0x%08x (pc=0x%04x)", uAddress, errpc); 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) void DSP_Update(int cycles)
{ {
if (g_hDSPThread)
{
return;
}
#ifdef _WIN32 #ifdef _WIN32
if (g_Dialog.CanDoStep()) if (g_Dialog.CanDoStep())
{ {