diff --git a/src/audio/dai.c b/src/audio/dai.c index fab6f36019ef..6a6b3386ef52 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -73,7 +73,10 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) struct comp_dev *dev = arg; struct dai_data *dd = comp_get_drvdata(dev); uint32_t bytes = next->elem.size; + struct comp_buffer *source; + struct comp_buffer *sink; void *buffer_ptr; + int ret; comp_dbg(dev, "dai_dma_cb()"); @@ -99,17 +102,32 @@ static void dai_dma_cb(void *arg, enum notify_id type, void *data) } if (dev->direction == SOF_IPC_STREAM_PLAYBACK) { - dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer, - dd->process, bytes); + ret = dma_buffer_copy_to(dd->local_buffer, dd->dma_buffer, + dd->process, bytes); buffer_ptr = dd->local_buffer->stream.r_ptr; } else { - dma_buffer_copy_from(dd->dma_buffer, dd->local_buffer, - dd->process, bytes); + ret = dma_buffer_copy_from(dd->dma_buffer, dd->local_buffer, + dd->process, bytes); buffer_ptr = dd->local_buffer->stream.w_ptr; } + /* assert dma_buffer_copy succeed */ + if (ret < 0) { + source = dev->direction == SOF_IPC_STREAM_PLAYBACK ? + dd->local_buffer : dd->dma_buffer; + sink = dev->direction == SOF_IPC_STREAM_PLAYBACK ? + dd->dma_buffer : dd->local_buffer; + comp_err(dev, "dai_dma_cb() dma buffer copy failed, dir %d bytes %d avail %d free %d", + dev->direction, bytes, + audio_stream_get_avail_samples(&source->stream) * + audio_stream_frame_bytes(&source->stream), + audio_stream_get_free_samples(&sink->stream) * + audio_stream_frame_bytes(&sink->stream)); + return; + } + /* update host position (in bytes offset) for drivers */ dev->position += bytes; if (dd->dai_pos) { diff --git a/src/audio/host.c b/src/audio/host.c index 7051a1ccdbac..4a7f7c2b597a 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -130,13 +130,32 @@ static uint32_t host_dma_get_split(struct host_data *hd, uint32_t bytes) static void host_update_position(struct comp_dev *dev, uint32_t bytes) { struct host_data *hd = comp_get_drvdata(dev); + struct comp_buffer *source; + struct comp_buffer *sink; + int ret; + if (dev->direction == SOF_IPC_STREAM_PLAYBACK) - dma_buffer_copy_from(hd->dma_buffer, hd->local_buffer, - hd->process, bytes); + ret = dma_buffer_copy_from(hd->dma_buffer, hd->local_buffer, + hd->process, bytes); else - dma_buffer_copy_to(hd->local_buffer, hd->dma_buffer, - hd->process, bytes); + ret = dma_buffer_copy_to(hd->local_buffer, hd->dma_buffer, + hd->process, bytes); + + /* assert dma_buffer_copy succeed */ + if (ret < 0) { + source = dev->direction == SOF_IPC_STREAM_PLAYBACK ? + hd->dma_buffer : hd->local_buffer; + sink = dev->direction == SOF_IPC_STREAM_PLAYBACK ? + hd->local_buffer : hd->dma_buffer; + comp_err(dev, "host_update_position() dma buffer copy failed, dir %d bytes %d avail %d free %d", + dev->direction, bytes, + audio_stream_get_avail_samples(&source->stream) * + audio_stream_frame_bytes(&source->stream), + audio_stream_get_free_samples(&sink->stream) * + audio_stream_frame_bytes(&sink->stream)); + return; + } dev->position += bytes; diff --git a/src/audio/pcm_converter/pcm_converter.c b/src/audio/pcm_converter/pcm_converter.c index 507ae460ff99..469f69cfa1d7 100644 --- a/src/audio/pcm_converter/pcm_converter.c +++ b/src/audio/pcm_converter/pcm_converter.c @@ -14,9 +14,9 @@ #include #include -void pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream *sink, uint32_t ooffset, - uint32_t samples, pcm_converter_lin_func converter) +int pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, + uint32_t samples, pcm_converter_lin_func converter) { const int s_size_in = audio_stream_sample_bytes(source); const int s_size_out = audio_stream_sample_bytes(sink); @@ -30,8 +30,11 @@ void pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, int chunk; int N1, N2; - assert(audio_stream_get_avail_samples(source) >= samples + ioffset); - assert(audio_stream_get_free_samples(sink) >= samples + ooffset); + /* assert enough avail/free samples in source and sink buffer */ + if (audio_stream_get_avail_samples(source) < samples + ioffset) + return -EINVAL; + if (audio_stream_get_free_samples(sink) < samples + ooffset) + return -EINVAL; while (i < samples) { /* calculate chunk size */ @@ -51,4 +54,6 @@ void pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, w_ptr = audio_stream_wrap(sink, w_ptr + chunk * s_size_out); i += chunk; } + + return samples; } diff --git a/src/audio/pcm_converter/pcm_converter_generic.c b/src/audio/pcm_converter/pcm_converter_generic.c index da77e26296f3..eb61aa697647 100644 --- a/src/audio/pcm_converter/pcm_converter_generic.c +++ b/src/audio/pcm_converter/pcm_converter_generic.c @@ -26,9 +26,9 @@ #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE -static void pcm_convert_s16_to_s24(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s16_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint32_t buff_frag = 0; int16_t *src; @@ -41,11 +41,13 @@ static void pcm_convert_s16_to_s24(const struct audio_stream *source, *dst = *src << 8; buff_frag++; } + + return samples; } -static void pcm_convert_s24_to_s16(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s24_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint32_t buff_frag = 0; int32_t *src; @@ -58,15 +60,17 @@ static void pcm_convert_s24_to_s16(const struct audio_stream *source, *dst = sat_int16(Q_SHIFT_RND(sign_extend_s24(*src), 23, 15)); buff_frag++; } + + return samples; } #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE -static void pcm_convert_s16_to_s32(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s16_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint32_t buff_frag = 0; int16_t *src; @@ -79,11 +83,13 @@ static void pcm_convert_s16_to_s32(const struct audio_stream *source, *dst = *src << 16; buff_frag++; } + + return samples; } -static void pcm_convert_s32_to_s16(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint32_t buff_frag = 0; int32_t *src; @@ -96,15 +102,17 @@ static void pcm_convert_s32_to_s16(const struct audio_stream *source, *dst = sat_int16(Q_SHIFT_RND(*src, 31, 15)); buff_frag++; } + + return samples; } #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ #if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE -static void pcm_convert_s24_to_s32(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s24_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint32_t buff_frag = 0; int32_t *src; @@ -117,11 +125,13 @@ static void pcm_convert_s24_to_s32(const struct audio_stream *source, *dst = *src << 8; buff_frag++; } + + return samples; } -static void pcm_convert_s32_to_s24(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { uint32_t buff_frag = 0; int32_t *src; @@ -134,6 +144,8 @@ static void pcm_convert_s32_to_s24(const struct audio_stream *source, *dst = sat_int24(Q_SHIFT_RND(*src, 31, 23)); buff_frag++; } + + return samples; } #endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ @@ -272,20 +284,20 @@ static void pcm_convert_f_to_s16_lin(const void *psrc, void *pdst, dst[i] = sat_int16(_pcm_convert_f_to_i(src[i], 15)); } -static void pcm_convert_s16_to_f(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s16_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_s16_to_f_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_s16_to_f_lin); } -static void pcm_convert_f_to_s16(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_f_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_f_to_s16_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_f_to_s16_lin); } #endif /* CONFIG_FORMAT_FLOAT && CONFIG_FORMAT_S16LE */ @@ -316,20 +328,20 @@ static void pcm_convert_f_to_s24_lin(const void *psrc, void *pdst, dst[i] = sat_int24(_pcm_convert_f_to_i(src[i], 23)); } -static void pcm_convert_s24_to_f(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s24_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_s24_to_f_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_s24_to_f_lin); } -static void pcm_convert_f_to_s24(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_f_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_f_to_s24_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_f_to_s24_lin); } #endif /* CONFIG_FORMAT_FLOAT && CONFIG_FORMAT_S24LE */ @@ -360,20 +372,20 @@ static void pcm_convert_f_to_s32_lin(const void *psrc, void *pdst, dst[i] = _pcm_convert_f_to_i(src[i], 31); } -static void pcm_convert_s32_to_f(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_s32_to_f_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_s32_to_f_lin); } -static void pcm_convert_f_to_s32(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_f_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_f_to_s32_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_f_to_s32_lin); } #endif /* CONFIG_FORMAT_FLOAT && CONFIG_FORMAT_S32LE */ diff --git a/src/audio/pcm_converter/pcm_converter_hifi3.c b/src/audio/pcm_converter/pcm_converter_hifi3.c index 5f4f94632ba0..1ed000872531 100644 --- a/src/audio/pcm_converter/pcm_converter_hifi3.c +++ b/src/audio/pcm_converter/pcm_converter_hifi3.c @@ -45,9 +45,9 @@ static void pcm_converter_setup_circular(const struct audio_stream *source) * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. */ -static void pcm_convert_s16_to_s24(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s16_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { ae_int16 *in = audio_stream_read_frag(source, ioffset, sizeof(int16_t)); ae_int32 *out = audio_stream_write_frag(sink, ooffset, sizeof(int32_t)); @@ -59,7 +59,7 @@ static void pcm_convert_s16_to_s24(const struct audio_stream *source, /* nothing to do */ if (!samples) - return; + return samples; /* required alignment for AE_L16X4_XC */ while (!IS_ALIGNED((uintptr_t)in, 8)) { @@ -77,7 +77,7 @@ static void pcm_convert_s16_to_s24(const struct audio_stream *source, sizeof(ae_int32)); if (++i == samples) - return; + return samples; } in16x4 = (ae_int16x4 *)in; @@ -123,6 +123,8 @@ static void pcm_convert_s16_to_s24(const struct audio_stream *source, AE_S32_L_XC(AE_SRAI32(AE_CVT32X2F16_32(sample), 8), out, sizeof(ae_int32)); } + + return samples; } /** @@ -146,10 +148,11 @@ static ae_int32x2 pcm_shift_s24_to_s16(ae_int32x2 sample) * \param[in,out] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s24_to_s16(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s24_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { ae_int32x2 *in = audio_stream_read_frag(source, ioffset, sizeof(int32_t)); @@ -164,7 +167,7 @@ static void pcm_convert_s24_to_s16(const struct audio_stream *source, /* nothing to do */ if (!samples) - return; + return samples; /* required alignment for AE_L32X2_XC */ if (!IS_ALIGNED((uintptr_t)in, 8)) { @@ -236,7 +239,7 @@ static void pcm_convert_s24_to_s16(const struct audio_stream *source, /* no more samples to process */ if (leftover == 1) - return; + return samples; /* store one 16 bit sample */ AE_S16_0_XC(AE_MOVAD16_0(sample), (ae_int16 *)out, @@ -244,6 +247,8 @@ static void pcm_convert_s24_to_s16(const struct audio_stream *source, leftover -= 2; } + + return samples; } #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE */ @@ -255,10 +260,11 @@ static void pcm_convert_s24_to_s16(const struct audio_stream *source, * \param[in,out] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s16_to_s32(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s16_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { ae_int16 *in = audio_stream_read_frag(source, ioffset, sizeof(int16_t)); @@ -272,7 +278,7 @@ static void pcm_convert_s16_to_s32(const struct audio_stream *source, /* nothing to do */ if (!samples) - return; + return samples; /* required alignment for AE_L16X4_XC */ while (!IS_ALIGNED((uintptr_t)in, 8)) { @@ -289,7 +295,7 @@ static void pcm_convert_s16_to_s32(const struct audio_stream *source, AE_S32_L_XC(AE_CVT32X2F16_32(sample), out, sizeof(ae_int32)); if (++i == samples) - return; + return samples; } in16x4 = (ae_int16x4 *)in; @@ -332,6 +338,8 @@ static void pcm_convert_s16_to_s32(const struct audio_stream *source, /* store one 32 bit sample */ AE_S32_L_XC(AE_CVT32X2F16_32(sample), out, sizeof(ae_int32)); } + + return samples; } /** @@ -339,10 +347,11 @@ static void pcm_convert_s16_to_s32(const struct audio_stream *source, * \param[in,out] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s32_to_s16(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { ae_int32x2 *in = audio_stream_read_frag(source, ioffset, sizeof(int32_t)); @@ -357,7 +366,7 @@ static void pcm_convert_s32_to_s16(const struct audio_stream *source, /* nothing to do */ if (!samples) - return; + return samples; /* required alignment for AE_L32X2_XC */ if (!IS_ALIGNED((uintptr_t)in, 8)) { @@ -425,7 +434,7 @@ static void pcm_convert_s32_to_s16(const struct audio_stream *source, /* no more samples to process */ if (leftover == 1) - return; + return samples; /* store one 16 bit sample */ AE_S16_0_XC(AE_MOVAD16_0(sample), (ae_int16 *)out, @@ -433,6 +442,8 @@ static void pcm_convert_s32_to_s16(const struct audio_stream *source, leftover -= 2; } + + return samples; } #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ @@ -444,10 +455,11 @@ static void pcm_convert_s32_to_s16(const struct audio_stream *source, * \param[in,out] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s24_to_s32(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s24_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { ae_int32x2 *in = audio_stream_read_frag(source, ioffset, sizeof(int32_t)); @@ -459,7 +471,7 @@ static void pcm_convert_s24_to_s32(const struct audio_stream *source, /* nothing to do */ if (!samples) - return; + return samples; /* required alignment for AE_L32X2_XC */ if (!IS_ALIGNED((uintptr_t)in, 8)) { @@ -499,7 +511,7 @@ static void pcm_convert_s24_to_s32(const struct audio_stream *source, /* no more samples to process */ if (i == samples) - return; + return samples; /* set source as circular buffer */ pcm_converter_setup_circular(source); @@ -512,6 +524,8 @@ static void pcm_convert_s24_to_s32(const struct audio_stream *source, /* shift left and store one 32 bit sample */ AE_S32_L_XC(AE_SLAI32(sample, 8), (ae_int32 *)out, 0); + + return samples; } /** @@ -534,10 +548,11 @@ static ae_int32x2 pcm_shift_s32_to_s24(ae_int32x2 sample) * \param[in,out] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s32_to_s24(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { ae_int32x2 *in = audio_stream_read_frag(source, ioffset, sizeof(int32_t)); @@ -549,7 +564,7 @@ static void pcm_convert_s32_to_s24(const struct audio_stream *source, /* nothing to do */ if (!samples) - return; + return samples; /* required alignment for AE_L32X2_XC */ if (!IS_ALIGNED((uintptr_t)in, 8)) { @@ -590,7 +605,7 @@ static void pcm_convert_s32_to_s24(const struct audio_stream *source, /* no more samples to process */ if (i == samples) - return; + return samples; /* set source as circular buffer */ pcm_converter_setup_circular(source); @@ -604,6 +619,8 @@ static void pcm_convert_s32_to_s24(const struct audio_stream *source, /* shift right and store one 32 bit sample */ sample = pcm_shift_s32_to_s24(sample); AE_S32_L_XC(sample, (ae_int32 *)out, 0); + + return samples; } #endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ @@ -675,13 +692,14 @@ static void pcm_convert_f_to_s16_lin(const void *psrc, void *pdst, * \param[in] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s16_to_f(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s16_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_s16_to_f_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_s16_to_f_lin); } /** @@ -689,13 +707,14 @@ static void pcm_convert_s16_to_f(const struct audio_stream *source, * \param[in] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_f_to_s16(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_f_to_s16(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_f_to_s16_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_f_to_s16_lin); } #endif /* CONFIG_FORMAT_FLOAT && CONFIG_FORMAT_S16LE */ @@ -773,13 +792,14 @@ static void pcm_convert_f_to_s24_lin(const void *psrc, void *pdst, * \param[in] psrc source linear buffer. * \param[out] pdst destination linear buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s24_to_f(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s24_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_s24_to_f_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_s24_to_f_lin); } /** @@ -787,13 +807,14 @@ static void pcm_convert_s24_to_f(const struct audio_stream *source, * \param[in] psrc source linear buffer. * \param[out] pdst destination linear buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_f_to_s24(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_f_to_s24(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_f_to_s24_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_f_to_s24_lin); } #endif /* CONFIG_FORMAT_FLOAT && CONFIG_FORMAT_24LE */ @@ -868,13 +889,14 @@ static void pcm_convert_f_to_s32_lin(const void *psrc, void *pdst, * \param[in] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_s32_to_f(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_s32_to_f(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_s32_to_f_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_s32_to_f_lin); } /** @@ -882,13 +904,14 @@ static void pcm_convert_s32_to_f(const struct audio_stream *source, * \param[in] source Source buffer. * \param[in,out] sink Destination buffer. * \param[in] samples Number of samples to process. + * \return error code or number of processed samples. */ -static void pcm_convert_f_to_s32(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples) +static int pcm_convert_f_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples) { - pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, - pcm_convert_f_to_s32_lin); + return pcm_convert_as_linear(source, ioffset, sink, ooffset, samples, + pcm_convert_f_to_s32_lin); } #endif /* CONFIG_FORMAT_FLOAT && CONFIG_FORMAT_32LE */ #endif /* XCHAL_HAVE_FP */ diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index d46b5c3f264b..ed1c57717101 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -550,8 +550,9 @@ audio_stream_frames_without_wrap(const struct audio_stream *source, * @param sink Sink buffer. * @param ooffset Offset (in samples) in sink buffer to start writing to. * @param samples Number of samples to copy. + * @return number of processed samples. */ -static inline void audio_stream_copy(const struct audio_stream *source, +static inline int audio_stream_copy(const struct audio_stream *source, uint32_t ioffset, struct audio_stream *sink, uint32_t ooffset, uint32_t samples) @@ -582,6 +583,8 @@ static inline void audio_stream_copy(const struct audio_stream *source, src = audio_stream_wrap(source, src); snk = audio_stream_wrap(sink, snk); } + + return samples; } /** @}*/ diff --git a/src/include/sof/audio/pcm_converter.h b/src/include/sof/audio/pcm_converter.h index 74e78450653c..50d0718d675a 100644 --- a/src/include/sof/audio/pcm_converter.h +++ b/src/include/sof/audio/pcm_converter.h @@ -41,10 +41,11 @@ struct audio_stream; * \param sink output buffer, write pointer is not modified * \param ooffset offset to first sample in sink stream * \param samples number of samples to convert + * \return error code or number of processed samples. */ -typedef void (*pcm_converter_func)(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t samples); +typedef int (*pcm_converter_func)(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples); /** * \brief PCM conversion function interface for data in linear buffer @@ -100,9 +101,10 @@ pcm_get_conversion_function(enum sof_ipc_frame in, * \param ooffset offset to first sample in sink stream * \param samples number of samples to convert * \param converter core conversion function working on linear memory regions + * \return error code or number of processed samples */ -void pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, - struct audio_stream *sink, uint32_t ooffset, - uint32_t samples, pcm_converter_lin_func converter); +int pcm_convert_as_linear(const struct audio_stream *source, uint32_t ioffset, + struct audio_stream *sink, uint32_t ooffset, + uint32_t samples, pcm_converter_lin_func converter); #endif /* __SOF_AUDIO_PCM_CONVERTER_H__ */ diff --git a/src/include/sof/lib/dma.h b/src/include/sof/lib/dma.h index ef5383498d8b..59c3a398ea30 100644 --- a/src/include/sof/lib/dma.h +++ b/src/include/sof/lib/dma.h @@ -222,9 +222,9 @@ struct dma_info { }; struct audio_stream; -typedef void (*dma_process_func)(const struct audio_stream *source, - uint32_t ioffset, struct audio_stream *sink, - uint32_t ooffset, uint32_t frames); +typedef int (*dma_process_func)(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t frames); /** * \brief API to initialize a platform DMA controllers. @@ -607,12 +607,12 @@ typedef void (*dma_process)(const struct audio_stream *, struct audio_stream *, uint32_t); /* copies data from DMA buffer using provided processing function */ -void dma_buffer_copy_from(struct comp_buffer *source, struct comp_buffer *sink, - dma_process_func process, uint32_t source_bytes); +int dma_buffer_copy_from(struct comp_buffer *source, struct comp_buffer *sink, + dma_process_func process, uint32_t source_bytes); /* copies data to DMA buffer using provided processing function */ -void dma_buffer_copy_to(struct comp_buffer *source, struct comp_buffer *sink, - dma_process_func process, uint32_t sink_bytes); +int dma_buffer_copy_to(struct comp_buffer *source, struct comp_buffer *sink, + dma_process_func process, uint32_t sink_bytes); /* generic DMA DSP <-> Host copier */ diff --git a/src/lib/dma.c b/src/lib/dma.c index 41d9293376be..9ae2450d8d8b 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -189,20 +189,21 @@ void dma_sg_free(struct dma_sg_elem_array *elem_array) dma_sg_init(elem_array); } -void dma_buffer_copy_from(struct comp_buffer *source, struct comp_buffer *sink, - dma_process_func process, uint32_t source_bytes) +int dma_buffer_copy_from(struct comp_buffer *source, struct comp_buffer *sink, + dma_process_func process, uint32_t source_bytes) { struct audio_stream *istream = &source->stream; uint32_t samples = source_bytes / audio_stream_sample_bytes(istream); uint32_t sink_bytes = audio_stream_sample_bytes(&sink->stream) * samples; + int ret; /* source buffer contains data copied by DMA */ audio_stream_invalidate(istream, source_bytes); /* process data */ - process(istream, 0, &sink->stream, 0, samples); + ret = process(istream, 0, &sink->stream, 0, samples); buffer_writeback(sink, sink_bytes); @@ -212,21 +213,24 @@ void dma_buffer_copy_from(struct comp_buffer *source, struct comp_buffer *sink, */ audio_stream_consume(istream, source_bytes); comp_update_buffer_produce(sink, sink_bytes); + + return ret; } -void dma_buffer_copy_to(struct comp_buffer *source, struct comp_buffer *sink, - dma_process_func process, uint32_t sink_bytes) +int dma_buffer_copy_to(struct comp_buffer *source, struct comp_buffer *sink, + dma_process_func process, uint32_t sink_bytes) { struct audio_stream *ostream = &sink->stream; uint32_t samples = sink_bytes / audio_stream_sample_bytes(ostream); uint32_t source_bytes = audio_stream_sample_bytes(&source->stream) * samples; + int ret; buffer_invalidate(source, source_bytes); /* process data */ - process(&source->stream, 0, ostream, 0, samples); + ret = process(&source->stream, 0, ostream, 0, samples); /* sink buffer contains data meant to copied to DMA */ audio_stream_writeback(ostream, sink_bytes); @@ -237,4 +241,6 @@ void dma_buffer_copy_to(struct comp_buffer *source, struct comp_buffer *sink, */ audio_stream_produce(ostream, sink_bytes); comp_update_buffer_consume(source, source_bytes); + + return ret; }