use libsamplerate for conversion

This commit is contained in:
Squall Leonhart 2024-01-20 05:13:21 +11:00 committed by Squall-Leonhart
parent f915ec5972
commit 139aff1b50
2 changed files with 52 additions and 27 deletions

View File

@ -204,21 +204,22 @@ IF(SDL2_LIBRARY_TEMP)
# Add libsamplerate with vcpkg # Add libsamplerate with vcpkg
if(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg") if(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg")
if(WIN32) find_package(SampleRate CONFIG REQUIRED)
unset(arch_suffix) if(WIN32)
unset(path_prefix) unset(arch_suffix)
if(VCPKG_TARGET_TRIPLET MATCHES -static) unset(path_prefix)
set(arch_suffix -static) if(VCPKG_TARGET_TRIPLET MATCHES -static)
endif() set(arch_suffix -static)
if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$") endif()
set(path_prefix debug) if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$")
endif() set(path_prefix debug)
set(installed_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/${path_prefix}) endif()
set(installed_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/${path_prefix})
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${installed_prefix}/lib/samplerate.lib) SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} SampleRate::samplerate)
else() else()
SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} -lsamplerate) SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} SampleRate::samplerate)
endif() endif()
endif() endif()
# Add some stuff from pkg-config, if available # Add some stuff from pkg-config, if available

View File

@ -18,6 +18,7 @@
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <SDL_events.h> #include <SDL_events.h>
#include <samplerate.h>
#include "SoundSDL.h" #include "SoundSDL.h"
#include "../gba/Globals.h" #include "../gba/Globals.h"
#include "../gba/Sound.h" #include "../gba/Sound.h"
@ -83,28 +84,52 @@ void SoundSDL::write(uint16_t * finalWave, int length) {
SDL_LockMutex(mutex); SDL_LockMutex(mutex);
if (SDL_GetAudioDeviceStatus(sound_device) != SDL_AUDIO_PLAYING) if (SDL_GetAudioDeviceStatus(sound_device) != SDL_AUDIO_PLAYING)
SDL_PauseAudioDevice(sound_device, 0); SDL_PauseAudioDevice(sound_device, 0);
std::size_t samples = length / 4; std::size_t samples = length / 4;
std::size_t avail; std::size_t avail;
// Create a new SRC_STATE object for the resampling
int error;
SRC_STATE* src_state = src_new(SRC_SINC_FASTEST, 2, &error);
if (!src_state) {
// Handle the error
}
// Set up the SRC_DATA struct
SRC_DATA src_data;
src_data.data_in = finalWave;
src_data.input_frames = length / 2;
src_data.data_out = finalWave;
src_data.output_frames = length / 2;
src_data.src_ratio = (double)desired_sample_rate / current_sample_rate;
// Perform the resampling
error = src_process(src_state, &src_data);
if (error) {
// Handle the error
}
// Clean up
src_delete(src_state);
while ((avail = samples_buf.avail() / 2) < samples) { while ((avail = samples_buf.avail() / 2) < samples) {
samples_buf.write(finalWave, avail * 2); samples_buf.write(finalWave, avail * 2);
finalWave += avail * 2; finalWave += avail * 2;
samples -= avail; samples -= avail;
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
SDL_SemPost(data_available); SDL_SemPost(data_available);
if (should_wait()) if (should_wait())
SDL_SemWait(data_read); SDL_SemWait(data_read);
else else
// Drop the remainder of the audio data // Drop the remainder of the audio data
return; return;
SDL_LockMutex(mutex); SDL_LockMutex(mutex);
} }
samples_buf.write(finalWave, samples * 2); samples_buf.write(finalWave, samples * 2);
@ -112,7 +137,6 @@ void SoundSDL::write(uint16_t * finalWave, int length) {
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
} }
bool SoundSDL::init(long sampleRate) { bool SoundSDL::init(long sampleRate) {
if (initialized) deinit(); if (initialized) deinit();