[Audio] Remove manual memory allocations

* Remove explicit calls to new or malloc in favor of owned objects.
* Move AudioSdl to the sdl frontend, it is no longer used by the wx
  frontend.
This commit is contained in:
Fabrice de Gans 2024-04-05 17:29:47 -07:00 committed by Rafael Kitover
parent 56320ec6d1
commit 64abd3e8dc
16 changed files with 175 additions and 199 deletions

View File

@ -1,4 +1,3 @@
add_subdirectory(audio_sdl)
add_subdirectory(av_recording) add_subdirectory(av_recording)
add_subdirectory(draw_text) add_subdirectory(draw_text)
add_subdirectory(filters) add_subdirectory(filters)

View File

@ -1,14 +0,0 @@
add_library(vbam-components-audio-sdl OBJECT)
target_sources(vbam-components-audio-sdl
PRIVATE audio_sdl.cpp
PUBLIC audio_sdl.h
)
target_include_directories(vbam-components-audio-sdl
PUBLIC ${SDL2_INCLUDE_DIRS}
)
target_link_libraries(vbam-components-audio-sdl
PUBLIC vbam-core-base ${VBAM_SDL2_LIBS}
)

View File

@ -2,8 +2,9 @@
#define VBAM_CORE_BASE_SYSTEM_H_ #define VBAM_CORE_BASE_SYSTEM_H_
#include <cstdint> #include <cstdint>
#include <memory>
class SoundDriver; #include "core/base/sound_driver.h"
enum IMAGE_TYPE { enum IMAGE_TYPE {
IMAGE_UNKNOWN = -1, IMAGE_UNKNOWN = -1,
@ -89,7 +90,7 @@ extern bool systemReadJoypads();
extern uint32_t systemReadJoypad(int); extern uint32_t systemReadJoypad(int);
extern uint32_t systemGetClock(); extern uint32_t systemGetClock();
extern void systemSetTitle(const char*); extern void systemSetTitle(const char*);
extern SoundDriver* systemSoundInit(); extern std::unique_ptr<SoundDriver> systemSoundInit();
extern void systemOnWriteDataToSoundBuffer(const uint16_t* finalWave, int length); extern void systemOnWriteDataToSoundBuffer(const uint16_t* finalWave, int length);
extern void systemOnSoundShutdown(); extern void systemOnSoundShutdown();
extern void systemScreenMessage(const char*); extern void systemScreenMessage(const char*);

View File

@ -34,7 +34,7 @@
#define NR51 0x81 #define NR51 0x81
#define NR52 0x84 #define NR52 0x84
SoundDriver* soundDriver = 0; std::unique_ptr<SoundDriver> soundDriver;
extern bool stopState; // TODO: silence sound when true extern bool stopState; // TODO: silence sound when true
@ -469,10 +469,7 @@ static void remake_stereo_buffer()
void soundShutdown() void soundShutdown()
{ {
if (soundDriver) { soundDriver.reset();
delete soundDriver;
soundDriver = 0;
}
systemOnSoundShutdown(); systemOnSoundShutdown();

View File

@ -23,14 +23,16 @@
class SoundRetro : public SoundDriver { class SoundRetro : public SoundDriver {
public: public:
SoundRetro(); SoundRetro();
virtual ~SoundRetro(); ~SoundRetro() override;
virtual bool init(long sampleRate); private:
virtual void pause(); // SoundDriver implementation.
virtual void reset(); bool init(long sampleRate) override;
virtual void resume(); void pause() override;
virtual void write(uint16_t* finalWave, int length); void reset() override;
virtual void setThrottle(unsigned short throttle); void resume() override;
void write(uint16_t *finalWave, int length) override;
void setThrottle(unsigned short throttle_) override;
}; };
#endif // __VBA_SOUND_RETRO_H__ #endif // __VBA_SOUND_RETRO_H__

View File

@ -1949,10 +1949,10 @@ uint32_t systemGetClock(void)
return 0; return 0;
} }
SoundDriver* systemSoundInit(void) std::unique_ptr<SoundDriver> systemSoundInit(void)
{ {
soundShutdown(); soundShutdown();
return new SoundRetro(); return std::make_unique<SoundRetro>();
} }
void log(const char* defaultMsg, ...) void log(const char* defaultMsg, ...)

View File

@ -7,6 +7,8 @@ add_executable(vbam WIN32)
target_sources(vbam target_sources(vbam
PRIVATE PRIVATE
audio_sdl.cpp
audio_sdl.h
ConfigManager.cpp ConfigManager.cpp
ConfigManager.h ConfigManager.h
dictionary.c dictionary.c
@ -38,15 +40,19 @@ if(ENABLE_LIRC)
set(LIRC_CLIENT_LIBRARY lirc_client) set(LIRC_CLIENT_LIBRARY lirc_client)
endif() endif()
target_include_directories(vbam
PRIVATE ${SDL2_INCLUDE_DIRS}
)
target_link_libraries(vbam target_link_libraries(vbam
vbam-core vbam-core
vbam-components-audio-sdl
vbam-components-draw-text vbam-components-draw-text
vbam-components-filters vbam-components-filters
vbam-components-filters-agb vbam-components-filters-agb
vbam-components-filters-interframe vbam-components-filters-interframe
vbam-components-user-config vbam-components-user-config
${OPENGL_LIBRARIES} ${OPENGL_LIBRARIES}
${VBAM_SDL2_LIBS}
) )
if(WIN32) if(WIN32)

View File

@ -68,6 +68,8 @@
#pragma comment(lib, "OpenGL32") #pragma comment(lib, "OpenGL32")
#include <Windows.h> #include <Windows.h>
#define strdup _strdup
#endif // defined(_WIN32) #endif // defined(_WIN32)
#if defined(__APPLE__) #if defined(__APPLE__)
@ -91,7 +93,6 @@
#include <sys/poll.h> #include <sys/poll.h>
#endif #endif
#include "components/audio_sdl/audio_sdl.h"
#include "components/draw_text/draw_text.h" #include "components/draw_text/draw_text.h"
#include "components/filters_agb/filters_agb.h" #include "components/filters_agb/filters_agb.h"
#include "components/user_config/user_config.h" #include "components/user_config/user_config.h"
@ -110,6 +111,7 @@
#include "core/gba/gbaRtc.h" #include "core/gba/gbaRtc.h"
#include "core/gba/gbaSound.h" #include "core/gba/gbaSound.h"
#include "sdl/ConfigManager.h" #include "sdl/ConfigManager.h"
#include "sdl/audio_sdl.h"
#include "sdl/filters.h" #include "sdl/filters.h"
#include "sdl/inputSDL.h" #include "sdl/inputSDL.h"
@ -2315,11 +2317,10 @@ uint8_t systemGetSensorDarkness()
return 0xE8; return 0xE8;
} }
SoundDriver* systemSoundInit() std::unique_ptr<SoundDriver> systemSoundInit() {
{
soundShutdown(); soundShutdown();
return new SoundSDL(); return std::make_unique<SoundSDL>();
} }
void systemOnSoundShutdown() void systemOnSoundShutdown()

View File

@ -15,7 +15,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "components/audio_sdl/audio_sdl.h" #include "sdl/audio_sdl.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>

View File

@ -15,34 +15,34 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef VBAM_COMPONENTS_AUDIO_SDL_AUDIO_SDL_H_ #ifndef VBAM_SDL_AUDIO_SDL_H_
#define VBAM_COMPONENTS_AUDIO_SDL_AUDIO_SDL_H_ #define VBAM_SDL_AUDIO_SDL_H_
#include <SDL.h> #include <SDL.h>
#include "core/base/ringbuffer.h" #include "core/base/ringbuffer.h"
#include "core/base/sound_driver.h" #include "core/base/sound_driver.h"
class SoundSDL : public SoundDriver { class SoundSDL final : public SoundDriver {
public: public:
SoundSDL(); SoundSDL();
virtual ~SoundSDL(); ~SoundSDL() override;
virtual bool init(long sampleRate);
virtual void pause();
virtual void reset();
virtual void resume();
virtual void write(uint16_t *finalWave, int length);
virtual void setThrottle(unsigned short throttle_);
protected:
static void soundCallback(void* data, uint8_t* stream, int length);
virtual void read(uint16_t* stream, int length);
virtual bool should_wait();
virtual std::size_t buffer_size();
virtual void deinit();
private: private:
static void soundCallback(void* data, uint8_t* stream, int length);
void read(uint16_t* stream, int length);
bool should_wait();
std::size_t buffer_size();
void deinit();
// SoundDriver implementation.
bool init(long sampleRate) override;
void pause() override;
void reset() override;
void resume() override;
void write(uint16_t *finalWave, int length) override;
void setThrottle(unsigned short throttle_) override;
RingBuffer<uint16_t> samples_buf; RingBuffer<uint16_t> samples_buf;
SDL_AudioDeviceID sound_device = 0; SDL_AudioDeviceID sound_device = 0;
@ -60,4 +60,4 @@ private:
static const double buftime; static const double buftime;
}; };
#endif // VBAM_COMPONENTS_AUDIO_SDL_AUDIO_SDL_H_ #endif // VBAM_SDL_AUDIO_SDL_H_

View File

@ -38,15 +38,15 @@ private:
public: public:
DirectSound(); DirectSound();
virtual ~DirectSound(); ~DirectSound() override;
bool init(long sampleRate) override; // initialize the primary and secondary sound buffer // SoundDriver implementation.
void setThrottle(unsigned short throttle_) override; // set game speed bool init(long sampleRate) override;
void pause() override; // pause the secondary sound buffer void pause() override;
void reset() override; // stop and reset the secondary sound buffer void reset() override;
void resume() override; // resume the secondary sound buffer void resume() override;
void write(uint16_t* finalWave, void write(uint16_t *finalWave, int length) override;
int length) override; // write the emulated sound to the secondary sound buffer void setThrottle(unsigned short throttle_) override;
}; };
DirectSound::DirectSound() DirectSound::DirectSound()
@ -336,9 +336,9 @@ void DirectSound::write(uint16_t* finalWave, int)
} }
} }
SoundDriver* newDirectSound() std::unique_ptr<SoundDriver> newDirectSound()
{ {
return new DirectSound(); return std::make_unique<DirectSound>();
} }
struct devnames { struct devnames {

View File

@ -60,7 +60,7 @@ int FAGetDev(FAudio* fa)
if (audio_device.empty()) if (audio_device.empty())
return 0; return 0;
else { else {
int ret = GetFADevices(fa, NULL, NULL, &audio_device); int ret = GetFADevices(fa, nullptr, nullptr, &audio_device);
return ret < 0 ? 0 : ret; return ret < 0 ? 0 : ret;
} }
} }
@ -94,19 +94,18 @@ public:
private: private:
void* buffer_end_event_; void* buffer_end_event_;
static void StaticOnBufferEnd(FAudioVoiceCallback* callback, void * pBufferContext) { static void StaticOnBufferEnd(FAudioVoiceCallback* callback, void*) {
FAudio_BufferNotify* self = static_cast<FAudio_BufferNotify*>(callback); FAudio_BufferNotify* self = static_cast<FAudio_BufferNotify*>(callback);
if (self != nullptr && self->buffer_end_event_ != NULL) if (self != nullptr && self->buffer_end_event_ != nullptr) {
{
SetEvent(self->buffer_end_event_); SetEvent(self->buffer_end_event_);
} }
} }
static void StaticOnVoiceProcessingPassStart(FAudioVoiceCallback* callback, uint32_t BytesRequired) {} static void StaticOnVoiceProcessingPassStart(FAudioVoiceCallback*, uint32_t) {}
static void StaticOnVoiceProcessingPassEnd(FAudioVoiceCallback* callback) {} static void StaticOnVoiceProcessingPassEnd(FAudioVoiceCallback*) {}
static void StaticOnStreamEnd(FAudioVoiceCallback* callback) {} static void StaticOnStreamEnd(FAudioVoiceCallback*) {}
static void StaticOnBufferStart(FAudioVoiceCallback* callback, void * pBufferContext) {} static void StaticOnBufferStart(FAudioVoiceCallback*, void*) {}
static void StaticOnLoopEnd(FAudioVoiceCallback* callback, void * pBufferContext) {} static void StaticOnLoopEnd(FAudioVoiceCallback*, void*) {}
static void StaticOnVoiceError(FAudioVoiceCallback* callback, void * pBufferContext, uint32_t Error) {} static void StaticOnVoiceError(FAudioVoiceCallback*, void*, uint32_t) {}
}; };
class FAudio_Output class FAudio_Output
@ -115,31 +114,27 @@ public:
FAudio_Output(); FAudio_Output();
~FAudio_Output(); ~FAudio_Output();
// Initialization
bool init(long sampleRate);
// Sound Data Feed
void write(uint16_t* finalWave, int length);
// Play Control
void pause();
void resume();
void reset();
void close();
void device_change(); void device_change();
// Configuration Changes
void setThrottle(unsigned short throttle_);
private: private:
void close();
// SoundDriver implementation.
bool init(long sampleRate) override;
void pause() override;
void reset() override;
void resume() override;
void write(uint16_t* finalWave, int length) override;
void setThrottle(unsigned short throttle_) override;
bool failed; bool failed;
bool initialized; bool initialized;
bool playing; bool playing;
uint32_t freq; uint32_t freq_;
uint32_t bufferCount; const uint32_t buffer_count_;
uint8_t* buffers; std::vector<uint8_t> buffers_;
int currentBuffer; int currentBuffer;
int soundBufferLen; int sound_buffer_len_;
volatile bool device_changed; volatile bool device_changed;
@ -180,21 +175,18 @@ public:
FAudio_Device_Notifier f_notifier; FAudio_Device_Notifier f_notifier;
// Class Implementation // Class Implementation
FAudio_Output::FAudio_Output() FAudio_Output::FAudio_Output() : buffer_count_(OPTION(kSoundBuffers)) {
{
failed = false; failed = false;
initialized = false; initialized = false;
playing = false; playing = false;
freq = 0; freq_ = 0;
bufferCount = OPTION(kSoundBuffers);
buffers = NULL;
currentBuffer = 0; currentBuffer = 0;
device_changed = false; device_changed = false;
faud = NULL; faud = nullptr;
mVoice = NULL; mVoice = nullptr;
sVoice = NULL; sVoice = nullptr;
memset(&buf, NULL, sizeof(buf)); memset(&buf, 0, sizeof(buf));
memset(&vState, NULL, sizeof(vState)); memset(&vState, 0, sizeof(vState));
f_notifier.do_register(this); f_notifier.do_register(this);
} }
@ -214,22 +206,17 @@ void FAudio_Output::close()
} }
FAudioVoice_DestroyVoice(sVoice); FAudioVoice_DestroyVoice(sVoice);
sVoice = NULL; sVoice = nullptr;
}
if (buffers) {
free(buffers);
buffers = NULL;
} }
if (mVoice) { if (mVoice) {
FAudioVoice_DestroyVoice(mVoice); FAudioVoice_DestroyVoice(mVoice);
mVoice = NULL; mVoice = nullptr;
} }
if (faud) { if (faud) {
FAudio_Release(faud); FAudio_Release(faud);
faud = NULL; faud = nullptr;
} }
} }
@ -257,30 +244,30 @@ bool FAudio_Output::init(long sampleRate)
return false; return false;
} }
freq = sampleRate; freq_ = sampleRate;
// 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; sound_buffer_len_ = (freq_ / 60) * 4;
// create own buffers to store sound data because it must not be // create own buffers to store sound data because it must not be
// manipulated while the voice plays from it // manipulated while the voice plays from it.
buffers = (uint8_t*)malloc((bufferCount + 1) * soundBufferLen); // +1 because we need one temporary buffer when all others are in use.
// + 1 because we need one temporary buffer when all others are in use buffers_.resize((buffer_count_ + 1) * sound_buffer_len_);
FAudioWaveFormatEx wfx; static const uint16_t kNumChannels = 2;
memset(&wfx, NULL, sizeof(wfx)); static const uint16_t kBitsPerSample = 16;
wfx.wFormatTag = FAUDIO_FORMAT_PCM; static const uint16_t kBlockAlign = kNumChannels * (kBitsPerSample / 8);
wfx.nChannels = 2; FAudioWaveFormatEx wfx {
wfx.nSamplesPerSec = freq; /*.wFormatTag=*/ FAUDIO_FORMAT_PCM,
wfx.wBitsPerSample = 16; /*.nChannels=*/kNumChannels,
wfx.nBlockAlign = wfx.nChannels * (wfx.wBitsPerSample / 8); /*.nSamplesPerSec=*/freq_,
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; /*.nAvgBytesPerSec=*/freq_ * kBlockAlign,
/*.nBlockAlign=*/kNumChannels * (kBitsPerSample / 8),
/*.wBitsPerSample=*/kBitsPerSample,
/*.cbSize=*/0,
};
// create sound receiver // create sound receiver
hr = FAudio_CreateMasteringVoice(faud, hr = FAudio_CreateMasteringVoice(faud, &mVoice, FAUDIO_DEFAULT_CHANNELS,
&mVoice, FAUDIO_DEFAULT_SAMPLERATE, 0, FAGetDev(faud), nullptr);
FAUDIO_DEFAULT_CHANNELS,
FAUDIO_DEFAULT_SAMPLERATE,
0,
FAGetDev(faud),
NULL);
if (hr != 0) { if (hr != 0) {
wxLogError(_("FAudio: Creating mastering voice failed!")); wxLogError(_("FAudio: Creating mastering voice failed!"));
@ -289,8 +276,7 @@ bool FAudio_Output::init(long sampleRate)
} }
// create sound emitter // create sound emitter
//This should be FAudio_CreateSourceVoice() hr = FAudio_CreateSourceVoice(faud, &sVoice, &wfx, 0, 4.0f, &notify, nullptr, nullptr);
hr = FAudio_CreateSourceVoice(faud, &sVoice, &wfx, 0, 4.0f, &notify, NULL, NULL);
if (hr != 0) { if (hr != 0) {
wxLogError(_("FAudio: Creating source voice failed!")); wxLogError(_("FAudio: Creating source voice failed!"));
@ -301,13 +287,8 @@ bool FAudio_Output::init(long sampleRate)
if (OPTION(kSoundUpmix)) { if (OPTION(kSoundUpmix)) {
// set up stereo upmixing // set up stereo upmixing
FAudioDeviceDetails dd {}; FAudioDeviceDetails dd {};
//memset(&dd, NULL, sizeof(dd));
assert(FAudio_GetDeviceDetails(faud, 0, &dd) == 0); assert(FAudio_GetDeviceDetails(faud, 0, &dd) == 0);
float* matrix = NULL; std::vector<float> matrix(sizeof(float) * 2 * dd.OutputFormat.Format.nChannels);
matrix = (float*)malloc(sizeof(float) * 2 * dd.OutputFormat.Format.nChannels);
if (matrix == NULL)
return false;
bool matrixAvailable = true; bool matrixAvailable = true;
@ -398,12 +379,10 @@ bool FAudio_Output::init(long sampleRate)
} }
if (matrixAvailable) { if (matrixAvailable) {
hr = FAudioVoice_SetOutputMatrix(sVoice, NULL, 2, dd.OutputFormat.Format.nChannels, matrix, FAUDIO_DEFAULT_CHANNELS); hr = FAudioVoice_SetOutputMatrix(sVoice, nullptr, 2, dd.OutputFormat.Format.nChannels,
matrix.data(), FAUDIO_DEFAULT_CHANNELS);
assert(hr == 0); assert(hr == 0);
} }
free(matrix);
matrix = NULL;
} }
hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW); hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW);
@ -415,8 +394,7 @@ bool FAudio_Output::init(long sampleRate)
return true; return true;
} }
void FAudio_Output::write(uint16_t* finalWave, int length) void FAudio_Output::write(uint16_t* finalWave, int) {
{
uint32_t flags = 0; uint32_t flags = 0;
if (!initialized || failed) if (!initialized || failed)
return; return;
@ -425,14 +403,14 @@ void FAudio_Output::write(uint16_t* finalWave, int length)
if (device_changed) { if (device_changed) {
close(); close();
if (!init(freq)) if (!init(freq_))
return; return;
} }
FAudioSourceVoice_GetState(sVoice, &vState, flags); FAudioSourceVoice_GetState(sVoice, &vState, flags);
assert(vState.BuffersQueued <= bufferCount); assert(vState.BuffersQueued <= buffer_count_);
if (vState.BuffersQueued < bufferCount) { if (vState.BuffersQueued < buffer_count_) {
if (vState.BuffersQueued == 0) { if (vState.BuffersQueued == 0) {
// buffers ran dry // buffers ran dry
if (systemVerbose & VERBOSE_SOUNDOUTPUT) { if (systemVerbose & VERBOSE_SOUNDOUTPUT) {
@ -458,12 +436,12 @@ void FAudio_Output::write(uint16_t* finalWave, int length)
} }
// copy & protect the audio data in own memory area while playing it // copy & protect the audio data in own memory area while playing it
memcpy(&buffers[currentBuffer * soundBufferLen], finalWave, soundBufferLen); memcpy(&buffers_[currentBuffer * sound_buffer_len_], finalWave, sound_buffer_len_);
buf.AudioBytes = soundBufferLen; buf.AudioBytes = sound_buffer_len_;
buf.pAudioData = &buffers[currentBuffer * soundBufferLen]; buf.pAudioData = &buffers_[currentBuffer * sound_buffer_len_];
currentBuffer++; currentBuffer++;
currentBuffer %= (bufferCount + 1); // + 1 because we need one temporary buffer currentBuffer %= (buffer_count_ + 1); // + 1 because we need one temporary buffer
uint32_t hr = FAudioSourceVoice_SubmitSourceBuffer(sVoice, &buf, NULL); [[maybe_unused]] uint32_t hr = FAudioSourceVoice_SubmitSourceBuffer(sVoice, &buf, nullptr);
assert(hr == 0); assert(hr == 0);
} }
@ -473,7 +451,7 @@ void FAudio_Output::pause()
return; return;
if (playing) { if (playing) {
uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW); [[maybe_unused]] uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); assert(hr == 0);
playing = false; playing = false;
} }
@ -485,7 +463,7 @@ void FAudio_Output::resume()
return; return;
if (!playing) { if (!playing) {
uint32_t hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW); [[maybe_unused]] int32_t hr = FAudioSourceVoice_Start(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); assert(hr == 0);
playing = true; playing = true;
} }
@ -497,7 +475,7 @@ void FAudio_Output::reset()
return; return;
if (playing) { if (playing) {
uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW); [[maybe_unused]] uint32_t hr = FAudioSourceVoice_Stop(sVoice, 0, FAUDIO_COMMIT_NOW);
assert(hr == 0); assert(hr == 0);
} }
@ -514,7 +492,8 @@ void FAudio_Output::setThrottle(unsigned short throttle_)
if (throttle_ == 0) if (throttle_ == 0)
throttle_ = 100; throttle_ = 100;
uint32_t hr = FAudioSourceVoice_SetFrequencyRatio(sVoice, (float)throttle_ / 100.0f, FAUDIO_COMMIT_NOW); [[maybe_unused]] uint32_t hr =
FAudioSourceVoice_SetFrequencyRatio(sVoice, (float)throttle_ / 100.0f, FAUDIO_COMMIT_NOW);
assert(hr == 0); assert(hr == 0);
} }
@ -545,15 +524,16 @@ HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::QueryInterface(REFIID riid, VO
} else if (__uuidof(IMMNotificationClient) == riid) { } else if (__uuidof(IMMNotificationClient) == riid) {
*ppvInterface = (IMMNotificationClient*)this; *ppvInterface = (IMMNotificationClient*)this;
} else { } else {
*ppvInterface = NULL; *ppvInterface = nullptr;
return E_NOINTERFACE; return E_NOINTERFACE;
} }
return S_OK; return S_OK;
} }
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDefaultDeviceChanged(EDataFlow flow,
{ ERole,
LPCWSTR pwstrDeviceId) {
if (flow == eRender && last_device.compare(pwstrDeviceId) != 0) { if (flow == eRender && last_device.compare(pwstrDeviceId) != 0) {
last_device = pwstrDeviceId; last_device = pwstrDeviceId;
EnterCriticalSection(&lock); EnterCriticalSection(&lock);
@ -568,16 +548,26 @@ HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDefaultDeviceChanged(EDataFl
return S_OK; return S_OK;
} }
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDeviceAdded(LPCWSTR pwstrDeviceId) { return S_OK; } HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDeviceAdded(LPCWSTR) {
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDeviceRemoved(LPCWSTR pwstrDeviceId) { return S_OK; } return S_OK;
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) { return S_OK; } }
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) { return S_OK; } HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDeviceRemoved(LPCWSTR) {
return S_OK;
}
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnDeviceStateChanged(LPCWSTR, DWORD) {
return S_OK;
}
HRESULT STDMETHODCALLTYPE FAudio_Device_Notifier::OnPropertyValueChanged(LPCWSTR,
const PROPERTYKEY) {
return S_OK;
}
void FAudio_Device_Notifier::do_register(FAudio_Output* p_instance) void FAudio_Device_Notifier::do_register(FAudio_Output* p_instance)
{ {
if (InterlockedIncrement(&registered) == 1) { if (InterlockedIncrement(&registered) == 1) {
pEnumerator = NULL; pEnumerator = nullptr;
HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator); HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
pEnumerator->RegisterEndpointNotificationCallback(this); pEnumerator->RegisterEndpointNotificationCallback(this);
@ -595,7 +585,7 @@ void FAudio_Device_Notifier::do_unregister(FAudio_Output* p_instance)
if (pEnumerator) { if (pEnumerator) {
pEnumerator->UnregisterEndpointNotificationCallback(this); pEnumerator->UnregisterEndpointNotificationCallback(this);
pEnumerator->Release(); pEnumerator->Release();
pEnumerator = NULL; pEnumerator = nullptr;
} }
} }
@ -617,7 +607,7 @@ void FAudio_Device_Notifier::do_unregister(FAudio_Output* p_instance)
bool GetFADevices(wxArrayString& names, wxArrayString& ids) bool GetFADevices(wxArrayString& names, wxArrayString& ids)
{ {
uint32_t hr; uint32_t hr;
FAudio* fa = NULL; FAudio* fa = nullptr;
uint32_t flags = 0; uint32_t flags = 0;
#ifdef _DEBUG #ifdef _DEBUG
flags = FAUDIO_DEBUG_ENGINE; flags = FAUDIO_DEBUG_ENGINE;
@ -629,13 +619,12 @@ bool GetFADevices(wxArrayString& names, wxArrayString& ids)
return false; return false;
} }
GetFADevices(fa, &names, &ids, NULL); GetFADevices(fa, &names, &ids, nullptr);
FAudio_Release(fa); FAudio_Release(fa);
return true; return true;
} }
// Class Declaration // Class Declaration
SoundDriver* newFAudio_Output() std::unique_ptr<SoundDriver> newFAudio_Output() {
{ return std::make_unique<FAudio_Output>();
return new FAudio_Output();
} }

