Skip to content

Commit

Permalink
Tools: Testbench: File write DAI needs data structures of DAI
Browse files Browse the repository at this point in the history
Previously the file component stored component data to device
private data similarly as processing components. However the
pipeline treats file as DAI. Without this patch the missing driver
and DAI operation get_init_delay_ms() causes a segfault in pipeline
parameters walk. It is sufficient for the walk to pass to have just
rzalloc() cleared pointers in driver structure.

The file component data is now placed into DAI private data.

Signed-off-by: Seppo Ingalsuo <[email protected]>
  • Loading branch information
singalsu authored and lgirdwood committed Sep 15, 2021
1 parent 93731c5 commit f47b823
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 38 deletions.
103 changes: 67 additions & 36 deletions tools/testbench/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,10 @@ static inline void buffer_check_wrap_16(int16_t **ptr, int16_t *end,
* Read 32-bit samples from file
* currently only supports txt files
*/
static int read_samples_32(struct comp_dev *dev,
static int read_samples_32(struct file_comp_data *cd,
const struct audio_stream *sink,
int n, int fmt, int nch)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
int32_t *dest = (int32_t *)sink->w_ptr;
int32_t sample;
int n_wrap;
Expand Down Expand Up @@ -131,11 +130,10 @@ static int read_samples_32(struct comp_dev *dev,
* Read 16-bit samples from file
* currently only supports txt files
*/
static int read_samples_16(struct comp_dev *dev,
static int read_samples_16(struct file_comp_data *cd,
const struct audio_stream *sink,
int n, int nch)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
int16_t *dest = (int16_t *)sink->w_ptr;
int i, n_wrap, n_min, ret;
int n_samples = 0;
Expand Down Expand Up @@ -190,10 +188,9 @@ static int read_samples_16(struct comp_dev *dev,
* Write 16-bit samples from file
* currently only supports txt files
*/
static int write_samples_16(struct comp_dev *dev, struct audio_stream *source,
static int write_samples_16(struct file_comp_data *cd, struct audio_stream *source,
int n, int nch)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
int16_t *src = (int16_t *)source->r_ptr;
int i, n_wrap, n_min, ret;
int n_samples = 0;
Expand Down Expand Up @@ -245,10 +242,9 @@ static int write_samples_16(struct comp_dev *dev, struct audio_stream *source,
* Write 32-bit samples from file
* currently only supports txt files
*/
static int write_samples_32(struct comp_dev *dev, struct audio_stream *source,
static int write_samples_32(struct file_comp_data *cd, struct audio_stream *source,
int n, int fmt, int nch)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
int32_t *src = (int32_t *)source->r_ptr;
int i, n_wrap, n_min, ret;
int n_samples = 0;
Expand Down Expand Up @@ -319,21 +315,22 @@ static int write_samples_32(struct comp_dev *dev, struct audio_stream *source,
static int file_s32_default(struct comp_dev *dev, struct audio_stream *sink,
struct audio_stream *source, uint32_t frames)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
int nch;
int n_samples = 0;

switch (cd->fs.mode) {
case FILE_READ:
/* read samples */
nch = sink->channels;
n_samples = read_samples_32(dev, sink, frames * nch,
n_samples = read_samples_32(cd, sink, frames * nch,
SOF_IPC_FRAME_S32_LE, nch);
break;
case FILE_WRITE:
/* write samples */
nch = source->channels;
n_samples = write_samples_32(dev, source, frames * nch,
n_samples = write_samples_32(cd, source, frames * nch,
SOF_IPC_FRAME_S32_LE, nch);
break;
default:
Expand All @@ -349,20 +346,21 @@ static int file_s32_default(struct comp_dev *dev, struct audio_stream *sink,
static int file_s16(struct comp_dev *dev, struct audio_stream *sink,
struct audio_stream *source, uint32_t frames)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
int nch;
int n_samples = 0;

switch (cd->fs.mode) {
case FILE_READ:
/* read samples */
nch = sink->channels;
n_samples = read_samples_16(dev, sink, frames * nch, nch);
n_samples = read_samples_16(cd, sink, frames * nch, nch);
break;
case FILE_WRITE:
/* write samples */
nch = source->channels;
n_samples = write_samples_16(dev, source, frames * nch, nch);
n_samples = write_samples_16(cd, source, frames * nch, nch);
break;
default:
/* TODO: duplex mode */
Expand All @@ -377,21 +375,22 @@ static int file_s16(struct comp_dev *dev, struct audio_stream *sink,
static int file_s24(struct comp_dev *dev, struct audio_stream *sink,
struct audio_stream *source, uint32_t frames)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
int nch;
int n_samples = 0;

switch (cd->fs.mode) {
case FILE_READ:
/* read samples */
nch = sink->channels;
n_samples = read_samples_32(dev, sink, frames * nch,
n_samples = read_samples_32(cd, sink, frames * nch,
SOF_IPC_FRAME_S24_4LE, nch);
break;
case FILE_WRITE:
/* write samples */
nch = source->channels;
n_samples = write_samples_32(dev, source, frames * nch,
n_samples = write_samples_32(cd, source, frames * nch,
SOF_IPC_FRAME_S24_4LE, nch);
break;
default:
Expand Down Expand Up @@ -420,26 +419,41 @@ static struct comp_dev *file_new(const struct comp_driver *drv,
struct comp_ipc_config *config,
void *spec)
{
const struct dai_driver *fdrv;
struct comp_dev *dev;
struct ipc_comp_file *ipc_file = spec;
struct dai_data *dd;
struct dai *fdai;
struct file_comp_data *cd;

debug_print("file_new()\n");


dev = comp_alloc(drv, sizeof(*dev));
if (!dev)
return NULL;
dev->ipc_config = *config;

/* allocate memory for file comp data */
cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
if (!cd) {
free(dev);
return NULL;
}
dd = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*dd));
if (!dd)
goto error_skip_dd;

fdai = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*fdai));
if (!fdai)
goto error_skip_dai;

comp_set_drvdata(dev, cd);
fdrv = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*fdrv));
if (!fdrv)
goto error_skip_drv;

cd = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
if (!cd)
goto error_skip_cd;

fdai->drv = fdrv;
dd->dai = fdai;
comp_set_drvdata(dev, dd);
comp_set_drvdata(dd->dai, cd);

/* default function for processing samples */
cd->file_func = file_s32_default;
Expand All @@ -464,19 +478,15 @@ static struct comp_dev *file_new(const struct comp_driver *drv,
if (!cd->fs.rfh) {
fprintf(stderr, "error: opening file %s for reading - %s\n",
cd->fs.fn, strerror(errno));
free(cd);
free(dev);
return NULL;
goto error;
}
break;
case FILE_WRITE:
cd->fs.wfh = fopen(cd->fs.fn, "w+");
if (!cd->fs.wfh) {
fprintf(stderr, "error: opening file %s for writing - %s\n",
cd->fs.fn, strerror(errno));
free(cd);
free(dev);
return NULL;
goto error;
}
break;
default:
Expand All @@ -486,15 +496,30 @@ static struct comp_dev *file_new(const struct comp_driver *drv,

cd->fs.reached_eof = 0;
cd->fs.n = 0;

dev->state = COMP_STATE_READY;

return dev;

error:
free(cd);

error_skip_cd:
free((void *)fdrv);

error_skip_drv:
free(fdai);

error_skip_dai:
free(dd);

error_skip_dd:
free(dev);
return NULL;
}

static void file_free(struct comp_dev *dev)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);

comp_dbg(dev, "file_free()");

Expand All @@ -505,6 +530,9 @@ static void file_free(struct comp_dev *dev)

free(cd->fs.fn);
free(cd);
free((void *)dd->dai->drv);
free(dd->dai);
free(dd);
free(dev);
}

Expand Down Expand Up @@ -585,7 +613,8 @@ static int file_cmd(struct comp_dev *dev, int cmd, void *data,
static int file_copy(struct comp_dev *dev)
{
struct comp_buffer *buffer;
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
int snk_frames;
int src_frames;
int bytes = cd->sample_container_bytes;
Expand Down Expand Up @@ -639,7 +668,8 @@ static int file_copy(struct comp_dev *dev)
static int file_prepare(struct comp_dev *dev)
{
struct comp_buffer *buffer = NULL;
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);
struct audio_stream *stream;
int periods;
int ret = 0;
Expand Down Expand Up @@ -747,7 +777,8 @@ static int file_reset(struct comp_dev *dev)
static int file_get_hw_params(struct comp_dev *dev,
struct sof_ipc_stream_params *params, int dir)
{
struct file_comp_data *cd = comp_get_drvdata(dev);
struct dai_data *dd = comp_get_drvdata(dev);
struct file_comp_data *cd = comp_get_drvdata(dd->dai);

comp_info(dev, "file_hw_params()");
params->direction = dir;
Expand Down
7 changes: 5 additions & 2 deletions tools/testbench/testbench.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ int main(int argc, char **argv)
struct pipeline *p;
struct pipeline *curr_p;
struct comp_dev *cd;
struct dai_data *dd;
struct file_comp_data *frcd, *fwcd;
char pipeline[DEBUG_MSG_LEN];
clock_t tic, toc;
Expand Down Expand Up @@ -317,15 +318,17 @@ int main(int argc, char **argv)
fprintf(stderr, "error: failed to get pointers to filewrite\n");
exit(EXIT_FAILURE);
}
fwcd = comp_get_drvdata(pcm_dev->cd);
dd = comp_get_drvdata(pcm_dev->cd);
fwcd = comp_get_drvdata(dd->dai);

/* Get pointer to fileread */
pcm_dev = ipc_get_comp_by_id(sof_get()->ipc, tp.fr_id);
if (!pcm_dev) {
fprintf(stderr, "error: failed to get pointers to fileread\n");
exit(EXIT_FAILURE);
}
frcd = comp_get_drvdata(pcm_dev->cd);
dd = comp_get_drvdata(pcm_dev->cd);
frcd = comp_get_drvdata(dd->dai);

/* Run pipeline until EOF from fileread */
pcm_dev = ipc_get_comp_by_id(sof_get()->ipc, tp.sched_id);
Expand Down

0 comments on commit f47b823

Please sign in to comment.