Made the MFC port use the new sound framework. Win32 devs, please check.

This commit is contained in:
bgk 2008-12-26 17:55:22 +00:00
parent 9ab357571a
commit a970f93727
7 changed files with 66 additions and 61 deletions

View File

@ -61,6 +61,8 @@ public:
* Return the size in bytes of the core sound buffer. * Return the size in bytes of the core sound buffer.
*/ */
virtual int getBufferLength() = 0; virtual int getBufferLength() = 0;
virtual void setThrottle(unsigned short throttle) { };
}; };
#endif // __VBA_SOUND_DRIVER_H__ #endif // __VBA_SOUND_DRIVER_H__

View File

@ -16,7 +16,7 @@
extern bool soundBufferLow; extern bool soundBufferLow;
class DirectSound : public ISound class DirectSound : public SoundDriver
{ {
private: private:
LPDIRECTSOUND8 pDirectSound; // DirectSound interface LPDIRECTSOUND8 pDirectSound; // DirectSound interface
@ -25,6 +25,7 @@ private:
LPDIRECTSOUNDNOTIFY8 dsbNotify; LPDIRECTSOUNDNOTIFY8 dsbNotify;
HANDLE dsbEvent; HANDLE dsbEvent;
WAVEFORMATEX wfx; // Primary buffer wave format WAVEFORMATEX wfx; // Primary buffer wave format
int soundBufferLen;
int soundBufferTotalLen; int soundBufferTotalLen;
unsigned int soundNextPosition; unsigned int soundNextPosition;
@ -32,11 +33,12 @@ public:
DirectSound(); DirectSound();
virtual ~DirectSound(); virtual ~DirectSound();
bool init(); // initialize the primary and secondary sound buffer bool init(int quality); // initialize the primary and secondary sound buffer
void pause(); // pause the secondary sound buffer void pause(); // pause the secondary sound buffer
void reset(); // stop and reset the secondary sound buffer void reset(); // stop and reset the secondary sound buffer
void resume(); // resume the secondary sound buffer void resume(); // resume the secondary sound buffer
void write(); // write the emulated sound to the secondary sound buffer void write(const u16 * finalWave, int length); // write the emulated sound to the secondary sound buffer
virtual int getBufferLength();
}; };
@ -82,7 +84,7 @@ DirectSound::~DirectSound()
} }
bool DirectSound::init() bool DirectSound::init(int quality)
{ {
HRESULT hr; HRESULT hr;
DWORD freq; DWORD freq;
@ -120,7 +122,7 @@ bool DirectSound::init()
return false; return false;
} }
freq = 44100 / soundQuality; freq = 44100 / quality;
// calculate the number of samples per frame first // calculate the number of samples per frame first
// then multiply it with the size of a sample frame (16 bit * stereo) // then multiply it with the size of a sample frame (16 bit * stereo)
soundBufferLen = ( freq / 60 ) * 4; soundBufferLen = ( freq / 60 ) * 4;
@ -221,7 +223,7 @@ void DirectSound::resume()
} }
void DirectSound::write() void DirectSound::write(const u16 * finalWave, int length)
{ {
if(!pDirectSound) return; if(!pDirectSound) return;
@ -291,9 +293,9 @@ void DirectSound::write()
if( SUCCEEDED( hr ) ) { if( SUCCEEDED( hr ) ) {
// Write to pointers. // Write to pointers.
CopyMemory( lpvPtr1, soundFinalWave, dwBytes1 ); CopyMemory( lpvPtr1, finalWave, dwBytes1 );
if ( lpvPtr2 ) { if ( lpvPtr2 ) {
CopyMemory( lpvPtr2, soundFinalWave + dwBytes1, dwBytes2 ); CopyMemory( lpvPtr2, finalWave + dwBytes1, dwBytes2 );
} }
// Release the data back to DirectSound. // Release the data back to DirectSound.
@ -304,8 +306,12 @@ void DirectSound::write()
} }
} }
int DirectSound::getBufferLength()
{
return soundBufferLen;
}
ISound *newDirectSound() SoundDriver *newDirectSound()
{ {
return new DirectSound(); return new DirectSound();
} }

View File