View File

@ -31,7 +31,7 @@ struct OPENALFNTABLE;
class OpenAL : public SoundDriver { class OpenAL : public SoundDriver {
public: public:
OpenAL(); OpenAL();
virtual ~OpenAL(); ~OpenAL() override;
static bool GetDevices(wxArrayString& names, wxArrayString& ids); static bool GetDevices(wxArrayString& names, wxArrayString& ids);
bool init(long sampleRate); // initialize the sound buffer queue bool init(long sampleRate); // initialize the sound buffer queue
@ -327,10 +327,10 @@ void OpenAL::write(uint16_t* finalWave, int length)
} }
} }
SoundDriver* newOpenAL() std::unique_ptr<SoundDriver> newOpenAL()
{ {
winlog("newOpenAL\n"); winlog("newOpenAL\n");
return new OpenAL(); return std::make_unique<OpenAL>();
} }
bool GetOALDevices(wxArrayString& names, wxArrayString& ids) bool GetOALDevices(wxArrayString& names, wxArrayString& ids)

View File

@ -1227,7 +1227,7 @@ void systemGbBorderOn()
} }
class SoundDriver; class SoundDriver;
SoundDriver* systemSoundInit() std::unique_ptr<SoundDriver> systemSoundInit()
{ {
soundShutdown(); soundShutdown();

View File

@ -714,21 +714,21 @@ private:
// I should add this to SoundDriver, but wxArrayString is wx-specific // I should add this to SoundDriver, but wxArrayString is wx-specific
// I suppose I could make subclass wxSoundDriver. maybe later. // I suppose I could make subclass wxSoundDriver. maybe later.
class SoundDriver; class SoundDriver;
extern SoundDriver* newOpenAL(); extern std::unique_ptr<SoundDriver> newOpenAL();
extern bool GetOALDevices(wxArrayString& names, wxArrayString& ids); extern bool GetOALDevices(wxArrayString& names, wxArrayString& ids);
#if defined(__WXMSW__) #if defined(__WXMSW__)
extern SoundDriver* newDirectSound(); extern std::unique_ptr<SoundDriver> newDirectSound();
extern bool GetDSDevices(wxArrayString& names, wxArrayString& ids); extern bool GetDSDevices(wxArrayString& names, wxArrayString& ids);
#endif // defined(__WXMSW__) #endif // defined(__WXMSW__)
#if defined(VBAM_ENABLE_XAUDIO2) #if defined(VBAM_ENABLE_XAUDIO2)
extern SoundDriver* newXAudio2_Output(); extern std::unique_ptr<SoundDriver> newXAudio2_Output();
extern bool GetXA2Devices(wxArrayString& names, wxArrayString& ids); extern bool GetXA2Devices(wxArrayString& names, wxArrayString& ids);
#endif // defined(VBAM_ENABLE_XAUDIO2) #endif // defined(VBAM_ENABLE_XAUDIO2)
#if defined(VBAM_ENABLE_FAUDIO) #if defined(VBAM_ENABLE_FAUDIO)
extern SoundDriver* newFAudio_Output(); extern std::unique_ptr<SoundDriver> newFAudio_Output();
extern bool GetFADevices(wxArrayString& names, wxArrayString& ids); extern bool GetFADevices(wxArrayString& names, wxArrayString& ids);
#endif // defined(VBAM_ENABLE_FAUDIO) #endif // defined(VBAM_ENABLE_FAUDIO)

View File

@ -236,25 +236,20 @@ class XAudio2_Output
: public SoundDriver { : public SoundDriver {
public: public:
XAudio2_Output(); XAudio2_Output();
~XAudio2_Output(); ~XAudio2_Output() override;
// Initialization
bool init(long sampleRate);
// Sound Data Feed
void write(uint16_t* finalWave, int length);
// Play Control
void pause();
void resume();
void reset();
void close();
void device_change(); void device_change();
// Configuration Changes
void setThrottle(unsigned short throttle);
private: private:
void close();
// SoundDriver implementation.
bool init(long sampleRate) override;
void pause() override;
void reset() override;
void resume() override;
void write(uint16_t *finalWave, int length) override;
void setThrottle(unsigned short throttle_) override;
bool failed; bool failed;
bool initialized; bool initialized;
bool playing; bool playing;
@ -614,7 +609,7 @@ void xaudio2_device_changed(XAudio2_Output* instance)
instance->device_change(); instance->device_change();
} }
SoundDriver* newXAudio2_Output() std::unique_ptr<SoundDriver> newXAudio2_Output()
{ {
return new XAudio2_Output(); return std::make_unique<XAudio2_Output>();
} }