2012-03-27 23:52:15 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2007 Thom Johansen
|
|
|
|
* Copyright (C) 2012 Michael Sevakis
|
|
|
|
*
|
|
|
|
* This program 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 Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2013-05-27 07:23:33 +00:00
|
|
|
#include "rbcodecconfig.h"
|
|
|
|
#include "platform.h"
|
2013-05-23 17:58:51 +00:00
|
|
|
#include "fixedpoint.h"
|
2012-03-27 23:52:15 +00:00
|
|
|
#include "dsp_proc_entry.h"
|
|
|
|
#include "dsp_filter.h"
|
2012-04-29 21:31:30 +00:00
|
|
|
#include "tone_controls.h"
|
2013-05-23 17:58:51 +00:00
|
|
|
#include "dsp_misc.h"
|
2012-03-27 23:52:15 +00:00
|
|
|
|
|
|
|
/* These apply to all DSP streams to remain as consistant as possible with
|
|
|
|
* the behavior of hardware tone controls */
|
|
|
|
|
|
|
|
/* Cutoffs in HZ - not adjustable for now */
|
|
|
|
static const unsigned int tone_bass_cutoff = 200;
|
|
|
|
static const unsigned int tone_treble_cutoff = 3500;
|
|
|
|
|
|
|
|
/* Current bass and treble gain values */
|
|
|
|
static int tone_bass = 0;
|
|
|
|
static int tone_treble = 0;
|
|
|
|
|
2013-05-23 17:58:51 +00:00
|
|
|
/* Current prescaler setting */
|
|
|
|
static int tone_prescale = 0;
|
|
|
|
|
2012-03-27 23:52:15 +00:00
|
|
|
/* Data for each DSP */
|
|
|
|
static struct dsp_filter tone_filters[DSP_COUNT] IBSS_ATTR;
|
|
|
|
|
2013-05-23 17:58:51 +00:00
|
|
|
static void update_filter(int id, unsigned int fout)
|
|
|
|
{
|
|
|
|
filter_bishelf_coefs(fp_div(tone_bass_cutoff, fout, 32),
|
|
|
|
fp_div(tone_treble_cutoff, fout, 32),
|
|
|
|
tone_bass, tone_treble, -tone_prescale,
|
|
|
|
&tone_filters[id]);
|
|
|
|
}
|
|
|
|
|
2012-03-27 23:52:15 +00:00
|
|
|
/* Update the filters' coefficients based upon the bass/treble settings */
|
|
|
|
void tone_set_prescale(int prescale)
|
|
|
|
{
|
|
|
|
int bass = tone_bass;
|
|
|
|
int treble = tone_treble;
|
|
|
|
|
2013-05-23 17:58:51 +00:00
|
|
|
tone_prescale = prescale;
|
2012-03-27 23:52:15 +00:00
|
|
|
|
|
|
|
struct dsp_config *dsp;
|
|
|
|
for (int i = 0; (dsp = dsp_get_config(i)); i++)
|
|
|
|
{
|
2013-05-23 17:58:51 +00:00
|
|
|
update_filter(i, dsp_get_output_frequency(dsp));
|
2012-03-27 23:52:15 +00:00
|
|
|
|
|
|
|
bool enable = bass != 0 || treble != 0;
|
|
|
|
dsp_proc_enable(dsp, DSP_PROC_TONE_CONTROLS, enable);
|
|
|
|
|
2013-05-23 17:58:51 +00:00
|
|
|
if (enable && !dsp_proc_active(dsp, DSP_PROC_TONE_CONTROLS))
|
2012-03-27 23:52:15 +00:00
|
|
|
{
|
2013-05-23 17:58:51 +00:00
|
|
|
filter_flush(&tone_filters[i]); /* Going online */
|
2012-03-27 23:52:15 +00:00
|
|
|
dsp_proc_activate(dsp, DSP_PROC_TONE_CONTROLS, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Prescaler is always set after setting bass/treble, so we wait with
|
|
|
|
* calculating coefs until such time. */
|
|
|
|
|
|
|
|
/* Change the bass setting */
|
|
|
|
void tone_set_bass(int bass)
|
|
|
|
{
|
|
|
|
tone_bass = bass;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Change the treble setting */
|
|
|
|
void tone_set_treble(int treble)
|
|
|
|
{
|
|
|
|
tone_treble = treble;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply the tone control filter in-place */
|
|
|
|
static void tone_process(struct dsp_proc_entry *this,
|
|
|
|
struct dsp_buffer **buf_p)
|
|
|
|
{
|
|
|
|
struct dsp_buffer *buf = *buf_p;
|
2012-12-19 22:34:57 +00:00
|
|
|
filter_process((struct dsp_filter *)this->data, buf->p32, buf->remcount,
|
2012-03-27 23:52:15 +00:00
|
|
|
buf->format.num_channels);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* DSP message hook */
|
|
|
|
static intptr_t tone_configure(struct dsp_proc_entry *this,
|
|
|
|
struct dsp_config *dsp,
|
|
|
|
unsigned int setting,
|
|
|
|
intptr_t value)
|
|
|
|
{
|
|
|
|
switch (setting)
|
|
|
|
{
|
|
|
|
case DSP_PROC_INIT:
|
|
|
|
if (value != 0)
|
2012-12-19 22:34:57 +00:00
|
|
|
break; /* Already enabled */
|
|
|
|
|
2012-03-27 23:52:15 +00:00
|
|
|
this->data = (intptr_t)&tone_filters[dsp_get_id(dsp)];
|
2012-12-19 22:34:57 +00:00
|
|
|
this->process = tone_process;
|
|
|
|
/* Fall-through */
|
2012-03-27 23:52:15 +00:00
|
|
|
case DSP_FLUSH:
|
|
|
|
filter_flush((struct dsp_filter *)this->data);
|
|
|
|
break;
|
2013-05-23 17:58:51 +00:00
|
|
|
|
|
|
|
case DSP_SET_OUT_FREQUENCY:
|
|
|
|
update_filter(dsp_get_id(dsp), value);
|
|
|
|
break;
|
2012-03-27 23:52:15 +00:00
|
|
|
}
|
|
|
|
|
2012-12-19 22:34:57 +00:00
|
|
|
return 0;
|
2012-03-27 23:52:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Database entry */
|
|
|
|
DSP_PROC_DB_ENTRY(TONE_CONTROLS,
|
|
|
|
tone_configure);
|