@ -7,7 +7,7 @@
#ifndef NO_OAL #ifndef NO_OAL
// Interface // Interface
#include "Sound.h" #include "../common/SoundDriver.h"
// OpenAL // OpenAL
#include <al.h> #include <al.h>
@ -31,17 +31,18 @@
#define debugState() // #define debugState() //
#endif #endif
class OpenAL : public ISound class OpenAL : public SoundDriver
{ {
public: public:
OpenAL(); OpenAL();
virtual ~OpenAL(); virtual ~OpenAL();
bool init(); // initialize the sound buffer queue bool init(int quality); // initialize the sound buffer queue
void pause(); // pause the secondary sound buffer void pause(); // pause the secondary sound buffer
void reset(); // stop and reset the secondary sound buffer void reset(); // stop and reset the secondary sound buffer
void resume(); // play/resume the secondary sound buffer void resume(); // play/resume the secondary sound buffer
void write(); // write the emulated sound to a sound buffer void write(const u16 * finalWave, int length); // write the emulated sound to a sound buffer
virtual int getBufferLength();
private: private:
OPENALFNTABLE ALFunction; OPENALFNTABLE ALFunction;
@ -53,6 +54,7 @@ private:
ALuint tempBuffer; ALuint tempBuffer;
ALuint source; ALuint source;
int freq; int freq;
int soundBufferLen;
#ifdef LOGALL #ifdef LOGALL
void debugState(); void debugState();
@ -143,7 +145,7 @@ void OpenAL::debugState()
#endif #endif
bool OpenAL::init() bool OpenAL::init(int quality)
{ {
winlog( "OpenAL::init\n" ); winlog( "OpenAL::init\n" );
assert( initialized == false ); assert( initialized == false );
@ -172,7 +174,7 @@ bool OpenAL::init()
ALFunction.alGenSources( 1, &source ); ALFunction.alGenSources( 1, &source );
ASSERT_SUCCESS; ASSERT_SUCCESS;
freq = 44100 / soundQuality; freq = 44100 / quality;
// calculate the number of samples per frame first // calculate the number of samples per frame first
// then multiply it with the size of a sample frame (16 bit * stereo) // then multiply it with the size of a sample frame (16 bit * stereo)
@ -240,7 +242,7 @@ void OpenAL::reset()
} }
void OpenAL::write() void OpenAL::write(const u16 * finalWave, int length)
{ {
if( !initialized ) return; if( !initialized ) return;
winlog( "OpenAL::write\n" ); winlog( "OpenAL::write\n" );
@ -256,7 +258,7 @@ void OpenAL::write()
for( int i = 0 ; i < theApp.oalBufferCount ; i++ ) { for( int i = 0 ; i < theApp.oalBufferCount ; i++ ) {
// Filling the buffers explicitly with silence would be cleaner, // Filling the buffers explicitly with silence would be cleaner,
// but the very first sample is usually silence anyway. // but the very first sample is usually silence anyway.
ALFunction.alBufferData( buffer[i], AL_FORMAT_STEREO16, soundFinalWave, soundBufferLen, freq ); ALFunction.alBufferData( buffer[i], AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq );
ASSERT_SUCCESS; ASSERT_SUCCESS;
} }
@ -302,7 +304,7 @@ void OpenAL::write()
ASSERT_SUCCESS; ASSERT_SUCCESS;
// refill buffer // refill buffer
ALFunction.alBufferData( tempBuffer, AL_FORMAT_STEREO16, soundFinalWave, soundBufferLen, freq ); ALFunction.alBufferData( tempBuffer, AL_FORMAT_STEREO16, finalWave, soundBufferLen, freq );
ASSERT_SUCCESS; ASSERT_SUCCESS;
// requeue buffer // requeue buffer
@ -319,8 +321,12 @@ void OpenAL::write()
} }
} }
int OpenAL::getBufferLength()
{
return soundBufferLen;
}
ISound *newOpenAL() SoundDriver *newOpenAL()
{ {
winlog( "newOpenAL\n" ); winlog( "newOpenAL\n" );
return new OpenAL(); return new OpenAL();

View File

@ -1,25 +0,0 @@
#pragma once
enum AUDIO_API {
DIRECTSOUND = 0
#ifndef NO_OAL
, OPENAL_SOUND = 1
#endif
#ifndef NO_XAUDIO2
, XAUDIO2 = 2
#endif
};
class ISound
{
public:
virtual ~ISound() {};
virtual bool init() = 0;
virtual void pause() = 0;
virtual void reset() = 0;
virtual void resume() = 0;
virtual void write() = 0;
virtual void setThrottle( unsigned short throttle ) {};
};

View File

@ -85,12 +85,12 @@ extern IDisplay *newDirect3DDisplay();
extern Input *newDirectInput(); extern Input *newDirectInput();
extern ISound *newDirectSound(); extern SoundDriver *newDirectSound();
#ifndef NO_OAL #ifndef NO_OAL
extern ISound *newOpenAL(); extern SoundDriver *newOpenAL();
#endif #endif
#ifndef NO_XAUDIO2 #ifndef NO_XAUDIO2
extern ISound *newXAudio2_Output(); extern SoundDriver *newXAudio2_Output();
#endif #endif
extern void remoteStubSignal(int, int); extern void remoteStubSignal(int, int);
@ -1256,7 +1256,8 @@ bool systemSoundInit()
#endif #endif
} }
bool retVal = theApp.sound->init(); bool retVal = theApp.sound->init(soundQuality);
soundBufferLen = theApp.sound->getBufferLength();
if( retVal ) { if( retVal ) {
theApp.sound->setThrottle( theApp.throttle ); theApp.sound->setThrottle( theApp.throttle );
@ -1342,7 +1343,7 @@ void systemWriteDataToSoundBuffer()
} }
if( theApp.sound ) { if( theApp.sound ) {
theApp.sound->write(); theApp.sound->write(soundFinalWave, soundBufferLen);
} }
} }

View File

