1
0
Fork 0
forked from len0rd/rockbox

rbcodec dsp: Refactor DSP init routines, restore INIT_ATTR

Refactor DSP init routines so there is a dedicated init function
for the stages that need it. Remove the DSP_INIT configure message.
This allows the init code to be safely marked INIT_ATTR, saving a
bit of code size, and allowing the linker to verify that there are
no unsafe references to the init routines.

Change-Id: I1702f0f579bbb300a6fe7d0e67b13aa2e9dd7f8a
This commit is contained in:
Aidan MacDonald 2022-12-03 15:33:15 +00:00
parent 34a092a997
commit 6e794c9a2d
10 changed files with 62 additions and 35 deletions

View file

@ -24,6 +24,9 @@
#include "dsp_core.h" #include "dsp_core.h"
#include "dsp_sample_io.h" #include "dsp_sample_io.h"
#include "tdspeed.h"
#include "resample.h"
/* Define LOGF_ENABLE to enable logf output in this file */ /* Define LOGF_ENABLE to enable logf output in this file */
/*#define LOGF_ENABLE*/ /*#define LOGF_ENABLE*/
#include "logf.h" #include "logf.h"
@ -70,6 +73,11 @@ dsp_proc_slot_arr[DSP_NUM_PROC_STAGES+DSP_VOICE_NUM_PROC_STAGES] IBSS_ATTR;
/* General DSP config */ /* General DSP config */
static struct dsp_config dsp_conf[DSP_COUNT] IBSS_ATTR; static struct dsp_config dsp_conf[DSP_COUNT] IBSS_ATTR;
static const dsp_proc_init_fn_type dsp_init_fn[] INITDATA_ATTR = {
&dsp_timestretch_init,
&dsp_resample_init,
};
/** Processing stages support functions **/ /** Processing stages support functions **/
static const struct dsp_proc_db_entry * static const struct dsp_proc_db_entry *
proc_db_entry(const struct dsp_proc_slot *s) proc_db_entry(const struct dsp_proc_slot *s)
@ -517,12 +525,15 @@ void dsp_init(void)
count = slot_count[i]; count = slot_count[i];
dsp->slot_free_mask = MASK_N(uint32_t, count, shift); dsp->slot_free_mask = MASK_N(uint32_t, count, shift);
intptr_t value = i; dsp_sample_io_init(&dsp->io_data, i);
dsp_sample_io_configure(&dsp->io_data, DSP_INIT, &value);
/* Notify each db entry of global init for each DSP */ /* Enable misc handler by default for the audio DSP */
for (unsigned int j = 0; j < DSP_NUM_PROC_STAGES; j++) if (i == CODEC_IDX_AUDIO)
dsp_proc_database[j]->configure(NULL, dsp, DSP_INIT, i); dsp_proc_enable(dsp, DSP_PROC_MISC_HANDLER, true);
/* Call global init for DSPs that need it */
for (unsigned int j = 0; j < ARRAYLEN(dsp_init_fn); ++j)
dsp_init_fn[j](dsp, i);
dsp_configure(dsp, DSP_RESET, 0); dsp_configure(dsp, DSP_RESET, 0);
} }

View file

