Skip to content
Closed
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
23 changes: 22 additions & 1 deletion src/audio/codec_adapter/codec/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,22 @@ int codec_prepare(struct comp_dev *dev)
return ret;
}

static int process_passthrough(struct comp_dev *dev)
{
int ret;
struct codec_data *codec = comp_get_codec(dev);

ret = memcpy_s(codec->cpd.out_buff, codec->cpd.avail, codec->cpd.in_buff, codec->cpd.avail);
if (ret) {
comp_err(dev, "process_through() error %d: failed to copy data from in to out",
ret);
codec->cpd.produced = 0;
return ret;
}
codec->cpd.produced = codec->cpd.avail;
return 0;
}

int codec_process(struct comp_dev *dev)
{
int ret;
Expand All @@ -260,7 +276,12 @@ int codec_process(struct comp_dev *dev)
return -EPERM;
}

ret = codec->ops->process(dev);
// TODO: how to set cd->passthrough flag?
if (cd->passthrough) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

via topology?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yea, but we have no example of enum or on/off controls I think is why it's left as a todo

Copy link
Member

Choose a reason for hiding this comment

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

@juimonen any example so thi scan be added into topology and code here ?

Copy link
Contributor

Choose a reason for hiding this comment

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

we have examples of enums in tdfb, @johnylin76 please us those

