AutoRelease better log and null handling

This commit is contained in:
Simone Coco
2024-05-20 15:13:30 +02:00
parent 315a522dbf
commit 7479ad46a6
6 changed files with 42 additions and 34 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@
*build*/ *build*/
.idea/ .idea/
roms/ roms/
saves/
*.bin *.bin
*.sh *.sh
.cache/ .cache/

View File

@@ -7,7 +7,6 @@ struct Event;
namespace n64 { namespace n64 {
struct Core { struct Core {
~Core() { Stop(); }
Core(ParallelRDP&); Core(ParallelRDP&);
void Stop(); void Stop();
void LoadROM(const std::string&); void LoadROM(const std::string&);

View File

@@ -9,14 +9,22 @@ namespace n64 {
void audioCallback(void* user, Uint8* stream, int length) { void audioCallback(void* user, Uint8* stream, int length) {
auto audioDevice = (AudioDevice*)user; auto audioDevice = (AudioDevice*)user;
int gotten = 0; int gotten = 0, available = 0;
audioDevice->LockMutex(); if (audioDevice) {
int available = SDL_AudioStreamAvailable(audioDevice->GetStream()); audioDevice->LockMutex();
}
if (available > 0) {
gotten = SDL_AudioStreamGet(audioDevice->GetStream(), stream, length); if (audioDevice) {
available = SDL_AudioStreamAvailable(audioDevice->GetStream().get());
}
if (available > 0 && audioDevice) {
gotten = SDL_AudioStreamGet(audioDevice->GetStream().get(), stream, length);
}
if (audioDevice) {
audioDevice->UnlockMutex();
} }
audioDevice->UnlockMutex();
int gottenSamples = (int)(gotten / sizeof(float)); int gottenSamples = (int)(gotten / sizeof(float));
auto* out = (float*)stream; auto* out = (float*)stream;
@@ -28,13 +36,11 @@ void audioCallback(void* user, Uint8* stream, int length) {
} }
} }
AudioDevice::AudioDevice() { AudioDevice::AudioDevice() : audioStream(SDL_NewAudioStream, SDL_FreeAudioStream, "audioStream", SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE),
audioStreamMutex(SDL_CreateMutex, SDL_DestroyMutex, "audioStreamMutex") {
SDL_InitSubSystem(SDL_INIT_AUDIO); SDL_InitSubSystem(SDL_INIT_AUDIO);
audioStream = SDL_NewAudioStream(SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE);
audioStreamMutex = SDL_CreateMutex(); if(!audioStreamMutex.get()) {
if(!audioStreamMutex) {
Util::panic("Unable to initialize audio mutex: {}", SDL_GetError()); Util::panic("Unable to initialize audio mutex: {}", SDL_GetError());
} }
@@ -59,17 +65,15 @@ void AudioDevice::PushSample(float left, float volumeL, float right, float volum
float adjustedR = right * volumeR; float adjustedR = right * volumeR;
float samples[2]{ adjustedL, adjustedR }; float samples[2]{ adjustedL, adjustedR };
auto availableBytes = (float)SDL_AudioStreamAvailable(audioStream); auto availableBytes = (float)SDL_AudioStreamAvailable(audioStream.get());
if(availableBytes <= BYTES_PER_HALF_SECOND) { if(availableBytes <= BYTES_PER_HALF_SECOND) {
SDL_AudioStreamPut(audioStream, samples, 2 * sizeof(float)); SDL_AudioStreamPut(audioStream.get(), samples, 2 * sizeof(float));
} }
} }
void AudioDevice::AdjustSampleRate(int sampleRate) { void AudioDevice::AdjustSampleRate(int sampleRate) {
LockMutex(); LockMutex();
if(audioStream) SDL_FreeAudioStream(audioStream); audioStream.Construct(SDL_NewAudioStream, SYSTEM_SAMPLE_FORMAT, 2, sampleRate, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE);
audioStream = SDL_NewAudioStream(SYSTEM_SAMPLE_FORMAT, 2, sampleRate, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE);
UnlockMutex(); UnlockMutex();
} }
} }

View File

@@ -1,30 +1,28 @@
#pragma once #pragma once
#include <common.hpp> #include <MemoryHelpers.hpp>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
namespace n64 { namespace n64 {
struct AudioDevice { struct AudioDevice {
AudioDevice(); AudioDevice();
~AudioDevice() {
SDL_FreeAudioStream(audioStream);
SDL_DestroyMutex(audioStreamMutex);
}
void PushSample(float, float, float, float); void PushSample(float, float, float, float);
void AdjustSampleRate(int); void AdjustSampleRate(int);
void LockMutex() { void LockMutex() {
if(audioStreamMutex) if(audioStreamMutex.get())
SDL_LockMutex(audioStreamMutex); SDL_LockMutex(audioStreamMutex.get());
} }
void UnlockMutex() { void UnlockMutex() {
if (audioStreamMutex) if (audioStreamMutex.get())
SDL_UnlockMutex(audioStreamMutex); SDL_UnlockMutex(audioStreamMutex.get());
} }
SDL_AudioStream* GetStream() { return audioStream; } Util::AutoRelease<SDL_AudioStream, const SDL_AudioFormat, const Uint8, const int, const SDL_AudioFormat,
const Uint8, const int>& GetStream() { return audioStream; }
private: private:
SDL_AudioStream* audioStream = nullptr; Util::AutoRelease<SDL_AudioStream, const SDL_AudioFormat, const Uint8, const int, const SDL_AudioFormat,
SDL_mutex* audioStreamMutex = nullptr; const Uint8, const int> audioStream;
Util::AutoRelease<SDL_mutex> audioStreamMutex;
SDL_AudioSpec audioSpec{}; SDL_AudioSpec audioSpec{};
SDL_AudioSpec request{}; SDL_AudioSpec request{};
SDL_AudioDeviceID handle{}; SDL_AudioDeviceID handle{};

View File

@@ -6,7 +6,7 @@
EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform_, std::unique_ptr<ParallelRDP::WindowInfo>&& windowInfo_, SettingsWindow& settings) noexcept EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform_, std::unique_ptr<ParallelRDP::WindowInfo>&& windowInfo_, SettingsWindow& settings) noexcept
: instance(std::move(instance_)), wsiPlatform(std::move(wsiPlatform_)), : instance(std::move(instance_)), wsiPlatform(std::move(wsiPlatform_)),
windowInfo(std::move(windowInfo_)), windowInfo(std::move(windowInfo_)),
controller(SDL_GameControllerClose), controller(SDL_GameControllerClose, "GameController"),
core(parallel), settings(settings) {} core(parallel), settings(settings) {}
[[noreturn]] void EmuThread::run() noexcept { [[noreturn]] void EmuThread::run() noexcept {

View File

@@ -8,13 +8,18 @@
namespace Util { namespace Util {
template <class T, typename... Args> template <class T, typename... Args>
struct AutoRelease { struct AutoRelease {
AutoRelease(void (*dtor)(T*)) : dtor(dtor) { } AutoRelease(void (*dtor)(T*), const char* name = "") : dtor(dtor), name(name) { }
AutoRelease(T* (*ctor)(Args...), void (*dtor)(T*), Args... args) : dtor(dtor) { AutoRelease(T* (*ctor)(Args...), void (*dtor)(T*), const char* name = "", Args... args) : dtor(dtor), name(name) {
thing = ctor(args...); thing = ctor(args...);
} }
T* get() { return thing; } T* get() {
if (!thing) {
Util::panic("AutoRelease::{} is null!", name);
}
return thing;
}
void Construct(T* (*ctor)(Args...), Args... args) { void Construct(T* (*ctor)(Args...), Args... args) {
if(thing) { if(thing) {
@@ -36,6 +41,7 @@ struct AutoRelease {
} }
} }
private: private:
const char* name = "";
T* thing = nullptr; T* thing = nullptr;
void (*dtor)(T*) = nullptr; void (*dtor)(T*) = nullptr;
}; };