@ -32,7 +32,6 @@ enum dsp_ids
enum dsp_settings enum dsp_settings
{ {
DSP_INIT, /* For dsp_init */
DSP_RESET, DSP_RESET,
DSP_SET_FREQUENCY, DSP_SET_FREQUENCY,
DSP_SET_SAMPLE_DEPTH, DSP_SET_SAMPLE_DEPTH,

View file

@ -149,13 +149,6 @@ unsigned int dsp_get_output_frequency(struct dsp_config *dsp)
return dsp_configure(dsp, DSP_GET_OUT_FREQUENCY, 0); return dsp_configure(dsp, DSP_GET_OUT_FREQUENCY, 0);
} }
static void misc_dsp_init(struct dsp_config *dsp, unsigned int dsp_id)
{
/* Enable us for the audio DSP at startup */
if (dsp_id == CODEC_IDX_AUDIO)
dsp_proc_enable(dsp, DSP_PROC_MISC_HANDLER, true);
}
/* This is a null-processing stage that monitors as an enabled stage but never /* This is a null-processing stage that monitors as an enabled stage but never
* becomes active in processing samples. It only hooks messages. */ * becomes active in processing samples. It only hooks messages. */
@ -167,10 +160,6 @@ static intptr_t misc_handler_configure(struct dsp_proc_entry *this,
{ {
switch (setting) switch (setting)
{ {
case DSP_INIT:
misc_dsp_init(dsp, value);
break;
case DSP_PROC_CLOSE: case DSP_PROC_CLOSE:
/* This stage should be enabled at all times */ /* This stage should be enabled at all times */
DEBUGF("DSP_PROC_MISC_HANDLER - Error: Closing!\n"); DEBUGF("DSP_PROC_MISC_HANDLER - Error: Closing!\n");

View file

@ -127,6 +127,8 @@ typedef intptr_t (*dsp_proc_config_fn_type)(struct dsp_proc_entry *this,
struct dsp_config *dsp, struct dsp_config *dsp,
unsigned int setting, unsigned int setting,
intptr_t value); intptr_t value);
typedef void (*dsp_proc_init_fn_type)(struct dsp_config *dsp,
unsigned int dsp_id);
/* Enable/disable a processing stage - not to be called during processing /* Enable/disable a processing stage - not to be called during processing
* by processing code! */ * by processing code! */

View file

@ -36,6 +36,13 @@ static void format_change_set(struct sample_io_data *this)
this->format_dirty = 1; this->format_dirty = 1;
} }
void dsp_sample_io_init(struct sample_io_data *this, unsigned int dsp_id)
{
this->output_sampr = DSP_OUT_DEFAULT_HZ;
dsp_sample_input_init(this, dsp_id);
dsp_sample_output_init(this);
}
bool dsp_sample_io_configure(struct sample_io_data *this, bool dsp_sample_io_configure(struct sample_io_data *this,
unsigned int setting, unsigned int setting,
intptr_t *value_p) intptr_t *value_p)
@ -44,12 +51,6 @@ bool dsp_sample_io_configure(struct sample_io_data *this,
switch (setting) switch (setting)
{ {
case DSP_INIT:
this->output_sampr = DSP_OUT_DEFAULT_HZ;
dsp_sample_input_init(this, value);
dsp_sample_output_init(this);
break;
case DSP_RESET: case DSP_RESET:
/* Reset all sample descriptions to default */ /* Reset all sample descriptions to default */
format_change_set(this); format_change_set(this);

View file

@ -56,17 +56,18 @@ struct sample_io_data
uint8_t output_version; /* Format version of src buffer at output */ uint8_t output_version; /* Format version of src buffer at output */
}; };
void dsp_sample_input_init(struct sample_io_data *this, unsigned int dsp_id); void dsp_sample_input_init(struct sample_io_data *this, unsigned int dsp_id) INIT_ATTR;
void dsp_sample_input_flush(struct sample_io_data *this); void dsp_sample_input_flush(struct sample_io_data *this);
void dsp_sample_input_format_change(struct sample_io_data *this, void dsp_sample_input_format_change(struct sample_io_data *this,
struct sample_format *format); struct sample_format *format);
void dsp_sample_output_init(struct sample_io_data *this); void dsp_sample_output_init(struct sample_io_data *this) INIT_ATTR;
void dsp_sample_output_flush(struct sample_io_data *this); void dsp_sample_output_flush(struct sample_io_data *this);
void dsp_sample_output_format_change(struct sample_io_data *this, void dsp_sample_output_format_change(struct sample_io_data *this,
struct sample_format *format); struct sample_format *format);
/* Sample IO watches the format setting from the codec */ /* Sample IO watches the format setting from the codec */
void dsp_sample_io_init(struct sample_io_data *this, unsigned int dsp_id) INIT_ATTR;
bool dsp_sample_io_configure(struct sample_io_data *this, bool dsp_sample_io_configure(struct sample_io_data *this,
unsigned int setting, unsigned int setting,
intptr_t *value_p); intptr_t *value_p);

View file

@ -26,6 +26,7 @@
#include "fixedpoint.h" #include "fixedpoint.h"
#include "dsp_proc_entry.h" #include "dsp_proc_entry.h"
#include "dsp_misc.h" #include "dsp_misc.h"
#include "resample.h"
#include <string.h> #include <string.h>
/** /**
@ -262,7 +263,7 @@ static intptr_t resample_new_format(struct dsp_proc_entry *this,
return PROC_NEW_FORMAT_DEACTIVATED; return PROC_NEW_FORMAT_DEACTIVATED;
} }
static void resample_dsp_init(struct dsp_config *dsp, unsigned int dsp_id) void dsp_resample_init(struct dsp_config *dsp, unsigned int dsp_id)
{ {
int32_t *lbuf, *rbuf; int32_t *lbuf, *rbuf;
@ -310,10 +311,6 @@ static intptr_t resample_configure(struct dsp_proc_entry *this,
switch (setting) switch (setting)
{ {
case DSP_INIT:
resample_dsp_init(dsp, value);
break;
case DSP_FLUSH: case DSP_FLUSH:
resample_flush(this); resample_flush(this);
break; break;

View file

@ -0,0 +1,26 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2022 Aidan MacDonald
*
* 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.
*
****************************************************************************/
#ifndef _DSP_RESAMPLE_H
#define _DSP_RESAMPLE_H
void dsp_resample_init(struct dsp_config *dsp, unsigned int dsp_id) INIT_ATTR;
#endif /* _DSP_RESAMPLE_H */

View file

@ -521,8 +521,12 @@ static intptr_t tdspeed_new_format(struct dsp_proc_entry *this,
(void)this; (void)this;
} }
static void tdspeed_dsp_init(struct tdspeed_state_s *st, unsigned int dsp_id) void dsp_timestretch_init(struct dsp_config *dsp, unsigned int dsp_id)
{ {
(void)dsp;
struct tdspeed_state_s *st = &tdspeed_state;
/* everything is at 100% until dsp_set_timestretch is called with /* everything is at 100% until dsp_set_timestretch is called with
some other value and timestretch is enabled at the time */ some other value and timestretch is enabled at the time */
if (dsp_id == CODEC_IDX_AUDIO) if (dsp_id == CODEC_IDX_AUDIO)
@ -541,10 +545,6 @@ static intptr_t tdspeed_configure(struct dsp_proc_entry *this,
switch (setting) switch (setting)
{ {
case DSP_INIT:
tdspeed_dsp_init(st, value);
break;
case DSP_FLUSH: case DSP_FLUSH:
tdspeed_flush(); tdspeed_flush();
break; break;

View file

@ -40,6 +40,7 @@ void dsp_timestretch_enable(bool enable);
void dsp_set_timestretch(int32_t percent); void dsp_set_timestretch(int32_t percent);
int32_t dsp_get_timestretch(void); int32_t dsp_get_timestretch(void);
bool dsp_timestretch_available(void); bool dsp_timestretch_available(void);
void dsp_timestretch_init(struct dsp_config *dsp, unsigned int dsp_id) INIT_ATTR;
void tdspeed_move(int i, void* current, void* new); void tdspeed_move(int i, void* current, void* new);
#endif /* _TDSPEED_H */ #endif /* _TDSPEED_H */