From d1d0d891fa8556de2b1535343d6ffa19a3749240 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Wed, 10 Dec 2025 18:35:05 +0100 Subject: [PATCH] fix. sound fx --- src/audio/SoundEffect.cpp | 66 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/audio/SoundEffect.cpp b/src/audio/SoundEffect.cpp index 24317bd..2a34b66 100644 --- a/src/audio/SoundEffect.cpp +++ b/src/audio/SoundEffect.cpp @@ -20,6 +20,9 @@ #pragma comment(lib, "mfuuid.lib") #pragma comment(lib, "ole32.lib") using Microsoft::WRL::ComPtr; +#elif defined(__APPLE__) +#include +#include #endif // SoundEffect implementation @@ -143,7 +146,7 @@ bool SoundEffect::loadWAV(const std::string& filePath) { } bool SoundEffect::loadMP3(const std::string& filePath) { -#ifdef _WIN32 +#if defined(_WIN32) static bool mfInitialized = false; if (!mfInitialized) { if (FAILED(MFStartup(MF_VERSION))) { @@ -222,6 +225,67 @@ bool SoundEffect::loadMP3(const std::string& filePath) { channels = 2; sampleRate = 44100; return true; +#elif defined(__APPLE__) + CFURLRef url = CFURLCreateFromFileSystemRepresentation(nullptr, reinterpret_cast(filePath.c_str()), filePath.size(), false); + if (!url) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "[SoundEffect] Failed to create URL for %s", filePath.c_str()); + return false; + } + + ExtAudioFileRef audioFile = nullptr; + OSStatus status = ExtAudioFileOpenURL(url, &audioFile); + CFRelease(url); + if (status != noErr || !audioFile) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "[SoundEffect] ExtAudioFileOpenURL failed (%d) for %s", static_cast(status), filePath.c_str()); + return false; + } + + AudioStreamBasicDescription clientFormat{}; + clientFormat.mSampleRate = 44100.0; + clientFormat.mFormatID = kAudioFormatLinearPCM; + clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + clientFormat.mBitsPerChannel = 16; + clientFormat.mChannelsPerFrame = 2; + clientFormat.mFramesPerPacket = 1; + clientFormat.mBytesPerFrame = (clientFormat.mBitsPerChannel / 8) * clientFormat.mChannelsPerFrame; + clientFormat.mBytesPerPacket = clientFormat.mBytesPerFrame * clientFormat.mFramesPerPacket; + + status = ExtAudioFileSetProperty(audioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(clientFormat), &clientFormat); + if (status != noErr) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "[SoundEffect] Failed to set client format (%d) for %s", static_cast(status), filePath.c_str()); + ExtAudioFileDispose(audioFile); + return false; + } + + const UInt32 framesPerBuffer = 2048; + std::vector buffer(framesPerBuffer * clientFormat.mChannelsPerFrame); + while (true) { + AudioBufferList abl{}; + abl.mNumberBuffers = 1; + abl.mBuffers[0].mNumberChannels = clientFormat.mChannelsPerFrame; + abl.mBuffers[0].mDataByteSize = framesPerBuffer * clientFormat.mBytesPerFrame; + abl.mBuffers[0].mData = buffer.data(); + + UInt32 framesToRead = framesPerBuffer; + status = ExtAudioFileRead(audioFile, &framesToRead, &abl); + if (status != noErr) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "[SoundEffect] ExtAudioFileRead failed (%d) for %s", static_cast(status), filePath.c_str()); + ExtAudioFileDispose(audioFile); + return false; + } + + if (framesToRead == 0) { + break; // EOF + } + + size_t samplesRead = static_cast(framesToRead) * clientFormat.mChannelsPerFrame; + pcmData.insert(pcmData.end(), buffer.data(), buffer.data() + samplesRead); + } + + ExtAudioFileDispose(audioFile); + channels = static_cast(clientFormat.mChannelsPerFrame); + sampleRate = static_cast(clientFormat.mSampleRate); + return !pcmData.empty(); #else SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "[SoundEffect] MP3 support not available on this platform"); return false;