Unverified Commit 40e92255 authored by RobLoach's avatar RobLoach
Browse files

Update libretro

parent 759e1d7b
......@@ -61,8 +61,7 @@ SOURCES_C += $(LUALIB_DIR)/lapi.c \
$(LUALIB_DIR)/ldump.c
endif
SOURCES_C += $(CORE_DIR)/libretro-common/formats/png/rpng_decode.c \
$(CORE_DIR)/libretro-common/formats/png/rpng_fbio.c
SOURCES_C += $(CORE_DIR)/libretro-common/formats/png/rpng.c
ifneq ($(STATIC_LINKING), 1)
SOURCES_C += \
......@@ -76,7 +75,10 @@ SOURCES_C += \
$(CORE_DIR)/libretro-common/compat/compat_strcasestr.c \
$(CORE_DIR)/libretro-common/compat/compat_strl.c \
$(CORE_DIR)/libretro-common/encodings/encoding_utf.c \
$(CORE_DIR)/libretro-common/file/file_path.c \
$(CORE_DIR)/libretro-common/time/rtime.c \
$(CORE_DIR)/libretro-common/streams/file_stream.c \
$(CORE_DIR)/libretro-common/streams/trans_stream.c \
$(CORE_DIR)/libretro-common/vfs/vfs_implementation.c \
$(CORE_DIR)/libretro-common/compat/fopen_utf8.c
ifeq ($(HAVE_NEON),1)
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (audio_mix.c).
......@@ -20,7 +20,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <audio/audio_mix.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memalign.h>
#include <retro_environment.h>
#if defined(__SSE2__)
#include <emmintrin.h>
......@@ -28,6 +33,12 @@
#include <altivec.h>
#endif
#include <retro_miscellaneous.h>
#include <audio/audio_mix.h>
#include <streams/file_stream.h>
#include <audio/conversion/float_to_s16.h>
#include <audio/conversion/s16_to_float.h>
void audio_mix_volume_C(float *out, const float *in, float vol, size_t samples)
{
size_t i;
......@@ -38,7 +49,7 @@ void audio_mix_volume_C(float *out, const float *in, float vol, size_t samples)
#ifdef __SSE2__
void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t samples)
{
size_t i;
size_t i, remaining_samples;
__m128 volume = _mm_set1_ps(vol);
for (i = 0; i + 16 <= samples; i += 16, out += 16, in += 16)
......@@ -46,7 +57,7 @@ void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t sample
unsigned j;
__m128 input[4];
__m128 additive[4];
input[0] = _mm_loadu_ps(out + 0);
input[1] = _mm_loadu_ps(out + 4);
input[2] = _mm_loadu_ps(out + 8);
......@@ -61,7 +72,310 @@ void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t sample
_mm_storeu_ps(out + 4 * j, _mm_add_ps(input[j], additive[j]));
}
audio_mix_volume_C(out, in, vol, samples - i);
remaining_samples = samples - i;
for (i = 0; i < remaining_samples; i++)
out[i] += in[i] * vol;
}
#endif
void audio_mix_free_chunk(audio_chunk_t *chunk)
{
if (!chunk)
return;
#ifdef HAVE_RWAV
if (chunk->rwav && chunk->rwav->samples)
{
/* rwav_free only frees the samples */
rwav_free(chunk->rwav);
free(chunk->rwav);
}
#endif
if (chunk->buf)
free(chunk->buf);
if (chunk->upsample_buf)
memalign_free(chunk->upsample_buf);
if (chunk->float_buf)
memalign_free(chunk->float_buf);
if (chunk->float_resample_buf)
memalign_free(chunk->float_resample_buf);
if (chunk->resample_buf)
memalign_free(chunk->resample_buf);
if (chunk->resampler && chunk->resampler_data)
chunk->resampler->free(chunk->resampler_data);
free(chunk);
}
audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate)
{
#ifdef HAVE_RWAV
int sample_size;
int64_t len = 0;
void *buf = NULL;
audio_chunk_t *chunk = (audio_chunk_t*)malloc(sizeof(*chunk));
if (!chunk)
return NULL;
chunk->buf = NULL;
chunk->upsample_buf = NULL;
chunk->float_buf = NULL;
chunk->float_resample_buf = NULL;
chunk->resample_buf = NULL;
chunk->len = 0;
chunk->resample_len = 0;
chunk->rwav = (rwav_t*)malloc(sizeof(rwav_t));
chunk->sample_rate = sample_rate;
chunk->resample = false;
chunk->resampler = NULL;
chunk->resampler_data = NULL;
chunk->ratio = 0.00f;
chunk->rwav->bitspersample = 0;
chunk->rwav->numchannels = 0;
chunk->rwav->samplerate = 0;
chunk->rwav->numsamples = 0;
chunk->rwav->subchunk2size = 0;
chunk->rwav->samples = NULL;
if (!filestream_read_file(path, &buf, &len))
{
printf("Could not open WAV file for reading.\n");
goto error;
}
chunk->buf = buf;
chunk->len = len;
if (rwav_load(chunk->rwav, chunk->buf, chunk->len) == RWAV_ITERATE_ERROR)
{
printf("error: could not load WAV file\n");
goto error;
}
/* numsamples does not know or care about
* multiple channels, but we need space for 2 */
chunk->upsample_buf = (int16_t*)memalign_alloc(128,
chunk->rwav->numsamples * 2 * sizeof(int16_t));
sample_size = chunk->rwav->bitspersample / 8;
if (sample_size == 1)
{
unsigned i;
if (chunk->rwav->numchannels == 1)
{
for (i = 0; i < chunk->rwav->numsamples; i++)
{
uint8_t *sample = (
(uint8_t*)chunk->rwav->samples) + i;
chunk->upsample_buf[i * 2] =
(int16_t)((sample[0] - 128) << 8);
chunk->upsample_buf[(i * 2) + 1] =
(int16_t)((sample[0] - 128) << 8);
}
}
else if (chunk->rwav->numchannels == 2)
{
for (i = 0; i < chunk->rwav->numsamples; i++)
{
uint8_t *sample = (
(uint8_t*)chunk->rwav->samples) +
(i * 2);
chunk->upsample_buf[i * 2] =
(int16_t)((sample[0] - 128) << 8);
chunk->upsample_buf[(i * 2) + 1] =
(int16_t)((sample[1] - 128) << 8);
}
}
}
else if (sample_size == 2)
{
if (chunk->rwav->numchannels == 1)
{
unsigned i;
for (i = 0; i < chunk->rwav->numsamples; i++)
{
int16_t sample = ((int16_t*)
chunk->rwav->samples)[i];
chunk->upsample_buf[i * 2] = sample;
chunk->upsample_buf[(i * 2) + 1] = sample;
}
}
else if (chunk->rwav->numchannels == 2)
memcpy(chunk->upsample_buf, chunk->rwav->samples,
chunk->rwav->subchunk2size);
}
else if (sample_size != 2)
{
/* we don't support any other sample size besides 8 and 16-bit yet */
printf("error: we don't support a sample size of %d\n", sample_size);
goto error;
}
if (sample_rate != (int)chunk->rwav->samplerate)
{
chunk->resample = true;
chunk->ratio = (double)sample_rate / chunk->rwav->samplerate;
retro_resampler_realloc(&chunk->resampler_data,
&chunk->resampler,
NULL,
RESAMPLER_QUALITY_DONTCARE,
chunk->ratio);
if (chunk->resampler && chunk->resampler_data)
{
struct resampler_data info;
chunk->float_buf = (float*)memalign_alloc(128,
chunk->rwav->numsamples * 2 *
chunk->ratio * sizeof(float));
/* why is *3 needed instead of just *2? Does the
* sinc driver require more space than we know about? */
chunk->float_resample_buf = (float*)memalign_alloc(128,
chunk->rwav->numsamples * 3 *
chunk->ratio * sizeof(float));
convert_s16_to_float(chunk->float_buf,
chunk->upsample_buf, chunk->rwav->numsamples * 2, 1.0);
info.data_in = (const float*)chunk->float_buf;
info.data_out = chunk->float_resample_buf;
/* a 'frame' consists of two channels, so we set this
* to the number of samples irrespective of channel count */
info.input_frames = chunk->rwav->numsamples;
info.output_frames = 0;
info.ratio = chunk->ratio;
chunk->resampler->process(chunk->resampler_data, &info);
/* number of output_frames does not increase with
* multiple channels, but assume we need space for 2 */
chunk->resample_buf = (int16_t*)memalign_alloc(128,
info.output_frames * 2 * sizeof(int16_t));
chunk->resample_len = info.output_frames;
convert_float_to_s16(chunk->resample_buf,
chunk->float_resample_buf, info.output_frames * 2);
}
}
return chunk;
error:
audio_mix_free_chunk(chunk);
#endif
return NULL;
}
size_t audio_mix_get_chunk_num_samples(audio_chunk_t *chunk)
{
if (!chunk)
return 0;
#ifdef HAVE_RWAV
if (chunk->rwav)
{
if (chunk->resample)
return chunk->resample_len;
return chunk->rwav->numsamples;
}
#endif
/* no other filetypes supported yet */
return 0;
}
/**
* audio_mix_get_chunk_sample:
* @chunk : audio chunk instance
* @channel : channel of the sample (0=left, 1=right)
* @index : index of the sample
*
* Get a sample from an audio chunk.
*
* Returns: A signed 16-bit audio sample.
**/
int16_t audio_mix_get_chunk_sample(audio_chunk_t *chunk,
unsigned channel, size_t index)
{
if (!chunk)
return 0;
#ifdef HAVE_RWAV
if (chunk->rwav)
{
int sample_size = chunk->rwav->bitspersample / 8;
int16_t sample_out = 0;
/* 0 is the first/left channel */
uint8_t *sample = NULL;
if (chunk->resample)
sample = (uint8_t*)chunk->resample_buf +
(sample_size * index * chunk->rwav->numchannels)
+ (channel * sample_size);
else
sample = (uint8_t*)chunk->upsample_buf +
(sample_size * index * chunk->rwav->numchannels)
+ (channel * sample_size);
sample_out = (int16_t)*sample;
return sample_out;
}
#endif
/* no other filetypes supported yet */
return 0;
}
int16_t* audio_mix_get_chunk_samples(audio_chunk_t *chunk)
{
if (!chunk)
return 0;
#ifdef HAVE_RWAV
if (chunk->rwav)
{
int16_t *sample;
if (chunk->resample)
sample = chunk->resample_buf;
else
sample = chunk->upsample_buf;
return sample;
}
#endif
return NULL;
}
int audio_mix_get_chunk_num_channels(audio_chunk_t *chunk)
{
if (!chunk)
return 0;
#ifdef HAVE_RWAV
if (chunk->rwav)
return chunk->rwav->numchannels;
#endif
/* don't support other formats yet */
return 0;
}
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (float_to_s16.c).
......@@ -28,10 +28,16 @@
#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(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
static bool float_to_s16_neon_enabled = false;
void convert_float_s16_asm(int16_t *out, const float *in, size_t samples);
#endif
......@@ -42,7 +48,7 @@ void convert_float_s16_asm(int16_t *out, const float *in, size_t samples);
* @in : input buffer
* @samples : size of samples to be converted
*
* Converts floating point
* Converts floating point
* to signed integer 16-bit.
*
* C implementation callback function.
......@@ -72,7 +78,7 @@ void convert_float_to_s16(int16_t *out,
#elif defined(__ALTIVEC__)
int samples_in = samples;
/* Unaligned loads/store is a bit expensive,
/* Unaligned loads/store is a bit expensive,
* so we optimize for the good path (very likely). */
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
{
......@@ -91,7 +97,7 @@ void convert_float_to_s16(int16_t *out,
samples = samples_in;
i = 0;
#elif defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#elif defined(HAVE_ARM_NEON_OPTIMIZATIONS)
if (float_to_s16_neon_enabled)
{
size_t aligned_samples = samples & ~7;
......@@ -106,7 +112,7 @@ void convert_float_to_s16(int16_t *out,
#elif defined(_MIPS_ARCH_ALLEGREX)
#ifdef DEBUG
/* Make sure the buffers are 16 byte aligned, this should be
/* Make sure the buffers are 16 byte aligned, this should be
* the default behaviour of malloc in the PSPSDK.
* Assume alignment. */
retro_assert(((uintptr_t)in & 0xf) == 0);
......@@ -151,7 +157,7 @@ void convert_float_to_s16(int16_t *out,
**/
void convert_float_to_s16_init_simd(void)
{
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
unsigned cpu = cpu_features_get();
if (cpu & RETRO_SIMD_NEON)
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (float_to_s16_neon.S).
......@@ -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__)
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#ifndef __MACH__
.arm
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (float_to_s16_neon.S).
......@@ -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__)
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_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"
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (s16_to_float.c).
......@@ -29,7 +29,13 @@
#include <features/features_cpu.h>
#include <audio/conversion/s16_to_float.h>
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#if (defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)) || defined(HAVE_NEON)
#ifndef HAVE_ARM_NEON_OPTIMIZATIONS
#define HAVE_ARM_NEON_OPTIMIZATIONS
#endif
#endif
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
static bool s16_to_float_neon_enabled = false;
/* Avoid potential hard-float/soft-float ABI issues. */
......@@ -50,7 +56,7 @@ void convert_s16_float_asm(float *out, const int16_t *in,
void convert_s16_to_float(float *out,
const int16_t *in, size_t samples, float gain)
{
size_t i = 0;
unsigned i = 0;
#if defined(__SSE2__)
float fgain = gain / UINT32_C(0x80000000);
......@@ -73,11 +79,10 @@ void convert_s16_to_float(float *out,
#elif defined(__ALTIVEC__)
size_t samples_in = samples;
/* Unaligned loads/store is a bit expensive, so we
/* Unaligned loads/store is a bit expensive, so we
* optimize for the good path (very likely). */
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
{
size_t i;
const vector float gain_vec = { gain, gain , gain, gain };
const vector float zero_vec = { 0.0f, 0.0f, 0.0f, 0.0f};
......@@ -99,7 +104,7 @@ void convert_s16_to_float(float *out,
samples = samples_in;
i = 0;
#elif defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#elif defined(HAVE_ARM_NEON_OPTIMIZATIONS)
if (s16_to_float_neon_enabled)
{
size_t aligned_samples = samples & ~7;
......@@ -113,15 +118,18 @@ void convert_s16_to_float(float *out,
i = 0;
}
#elif defined(_MIPS_ARCH_ALLEGREX)
#endif
gain = gain / 0x8000;
#if defined(_MIPS_ARCH_ALLEGREX)
#ifdef DEBUG
/* Make sure the buffer is 16 byte aligned, this should be the
/* Make sure the buffer is 16 byte aligned, this should be the
* default behaviour of malloc in the PSPSDK.
* Only the output buffer can be assumed to be 16-byte aligned. */
retro_assert(((uintptr_t)out & 0xf) == 0);
#endif
gain = gain / 0x8000;
__asm__ (
".set push \n"
".set noreorder \n"
......@@ -166,10 +174,9 @@ void convert_s16_to_float(float *out,
}
#endif
gain = gain / 0x8000;
for (; i < samples; i++)
out[i] = (float)in[i] * gain;
out[i] = (float)in[i] * gain;
}
/**
......@@ -180,7 +187,7 @@ void convert_s16_to_float(float *out,
**/
void convert_s16_to_float_init_simd(void)
{
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#if defined(HAVE_ARM_NEON_OPTIMIZATIONS)
unsigned cpu = cpu_features_get();
if (cpu & RETRO_SIMD_NEON)
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (s16_to_float_neon.S).
......@@ -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__)
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#ifndef __MACH__
.arm
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (s16_to_float_neon.S).
......@@ -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__)
#if defined(__ARM_NEON__) && !defined(DONT_WANT_ARM_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"
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (compat_posix_string.c).
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (compat_strcasestr.c).
......
/* Copyright (C) 2010-2017 The RetroArch team
/* Copyright (C) 2010-2020 The RetroArch team