[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(draw_text)
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_
#include <cstdint>
#include <memory>
class SoundDriver;
#include "core/base/sound_driver.h"
enum IMAGE_TYPE {
IMAGE_UNKNOWN = -1,
@ -89,7 +90,7 @@ extern bool systemReadJoypads();
extern uint32_t systemReadJoypad(int);
extern uint32_t systemGetClock();
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 systemOnSoundShutdown();
extern void systemScreenMessage(const char*);

View File

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

View File

@ -23,14 +23,16 @@
class SoundRetro : public SoundDriver {
public:
SoundRetro();
virtual ~SoundRetro();
~SoundRetro() 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);
private:
// 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;
};
#endif // __VBA_SOUND_RETRO_H__

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
// along with this program; if not, write to the Free Software Foundation,
// 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 <iostream>

View File

@ -15,34 +15,34 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef VBAM_COMPONENTS_AUDIO_SDL_AUDIO_SDL_H_
#define VBAM_COMPONENTS_AUDIO_SDL_AUDIO_SDL_H_
#ifndef VBAM_SDL_AUDIO_SDL_H_
#define VBAM_SDL_AUDIO_SDL_H_
#include <SDL.h>
#include "core/base/ringbuffer.h"
#include "core/base/sound_driver.h"
class SoundSDL : public SoundDriver {
class SoundSDL final : public SoundDriver {
public:
SoundSDL();
virtual ~SoundSDL();
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();
~SoundSDL() override;
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;
SDL_AudioDeviceID sound_device = 0;
@ -60,4 +60,4 @@ private:
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:
DirectSound();
virtual ~DirectSound();
~DirectSound() override;
bool init(long sampleRate) override; // initialize the primary and secondary sound buffer
void setThrottle(unsigned short throttle_) override; // set game speed
void pause() override; // pause the secondary sound buffer
void reset() override; // stop and reset the secondary sound buffer
void resume() override; // resume the secondary sound buffer
void write(uint16_t* finalWave,
int length) override; // write the emulated sound to the secondary sound buffer
// 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;
};
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 {

View File

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

View File

@ -31,7 +31,7 @@ struct OPENALFNTABLE;
class OpenAL : public SoundDriver {
public:
OpenAL();
virtual ~OpenAL();
~OpenAL() override;
static bool GetDevices(wxArrayString& names, wxArrayString& ids);
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");
return new OpenAL();
return std::make_unique<OpenAL>();
}
bool GetOALDevices(wxArrayString& names, wxArrayString& ids)

View File

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

View File

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

View File

@ -236,25 +236,20 @@ class XAudio2_Output
: public SoundDriver {
public:
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();
// Configuration Changes
void setThrottle(unsigned short throttle);
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 initialized;
bool playing;
@ -614,7 +609,7 @@ void xaudio2_device_changed(XAudio2_Output* instance)
instance->device_change();
}
SoundDriver* newXAudio2_Output()
std::unique_ptr<SoundDriver> newXAudio2_Output()
{
return new XAudio2_Output();
return std::make_unique<XAudio2_Output>();
}