[Sound-open-firmware] [PATCH v2 2/3] tune: new component for file IO

Liam Girdwood liam.r.girdwood at intel.com
Thu May 10 17:40:35 CEST 2018


On Wed, 2018-05-09 at 15:58 -0700, Ranjani Sridharan wrote:
> This patch adds a new file component that testbench
> can use to read in samples and write out processed samples.
> 
> Signed-off-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> ---
>  tune/include/file.h |  71 +++++++
>  tune/src/file.c     | 602
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 673 insertions(+)
>  create mode 100644 tune/include/file.h
>  create mode 100644 tune/src/file.c
> 
> diff --git a/tune/include/file.h b/tune/include/file.h
> new file mode 100644
> index 0000000..07ce4aa
> --- /dev/null
> +++ b/tune/include/file.h
> @@ -0,0 +1,71 @@
> +/*
> + * Copyright (c) 2018, Intel Corporation
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *   * Redistributions of source code must retain the above copyright
> + *     notice, this list of conditions and the following disclaimer.
> + *   * Redistributions in binary form must reproduce the above copyright
> + *     notice, this list of conditions and the following disclaimer in the
> + *     documentation and/or other materials provided with the distribution.
> + *   * Neither the name of the Intel Corporation nor the
> + *     names of its contributors may be used to endorse or promote products
> + *     derived from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
> IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + *
> + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> + *         Liam Girdwood <liam.r.girdwood at linux.intel.com>
> + *         Keyon Jie <yang.jie at linux.intel.com>
> + *	   Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> + */
> +#ifndef _FILE_H
> +#define _FILE_H
> +
> +/* file component modes */
> +enum file_mode {
> +	FILE_READ = 0,
> +	FILE_WRITE,
> +	FILE_DUPLEX,
> +};
> +
> +/* file component state */
> +struct file_state {
> +	char *fn;
> +	FILE *rfh, *wfh; /* read/write file handle */
> +	int reached_eof;
> +	int n;
> +	enum file_mode mode;
> +};
> +
> +/* file comp data */
> +struct file_comp_data {
> +	uint32_t period_bytes;
> +	uint32_t channels;
> +	uint32_t frame_bytes;
> +	uint32_t rate;
> +	struct file_state fs;
> +	int (*file_func)(struct comp_dev *dev, struct comp_buffer *sink,
> +			 struct comp_buffer *source, uint32_t frames);
> +
> +};
> +
> +/* file IO ipc comp */
> +struct sof_ipc_comp_file {
> +	struct sof_ipc_comp comp;
> +	struct sof_ipc_comp_config config;
> +	char *fn;
> +	enum file_mode mode;
> +};
> +#endif
> diff --git a/tune/src/file.c b/tune/src/file.c
> new file mode 100644
> index 0000000..049432b
> --- /dev/null
> +++ b/tune/src/file.c
> @@ -0,0 +1,602 @@
> +/*
> + * Copyright (c) 2018, Intel Corporation
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *   * Redistributions of source code must retain the above copyright
> + *     notice, this list of conditions and the following disclaimer.
> + *   * Redistributions in binary form must reproduce the above copyright
> + *     notice, this list of conditions and the following disclaimer in the
> + *     documentation and/or other materials provided with the distribution.
> + *   * Neither the name of the Intel Corporation nor the
> + *     names of its contributors may be used to endorse or promote products
> + *     derived from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
> IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + *
> + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> + *	   Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> + */
> +
> +/* file component for reading/writing pcm samples to/from a file */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <stddef.h>
> +#include <errno.h>
> +#include <inttypes.h>
> +#include <sof/sof.h>
> +#include <sof/lock.h>
> +#include <sof/list.h>
> +#include <sof/stream.h>
> +#include <sof/work.h>
> +#include <sof/clock.h>
> +#include <sof/audio/component.h>
> +#include <sof/audio/format.h>
> +#include <sof/audio/pipeline.h>
> +#include <uapi/ipc.h>
> +#include "common_test.h"
> +#include "file.h"
> +
> +static inline void buffer_check_wrap_32(int32_t **ptr, int32_t *end,
> +					size_t size)
> +{
> +	if (*ptr >= end)
> +		*ptr = (int32_t *) ((size_t)*ptr - size);
> +}
> +
> +static inline void buffer_check_wrap_16(int16_t **ptr, int16_t *end,
> +					size_t size)
> +{
> +	if (*ptr >= end)
> +		*ptr = (int16_t *) ((size_t)*ptr - size);
> +}
> +
> +/*
> + * Read 32-bit samples from file
> + * currently only supports txt files
> + * TODO: support binary input files
> + */
> +static int read_samples_32(struct comp_dev *dev, struct comp_buffer *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_samples = 0;
> +	int i, n_wrap, n_min, ret;
> +
> +	while (n > 0) {
> +		n_wrap = (int32_t *) sink->end_addr - dest;
> +		/* check for buffer wrap and copy to the end of the buffer */

Can you put newlines before all comments/blocks (in all files), it's breaks
things up nicely :) (I don't care what checkpatch says about this - will fix).

> +		n_min = (n < n_wrap) ? n : n_wrap;
> +		while (n_min > 0) {
> +			n -= nch;
> +			n_min -= nch;
> +			/* copy sample per channel */
> +			for (i = 0; i < nch; i++) {
> +				/* read sample from file */
> +				if (fmt == SOF_IPC_FRAME_S32_LE)
> +					ret = fscanf(cd->fs.rfh, "%d", dest);


Why do we do an fscanf() here ?


> +				/* mask bits if 24-bit samples */
> +				if (fmt == SOF_IPC_FRAME_S24_4LE) {
> +					ret = fscanf(cd->fs.rfh, "%d",
> &sample);
> +					*dest = sample & 0x00ffffff;
> +				}
> +				dest++;
> +				/* quit if eof is reached */
> +				if (ret == EOF) {
> +					cd->fs.reached_eof = 1;
> +					goto quit;
> +				}
> +				n_samples++;
> +			}
> +		}
> +		/* check for buffer wrap and update pointer */
> +		buffer_check_wrap_32(&dest, sink->end_addr,
> +				     sink->size);
> +	}
> +quit:
> +	return n_samples;
> +}
> +
> +/*
> + * Read 16-bit samples from file
> + * currently only supports txt files
> + * TODO: support binary input files
> + */
> +static int read_samples_16(struct comp_dev *dev, struct comp_buffer *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;
> +
> +	/* copy samples */
> +	while (n > 0) {
> +		n_wrap = (int16_t *) sink->end_addr - dest;
> +		/* check for buffer wrap and copy to the end of the buffer */
> +		n_min = (n < n_wrap) ? n : n_wrap;
> +		while (n_min > 0) {
> +			n -= nch;
> +			n_min -= nch;
> +			/* copy sample per channel */
> +			for (i = 0; i < nch; i++) {
> +				/* read sample from file */
> +				ret = fscanf(cd->fs.rfh, "%hd", dest);
> +				dest++;
> +				if (ret == EOF) {
> +					cd->fs.reached_eof = 1;
> +					goto quit;
> +				}
> +				n_samples++;
> +			}
> +		}
> +		/* check for buffer wrap and update pointer */
> +		buffer_check_wrap_16(&dest, sink->end_addr,
> +				     sink->size);
> +	}
> +
> +quit:
> +	return n_samples;
> +}
> +
> +/*
> + * Write 16-bit samples from file
> + * currently only supports txt files
> + * TODO: support binary input files
> + */
> +static int write_samples_16(struct comp_dev *dev, struct comp_buffer *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;
> +
> +	/* copy samples */
> +	while (n > 0) {
> +		n_wrap = (int16_t *) source->end_addr - src;
> +		/* check for buffer wrap and copy to the end of the buffer */
> +		n_min = (n < n_wrap) ? n : n_wrap;
> +		while (n_min > 0) {
> +			n -= nch;
> +			n_min -= nch;
> +			/* copy sample per channel */
> +			for (i = 0; i < nch; i++) {
> +				/* write sample to file */
> +				ret = fprintf(cd->fs.wfh, "%d\n",
> +					      *src);
> +				src++;
> +				if (ret < 0)
> +					goto quit;
> +				n_samples++;
> +			}
> +		}
> +		/* check for buffer wrap and update pointer */
> +		buffer_check_wrap_16(&src, source->end_addr,
> +				     source->size);
> +	}
> +quit:
> +	return n_samples;
> +}
> +
> +/*
> + * Write 32-bit samples from file
> + * currently only supports txt files
> + * TODO: support binary input files
> + */
> +static int write_samples_32(struct comp_dev *dev, struct comp_buffer *source,
> +			    int n, int fmt, int nch)
> +{
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	int32_t *src = (int32_t *)source->r_ptr;
> +	int32_t sample;
> +	int i, n_wrap, n_min, ret;
> +	int n_samples = 0;
> +
> +	/* copy samples */
> +	while (n > 0) {
> +		n_wrap = (int32_t *) source->end_addr - src;
> +		/* check for buffer wrap and copy to the end of the buffer */
> +		n_min = (n < n_wrap) ? n : n_wrap;
> +		while (n_min > 0) {
> +			n -= nch;
> +			n_min -= nch;
> +			/* copy sample per channel */
> +			for (i = 0; i < nch; i++) {
> +				/* write sample to file */
> +				if (fmt == SOF_IPC_FRAME_S32_LE)
> +					ret = fprintf(cd->fs.wfh, "%d\n",
> +					      *src);
> +				if (fmt == SOF_IPC_FRAME_S24_4LE) {
> +					sample = *src << 8;
> +					ret = fprintf(cd->fs.wfh, "%d\n",
> +						      sample >> 8);
> +				}
> +				src++;
> +				if (ret < 0) {
> +					//cd->fs.write_fail = 1;

code to be removed ?

Liam

> +					goto quit;
> +				}
> +				n_samples++;
> +			}
> +		}
> +		/* check for buffer wrap and update pointer */
> +		buffer_check_wrap_32(&src, source->end_addr,
> +				     source->size);
> +	}
> +quit:
> +	return n_samples;
> +}
> +
> +/* function for processing 32-bit samples */
> +static int file_s32_default(struct comp_dev *dev, struct comp_buffer *sink,
> +			    struct comp_buffer *source, uint32_t frames)
> +{
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	int nch = dev->params.channels;
> +	int n_samples = 0;
> +
> +	switch (cd->fs.mode) {
> +	case FILE_READ:
> +		/* read samples */
> +		n_samples = read_samples_32(dev, sink, frames * nch,
> +					    SOF_IPC_FRAME_S32_LE, nch);
> +		break;
> +	case FILE_WRITE:
> +		/* write samples */
> +		n_samples = write_samples_32(dev, sink, frames * nch,
> +					     SOF_IPC_FRAME_S32_LE, nch);
> +		break;
> +	default:
> +		/* TODO: duplex mode */
> +		break;
> +	}
> +
> +	cd->fs.n += n_samples;
> +	return n_samples;
> +}
> +
> +/* function for processing 16-bit samples */
> +static int file_s16(struct comp_dev *dev, struct comp_buffer *sink,
> +		    struct comp_buffer *source, uint32_t frames)
> +{
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	int nch = dev->params.channels;
> +	int n_samples = 0;
> +
> +	switch (cd->fs.mode) {
> +	case FILE_READ:
> +		/* read samples */
> +		n_samples = read_samples_16(dev, sink, frames * nch, nch);
> +		break;
> +	case FILE_WRITE:
> +		/* write samples */
> +		n_samples = write_samples_16(dev, source, frames * nch, nch);
> +		break;
> +	default:
> +		/* TODO: duplex mode */
> +		break;
> +	}
> +
> +	cd->fs.n += n_samples;
> +	return n_samples;
> +}
> +
> +/* function for processing 24-bit samples */
> +static int file_s24(struct comp_dev *dev, struct comp_buffer *sink,
> +		    struct comp_buffer *source, uint32_t frames)
> +{
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	int nch = dev->params.channels;
> +	int n_samples = 0;
> +
> +	switch (cd->fs.mode) {
> +	case FILE_READ:
> +		/* read samples */
> +		n_samples = read_samples_32(dev, sink, frames * nch,
> +					    SOF_IPC_FRAME_S24_4LE, nch);
> +		break;
> +	case FILE_WRITE:
> +		/* write samples */
> +		n_samples = write_samples_32(dev, source, frames * nch,
> +					     SOF_IPC_FRAME_S24_4LE, nch);
> +		break;
> +	default:
> +		/* TODO: duplex mode */
> +		break;
> +	}
> +
> +	cd->fs.n += n_samples;
> +	return n_samples;
> +}
> +
> +static struct comp_dev *file_new(struct sof_ipc_comp *comp)
> +{
> +	struct comp_dev *dev;
> +	struct sof_ipc_comp_file *file;
> +	struct sof_ipc_comp_file *ipc_file
> +		= (struct sof_ipc_comp_file *) comp;
> +	struct file_comp_data *cd;
> +
> +	/* allocate memory for file comp */
> +	dev = malloc(COMP_SIZE(struct sof_ipc_comp_file));
> +	if (dev == NULL)
> +		return NULL;
> +
> +	/* copy file comp config */
> +	file = (struct sof_ipc_comp_file *) &dev->comp;
> +	memcpy(file, ipc_file, sizeof(struct sof_ipc_comp_file));
> +
> +	/* allocate  memory for file comp data */
> +	cd = malloc(sizeof(*cd));
> +	if (cd == NULL) {
> +		free(dev);
> +		return NULL;
> +	}
> +
> +	comp_set_drvdata(dev, cd);
> +	/* default function for processing samples */
> +	cd->file_func = file_s32_default;
> +
> +	/* Get filename from IPC and open file */
> +	cd->fs.fn = strdup(ipc_file->fn);
> +
> +	/* set file comp mode */
> +	cd->fs.mode = ipc_file->mode;
> +
> +	/* open file handle(s) depending on mode */
> +	switch (cd->fs.mode) {
> +	case FILE_READ:
> +		cd->fs.rfh = fopen(cd->fs.fn, "r");
> +		if (cd->fs.rfh == NULL) {
> +			printf("error: opening file %s\n", cd->fs.fn);
> +			free(cd);
> +			free(dev);
> +			return NULL;
> +		}
> +		break;
> +	case FILE_WRITE:
> +		cd->fs.wfh = fopen(cd->fs.fn, "w");
> +		if (cd->fs.wfh == NULL) {
> +			printf("error: opening file %s\n", cd->fs.fn);
> +			free(cd);
> +			free(dev);
> +			return NULL;
> +		}
> +		break;
> +	default:
> +		/* TODO: duplex mode */
> +		break;
> +	}
> +
> +	cd->fs.reached_eof = 0;
> +	cd->fs.n = 0;
> +
> +	return dev;
> +}
> +
> +static void file_free(struct comp_dev *dev)
> +{
> +	struct file_data *td = comp_get_drvdata(dev);
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +
> +	fclose(cd->fs.rfh);
> +	free(td);
> +	free(dev);
> +}
> +
> +/* set component audio stream parameters */
> +static int file_params(struct comp_dev *dev)
> +{
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
> +
> +	/* Need to compute this in non-host endpoint */
> +	dev->frame_bytes =
> +		dev->params.sample_container_bytes * dev->params.channels;
> +
> +	/* calculate period size based on config */
> +	cd->period_bytes = dev->frames * dev->frame_bytes;
> +
> +	/* File to sink supports only S32_LE/S16_LE/S24_4LE PCM formats */
> +	if ((config->frame_fmt != SOF_IPC_FRAME_S32_LE)
> +		&& (config->frame_fmt != SOF_IPC_FRAME_S24_4LE)
> +		&& (config->frame_fmt != SOF_IPC_FRAME_S16_LE))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int fr_cmd(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata)
> +{
> +	return -EINVAL;
> +}
> +
> +static int file_trigger(struct comp_dev *dev, int cmd)
> +{
> +	return comp_set_state(dev, cmd);
> +}
> +
> +/* used to pass standard and bespoke commands (with data) to component */
> +static int file_cmd(struct comp_dev *dev, int cmd, void *data)
> +{
> +	struct sof_ipc_ctrl_data *cdata = data;
> +	int ret = 0;
> +
> +	switch (cmd) {
> +	case COMP_CMD_SET_DATA:
> +		ret = fr_cmd(dev, cdata);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +/*
> + * copy and process stream samples
> + * returns the number of bytes copied
> + */
> +static int file_copy(struct comp_dev *dev)
> +{
> +	struct comp_buffer *buffer;
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	int ret = 0, bytes;
> +
> +	switch (cd->fs.mode) {
> +	case FILE_READ:
> +		/* file component sink buffer */
> +		buffer = list_first_item(&dev->bsink_list, struct
> comp_buffer,
> +				       source_list);
> +
> +		/* test sink has enough free frames */
> +		if (buffer->free >= cd->period_bytes && !cd->fs.reached_eof)
> {
> +			/* read PCM samples from file */
> +			ret = cd->file_func(dev, buffer, NULL, dev->frames);
> +
> +			/* update sink buffer pointers */
> +			bytes = dev->params.sample_container_bytes;
> +			if (ret > 0)
> +				comp_update_buffer_produce(buffer,
> +							   ret * bytes);
> +		}
> +		break;
> +	case FILE_WRITE:
> +		/* file component source buffer */
> +		buffer = list_first_item(&dev->bsource_list,
> +					 struct comp_buffer, sink_list);
> +
> +		/* test source has enough free frames */
> +		if (buffer->avail >= cd->period_bytes) {
> +			/* write PCM samples into file */
> +			ret = cd->file_func(dev, NULL, buffer, dev->frames);
> +
> +			/* update source buffer pointers */
> +			bytes = dev->params.sample_container_bytes;
> +			if (ret > 0)
> +				comp_update_buffer_consume(buffer,
> +							   ret * bytes);
> +		}
> +		break;
> +	default:
> +		/* TODO: duplex mode */
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int file_prepare(struct comp_dev *dev)
> +{
> +	struct sof_ipc_comp_config *config = COMP_GET_CONFIG(dev);
> +	struct comp_buffer *buffer = NULL;
> +	struct file_comp_data *cd = comp_get_drvdata(dev);
> +	int ret = 0, periods;
> +
> +	/* file component sink/source buffer */
> +	switch (cd->fs.mode) {
> +	case FILE_READ:
> +		buffer = list_first_item(&dev->bsink_list, struct
> comp_buffer,
> +					 source_list);
> +		periods = config->periods_sink;
> +		break;
> +	case FILE_WRITE:
> +		buffer = list_first_item(&dev->bsource_list,
> +					 struct comp_buffer, sink_list);
> +		periods = config->periods_source;
> +		break;
> +	default:
> +		/* TODO: duplex mode */
> +		break;
> +	}
> +
> +	if (!buffer) {
> +		printf("error: no sink/source buffer\n");
> +		return -EINVAL;
> +	}
> +
> +	switch (config->frame_fmt) {
> +	case(SOF_IPC_FRAME_S16_LE):
> +		/* set downstream buffer size */
> +		ret = buffer_set_size(buffer, dev->frames * 2 *
> +			periods * dev->params.channels);
> +		if (ret < 0) {
> +			printf("error: file buffer size set\n");
> +			return ret;
> +		}
> +		buffer_reset_pos(buffer);
> +
> +		/* set file function */
> +		cd->file_func = file_s16;
> +		break;
> +	case(SOF_IPC_FRAME_S24_4LE):
> +		/* set downstream buffer size */
> +		ret = buffer_set_size(buffer, dev->frames * 4 *
> +			periods * dev->params.channels);
> +		if (ret < 0) {
> +			printf("error: file buffer size set\n");
> +			return ret;
> +		}
> +		buffer_reset_pos(buffer);
> +		/* set file function */
> +		cd->file_func = file_s24;
> +		break;
> +	case(SOF_IPC_FRAME_S32_LE):
> +		/* set downstream buffer size */
> +		ret = buffer_set_size(buffer, dev->frames * 4 *
> +			periods * dev->params.channels);
> +		if (ret < 0) {
> +			printf("error: file buffer size set\n");
> +			return ret;
> +		}
> +		buffer_reset_pos(buffer);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	dev->state = COMP_STATE_PREPARE;
> +
> +	return ret;
> +}
> +
> +static int file_reset(struct comp_dev *dev)
> +{
> +	dev->state = COMP_STATE_INIT;
> +
> +	return 0;
> +}
> +
> +struct comp_driver comp_file = {
> +	.type = SOF_COMP_FILEREAD,
> +	.ops = {
> +		.new = file_new,
> +		.free = file_free,
> +		.params = file_params,
> +		.cmd = file_cmd,
> +		.trigger = file_trigger,
> +		.copy = file_copy,
> +		.prepare = file_prepare,
> +		.reset = file_reset,
> +	},
> +};
> +
> +void sys_comp_file_init(void)
> +{
> +	comp_register(&comp_file);
> +}
---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


More information about the Sound-open-firmware mailing list