AutoRelease better log and null handling
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
|||||||
*build*/
|
*build*/
|
||||||
.idea/
|
.idea/
|
||||||
roms/
|
roms/
|
||||||
|
saves/
|
||||||
*.bin
|
*.bin
|
||||||
*.sh
|
*.sh
|
||||||
.cache/
|
.cache/
|
||||||
|
|||||||
@@ -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&);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
if (audioDevice) {
|
||||||
audioDevice->LockMutex();
|
audioDevice->LockMutex();
|
||||||
int available = SDL_AudioStreamAvailable(audioDevice->GetStream());
|
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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{};
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user