Unverified Commit 1a6f4b20 authored by Libretro-Admin's avatar Libretro-Admin Committed by GitHub
Browse files

Merge pull request #50 from jdgleaver/vfs-fullpath

Replace direct file access with VFS routines and set 'need_fullpath = false'
parents 086035c8 1ed85a69
Pipeline #59008 passed with stages
in 8 minutes and 59 seconds
......@@ -10,54 +10,51 @@ INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
endif
SOURCES_C := \
$(CORE_DIR)/src/audio.c \
$(CORE_DIR)/src/cpu.c \
$(CORE_DIR)/src/crc32.c \
$(CORE_DIR)/src/cset.c \
$(CORE_DIR)/src/keyboard.c \
$(CORE_DIR)/src/score.c \
$(CORE_DIR)/src/table.c \
$(CORE_DIR)/src/vdc.c \
$(CORE_DIR)/src/vmachine.c \
$(CORE_DIR)/src/voice.c \
$(CORE_DIR)/src/vpp.c \
$(CORE_DIR)/src/vpp_cset.c \
$(CORE_DIR)/libretro.c \
$(CORE_DIR)/allegrowrapper/wrapalleg.c \
$(CORE_DIR)/src/vkeyb/ui.c \
$(CORE_DIR)/src/vkeyb/vkeyb.c \
$(CORE_DIR)/src/vkeyb/vkeyb_config.c \
$(CORE_DIR)/src/vkeyb/vkeyb_layout.c
$(CORE_DIR)/src/audio.c \
$(CORE_DIR)/src/cpu.c \
$(CORE_DIR)/src/cset.c \
$(CORE_DIR)/src/keyboard.c \
$(CORE_DIR)/src/score.c \
$(CORE_DIR)/src/table.c \
$(CORE_DIR)/src/vdc.c \
$(CORE_DIR)/src/vmachine.c \
$(CORE_DIR)/src/voice.c \
$(CORE_DIR)/src/vpp.c \
$(CORE_DIR)/src/vpp_cset.c \
$(CORE_DIR)/libretro.c \
$(CORE_DIR)/allegrowrapper/wrapalleg.c \
$(CORE_DIR)/src/vkeyb/ui.c \
$(CORE_DIR)/src/vkeyb/vkeyb.c \
$(CORE_DIR)/src/vkeyb/vkeyb_config.c \
$(CORE_DIR)/src/vkeyb/vkeyb_layout.c
ifneq ($(STATIC_LINKING), 1)
SOURCES_C += \
$(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
$(LIBRETRO_COMM_DIR)/time/rtime.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
$(LIBRETRO_COMM_DIR)/file/file_path.c
$(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \
$(LIBRETRO_COMM_DIR)/compat/compat_snprintf.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strl.c \
$(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.c \
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \
$(LIBRETRO_COMM_DIR)/file/file_path.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream_transforms.c \
$(LIBRETRO_COMM_DIR)/string/stdstring.c \
$(LIBRETRO_COMM_DIR)/time/rtime.c \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c
ifeq ($(HAVE_VOICE), 1)
SOURCES_C += \
$(LIBRETRO_COMM_DIR)/audio/audio_mixer.c \
$(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16.c \
$(LIBRETRO_COMM_DIR)/audio/resampler/audio_resampler.c \
$(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler.c \
$(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \
$(LIBRETRO_COMM_DIR)/compat/compat_snprintf.c \
$(LIBRETRO_COMM_DIR)/features/features_cpu.c \
$(LIBRETRO_COMM_DIR)/file/config_file.c \
$(LIBRETRO_COMM_DIR)/file/config_file_userdata.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/formats/wav/rwav.c \
$(LIBRETRO_COMM_DIR)/lists/string_list.c \
$(LIBRETRO_COMM_DIR)/memmap/memalign.c \
$(LIBRETRO_COMM_DIR)/memmap/memmap.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c
SOURCES_C += \
$(LIBRETRO_COMM_DIR)/audio/audio_mixer.c \
$(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16.c \
$(LIBRETRO_COMM_DIR)/audio/resampler/audio_resampler.c \
$(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler.c \
$(LIBRETRO_COMM_DIR)/features/features_cpu.c \
$(LIBRETRO_COMM_DIR)/file/config_file.c \
$(LIBRETRO_COMM_DIR)/file/config_file_userdata.c \
$(LIBRETRO_COMM_DIR)/formats/wav/rwav.c \
$(LIBRETRO_COMM_DIR)/lists/string_list.c \
$(LIBRETRO_COMM_DIR)/memmap/memalign.c
endif
ifeq ($(DEBUG),1)
SOURCES_C += $(CORE_DIR)/src/debug.c
endif
......@@ -267,28 +267,27 @@ static bool wav_to_float(const rwav_t* wav, float** pcm, size_t samples_out)
}
static bool one_shot_resample(const float* in, size_t samples_in,
unsigned rate, float** out, size_t* samples_out)
unsigned rate, const char *resampler_ident, enum resampler_quality quality,
float** out, size_t* samples_out)
{
struct resampler_data info;
void* data = NULL;
const retro_resampler_t* resampler = NULL;
float ratio = (double)s_rate / (double)rate;
if (!retro_resampler_realloc(&data, &resampler, NULL,
RESAMPLER_QUALITY_DONTCARE, ratio))
if (!retro_resampler_realloc(&data, &resampler,
resampler_ident, quality, ratio))
return false;
/*
* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
/* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
* add four more samples in the formula below just as safeguard, because
* resampler->process sometimes reports more output samples than the
* formula below calculates. Ideally, audio resamplers should have a
* function to return the number of samples they will output given a
* count of input samples.
*/
*samples_out = samples_in * ratio + 4;
* count of input samples. */
*samples_out = (size_t)(samples_in * ratio);
*out = (float*)memalign_alloc(16,
((*samples_out + 15) & ~15) * sizeof(float));
(((*samples_out + 4) + 15) & ~15) * sizeof(float));
if (*out == NULL)
return false;
......@@ -323,7 +322,8 @@ void audio_mixer_done(void)
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
}
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size,
const char *resampler_ident, enum resampler_quality quality)
{
#ifdef HAVE_RWAV
/* WAV data */
......@@ -333,9 +333,15 @@ audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
size_t samples = 0;
/* Result */
audio_mixer_sound_t* sound = NULL;
enum rwav_state rwav_ret = rwav_load(&wav, buffer, size);
if (rwav_ret != RWAV_ITERATE_DONE)
wav.bitspersample = 0;
wav.numchannels = 0;
wav.samplerate = 0;
wav.numsamples = 0;
wav.subchunk2size = 0;
wav.samples = NULL;
if ((rwav_load(&wav, buffer, size)) != RWAV_ITERATE_DONE)
return NULL;
samples = wav.numsamples * 2;
......@@ -347,8 +353,9 @@ audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size)
{
float* resampled = NULL;
if (!one_shot_resample(pcm, samples,
wav.samplerate, &resampled, &samples))
if (!one_shot_resample(pcm, samples, wav.samplerate,
resampler_ident, quality,
&resampled, &samples))
return NULL;
memalign_free((void*)pcm);
......@@ -508,6 +515,8 @@ static bool audio_mixer_play_ogg(
audio_mixer_sound_t* sound,
audio_mixer_voice_t* voice,
bool repeat, float volume,
const char *resampler_ident,
enum resampler_quality quality,
audio_mixer_stop_cb_t stop_cb)
{
stb_vorbis_info info;
......@@ -531,14 +540,20 @@ static bool audio_mixer_play_ogg(
ratio = (double)s_rate / (double)info.sample_rate;
if (!retro_resampler_realloc(&resampler_data,
&resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
&resamp, resampler_ident, quality,
ratio))
goto error;
}
/* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
* add four more samples in the formula below just as safeguard, because
* resampler->process sometimes reports more output samples than the
* formula below calculates. Ideally, audio resamplers should have a
* function to return the number of samples they will output given a
* count of input samples. */
samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
ogg_buffer = (float*)memalign_alloc(16,
((samples + 15) & ~15) * sizeof(float));
(((samples + 4) + 15) & ~15) * sizeof(float));
if (!ogg_buffer)
{
......@@ -656,6 +671,8 @@ static bool audio_mixer_play_flac(
audio_mixer_sound_t* sound,
audio_mixer_voice_t* voice,
bool repeat, float volume,
const char *resampler_ident,
enum resampler_quality quality,
audio_mixer_stop_cb_t stop_cb)
{
float ratio = 1.0f;
......@@ -672,14 +689,20 @@ static bool audio_mixer_play_flac(
ratio = (double)s_rate / (double)(dr_flac->sampleRate);
if (!retro_resampler_realloc(&resampler_data,
&resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
&resamp, resampler_ident, quality,
ratio))
goto error;
}
/* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
* add four more samples in the formula below just as safeguard, because
* resampler->process sometimes reports more output samples than the
* formula below calculates. Ideally, audio resamplers should have a
* function to return the number of samples they will output given a
* count of input samples. */
samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
flac_buffer = (float*)memalign_alloc(16,
((samples + 15) & ~15) * sizeof(float));
flac_buffer = (float*)memalign_alloc(16,
(((samples + 4) + 15) & ~15) * sizeof(float));
if (!flac_buffer)
{
......@@ -717,6 +740,8 @@ static bool audio_mixer_play_mp3(
audio_mixer_sound_t* sound,
audio_mixer_voice_t* voice,
bool repeat, float volume,
const char *resampler_ident,
enum resampler_quality quality,
audio_mixer_stop_cb_t stop_cb)
{
float ratio = 1.0f;
......@@ -742,14 +767,20 @@ static bool audio_mixer_play_mp3(
ratio = (double)s_rate / (double)(voice->types.mp3.stream.sampleRate);
if (!retro_resampler_realloc(&resampler_data,
&resamp, NULL, RESAMPLER_QUALITY_DONTCARE,
&resamp, resampler_ident, quality,
ratio))
goto error;
}
/* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
* add four more samples in the formula below just as safeguard, because
* resampler->process sometimes reports more output samples than the
* formula below calculates. Ideally, audio resamplers should have a
* function to return the number of samples they will output given a
* count of input samples. */
samples = (unsigned)(AUDIO_MIXER_TEMP_BUFFER * ratio);
mp3_buffer = (float*)memalign_alloc(16,
((samples + 15) & ~15) * sizeof(float));
(((samples + 4) + 15) & ~15) * sizeof(float));
if (!mp3_buffer)
{
......@@ -780,8 +811,11 @@ error:
}
#endif
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
float volume, audio_mixer_stop_cb_t stop_cb)
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound,
bool repeat, float volume,
const char *resampler_ident,
enum resampler_quality quality,
audio_mixer_stop_cb_t stop_cb)
{
unsigned i;
bool res = false;
......@@ -802,7 +836,8 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
break;
case AUDIO_MIXER_TYPE_OGG:
#ifdef HAVE_STB_VORBIS
res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
res = audio_mixer_play_ogg(sound, voice, repeat, volume,
resampler_ident, quality, stop_cb);
#endif
break;
case AUDIO_MIXER_TYPE_MOD:
......@@ -812,12 +847,14 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
break;
case AUDIO_MIXER_TYPE_FLAC:
#ifdef HAVE_DR_FLAC
res = audio_mixer_play_flac(sound, voice, repeat, volume, stop_cb);
res = audio_mixer_play_flac(sound, voice, repeat, volume,
resampler_ident, quality, stop_cb);
#endif
break;
case AUDIO_MIXER_TYPE_MP3:
#ifdef HAVE_DR_MP3
res = audio_mixer_play_mp3(sound, voice, repeat, volume, stop_cb);
res = audio_mixer_play_mp3(sound, voice, repeat, volume,
resampler_ident, quality, stop_cb);
#endif
break;
case AUDIO_MIXER_TYPE_NONE:
......
/* Copyright (C) 2010-2020 The RetroArch team
/* Copyright (C) 2010-2021 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (float_to_s16.c).
......@@ -28,37 +28,75 @@
#include <altivec.h>
#endif
#if (defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)) || defined(HAVE_NEON)
#ifndef HAVE_ARM_NEON_OPTIMIZATIONS
#define HAVE_ARM_NEON_OPTIMIZATIONS
#endif
#endif
#include <features/features_cpu.h>
#include <audio/conversion/float_to_s16.h>
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
#if (defined(__ARM_NEON__) || defined(HAVE_NEON))
static bool float_to_s16_neon_enabled = false;
void convert_float_s16_asm(int16_t *out, const float *in, size_t samples);
#ifdef HAVE_ARM_NEON_ASM_OPTIMIZATIONS
void convert_float_s16_asm(int16_t *out,
const float *in, size_t samples);
#else
#include <arm_neon.h>
#endif
/**
* convert_float_to_s16:
* @out : output buffer
* @in : input buffer
* @samples : size of samples to be converted
*
* Converts floating point
* to signed integer 16-bit.
*
* C implementation callback function.
**/
void convert_float_to_s16(int16_t *out,
const float *in, size_t samples)
{
size_t i = 0;
size_t i = 0;
if (float_to_s16_neon_enabled)
{
float gf = (1<<15);
float32x4_t vgf = {gf, gf, gf, gf};
while (samples >= 8)
{
#ifdef HAVE_ARM_NEON_ASM_OPTIMIZATIONS
size_t aligned_samples = samples & ~7;
if (aligned_samples)
convert_float_s16_asm(out, in, aligned_samples);
out += aligned_samples;
in += aligned_samples;
samples -= aligned_samples;
i = 0;
#else
int16x4x2_t oreg;
int32x4x2_t creg;
float32x4x2_t inreg = vld2q_f32(in);
creg.val[0] = vcvtq_s32_f32(vmulq_f32(inreg.val[0], vgf));
creg.val[1] = vcvtq_s32_f32(vmulq_f32(inreg.val[1], vgf));
oreg.val[0] = vqmovn_s32(creg.val[0]);
oreg.val[1] = vqmovn_s32(creg.val[1]);
vst2_s16(out, oreg);
in += 8;
out += 8;
samples -= 8;
#endif
}
}
for (; i < samples; i++)
{
int32_t val = (int32_t)(in[i] * 0x8000);
out[i] = (val > 0x7FFF) ? 0x7FFF :
(val < -0x8000 ? -0x8000 : (int16_t)val);
}
}
void convert_float_to_s16_init_simd(void)
{
uint64_t cpu = cpu_features_get();
if (cpu & RETRO_SIMD_NEON)
float_to_s16_neon_enabled = true;
}
#else
void convert_float_to_s16(int16_t *out,
const float *in, size_t samples)
{
size_t i = 0;
#if defined(__SSE2__)
__m128 factor = _mm_set1_ps((float)0x8000);
__m128 factor = _mm_set1_ps((float)0x8000);
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
{
......@@ -73,10 +111,10 @@ void convert_float_to_s16(int16_t *out,
_mm_storeu_si128((__m128i *)out, packed);
}
samples = samples - i;
i = 0;
samples = samples - i;
i = 0;
#elif defined(__ALTIVEC__)
int samples_in = samples;
int samples_in = samples;
/* Unaligned loads/store is a bit expensive,
* so we optimize for the good path (very likely). */
......@@ -92,25 +130,12 @@ void convert_float_to_s16(int16_t *out,
vec_st(vec_packs(result0, result1), 0, out);
}
samples_in -= i;
samples_in -= i;
}
samples = samples_in;
i = 0;
#elif defined(HAVE_ARM_NEON_OPTIMIZATIONS)
if (float_to_s16_neon_enabled)
{
size_t aligned_samples = samples & ~7;
if (aligned_samples)
convert_float_s16_asm(out, in, aligned_samples);
out = out + aligned_samples;
in = in + aligned_samples;
samples = samples - aligned_samples;
i = 0;
}
samples = samples_in;
i = 0;
#elif defined(_MIPS_ARCH_ALLEGREX)
#ifdef DEBUG
/* Make sure the buffers are 16 byte aligned, this should be
* the default behaviour of malloc in the PSPSDK.
......@@ -138,29 +163,16 @@ void convert_float_to_s16(int16_t *out,
".set pop \n"
:: "r"(in + i), "r"(out + i));
}
#endif
for (; i < samples; i++)
{
int32_t val = (int32_t)(in[i] * 0x8000);
out[i] = (val > 0x7FFF) ? 0x7FFF :
(val < -0x8000 ? -0x8000 : (int16_t)val);
int32_t val = (int32_t)(in[i] * 0x8000);
out[i] = (val > 0x7FFF)
? 0x7FFF
: (val < -0x8000 ? -0x8000 : (int16_t)val);
}
}
/**
* convert_float_to_s16_init_simd:
*
* Sets up function pointers for conversion
* functions based on CPU features.
**/
void convert_float_to_s16_init_simd(void)
{
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
unsigned cpu = cpu_features_get();
if (cpu & RETRO_SIMD_NEON)
float_to_s16_neon_enabled = true;
void convert_float_to_s16_init_simd(void) { }
#endif
}
......@@ -19,7 +19,7 @@
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_ASM_OPTIMIZATIONS)
#ifndef __MACH__
.arm
......
......@@ -19,7 +19,7 @@
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_ASM_OPTIMIZATIONS)
#if defined(__thumb__)
#define DECL_ARMMODE(x) " .align 2\n" " .global " x "\n" " .thumb\n" " .thumb_func\n" " .type " x ", %function\n" x ":\n"
......
......@@ -75,7 +75,6 @@ typedef struct rarch_sinc_resampler
float *phase_table;
float *buffer_l;
float *buffer_r;
unsigned enable_avx;
unsigned phase_bits;
unsigned subphase_bits;
unsigned subphase_mask;
......@@ -84,34 +83,27 @@ typedef struct rarch_sinc_resampler
uint32_t time;
float subphase_mod;
float kaiser_beta;
enum sinc_window window_type;
} rarch_sinc_resampler_t;
#if (defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)) || defined(HAVE_NEON)
#if TARGET_OS_IPHONE
#else
#ifndef WANT_NEON
#define WANT_NEON
#endif
#endif
#endif
#if (defined(__ARM_NEON__) || defined(HAVE_NEON))
#ifdef WANT_NEON
/* Assumes that taps >= 8, and that taps is a multiple of 8. */
#ifdef HAVE_ARM_NEON_ASM_OPTIMIZATIONS
void process_sinc_neon_asm(float *out, const float *left,
const float *right, const float *coeff, unsigned taps);
#else
#include <arm_neon.h>
#endif
/* Assumes that taps >= 8, and that taps is a multiple of 8. */
static void resampler_sinc_process_neon(void *re_, struct resampler_data *data)
{
rarch_sinc_resampler_t *resamp = (rarch_sinc_resampler_t*)re_;
unsigned phases = 1 << (resamp->phase_bits + resamp->subphase_bits);
uint32_t ratio = phases / data->ratio;
const float *input = data->data_in;
float *output = data->data_out;
size_t frames = data->input_frames;
size_t out_frames = 0;
while (frames)
{
while (frames && resamp->time >= phases)
......@@ -122,10 +114,10 @@ static void resampler_sinc_process_neon(void *re_, struct resampler_data *data)
resamp->ptr--;
resamp->buffer_l[resamp->ptr + resamp->taps] =
resamp->buffer_l[resamp->ptr] = *input++;
resamp->buffer_l[resamp->ptr] = *input++;
resamp->buffer_r[resamp->ptr + resamp->taps] =
resamp->buffer_r[resamp->ptr] = *input++;
resamp->buffer_r[resamp->ptr] = *input++;
resamp->time -= phases;
frames--;
......@@ -139,12 +131,32 @@ static void resampler_sinc_process_neon(void *re_, struct resampler_data *data)
{
unsigned phase = resamp->time >> resamp->subphase_bits;
const float *phase_table = resamp->phase_table + phase * taps;
#ifdef HAVE_ARM_NEON_ASM_OPTIMIZATIONS
process_sinc_neon_asm(output, buffer_l, buffer_r, phase_table, taps);
#else
unsigned i;
float32x4_t p1 = {0, 0, 0, 0}, p2 = {0, 0, 0, 0};
float32x2_t p3, p4;
output += 2;
for (i = 0; i < taps; i += 8)
{
float32x4x2_t coeff8 = vld2q_f32(&phase_table[i]);
float32x4x2_t left8 = vld2q_f32(&buffer_l[i]);
float32x4x2_t right8 = vld2q_f32(&buffer_r[i]);
p1 = vmlaq_f32(p1, left8.val[0], coeff8.val[0]);
p2 = vmlaq_f32(p2, right8.val[0], coeff8.val[0]);
p1 = vmlaq_f32(p1, left8.val[1], coeff8.val[1]);
p2 = vmlaq_f32(p2, right8.val[1], coeff8.val[1]);
}
p3 = vadd_f32(vget_low_f32(p1), vget_high_f32(p1));
p4 = vadd_f32(vget_low_f32(p2), vget_high_f32(p2));
vst1_f32(output, vpadd_f32(p3, p4));
#endif
output += 2;
out_frames++;
resamp->time += ratio;
resamp->time += ratio;
}
}
}
......@@ -154,7 +166,7 @@ static void resampler_sinc_process_neon(void *re_, struct resampler_data *data)
#endif
#if defined(__AVX__)
static void resampler_sinc_process_avx(void *re_, struct resampler_data *data)