Skip to content

Commit

Permalink
Audio: ASRC: Split IPC version code to speclfic file
Browse files Browse the repository at this point in the history
Move IPC3 related code to asrc_ipc3.c and IPC4 related code
to asrc_ipc4.c.

Signed-off-by: Andrula Song <[email protected]>
  • Loading branch information
andrula-song committed Dec 4, 2023
1 parent 22283c1 commit 79b9546
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 207 deletions.
2 changes: 2 additions & 0 deletions src/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,14 @@ set(sof_audio_modules mixer volume src asrc eq-fir eq-iir dcblock crossover tdfb
# sources for each module
if(CONFIG_IPC_MAJOR_3)
set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc3.c)
set(asrc_sources asrc/asrc_ipc3.c)
set(src_sources src/src.c src/src_ipc3.c src/src_generic.c)
set(eq-iir_sources eq_iir/eq_iir_ipc3.c eq_iir/eq_iir_generic.c)
set(eq-fir_sources eq_fir/eq_fir_ipc3.c)
set(tdfb_sources tdfb/tdfb_ipc3.c)
elseif(CONFIG_IPC_MAJOR_4)
set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc4.c)
set(asrc_sources asrc/asrc_ipc4.c)
set(src_sources src/src.c src/src_ipc4.c src/src_generic.c)
set(eq-iir_sources eq_iir/eq_iir_ipc4.c eq_iir/eq_iir_generic.c)
set(eq-fir_sources eq_fir/eq_fir_ipc4.c)
Expand Down
5 changes: 5 additions & 0 deletions src/audio/asrc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
add_local_sources(sof asrc.c asrc_farrow.c asrc_farrow_generic.c
asrc_farrow_hifi3.c)

if(CONFIG_IPC_MAJOR_3)
add_local_sources(sof asrc_ipc3.c)
elseif(CONFIG_IPC_MAJOR_4)
add_local_sources(sof asrc_ipc4.c)
endif()
211 changes: 4 additions & 207 deletions src/audio/asrc/asrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,76 +32,8 @@
#include <stdint.h>
#include "asrc.h"

#if CONFIG_IPC_MAJOR_4
#include <ipc4/base-config.h>
#include "asrc_ipc4.h"
#endif

/* Simple count value to prevent first delta timestamp
* from being input to low-pass filter.
*/
#define TS_STABLE_DIFF_COUNT 2

/* Low pass filter coefficient for measured drift factor,
* The low pass function is y(n) = c1 * x(n) + c2 * y(n -1)
* coefficient c2 needs to be 1 - c1.
*/
#define COEF_C1 Q_CONVERT_FLOAT(0.01, 30)
#define COEF_C2 Q_CONVERT_FLOAT(0.99, 30)

typedef void (*asrc_proc_func)(struct processing_module *mod,
const struct audio_stream *source,
struct audio_stream *sink,
int *consumed,
int *produced);

LOG_MODULE_REGISTER(asrc, CONFIG_SOF_LOG_LEVEL);

#ifndef CONFIG_IPC_MAJOR_4
/* c8ec72f6-8526-4faf-9d39-a23d0b541de2 */
DECLARE_SOF_RT_UUID("asrc", asrc_uuid, 0xc8ec72f6, 0x8526, 0x4faf,
0x9d, 0x39, 0xa2, 0x3d, 0x0b, 0x54, 0x1d, 0xe2);
#else
/* 66b4402d-b468-42f2-81a7-b37121863dd4 */
DECLARE_SOF_RT_UUID("asrc", asrc_uuid, 0x66b4402d, 0xb468, 0x42f2,
0x81, 0xa7, 0xb3, 0x71, 0x21, 0x86, 0x3d, 0xd4);
#endif

DECLARE_TR_CTX(asrc_tr, SOF_UUID(asrc_uuid), LOG_LEVEL_INFO);