ret = process_passthrough(dev);
} else {
ret = codec->ops->process(dev);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

no need for curly brackets here.

if (ret) {
comp_err(dev, "codec_prepare() error %d: codec process failed for codec_id %x",
ret, codec_id);
Expand Down
92 changes: 92 additions & 0 deletions src/audio/codec_adapter/codec_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ DECLARE_SOF_RT_UUID("codec_adapter", ca_uuid, 0xd8218443, 0x5ff3, 0x4a4c,

DECLARE_TR_CTX(ca_tr, SOF_UUID(ca_uuid), LOG_LEVEL_INFO);

#define ENUM_CTRL_PASSTHROUGH 0

/**
* \brief Create a codec adapter component.
* \param[in] drv - component driver pointer.
Expand Down Expand Up @@ -91,6 +93,7 @@ static struct comp_dev *codec_adapter_new(const struct comp_driver *drv,

dev->state = COMP_STATE_READY;
cd->state = PP_STATE_CREATED;
cd->passthrough = 0;

comp_cl_info(&comp_codec_adapter, "codec_adapter_new() done");
return dev;
Expand Down Expand Up @@ -620,6 +623,89 @@ static int codec_adapter_ctrl_set_data(struct comp_dev *dev,
return ret;
}

static int codec_adapter_ctrl_enum_set(struct sof_ipc_ctrl_data *cdata, struct comp_data *cd)
{
int ret;

switch (cdata->index) {
case ENUM_CTRL_PASSTHROUGH:
if (cdata->num_elems)
cd->passthrough = cdata->chanv[0].value;
break;
default:
comp_cl_err(&comp_codec_adapter,
"codec_adapter_ctrl_enum_set() error: invalid index=%d",
cdata->index);
ret = -EINVAL;
break;
}

return ret;
}

static int codec_adapter_set_value(struct comp_dev *dev,
struct sof_ipc_ctrl_data *cdata)
{
int ret;
struct comp_data *cd = comp_get_drvdata(dev);

switch (cdata->cmd) {
case SOF_CTRL_CMD_ENUM:
comp_dbg(dev, "codec_adapter_set_value(): SOF_CTRL_CMD_ENUM index=%d",
cdata->index);
ret = codec_adapter_ctrl_enum_set(cdata, cd);
break;
default:
comp_err(dev, "codec_adapter_set_value() error: invalid cdata->cmd");
ret = -EINVAL;
break;
}

return ret;
}

static int codec_adapter_ctrl_enum_get(struct sof_ipc_ctrl_data *cdata, struct comp_data *cd)
{
int ret;
int j;

switch (cdata->index) {
case ENUM_CTRL_PASSTHROUGH:
for (j = 0; j < cdata->num_elems; j++)
cdata->chanv[j].value = cd->passthrough;
break;
default:
comp_cl_err(&comp_codec_adapter,
"codec_adapter_ctrl_enum_get() error: invalid index=%d",
cdata->index);
ret = -EINVAL;
break;
}

return ret;
}

static int codec_adapter_get_value(struct comp_dev *dev,
struct sof_ipc_ctrl_data *cdata)
{
int ret;
struct comp_data *cd = comp_get_drvdata(dev);

switch (cdata->cmd) {
case SOF_CTRL_CMD_ENUM:
comp_dbg(dev, "codec_adapter_get_value(): SOF_CTRL_CMD_ENUM index=%d",
cdata->index);
ret = codec_adapter_ctrl_enum_get(cdata, cd);
break;
default:
comp_err(dev, "codec_adapter_get_value() error: invalid cdata->cmd");
ret = -EINVAL;
break;
}

return ret;
}

/* Used to pass standard and bespoke commands (with data) to component */
static int codec_adapter_cmd(struct comp_dev *dev, int cmd, void *data,
int max_data_size)
Expand All @@ -637,6 +723,12 @@ static int codec_adapter_cmd(struct comp_dev *dev, int cmd, void *data,
comp_err(dev, "codec_adapter_cmd() get_data not implemented yet.");
ret = -ENODATA;
break;
case COMP_CMD_SET_VALUE:
ret = codec_adapter_set_value(dev, cdata);
break;
case COMP_CMD_GET_VALUE:
ret = codec_adapter_get_value(dev, cdata);
break;
default:
comp_err(dev, "codec_adapter_cmd() error: unknown command");
ret = -EINVAL;
Expand Down
1 change: 1 addition & 0 deletions src/include/sof/audio/codec_adapter/codec/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ struct comp_data {
struct sof_ipc_stream_params stream_params;
uint32_t period_bytes; /** pipeline period bytes */
uint32_t deep_buff_bytes; /**< copy start threshold */
int passthrough:1; /**< data passthrough mode */
};

/*****************************************************************************/
Expand Down
3 changes: 3 additions & 0 deletions tools/topology/m4/codec_adapter.m4
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ define(`W_CODEC_ADAPTER',
` bytes ['
$6
` ]'
` enum ['
$7
` ]'

`}')

Expand Down
20 changes: 19 additions & 1 deletion tools/topology/sof/pipe-codec-adapter-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ include(`dai.m4')
include(`pipeline.m4')
include(`codec_adapter.m4')
include(`bytecontrol.m4')
include(`enumcontrol.m4')

#
# Controls
Expand Down Expand Up @@ -99,6 +100,20 @@ C_CONTROLBYTES(CA_RUNTIME_CONTROLBYTES_NAME_PIPE, PIPELINE_ID,
,
CA_RUNTIME_PARAMS)

define(CA_PASSTHRU_ENUM, concat(`ca_passthru_enum_', PIPELINE_ID))
define(CA_PASSTHRU_CONTROL, concat(`CA PassThrough', PIPELINE_ID))

# Codec adapter passthrough enum list
CONTROLENUM_LIST(CA_PASSTHRU_ENUM, LIST(` ', `"passthru off"', `"passthru on"'))

# Codec adapter passthrough enum control
C_CONTROLENUM(CA_PASSTHRU_CONTROL, PIPELINE_ID,
CA_PASSTHRU_ENUM,
LIST(` ', ENUM_CHANNEL(FC, 3, 0)),
CONTROLENUM_OPS(enum,
257 binds the mixer control to enum get/put handlers,
257, 257))

#
# Components and Buffers
#
Expand All @@ -112,7 +127,8 @@ ifdef(`CA_SCHEDULE_CORE',`', `define(`CA_SCHEDULE_CORE', `SCHEDULE_CORE')')
W_PCM_PLAYBACK(PCM_ID, Passthrough Playback, DAI_PERIODS, 0, SCHEDULE_CORE)

W_CODEC_ADAPTER(0, PIPELINE_FORMAT, DAI_PERIODS, DAI_PERIODS, CA_SCHEDULE_CORE,
LIST(` ', "CA_SETUP_CONTROLBYTES_NAME_PIPE", "CA_RUNTIME_CONTROLBYTES_NAME_PIPE"))
LIST(` ', "CA_SETUP_CONTROLBYTES_NAME_PIPE", "CA_RUNTIME_CONTROLBYTES_NAME_PIPE"),
LIST(` ', "CA_PASSTHRU_CONTROL"))

# Playback Buffers
W_BUFFER(0, COMP_BUFFER_SIZE(DAI_PERIODS,
Expand Down Expand Up @@ -145,6 +161,8 @@ indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Playback PCM_I

PCM_CAPABILITIES(Passthrough Playback PCM_ID, CAPABILITY_FORMAT_NAME(PIPELINE_FORMAT), PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536)

undefine(`CA_PASSTHRU_CONTROL')
undefine(`CA_PASSTHRU_ENUM')
undefine(`CA_RUNTIME_CONTROLBYTES_NAME_PIPE')
undefine(`CA_RUNTIME_PARAMS')
undefine(`CA_SETUP_CONTROLBYTES_NAME_PIPE')
Expand Down