mirror of
https://github.com/libretro/RetroArch
synced 2025-02-11 06:40:48 +00:00
Add hermite resampler core :) SRC is disabled by default.
This commit is contained in:
parent
caf3eb7b05
commit
820b124165
2
Makefile
2
Makefile
@ -19,6 +19,8 @@ endif
|
||||
ifeq ($(HAVE_SRC), 1)
|
||||
LIBS += $(SRC_LIBS)
|
||||
DEFINES += $(SRC_CFLAGS)
|
||||
else
|
||||
OBJ += audio/hermite.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CONFIGFILE), 1)
|
||||
|
@ -18,13 +18,13 @@ SSNES requires these libraries to build:
|
||||
|
||||
- [libsnes](http://byuu.org/bsnes/)
|
||||
- SDL
|
||||
- libsamplerate
|
||||
|
||||
SSNES can utilize these libraries if enabled:
|
||||
|
||||
- nvidia-cg-toolkit
|
||||
- libxml2 (bSNES XML shaders)
|
||||
- libfreetype2 (TTF font rendering on screen)
|
||||
- libsamplerate
|
||||
|
||||
SSNES needs at least one of these audio driver libraries:
|
||||
|
||||
|
@ -38,8 +38,6 @@
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
#include <samplerate.h>
|
||||
#else
|
||||
#error HAVE_SRC is not defined!
|
||||
#endif
|
||||
|
||||
|
||||
@ -144,7 +142,9 @@ static const int out_latency = 64;
|
||||
static const bool audio_sync = true;
|
||||
|
||||
// Defines the quality (and cpu reqirements) of samplerate conversion.
|
||||
#ifdef HAVE_SRC
|
||||
#define SAMPLERATE_QUALITY SRC_LINEAR
|
||||
#endif
|
||||
|
||||
// Enables use of rewind. This will incur some memory footprint depending on the save state buffer.
|
||||
// This rewind only works when using bSNES core atm.
|
||||
|
20
driver.c
20
driver.c
@ -166,10 +166,16 @@ void init_audio(void)
|
||||
else
|
||||
g_extern.audio_data.chunk_size = g_extern.audio_data.block_chunk_size;
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
int err;
|
||||
g_extern.source = src_new(g_settings.audio.src_quality, 2, &err);
|
||||
if (!g_extern.source)
|
||||
g_extern.audio_data.source = src_new(g_settings.audio.src_quality, 2, &err);
|
||||
if (!g_extern.audio_data.source)
|
||||
g_extern.audio_active = false;
|
||||
#else
|
||||
g_extern.audio_data.source = hermite_new();
|
||||
if (!g_extern.audio_data.source)
|
||||
g_extern.audio_active = false;
|
||||
#endif
|
||||
|
||||
size_t max_bufsamples = g_extern.audio_data.block_chunk_size > g_extern.audio_data.nonblock_chunk_size ?
|
||||
g_extern.audio_data.block_chunk_size : g_extern.audio_data.nonblock_chunk_size;
|
||||
@ -192,8 +198,14 @@ void uninit_audio(void)
|
||||
if ( driver.audio_data && driver.audio )
|
||||
driver.audio->free(driver.audio_data);
|
||||
|
||||
if ( g_extern.source )
|
||||
src_delete(g_extern.source);
|
||||
if ( g_extern.audio_data.source )
|
||||
{
|
||||
#ifdef HAVE_SRC
|
||||
src_delete(g_extern.audio_data.source);
|
||||
#else
|
||||
hermite_free(g_extern.audio_data.source);
|
||||
#endif
|
||||
}
|
||||
|
||||
free(g_extern.audio_data.data); g_extern.audio_data.data = NULL;
|
||||
free(g_extern.audio_data.outsamples); g_extern.audio_data.outsamples = NULL;
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
#include <samplerate.h>
|
||||
#else
|
||||
#include "audio/hermite.h"
|
||||
#endif
|
||||
|
||||
|
||||
@ -106,7 +108,6 @@ enum ssnes_game_type
|
||||
struct global
|
||||
{
|
||||
bool verbose;
|
||||
SRC_STATE *source;
|
||||
bool audio_active;
|
||||
bool video_active;
|
||||
|
||||
@ -140,6 +141,12 @@ struct global
|
||||
|
||||
struct
|
||||
{
|
||||
#ifdef HAVE_SRC
|
||||
SRC_STATE *source;
|
||||
#else
|
||||
hermite_resampler_t *source;
|
||||
#endif
|
||||
|
||||
float *data;
|
||||
size_t data_ptr;
|
||||
size_t chunk_size;
|
||||
|
@ -46,7 +46,6 @@ if [ $HAVE_FFMPEG != no ]; then
|
||||
fi
|
||||
|
||||
check_pkgconf SRC samplerate
|
||||
check_critical SRC "Cannot find libsamplerate."
|
||||
|
||||
check_lib DYNAMIC -ldl dlopen
|
||||
|
||||
|
@ -11,6 +11,7 @@ add_command_line_enable DYNAMIC "Enable dynamic loading of libsnes library." no
|
||||
add_command_line_string LIBSNES "libsnes library used" "-lsnes"
|
||||
add_command_line_enable FFMPEG "Enable FFmpeg recording support" no
|
||||
add_command_line_enable FILTER "Enable CPU filter support" no
|
||||
add_command_line_enable SRC "Enable libsamplerate support" no
|
||||
add_command_line_enable CONFIGFILE "Disable support for config file" yes
|
||||
add_command_line_enable CG "Enable Cg shader support" auto
|
||||
add_command_line_enable XML "Enable bSNES-style XML shader support" auto
|
||||
|
@ -122,7 +122,10 @@ static void set_defaults(void)
|
||||
strncpy(g_settings.audio.device, audio_device, sizeof(g_settings.audio.device));
|
||||
g_settings.audio.latency = out_latency;
|
||||
g_settings.audio.sync = audio_sync;
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
g_settings.audio.src_quality = SAMPLERATE_QUALITY;
|
||||
#endif
|
||||
|
||||
g_settings.rewind_enable = rewind_enable;
|
||||
g_settings.rewind_buffer_size = rewind_buffer_size;
|
||||
@ -300,6 +303,7 @@ static void parse_config_file(void)
|
||||
CONFIG_GET_INT(audio.latency, "audio_latency");
|
||||
CONFIG_GET_BOOL(audio.sync, "audio_sync");
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
if (config_get_int(conf, "audio_src_quality", &tmp_int))
|
||||
{
|
||||
int quals[] = { SRC_ZERO_ORDER_HOLD, SRC_LINEAR, SRC_SINC_FASTEST,
|
||||
@ -308,6 +312,7 @@ static void parse_config_file(void)
|
||||
if (tmp_int > 0 && tmp_int < 6)
|
||||
g_settings.audio.src_quality = quals[tmp_int];
|
||||
}
|
||||
#endif
|
||||
|
||||
CONFIG_GET_STRING(video.driver, "video_driver");
|
||||
CONFIG_GET_STRING(audio.driver, "audio_driver");
|
||||
|
51
ssnes.c
51
ssnes.c
@ -179,8 +179,8 @@ static void audio_sample(uint16_t left, uint16_t right)
|
||||
}
|
||||
#endif
|
||||
|
||||
g_extern.audio_data.data[g_extern.audio_data.data_ptr++] = (float)(*(int16_t*)&left)/0x8000;
|
||||
g_extern.audio_data.data[g_extern.audio_data.data_ptr++] = (float)(*(int16_t*)&right)/0x8000;
|
||||
g_extern.audio_data.data[g_extern.audio_data.data_ptr++] = (float)(int16_t)left/0x8000;
|
||||
g_extern.audio_data.data[g_extern.audio_data.data_ptr++] = (float)(int16_t)right/0x8000;
|
||||
|
||||
if (g_extern.audio_data.data_ptr >= g_extern.audio_data.chunk_size)
|
||||
{
|
||||
@ -188,20 +188,37 @@ static void audio_sample(uint16_t left, uint16_t right)
|
||||
if (g_extern.frame_is_reverse) // Disable fucked up audio when rewinding...
|
||||
memset(g_extern.audio_data.data, 0, g_extern.audio_data.chunk_size * sizeof(float));
|
||||
|
||||
SRC_DATA src_data;
|
||||
#ifdef HAVE_SRC
|
||||
SRC_DATA src_data = {
|
||||
.data_in = g_extern.audio_data.data,
|
||||
.data_out = g_extern.audio_data.outsamples,
|
||||
.input_frames = g_extern.audio_data.chunk_size / 2,
|
||||
.output_frames = g_extern.audio_data.chunk_size * 8,
|
||||
.end_of_input = 0,
|
||||
.src_ratio = (double)g_settings.audio.out_rate / (double)g_settings.audio.in_rate,
|
||||
};
|
||||
#else
|
||||
struct hermite_data re_data = {
|
||||
.in_data = g_extern.audio_data.data,
|
||||
.out_data = g_extern.audio_data.outsamples,
|
||||
.in_frames = g_extern.audio_data.chunk_size / 2,
|
||||
.ratio = (double)g_settings.audio.out_rate / (double)g_settings.audio.in_rate,
|
||||
};
|
||||
#endif
|
||||
|
||||
src_data.data_in = g_extern.audio_data.data;
|
||||
src_data.data_out = g_extern.audio_data.outsamples;
|
||||
src_data.input_frames = g_extern.audio_data.chunk_size / 2;
|
||||
src_data.output_frames = g_extern.audio_data.chunk_size * 8;
|
||||
src_data.end_of_input = 0;
|
||||
src_data.src_ratio = (double)g_settings.audio.out_rate / (double)g_settings.audio.in_rate;
|
||||
|
||||
src_process(g_extern.source, &src_data);
|
||||
#ifdef HAVE_SRC
|
||||
src_process(g_extern.audio_data.source, &src_data);
|
||||
#else
|
||||
size_t output_frames_gen = hermite_process(g_extern.audio_data.source, &re_data);
|
||||
#endif
|
||||
|
||||
if (g_extern.audio_data.use_float)
|
||||
{
|
||||
#ifdef HAVE_SRC
|
||||
if (driver.audio->write(driver.audio_data, g_extern.audio_data.outsamples, src_data.output_frames_gen * sizeof(float) * 2) < 0)
|
||||
#else
|
||||
if (driver.audio->write(driver.audio_data, g_extern.audio_data.outsamples, output_frames_gen * sizeof(float) * 2) < 0)
|
||||
#endif
|
||||
{
|
||||
fprintf(stderr, "SSNES [ERROR]: Audio backend failed to write. Will continue without sound.\n");
|
||||
g_extern.audio_active = false;
|
||||
@ -209,9 +226,21 @@ static void audio_sample(uint16_t left, uint16_t right)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_SRC
|
||||
src_float_to_short_array(g_extern.audio_data.outsamples, g_extern.audio_data.conv_outsamples, src_data.output_frames_gen * 2);
|
||||
#else
|
||||
for (unsigned i = 0; i < output_frames_gen * 2; i++)
|
||||
{
|
||||
int32_t val = g_extern.audio_data.outsamples[i] * 0x8000;
|
||||
g_extern.audio_data.conv_outsamples[i] = (val > 0x7FFF) ? 0x7FFF : (val < -0x8000 ? -0x8000 : (int16_t)val);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
if (driver.audio->write(driver.audio_data, g_extern.audio_data.conv_outsamples, src_data.output_frames_gen * sizeof(int16_t) * 2) < 0)
|
||||
#else
|
||||
if (driver.audio->write(driver.audio_data, g_extern.audio_data.conv_outsamples, output_frames_gen * sizeof(int16_t) * 2) < 0)
|
||||
#endif
|
||||
{
|
||||
fprintf(stderr, "SSNES [ERROR]: Audio backend failed to write. Will continue without sound.\n");
|
||||
g_extern.audio_active = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user