/* asrc component private data */
struct comp_data {
ipc_asrc_cfg ipc_config;
struct asrc_farrow *asrc_obj; /* ASRC core data */
struct comp_dev *dai_dev; /* Associated DAI component */
enum asrc_operation_mode mode; /* Control for push or pull mode */
uint64_t ts;
uint32_t sink_rate; /* Sample rate in Hz */
uint32_t source_rate; /* Sample rate in Hz */
uint32_t sink_format; /* For used PCM sample format */
uint32_t source_format; /* For used PCM sample format */
uint32_t copy_count; /* Count copy() operations */
int32_t ts_prev;
int32_t sample_prev;
int32_t skew; /* Rate factor in Q2.30 */
int32_t skew_min;
int32_t skew_max;
int ts_count;
int asrc_size; /* ASRC object size */
int buf_size; /* Samples buffer size */
int frames; /* IO buffer length */
int source_frames; /* Nominal # of frames to process at source */
int sink_frames; /* Nominal # of frames to process at sink */
int source_frames_max; /* Max # of frames to process at source */
int sink_frames_max; /* Max # of frames to process at sink */
int data_shift; /* Optional shift by 8 to process S24_4LE */
uint8_t *buf; /* Samples buffer for input and output */
uint8_t *ibuf[PLATFORM_MAX_CHANNELS]; /* Input channels pointers */
uint8_t *obuf[PLATFORM_MAX_CHANNELS]; /* Output channels pointers */
bool track_drift;
asrc_proc_func asrc_func; /* ASRC processing function */
};

/* In-line functions */

static inline void src_inc_wrap(int32_t **ptr, int32_t *end, size_t size)
Expand Down Expand Up @@ -269,49 +201,6 @@ static void src_copy_s16(struct processing_module *mod,
*n_written = out_frames;
}

#ifndef CONFIG_IPC_MAJOR_4
static inline uint32_t asrc_get_source_rate(const struct ipc_config_asrc *ipc_asrc)
{
return ipc_asrc->source_rate;
}

static inline uint32_t asrc_get_sink_rate(const struct ipc_config_asrc *ipc_asrc)
{
return ipc_asrc->sink_rate;
}

static inline uint32_t asrc_get_operation_mode(const struct ipc_config_asrc *ipc_asrc)
{
return ipc_asrc->operation_mode;
}

static inline bool asrc_get_asynchronous_mode(const struct ipc_config_asrc *ipc_asrc)
{
return ipc_asrc->asynchronous_mode;
}
#else
static inline uint32_t asrc_get_source_rate(const struct ipc4_asrc_module_cfg *ipc_asrc)
{
return ipc_asrc->base.audio_fmt.sampling_frequency;
}

static inline uint32_t asrc_get_sink_rate(const struct ipc4_asrc_module_cfg *ipc_asrc)
{
return ipc_asrc->out_freq;
}

static inline uint32_t asrc_get_operation_mode(const struct ipc4_asrc_module_cfg *ipc_asrc)
{
return ipc_asrc->asrc_mode & (1 << IPC4_MOD_ASRC_PUSH_MODE) ? ASRC_OM_PUSH : ASRC_OM_PULL;
}

static inline bool asrc_get_asynchronous_mode(const struct ipc4_asrc_module_cfg *ipc_asrc)
{
return false;
}

#endif

