ADDED sound output using Microsoft's new XAudio2 API
This commit is contained in:
parent
8359ac8351
commit
8c9a679eca
|
@ -901,6 +901,10 @@
|
||||||
RelativePath=".\src\win32\OpenGL.cpp"
|
RelativePath=".\src\win32\OpenGL.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\win32\XAudio2.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Linking"
|
Name="Linking"
|
||||||
|
@ -1438,36 +1442,44 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Res"
|
Name="Resources"
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
>
|
>
|
||||||
<File
|
|
||||||
RelativePath=".\res\DevInfo.txt"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\gpl.txt"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Known Bugs.txt"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\ReadMe.txt"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\win32\resource.h"
|
RelativePath=".\src\win32\resource.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\win32\VBA-M.ico"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\win32\VBA.rc"
|
RelativePath=".\src\win32\VBA.rc"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Documentation"
|
||||||
|
>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\win32\vba.rc2"
|
RelativePath=".\doc\authors.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\doc\DevInfo.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\doc\Known Bugs.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\doc\ReadMe.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\doc\todo.txt"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
|
|
@ -15,6 +15,7 @@ Known preprocessor switches:
|
||||||
- NO_OGL: Exclude OpenGL code
|
- NO_OGL: Exclude OpenGL code
|
||||||
- NO_D3D: Exclude Direct3D code
|
- NO_D3D: Exclude Direct3D code
|
||||||
- NO_OAL: Exclude OpenAL code
|
- NO_OAL: Exclude OpenAL code
|
||||||
|
- NO_XAUDIO2: Exclude XAudio2 code (supersedes DirectSound)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ Known Bugs:
|
||||||
- Audio core: assertation error occurs when disabling GB sound
|
- Audio core: assertation error occurs when disabling GB sound
|
||||||
- I think its best we mute sound instead, since some games rely on audio for timing.
|
- I think its best we mute sound instead, since some games rely on audio for timing.
|
||||||
Plus, blargg's GB_Snd_Emu is extremely optimized stuff. (Mudlord)
|
Plus, blargg's GB_Snd_Emu is extremely optimized stuff. (Mudlord)
|
||||||
- x64: Needs optimizations (x64 native code, whatever)
|
|
||||||
- Wrong bit depth image is displayed for 2 frames when switching from/to HQ3x/4x ASM
|
- Wrong bit depth image is displayed for 2 frames when switching from/to HQ3x/4x ASM
|
||||||
- This is caused by the 16bit hack which does not re-process the emulated image.
|
- This is caused by the 16bit hack which does not re-process the emulated image.
|
||||||
It results in the display devices treating the image at pix with the wrong bit depth.
|
It results in the display devices treating the image at pix with the wrong bit depth.
|
|
@ -434,6 +434,9 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
|
||||||
ON_WM_WINDOWPOSCHANGING()
|
ON_WM_WINDOWPOSCHANGING()
|
||||||
ON_COMMAND(ID_EMULATOR_BIOSFILES, &MainWnd::OnEmulatorBiosfiles)
|
ON_COMMAND(ID_EMULATOR_BIOSFILES, &MainWnd::OnEmulatorBiosfiles)
|
||||||
ON_COMMAND(ID_FILE_OPEN_GBC, &MainWnd::OnFileOpenGbc)
|
ON_COMMAND(ID_FILE_OPEN_GBC, &MainWnd::OnFileOpenGbc)
|
||||||
|
ON_WM_NCRBUTTONDOWN()
|
||||||
|
ON_COMMAND(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnOutputapiXaudio2)
|
||||||
|
ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_XAUDIO2, &MainWnd::OnUpdateOutputapiXaudio2)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1303,3 +1306,13 @@ void MainWnd::OnWindowPosChanging(WINDOWPOS* lpwndpos)
|
||||||
soundPause();
|
soundPause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWnd::OnNcRButtonDown(UINT nHitTest, CPoint point)
|
||||||
|
{
|
||||||
|
// pause sound before process is halted
|
||||||
|
if( emulating ) {
|
||||||
|
soundPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
CWnd::OnNcRButtonDown(nHitTest, point);
|
||||||
|
}
|
||||||
|
|
|
@ -422,6 +422,9 @@ public:
|
||||||
afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
|
afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
|
||||||
afx_msg void OnEmulatorBiosfiles();
|
afx_msg void OnEmulatorBiosfiles();
|
||||||
afx_msg void OnFileOpenGbc();
|
afx_msg void OnFileOpenGbc();
|
||||||
|
afx_msg void OnNcRButtonDown(UINT nHitTest, CPoint point);
|
||||||
|
afx_msg void OnOutputapiXaudio2();
|
||||||
|
afx_msg void OnUpdateOutputapiXaudio2(CCmdUI *pCmdUI);
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1740,6 +1740,27 @@ void MainWnd::OnUpdateOutputapiDirectsound(CCmdUI *pCmdUI)
|
||||||
pCmdUI->Enable(!theApp.aviRecording && !theApp.soundRecording);
|
pCmdUI->Enable(!theApp.aviRecording && !theApp.soundRecording);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWnd::OnOutputapiXaudio2()
|
||||||
|
{
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
if( theApp.audioAPI != XAUDIO2 ) {
|
||||||
|
theApp.audioAPI = XAUDIO2;
|
||||||
|
systemSoundShutdown();
|
||||||
|
systemSoundInit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWnd::OnUpdateOutputapiXaudio2(CCmdUI *pCmdUI)
|
||||||
|
{
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
pCmdUI->SetCheck( ( theApp.audioAPI == XAUDIO2 ) ? 1 : 0 );
|
||||||
|
pCmdUI->Enable(!theApp.aviRecording && !theApp.soundRecording);
|
||||||
|
#else
|
||||||
|
pCmdUI->Enable( FALSE );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void MainWnd::OnOutputapiOpenal()
|
void MainWnd::OnOutputapiOpenal()
|
||||||
{
|
{
|
||||||
#ifndef NO_OAL
|
#ifndef NO_OAL
|
||||||
|
|
|
@ -21,9 +21,12 @@
|
||||||
#define VBA_WIN32_SOUND_H
|
#define VBA_WIN32_SOUND_H
|
||||||
|
|
||||||
enum AUDIO_API {
|
enum AUDIO_API {
|
||||||
DIRECTSOUND
|
DIRECTSOUND = 0
|
||||||
#ifndef NO_OAL
|
#ifndef NO_OAL
|
||||||
, OPENAL_SOUND
|
, OPENAL_SOUND = 1
|
||||||
|
#endif
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
, XAUDIO2 = 2
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,6 +40,8 @@ class ISound
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
virtual void resume() = 0;
|
virtual void resume() = 0;
|
||||||
virtual void write() = 0;
|
virtual void write() = 0;
|
||||||
|
|
||||||
|
virtual void setThrottle( unsigned short throttle ) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -111,6 +111,9 @@ extern ISound *newDirectSound();
|
||||||
#ifndef NO_OAL
|
#ifndef NO_OAL
|
||||||
extern ISound *newOpenAL();
|
extern ISound *newOpenAL();
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
extern ISound *newXAudio2_Output();
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void remoteStubSignal(int, int);
|
extern void remoteStubSignal(int, int);
|
||||||
extern void remoteOutput(char *, u32);
|
extern void remoteOutput(char *, u32);
|
||||||
|
@ -902,7 +905,6 @@ void VBA::updateThrottle( unsigned short throttle )
|
||||||
|
|
||||||
if( throttle == 0 ) {
|
if( throttle == 0 ) {
|
||||||
autoFrameSkip = false;
|
autoFrameSkip = false;
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
Sm60FPS::K_fCpuSpeed = (float)throttle;
|
Sm60FPS::K_fCpuSpeed = (float)throttle;
|
||||||
Sm60FPS::K_fTargetFps = 60.0f * Sm60FPS::K_fCpuSpeed / 100;
|
Sm60FPS::K_fTargetFps = 60.0f * Sm60FPS::K_fCpuSpeed / 100;
|
||||||
|
@ -910,7 +912,10 @@ void VBA::updateThrottle( unsigned short throttle )
|
||||||
autoFrameSkip = true;
|
autoFrameSkip = true;
|
||||||
frameSkip = 0;
|
frameSkip = 0;
|
||||||
systemFrameSkip = 0;
|
systemFrameSkip = 0;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
if( theApp.sound ) {
|
||||||
|
theApp.sound->setThrottle( throttle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,10 +1202,21 @@ bool systemSoundInit()
|
||||||
case OPENAL_SOUND:
|
case OPENAL_SOUND:
|
||||||
theApp.sound = newOpenAL();
|
theApp.sound = newOpenAL();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
case XAUDIO2:
|
||||||
|
theApp.sound = newXAudio2_Output();
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return theApp.sound->init();
|
bool retVal = theApp.sound->init();
|
||||||
|
|
||||||
|
if( retVal ) {
|
||||||
|
theApp.sound->setThrottle( theApp.throttle );
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1448,6 +1464,9 @@ void VBA::loadSettings()
|
||||||
if( ( audioAPI != DIRECTSOUND )
|
if( ( audioAPI != DIRECTSOUND )
|
||||||
#ifndef NO_OAL
|
#ifndef NO_OAL
|
||||||
&& ( audioAPI != OPENAL_SOUND )
|
&& ( audioAPI != OPENAL_SOUND )
|
||||||
|
#endif
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
&& ( audioAPI != XAUDIO2 )
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
audioAPI = DIRECTSOUND;
|
audioAPI = DIRECTSOUND;
|
||||||
|
|
|
@ -9,39 +9,10 @@
|
||||||
//
|
//
|
||||||
#include "afxres.h"
|
#include "afxres.h"
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// German (Germany) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // German (Germany) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// English (U.S.) resources
|
// English (U.S.) resources
|
||||||
|
@ -1698,6 +1669,8 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "DirectSound", ID_OUTPUTAPI_DIRECTSOUND
|
MENUITEM "DirectSound", ID_OUTPUTAPI_DIRECTSOUND
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
|
MENUITEM "XAudio2", ID_OUTPUTAPI_XAUDIO2
|
||||||
|
MENUITEM SEPARATOR
|
||||||
MENUITEM "OpenAL", ID_OUTPUTAPI_OPENAL
|
MENUITEM "OpenAL", ID_OUTPUTAPI_OPENAL
|
||||||
MENUITEM " Configuration...", ID_OUTPUTAPI_OALCONFIGURATION
|
MENUITEM " Configuration...", ID_OUTPUTAPI_OALCONFIGURATION
|
||||||
MENUITEM SEPARATOR
|
MENUITEM SEPARATOR
|
||||||
|
@ -2219,6 +2192,12 @@ BEGIN
|
||||||
IDS_AVI_CANNOT_WRITE_VIDEO "Cannot write video frame to AVI file."
|
IDS_AVI_CANNOT_WRITE_VIDEO "Cannot write video frame to AVI file."
|
||||||
IDS_AVI_CANNOT_WRITE_AUDIO "Cannot write audio frame to AVI file."
|
IDS_AVI_CANNOT_WRITE_AUDIO "Cannot write audio frame to AVI file."
|
||||||
IDS_FILTER_GBCROM "Game Boy Color ROMs_*.GBC;*.CGB;*.ZIP;*.7Z;*.Z;*.GZ__"
|
IDS_FILTER_GBCROM "Game Boy Color ROMs_*.GBC;*.CGB;*.ZIP;*.7Z;*.Z;*.GZ__"
|
||||||
|
IDS_COM_FAILURE "The COM (Component Object Model) failed to initialize!"
|
||||||
|
IDS_XAUDIO2_FAILURE "The XAudio2 interface failed to initialize!"
|
||||||
|
IDS_XAUDIO2_CANNOT_CREATE_MASTERINGVOICE
|
||||||
|
"XAudio2: Creating mastering voice failed!"
|
||||||
|
IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE
|
||||||
|
"XAudio2: Creating source voice failed!"
|
||||||
END
|
END
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
#endif // English (U.S.) resources
|
||||||
|
@ -2242,7 +2221,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
2 TEXTINCLUDE
|
||||||
BEGIN
|
BEGIN
|
||||||
"#include ""afxres.h""\r\0"
|
"#include ""afxres.h""\r\r\0"
|
||||||
END
|
END
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
@ -2251,12 +2230,3 @@ END
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,295 @@
|
||||||
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
// Copyright (C) 2005-2006 VBA development team
|
||||||
|
// Copyright (C) 2007-2008 VBA-M development team
|
||||||
|
|
||||||
|
// 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; either version 2, or(at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// 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 for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_XAUDIO2
|
||||||
|
|
||||||
|
|
||||||
|
#define NBUFFERS 4
|
||||||
|
|
||||||
|
// MFC
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
// Interface
|
||||||
|
#include "Sound.h"
|
||||||
|
|
||||||
|
// XAudio2
|
||||||
|
#include <Xaudio2.h>
|
||||||
|
|
||||||
|
// Internals
|
||||||
|
#include "../Sound.h" // for soundBufferLen, soundFinalWave and soundQuality
|
||||||
|
#include "../System.h" // for systemMessage()
|
||||||
|
#include "../Globals.h" // for 'speedup' and 'synchronize'
|
||||||
|
|
||||||
|
|
||||||
|
// Class Declaration
|
||||||
|
class XAudio2_Output
|
||||||
|
: public ISound
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XAudio2_Output();
|
||||||
|
~XAudio2_Output();
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
// Sound Data Feed
|
||||||
|
void write();
|
||||||
|
|
||||||
|
// Play Control
|
||||||
|
void pause();
|
||||||
|
void resume();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
// Configuration Changes
|
||||||
|
void setThrottle( unsigned short throttle );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool failed;
|
||||||
|
bool initialized;
|
||||||
|
bool playing;
|
||||||
|
UINT32 freq;
|
||||||
|
BYTE *buffers;
|
||||||
|
int currentBuffer;
|
||||||
|
|
||||||
|
IXAudio2 *xaud;
|
||||||
|
IXAudio2MasteringVoice *mVoice; // dest
|
||||||
|
IXAudio2SourceVoice *sVoice; // source
|
||||||
|
XAUDIO2_BUFFER buf;
|
||||||
|
XAUDIO2_VOICE_STATE vState;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Class Implementation
|
||||||
|
XAudio2_Output::XAudio2_Output()
|
||||||
|
{
|
||||||
|
failed = false;
|
||||||
|
initialized = false;
|
||||||
|
playing = false;
|
||||||
|
freq = 0;
|
||||||
|
buffers = 0;
|
||||||
|
currentBuffer = 0;
|
||||||
|
|
||||||
|
xaud = NULL;
|
||||||
|
mVoice = NULL;
|
||||||
|
sVoice = NULL;
|
||||||
|
ZeroMemory( &buf, sizeof( buf ) );
|
||||||
|
ZeroMemory( &vState, sizeof( vState ) );
|
||||||
|
|
||||||
|
if( S_OK != CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) {
|
||||||
|
systemMessage( IDS_COM_FAILURE, NULL );
|
||||||
|
failed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XAudio2_Output::~XAudio2_Output()
|
||||||
|
{
|
||||||
|
initialized = false;
|
||||||
|
|
||||||
|
if( sVoice ) {
|
||||||
|
if( playing ) {
|
||||||
|
sVoice->Stop( 0 );
|
||||||
|
}
|
||||||
|
sVoice->DestroyVoice();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( buffers ) {
|
||||||
|
free( buffers );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mVoice ) {
|
||||||
|
mVoice->DestroyVoice();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xaud ) {
|
||||||
|
xaud->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool XAudio2_Output::init()
|
||||||
|
{
|
||||||
|
if( failed || initialized ) return false;
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
UINT32 flags = 0;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
flags |= XAUDIO2_DEBUG_ENGINE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hr = XAudio2Create( &xaud, flags );
|
||||||
|
|
||||||
|
if( FAILED( hr ) ) {
|
||||||
|
systemMessage( IDS_XAUDIO2_FAILURE, NULL );
|
||||||
|
failed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
freq = 44100 / (UINT32)soundQuality;
|
||||||
|
|
||||||
|
// calculate the number of samples per frame first
|
||||||
|
// then multiply it with the size of a sample frame (16 bit * stereo)
|
||||||
|
soundBufferLen = ( freq / 60 ) * 4;
|
||||||
|
|
||||||
|
// create own buffers because sound data must not be manipulated
|
||||||
|
// by the audio emulation core while it is still being played back
|
||||||
|
buffers = (BYTE *)malloc( ( NBUFFERS + 1 ) * soundBufferLen );
|
||||||
|
// + 1 because we need one temporary buffer when all others are still playing
|
||||||
|
|
||||||
|
WAVEFORMATEX wfx;
|
||||||
|
ZeroMemory( &wfx, sizeof( wfx ) );
|
||||||
|
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
wfx.nChannels = 2;
|
||||||
|
wfx.nSamplesPerSec = freq;
|
||||||
|
wfx.wBitsPerSample = 16;
|
||||||
|
wfx.nBlockAlign = wfx.nChannels * ( wfx.wBitsPerSample / 8 );
|
||||||
|
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||||
|
|
||||||
|
|
||||||
|
// Create Sound Receiver
|
||||||
|
hr = xaud->CreateMasteringVoice( &mVoice, 2, freq );
|
||||||
|
|
||||||
|
if( FAILED( hr ) ) {
|
||||||
|
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_MASTERINGVOICE, NULL );
|
||||||
|
failed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create Sound Emitter
|
||||||
|
hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, XAUDIO2_MAX_FREQ_RATIO );
|
||||||
|
|
||||||
|
if( FAILED( hr ) ) {
|
||||||
|
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE, NULL );
|
||||||
|
failed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sVoice->Start( 0 );
|
||||||
|
playing = true;
|
||||||
|
|
||||||
|
|
||||||
|
setsystemSoundOn( true );
|
||||||
|
initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XAudio2_Output::write()
|
||||||
|
{
|
||||||
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
|
bool drop = false;
|
||||||
|
|
||||||
|
// copy & protect the audio data in own memory area while playing it
|
||||||
|
CopyMemory( &buffers[ currentBuffer * soundBufferLen ], soundFinalWave, soundBufferLen );
|
||||||
|
|
||||||
|
buf.AudioBytes = soundBufferLen;
|
||||||
|
buf.pAudioData = &buffers[ currentBuffer * soundBufferLen ];
|
||||||
|
|
||||||
|
currentBuffer++;
|
||||||
|
currentBuffer %= ( NBUFFERS + 1 );
|
||||||
|
|
||||||
|
while( true ) {
|
||||||
|
sVoice->GetState( &vState );
|
||||||
|
ASSERT( vState.BuffersQueued <= NBUFFERS );
|
||||||
|
|
||||||
|
if( vState.BuffersQueued == NBUFFERS ) {
|
||||||
|
// all buffers filled
|
||||||
|
if( speedup || !synchronize || theApp.throttle ) {
|
||||||
|
drop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( synchronize ) {
|
||||||
|
// wait for about half the time one buffer needs to finish
|
||||||
|
// unoptimized: ( sourceBufferLen * 1000 ) / ( freq * 2 * 2 ) * 1/2
|
||||||
|
Sleep( soundBufferLen / ( freq >> 7 ) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// still room for new audio
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !drop ) {
|
||||||
|
// add the sound buffer to the queue
|
||||||
|
sVoice->SubmitSourceBuffer( &buf );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XAudio2_Output::pause()
|
||||||
|
{
|
||||||
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
|
if( playing ) {
|
||||||
|
sVoice->Stop( 0 );
|
||||||
|
playing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XAudio2_Output::resume()
|
||||||
|
{
|
||||||
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
|
if( !playing ) {
|
||||||
|
sVoice->Start( 0 );
|
||||||
|
playing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XAudio2_Output::reset()
|
||||||
|
{
|
||||||
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
|
if( playing ) {
|
||||||
|
sVoice->Stop( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
sVoice->FlushSourceBuffers();
|
||||||
|
sVoice->Start( 0 );
|
||||||
|
playing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XAudio2_Output::setThrottle( unsigned short throttle )
|
||||||
|
{
|
||||||
|
if( throttle == 0 ) throttle = 100;
|
||||||
|
sVoice->SetFrequencyRatio( (float)throttle / 100.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISound *newXAudio2_Output()
|
||||||
|
{
|
||||||
|
return new XAudio2_Output();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #ifndef NO_XAUDIO2
|
|
@ -538,6 +538,10 @@
|
||||||
#define IDS_AVI_CANNOT_WRITE_VIDEO 2005
|
#define IDS_AVI_CANNOT_WRITE_VIDEO 2005
|
||||||
#define IDS_AVI_CANNOT_WRITE_AUDIO 2006
|
#define IDS_AVI_CANNOT_WRITE_AUDIO 2006
|
||||||
#define IDS_FILTER_GBCROM 2007
|
#define IDS_FILTER_GBCROM 2007
|
||||||
|
#define IDS_COM_FAILURE 2008
|
||||||
|
#define IDS_XAUDIO2_FAILURE 2009
|
||||||
|
#define IDS_XAUDIO2_CANNOT_CREATE_MASTERINGVOICE 2010
|
||||||
|
#define IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE 2011
|
||||||
#define ID_HELP_ABOUT 40001
|
#define ID_HELP_ABOUT 40001
|
||||||
#define ID_FILE_EXIT 40002
|
#define ID_FILE_EXIT 40002
|
||||||
#define ID_OPTIONS_VIDEO_FRAMESKIP_0 40003
|
#define ID_OPTIONS_VIDEO_FRAMESKIP_0 40003
|
||||||
|
@ -845,13 +849,14 @@
|
||||||
#define ID_EMULATOR_BIOSFILES 40356
|
#define ID_EMULATOR_BIOSFILES 40356
|
||||||
#define ID_FILE_OPENGBC 40357
|
#define ID_FILE_OPENGBC 40357
|
||||||
#define ID_FILE_OPEN_GBC 40358
|
#define ID_FILE_OPEN_GBC 40358
|
||||||
|
#define ID_OUTPUTAPI_XAUDIO2 40359
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 163
|
#define _APS_NEXT_RESOURCE_VALUE 163
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40359
|
#define _APS_NEXT_COMMAND_VALUE 40360
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1284
|
#define _APS_NEXT_CONTROL_VALUE 1284
|
||||||
#define _APS_NEXT_SYMED_VALUE 103
|
#define _APS_NEXT_SYMED_VALUE 103
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
// Target for Windows 2000 (Required by GetMenuBar and other functions)
|
// Target for Windows 2000 (Required by GetMenuBar and other functions)
|
||||||
#define NTDDI_VERSION NTDDI_WIN2K // new
|
#define NTDDI_VERSION NTDDI_WIN2K // new
|
||||||
#define _WIN32_WINNT 0x0500 // old
|
#define _WIN32_WINNT 0x0500 // old
|
||||||
//#define WINVER 0x0500
|
|
||||||
|
|
||||||
// Enable STRICT type checking
|
// Enable STRICT type checking
|
||||||
#define STRICT
|
#define STRICT
|
||||||
|
@ -36,3 +35,4 @@
|
||||||
#include <afxcmn.h>
|
#include <afxcmn.h>
|
||||||
#include <afxdlgs.h>
|
#include <afxdlgs.h>
|
||||||
#include "VBA.h"
|
#include "VBA.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
Loading…
Reference in New Issue