Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio: ASRC: Code reorganization #8514

Merged
merged 4 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ 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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singalsu @andrula-song @btian1 These should really be in src/audio/module_name/CMakefile.txt (same rule applies to Kconfig too)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, shall we use a separate pr to do the clean up once we finished all module converter.
this is because the in-complete of Cmakelist in module, some does not have, some does not used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood , this change is based on search, so I request use a separate PR to track clean up src/audio/cMakeList.txt

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, "asrc_sources" was not set before this PR, so why do it now. It seems we already go to the asrc subdirectory, so I don't see why we need to add individual source files here.

Copy link
Contributor Author

@andrula-song andrula-song Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, it is first set in line 196 as "set(asrc_sources asrc/asrc.c asrc/asrc_farrow.c asrc/asrc_farrow_generic.c)". Adding here is just to keep the asrc_sources right after I refine ASRC code.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack @andrula-song . I still don't understand why we set the module sources list twice, but clearly this was not added in this PR, so should not block this one. Let's handle separately.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand why we set the module sources list twice,

Same "LIBRARY" explanation as in #8595 (comment), isn't it?

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)
Expand All @@ -185,6 +186,7 @@ if(CONFIG_IPC_MAJOR_3)
set(dcblock_sources dcblock/dcblock_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()
kv2019i marked this conversation as resolved.
Show resolved Hide resolved
224 changes: 7 additions & 217 deletions src/audio/asrc/asrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// Copyright(c) 2019-2022 Intel Corporation. All rights reserved.

#include <sof/audio/asrc/asrc_farrow.h>
#include "asrc_farrow.h"
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/buffer.h>
#include <sof/audio/component.h>
Expand Down Expand Up @@ -30,81 +30,10 @@
#include <errno.h>
#include <stddef.h>
#include <stdint.h>

#if CONFIG_IPC_MAJOR_4
#include <ipc4/base-config.h>
#include <ipc4/asrc.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);
#include "asrc.h"

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 {
#if CONFIG_IPC_MAJOR_4
struct ipc4_asrc_module_cfg ipc_config;
#else
struct ipc_config_asrc ipc_config;
#endif
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 @@ -272,58 +201,11 @@ 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)
andrula-song marked this conversation as resolved.
Show resolved Hide resolved
{
struct comp_dev *dev = mod->dev;
struct module_data *mod_data = &mod->priv;
#ifndef CONFIG_IPC_MAJOR_4
const struct ipc_config_asrc *ipc_asrc = mod_data->cfg.init_data;
#else
const struct ipc4_asrc_module_cfg *ipc_asrc = mod_data->cfg.init_data;
#endif
andrula-song marked this conversation as resolved.
Show resolved Hide resolved
const ipc_asrc_cfg *ipc_asrc = (const ipc_asrc_cfg *)mod_data->cfg.init_data;
struct comp_data *cd;

comp_info(dev, "asrc_init(), source_rate=%d, sink_rate=%d, asynchronous_mode=%d, operation_mode=%d",
Expand Down Expand Up @@ -351,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 @@ -506,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 @@ -521,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 @@ -614,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
Loading