static int asrc_init(struct processing_module *mod)
{
struct comp_dev *dev = mod->dev;
Expand Down Expand Up @@ -344,7 +233,7 @@ static int asrc_init(struct processing_module *mod)

/* Use skew tracking for DAI if it was requested. The skew
* is initialized here to zero. It is set later in prepare() to
* to 1.0 if there is no filtered skew factor from previous run.
* 1.0 if there is no filtered skew factor from previous run.
*/
cd->track_drift = asrc_get_asynchronous_mode(ipc_asrc);
cd->skew = 0;
Expand Down Expand Up @@ -499,9 +388,7 @@ static int asrc_params(struct processing_module *mod)

comp_info(dev, "asrc_params()");

#if CONFIG_IPC_MAJOR_4
ipc4_base_module_cfg_to_stream_params(&cd->ipc_config.base, pcm_params);
#endif
asrc_set_stream_params(cd, pcm_params);

err = asrc_verify_params(mod, pcm_params);
if (err < 0) {
Expand All @@ -514,11 +401,9 @@ static int asrc_params(struct processing_module *mod)
sinkb = list_first_item(&dev->bsink_list, struct comp_buffer,
source_list);

#if CONFIG_IPC_MAJOR_4
/* update the source/sink buffer formats. Sink rate will be modified below */
ipc4_update_buffer_format(sourceb, &cd->ipc_config.base.audio_fmt);
ipc4_update_buffer_format(sinkb, &cd->ipc_config.base.audio_fmt);
#endif
asrc_update_buffer_format(sourceb, cd);
asrc_update_buffer_format(sinkb, cd);

/* Don't change sink rate if value from IPC is 0 (auto detect) */
if (asrc_get_sink_rate(&cd->ipc_config))
Expand Down Expand Up @@ -607,94 +492,6 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd)
return 0;
}

#if CONFIG_IPC_MAJOR_4
static int asrc_dai_configure_timestamp(struct comp_data *cd)
{
if (cd->dai_dev) {
struct processing_module *mod = comp_get_drvdata(cd->dai_dev);
struct module_data *md = &mod->priv;

return md->ops->endpoint_ops->dai_ts_config(cd->dai_dev);
}

return -EINVAL;
}

static int asrc_dai_start_timestamp(struct comp_data *cd)
{
if (cd->dai_dev) {
struct processing_module *mod = comp_get_drvdata(cd->dai_dev);
struct module_data *md = &mod->priv;

return md->ops->endpoint_ops->dai_ts_start(cd->dai_dev);
}

return -EINVAL;
}

static int asrc_dai_stop_timestamp(struct comp_data *cd)
{
if (cd->dai_dev) {
struct processing_module *mod = comp_get_drvdata(cd->dai_dev);
struct module_data *md = &mod->priv;

return md->ops->endpoint_ops->dai_ts_stop(cd->dai_dev);
}

return -EINVAL;
}

#if CONFIG_ZEPHYR_NATIVE_DRIVERS
static int asrc_dai_get_timestamp(struct comp_data *cd,
struct dai_ts_data *tsd)
#else
static int asrc_dai_get_timestamp(struct comp_data *cd,
struct timestamp_data *tsd)
#endif
{
if (cd->dai_dev) {
struct processing_module *mod = comp_get_drvdata(cd->dai_dev);
struct module_data *md = &mod->priv;

return md->ops->endpoint_ops->dai_ts_get(cd->dai_dev, tsd);
}

return -EINVAL;
}
#else
static int asrc_dai_configure_timestamp(struct comp_data *cd)
{
if (cd->dai_dev)
return cd->dai_dev->drv->ops.dai_ts_config(cd->dai_dev);

return -EINVAL;
}

static int asrc_dai_start_timestamp(struct comp_data *cd)
{
if (cd->dai_dev)
return cd->dai_dev->drv->ops.dai_ts_start(cd->dai_dev);

return -EINVAL;
}

static int asrc_dai_stop_timestamp(struct comp_data *cd)
{
if (cd->dai_dev)
return cd->dai_dev->drv->ops.dai_ts_stop(cd->dai_dev);

return -EINVAL;
}

static int asrc_dai_get_timestamp(struct comp_data *cd, struct timestamp_data *tsd)
{
if (!cd->dai_dev)
return -EINVAL;

return cd->dai_dev->drv->ops.dai_ts_get(cd->dai_dev, tsd);
}
#endif

static int asrc_trigger(struct processing_module *mod, int cmd)
{
struct comp_data *cd = module_get_private_data(mod);
Expand Down
Loading

0 comments on commit 79b9546

Please sign in to comment.