Audio fix
This commit is contained in:
@@ -15,7 +15,7 @@ namespace Game::Audio {
|
|||||||
SDL_AudioDeviceID getAudioDevice() const { return mDevice; }
|
SDL_AudioDeviceID getAudioDevice() const { return mDevice; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_AudioSpec mAudioSpec;
|
SDL_AudioSpec mAudioSpec{};
|
||||||
SDL_AudioDeviceID mDevice;
|
SDL_AudioDeviceID mDevice = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -32,6 +32,7 @@ namespace Game::Object {
|
|||||||
Uint8* mAudioBuffer = nullptr;
|
Uint8* mAudioBuffer = nullptr;
|
||||||
Uint32 mAudioLength = 0;
|
Uint32 mAudioLength = 0;
|
||||||
SDL_AudioStream* mAudioStream = nullptr;
|
SDL_AudioStream* mAudioStream = nullptr;
|
||||||
|
SDL_AudioSpec mSourceSpec{};
|
||||||
int mVolume;
|
int mVolume;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <state/gamestate.hpp>
|
#include <state/gamestate.hpp>
|
||||||
#include <game/gamemanager.hpp>
|
#include <game/gamemanager.hpp>
|
||||||
#include <audio/audio.hpp>
|
#include <audio/audio.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
namespace Game::Window {
|
namespace Game::Window {
|
||||||
class Window {
|
class Window {
|
||||||
@@ -24,14 +25,19 @@ namespace Game::Window {
|
|||||||
void setTargetFPS(int fps) { mTargetFPS = fps; }
|
void setTargetFPS(int fps) { mTargetFPS = fps; }
|
||||||
int getTargetFPS() { return mTargetFPS; }
|
int getTargetFPS() { return mTargetFPS; }
|
||||||
|
|
||||||
|
static SDL_Window* getSDLWindowBackend() { return sWindowBackend; }
|
||||||
|
|
||||||
Renderer::Renderer* getRenderer() { return &mRenderer; }
|
Renderer::Renderer* getRenderer() { return &mRenderer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static inline SDL_Window* sWindowBackend = nullptr;
|
||||||
SDL_Window* mWindow;
|
SDL_Window* mWindow;
|
||||||
Renderer::Renderer mRenderer;
|
Renderer::Renderer mRenderer;
|
||||||
Game::GameManager mGameManager;
|
Game::GameManager mGameManager;
|
||||||
std::jthread mGameThread;
|
std::jthread mGameThread;
|
||||||
bool mRunning;
|
bool mRunning;
|
||||||
int mTargetFPS = 60;
|
int mTargetFPS = 60;
|
||||||
|
size_t mFrameCount = 0;
|
||||||
|
std::chrono::steady_clock::time_point mLastFPSTime;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
#include <game/agame/player.hpp>
|
#include <game/agame/player.hpp>
|
||||||
|
#include <window/window.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace Game::AGame {
|
namespace Game::AGame {
|
||||||
void Player::start() {
|
void Player::start() {
|
||||||
mSound = Object::Sound("../resources/example.wav", Object::Format::WAV);
|
mSound = Object::Sound("../resources/example.wav", Object::Format::WAV);
|
||||||
mSound.play();
|
mSound.play();
|
||||||
|
|
||||||
mTransform.x = 640.f - (mTex->getWidth() / 2.f * mTransform.scaleX); // Start in the middle of the screen
|
int w, h;
|
||||||
mTransform.y = 360.f - (mTex->getHeight() / 2.f * mTransform.scaleY);
|
SDL_GetWindowSizeInPixels(Window::Window::getSDLWindowBackend(), &w, &h);
|
||||||
|
|
||||||
|
mTransform.x = w / 2.f - (mTex->getWidth() / 2.f * mTransform.scaleX * 0.25f); // Start in the middle of the screen
|
||||||
|
mTransform.y = h / 2.f - (mTex->getHeight() / 2.f * mTransform.scaleY * 0.25f);
|
||||||
mTransform.rotation = 0.f;
|
mTransform.rotation = 0.f;
|
||||||
|
|
||||||
|
LOG("W: " << w << " H: " << h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::update(float deltaTime) {
|
void Player::update(float deltaTime) {
|
||||||
@@ -18,6 +25,6 @@ namespace Game::AGame {
|
|||||||
//LOG(mName << " position: " << mTransform.x << ' ' << mTransform.y);
|
//LOG(mName << " position: " << mTransform.x << ' ' << mTransform.y);
|
||||||
//LOG("DeltaTime: " << deltaTime);
|
//LOG("DeltaTime: " << deltaTime);
|
||||||
mTransform.scaleX = 1.f + 1.f * std::sin(RUNNING_TIME() / 0.5f); // Pulsate scale for testing
|
mTransform.scaleX = 1.f + 1.f * std::sin(RUNNING_TIME() / 0.5f); // Pulsate scale for testing
|
||||||
//mTransform.scaleY = 1.f + 1.f * std::sin(SDL_GetTicks() / 500.f);
|
mTransform.scaleY = 1.f + 0.5f * std::cos(RUNNING_TIME() / 0.5f); // Pulsate scale for testing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,25 @@
|
|||||||
#include <object/sound.hpp>
|
#include <object/sound.hpp>
|
||||||
|
|
||||||
namespace Game::Object {
|
namespace Game::Object {
|
||||||
namespace {
|
|
||||||
static SDL_AudioSpec makeFloatStereo44100() {
|
|
||||||
SDL_AudioSpec spec{};
|
|
||||||
spec.freq = 44100;
|
|
||||||
spec.channels = 2;
|
|
||||||
spec.format = SDL_AUDIO_F32;
|
|
||||||
return spec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Sound::Sound(std::string path, Format format, int volume)
|
Sound::Sound(std::string path, Format format, int volume)
|
||||||
: mAudioBuffer(nullptr), mAudioLength(0), mAudioStream(nullptr), mVolume(volume) {
|
: mAudioBuffer(nullptr), mAudioLength(0), mAudioStream(nullptr), mSourceSpec{}, mVolume(volume) {
|
||||||
if (format == Format::WAV) {
|
if (format == Format::WAV) {
|
||||||
SDL_AudioSpec wavSpec = makeFloatStereo44100();
|
if (!SDL_LoadWAV(path.c_str(), &mSourceSpec, &mAudioBuffer, &mAudioLength)) {
|
||||||
|
|
||||||
if (!SDL_LoadWAV(path.c_str(), &wavSpec, &mAudioBuffer, &mAudioLength)) {
|
|
||||||
ERROR("Failed to load WAV file: " << SDL_GetError());
|
ERROR("Failed to load WAV file: " << SDL_GetError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("WAV file loaded successfully");
|
LOG("WAV file loaded successfully");
|
||||||
|
|
||||||
SDL_AudioSpec spec = makeFloatStereo44100();
|
|
||||||
mAudioStream = SDL_OpenAudioDeviceStream(
|
mAudioStream = SDL_OpenAudioDeviceStream(
|
||||||
Audio::Audio::getInstance().getAudioDevice(), &spec, nullptr, nullptr
|
Audio::Audio::getInstance().getAudioDevice(), &mSourceSpec, nullptr, nullptr
|
||||||
);
|
);
|
||||||
if (!mAudioStream) {
|
if (!mAudioStream) {
|
||||||
ERROR("Failed to create audio stream: " << SDL_GetError());
|
ERROR("Failed to create audio stream: " << SDL_GetError());
|
||||||
SDL_free(mAudioBuffer);
|
SDL_free(mAudioBuffer);
|
||||||
mAudioBuffer = nullptr;
|
mAudioBuffer = nullptr;
|
||||||
mAudioLength = 0;
|
mAudioLength = 0;
|
||||||
|
mSourceSpec = {};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERROR("Unsupported audio format");
|
ERROR("Unsupported audio format");
|
||||||
@@ -39,7 +27,7 @@ namespace Game::Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sound::Sound(const Sound& other)
|
Sound::Sound(const Sound& other)
|
||||||
: mAudioBuffer(nullptr), mAudioLength(0), mAudioStream(nullptr), mVolume(other.mVolume) {
|
: mAudioBuffer(nullptr), mAudioLength(0), mAudioStream(nullptr), mSourceSpec(other.mSourceSpec), mVolume(other.mVolume) {
|
||||||
if (&other == this) return;
|
if (&other == this) return;
|
||||||
|
|
||||||
if (other.mAudioBuffer && other.mAudioLength > 0) {
|
if (other.mAudioBuffer && other.mAudioLength > 0) {
|
||||||
@@ -53,9 +41,8 @@ namespace Game::Object {
|
|||||||
mAudioLength = other.mAudioLength;
|
mAudioLength = other.mAudioLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AudioSpec wavSpec = makeFloatStereo44100();
|
|
||||||
mAudioStream = SDL_OpenAudioDeviceStream(
|
mAudioStream = SDL_OpenAudioDeviceStream(
|
||||||
Audio::Audio::getInstance().getAudioDevice(), &wavSpec, nullptr, nullptr
|
Audio::Audio::getInstance().getAudioDevice(), &mSourceSpec, nullptr, nullptr
|
||||||
);
|
);
|
||||||
if (!mAudioStream) {
|
if (!mAudioStream) {
|
||||||
ERROR("Failed to create audio stream for copied Sound: " << SDL_GetError());
|
ERROR("Failed to create audio stream for copied Sound: " << SDL_GetError());
|
||||||
@@ -78,10 +65,8 @@ namespace Game::Object {
|
|||||||
newLength = other.mAudioLength;
|
newLength = other.mAudioLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AudioStream* newStream = nullptr;
|
SDL_AudioStream* newStream = SDL_OpenAudioDeviceStream(
|
||||||
SDL_AudioSpec wavSpec = makeFloatStereo44100();
|
Audio::Audio::getInstance().getAudioDevice(), &other.mSourceSpec, nullptr, nullptr
|
||||||
newStream = SDL_OpenAudioDeviceStream(
|
|
||||||
Audio::Audio::getInstance().getAudioDevice(), &wavSpec, nullptr, nullptr
|
|
||||||
);
|
);
|
||||||
if (!newStream) {
|
if (!newStream) {
|
||||||
ERROR("Failed to create audio stream for copied Sound: " << SDL_GetError());
|
ERROR("Failed to create audio stream for copied Sound: " << SDL_GetError());
|
||||||
@@ -95,6 +80,7 @@ namespace Game::Object {
|
|||||||
mAudioBuffer = newBuffer;
|
mAudioBuffer = newBuffer;
|
||||||
mAudioLength = newLength;
|
mAudioLength = newLength;
|
||||||
mAudioStream = newStream;
|
mAudioStream = newStream;
|
||||||
|
mSourceSpec = other.mSourceSpec;
|
||||||
mVolume = other.mVolume;
|
mVolume = other.mVolume;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -104,10 +90,12 @@ namespace Game::Object {
|
|||||||
: mAudioBuffer(other.mAudioBuffer),
|
: mAudioBuffer(other.mAudioBuffer),
|
||||||
mAudioLength(other.mAudioLength),
|
mAudioLength(other.mAudioLength),
|
||||||
mAudioStream(other.mAudioStream),
|
mAudioStream(other.mAudioStream),
|
||||||
|
mSourceSpec(other.mSourceSpec),
|
||||||
mVolume(other.mVolume) {
|
mVolume(other.mVolume) {
|
||||||
other.mAudioBuffer = nullptr;
|
other.mAudioBuffer = nullptr;
|
||||||
other.mAudioLength = 0;
|
other.mAudioLength = 0;
|
||||||
other.mAudioStream = nullptr;
|
other.mAudioStream = nullptr;
|
||||||
|
other.mSourceSpec = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound& Sound::operator=(Sound&& other) {
|
Sound& Sound::operator=(Sound&& other) {
|
||||||
@@ -118,11 +106,13 @@ namespace Game::Object {
|
|||||||
mAudioBuffer = other.mAudioBuffer;
|
mAudioBuffer = other.mAudioBuffer;
|
||||||
mAudioLength = other.mAudioLength;
|
mAudioLength = other.mAudioLength;
|
||||||
mAudioStream = other.mAudioStream;
|
mAudioStream = other.mAudioStream;
|
||||||
|
mSourceSpec = other.mSourceSpec;
|
||||||
mVolume = other.mVolume;
|
mVolume = other.mVolume;
|
||||||
|
|
||||||
other.mAudioBuffer = nullptr;
|
other.mAudioBuffer = nullptr;
|
||||||
other.mAudioLength = 0;
|
other.mAudioLength = 0;
|
||||||
other.mAudioStream = nullptr;
|
other.mAudioStream = nullptr;
|
||||||
|
other.mSourceSpec = {};
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -142,8 +132,20 @@ namespace Game::Object {
|
|||||||
|
|
||||||
void Sound::play() {
|
void Sound::play() {
|
||||||
if (mAudioStream && mAudioBuffer && mAudioLength > 0) {
|
if (mAudioStream && mAudioBuffer && mAudioLength > 0) {
|
||||||
|
SDL_ClearAudioStream(mAudioStream);
|
||||||
|
|
||||||
if (!SDL_PutAudioStreamData(mAudioStream, mAudioBuffer, mAudioLength)) {
|
if (!SDL_PutAudioStreamData(mAudioStream, mAudioBuffer, mAudioLength)) {
|
||||||
ERROR("Failed to queue audio data: " << SDL_GetError());
|
ERROR("Failed to queue audio data: " << SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_FlushAudioStream(mAudioStream)) {
|
||||||
|
ERROR("Failed to flush audio stream: " << SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_ResumeAudioStreamDevice(mAudioStream)) {
|
||||||
|
ERROR("Failed to resume audio stream device: " << SDL_GetError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace Game::Window {
|
|||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
SDL_DestroyWindow(mWindow);
|
SDL_DestroyWindow(mWindow);
|
||||||
mWindow = nullptr;
|
mWindow = nullptr;
|
||||||
|
sWindowBackend = nullptr;
|
||||||
LOG("Window destroyed successfully");
|
LOG("Window destroyed successfully");
|
||||||
}
|
}
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
@@ -41,12 +42,14 @@ namespace Game::Window {
|
|||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
sWindowBackend = mWindow;
|
||||||
|
|
||||||
LOG("Window created successfully");
|
LOG("Window created successfully");
|
||||||
|
|
||||||
if (!mRenderer.init(mWindow)) {
|
if (!mRenderer.init(mWindow)) {
|
||||||
SDL_DestroyWindow(mWindow);
|
SDL_DestroyWindow(mWindow);
|
||||||
mWindow = nullptr;
|
mWindow = nullptr;
|
||||||
|
sWindowBackend = nullptr;
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -77,6 +80,17 @@ namespace Game::Window {
|
|||||||
|
|
||||||
mRenderer.renderFrame();
|
mRenderer.renderFrame();
|
||||||
SDL_Delay(1000 / mTargetFPS); // Delay to cap the frame rate to the target FPS
|
SDL_Delay(1000 / mTargetFPS); // Delay to cap the frame rate to the target FPS
|
||||||
|
|
||||||
|
// Set the window title to show the current FPS for testing
|
||||||
|
mFrameCount++;
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - mLastFPSTime).count();
|
||||||
|
if (elapsed >= 1) {
|
||||||
|
int fps = static_cast<int>(mFrameCount / elapsed);
|
||||||
|
SDL_SetWindowTitle(mWindow, ("Game Window - FPS: " + std::to_string(fps)).c_str());
|
||||||
|
mFrameCount = 0;
|
||||||
|
mLastFPSTime = now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user