132 lines
3.0 KiB
C
132 lines
3.0 KiB
C
/* RetroArch - A frontend for libretro.
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
|
* Copyright (C) 2011-2014 - Daniel De Matteis
|
|
*
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "rarch_dsp.h"
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#ifdef RARCH_INTERNAL
|
|
#define rarch_dsp_plugin_init volume_dsp_plugin_init
|
|
#endif
|
|
|
|
struct volume_filter_data
|
|
{
|
|
#ifdef __GNUC__
|
|
float buf[4096] __attribute__((aligned(16)));
|
|
#else
|
|
float buf[4096];
|
|
#endif
|
|
float m_vol;
|
|
float m_pan_vol_l;
|
|
float m_pan_vol_r;
|
|
};
|
|
|
|
#if 0
|
|
static void pan2gain(float &left, float &right, int val)
|
|
{
|
|
left = (100 - val) / 100.0f;
|
|
right = (val + 100) / 100.0f;
|
|
if (left > 1.0)
|
|
left = 1.0;
|
|
if (right > 1.0)
|
|
right = 1.0;
|
|
}
|
|
|
|
static float db2gain(float val)
|
|
{
|
|
return powf(10.0, val / 20.0);
|
|
}
|
|
#endif
|
|
|
|
static void volume_process(void *data, const float *in, unsigned frames)
|
|
{
|
|
float vol_left, vol_right;
|
|
unsigned i;
|
|
struct volume_filter_data *vol = (struct volume_filter_data*)data;
|
|
|
|
if (!vol)
|
|
return;
|
|
|
|
vol_left = vol->m_vol * vol->m_pan_vol_l;
|
|
vol_right = vol->m_vol * vol->m_pan_vol_r;
|
|
|
|
for (i = 0; i < frames; i++)
|
|
{
|
|
vol->buf[(i << 1) + 0] = in[(i << 1) + 0] * vol_left;
|
|
vol->buf[(i << 1) + 1] = in[(i << 1) + 1] * vol_right;
|
|
}
|
|
}
|
|
|
|
static void *volume_dsp_init(const rarch_dsp_info_t *info)
|
|
{
|
|
struct volume_filter_data *vol = (struct volume_filter_data*)calloc(1, sizeof(*vol));
|
|
(void)info;
|
|
|
|
if (!vol)
|
|
return NULL;
|
|
|
|
vol->m_vol = 1.0;
|
|
vol->m_pan_vol_l = 1.0;
|
|
vol->m_pan_vol_r = 1.0;
|
|
|
|
return vol;
|
|
}
|
|
|
|
static void volume_dsp_process(void *data, rarch_dsp_output_t *output,
|
|
const rarch_dsp_input_t *input)
|
|
{
|
|
struct volume_filter_data *vol = (struct volume_filter_data*)data;
|
|
|
|
output->samples = vol->buf;
|
|
volume_process(vol, input->samples, input->frames);
|
|
output->frames = input->frames;
|
|
}
|
|
|
|
static void volume_dsp_free(void *data)
|
|
{
|
|
struct volume_filter_data *vol = (struct volume_filter_data*)data;
|
|
|
|
if (vol)
|
|
free(vol);
|
|
}
|
|
|
|
static void volume_dsp_config(void *data)
|
|
{
|
|
(void)data;
|
|
}
|
|
|
|
const struct dspfilter_implementation generic_volume_dsp = {
|
|
volume_dsp_init,
|
|
volume_dsp_process,
|
|
volume_dsp_free,
|
|
RARCH_DSP_API_VERSION,
|
|
volume_dsp_config,
|
|
"Volume",
|
|
NULL
|
|
};
|
|
|
|
const struct dspfilter_implementation *rarch_dsp_plugin_init(dspfilter_simd_mask_t simd)
|
|
{
|
|
(void)simd;
|
|
return &generic_volume_dsp;
|
|
}
|
|
|
|
#ifdef RARCH_INTERNAL
|
|
#undef rarch_dsp_plugin_init
|
|
#endif
|