@ -11,7 +11,7 @@
#include "Display.h" #include "Display.h"
#include "Input.h" #include "Input.h"
#include "IUpdate.h" #include "IUpdate.h"
#include "Sound.h" #include "../common/SoundDriver.h"
#include "../System.h" #include "../System.h"
#include "../Util.h" #include "../Util.h"
@ -40,6 +40,16 @@ enum pixelFilterType
FILTER_SIMPLE4X, FILTER_HQ4X FILTER_SIMPLE4X, FILTER_HQ4X
}; };
enum AUDIO_API {
DIRECTSOUND = 0
#ifndef NO_OAL
, OPENAL_SOUND = 1
#endif
#ifndef NO_XAUDIO2
, XAUDIO2 = 2
#endif
};
#define REWIND_SIZE 400000 #define REWIND_SIZE 400000
#define DEFAULT_BATTERY_DIR ".\\battery" #define DEFAULT_BATTERY_DIR ".\\battery"
@ -160,7 +170,7 @@ class VBA : public CWinApp
WavWriter *soundRecorder; WavWriter *soundRecorder;
CString soundRecordName; CString soundRecordName;
bool dsoundDisableHardwareAcceleration; bool dsoundDisableHardwareAcceleration;
ISound *sound; SoundDriver *sound;
bool aviRecording; bool aviRecording;
AVIWrite *aviRecorder; AVIWrite *aviRecorder;
CString aviRecordName; CString aviRecordName;

View File

@ -4,13 +4,12 @@
#include "stdafx.h" #include "stdafx.h"
// Interface // Interface
#include "Sound.h" #include "../common/SoundDriver.h"
// XAudio2 // XAudio2
#include <xaudio2.h> #include <xaudio2.h>
// Internals // Internals
#include "../Sound.h" // for soundBufferLen, soundFinalWave and soundQuality
#include "../System.h" // for systemMessage() #include "../System.h" // for systemMessage()
#include "../Globals.h" #include "../Globals.h"
@ -50,17 +49,17 @@ public:
// Class Declaration // Class Declaration
class XAudio2_Output class XAudio2_Output
: public ISound : public SoundDriver
{ {
public: public:
XAudio2_Output(); XAudio2_Output();
~XAudio2_Output(); ~XAudio2_Output();
// Initialization // Initialization
bool init(); bool init(int quality);
// Sound Data Feed // Sound Data Feed
void write(); void write(const u16 * finalWave, int length);
// Play Control // Play Control
void pause(); void pause();
@ -70,6 +69,7 @@ public:
// Configuration Changes // Configuration Changes
void setThrottle( unsigned short throttle ); void setThrottle( unsigned short throttle );
virtual int getBufferLength();
private: private:
bool failed; bool failed;
@ -79,6 +79,7 @@ private:
UINT32 bufferCount; UINT32 bufferCount;
BYTE *buffers; BYTE *buffers;
int currentBuffer; int currentBuffer;
int soundBufferLen;
IXAudio2 *xaud; IXAudio2 *xaud;
IXAudio2MasteringVoice *mVoice; // listener IXAudio2MasteringVoice *mVoice; // listener
@ -136,7 +137,7 @@ XAudio2_Output::~XAudio2_Output()
} }
bool XAudio2_Output::init() bool XAudio2_Output::init(int quality)
{ {
if( failed || initialized ) return false; if( failed || initialized ) return false;
@ -156,7 +157,7 @@ bool XAudio2_Output::init()
} }
freq = 44100 / (UINT32)soundQuality; freq = 44100 / (UINT32)quality;
// calculate the number of samples per frame first // calculate the number of samples per frame first
// then multiply it with the size of a sample frame (16 bit * stereo) // then multiply it with the size of a sample frame (16 bit * stereo)
@ -279,7 +280,7 @@ bool XAudio2_Output::init()
} }
void XAudio2_Output::write() void XAudio2_Output::write(const u16 * finalWave, int length)
{ {
if( !initialized || failed ) return; if( !initialized || failed ) return;
@ -311,7 +312,7 @@ void XAudio2_Output::write()
} }
// copy & protect the audio data in own memory area while playing it // copy & protect the audio data in own memory area while playing it
CopyMemory( &buffers[ currentBuffer * soundBufferLen ], soundFinalWave, soundBufferLen ); CopyMemory( &buffers[ currentBuffer * soundBufferLen ], finalWave, soundBufferLen );
buf.AudioBytes = soundBufferLen; buf.AudioBytes = soundBufferLen;
buf.pAudioData = &buffers[ currentBuffer * soundBufferLen ]; buf.pAudioData = &buffers[ currentBuffer * soundBufferLen ];
@ -372,8 +373,12 @@ void XAudio2_Output::setThrottle( unsigned short throttle )
ASSERT( hr == S_OK ); ASSERT( hr == S_OK );
} }
int XAudio2_Output::getBufferLength()
{
return soundBufferLen;
}
ISound *newXAudio2_Output() SoundDriver *newXAudio2_Output()
{ {
return new XAudio2_Output(); return new XAudio2_Output();
} }