Skip to content

Commit 2bc8574

Browse files
committed
module: volume: Rework module to use only sink/source api
Rework the volume module to only use the sink/source api to prepare sof for the full transition to pipeline 2.0. Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
1 parent 668dc6a commit 2bc8574

11 files changed

Lines changed: 592 additions & 842 deletions

src/audio/volume/volume.c

Lines changed: 102 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sof/audio/module_adapter/module/generic.h>
2222
#include <sof/audio/pipeline.h>
2323
#include <sof/audio/ipc-config.h>
24+
#include <sof/audio/sink_source_utils.h>
2425
#include <sof/common.h>
2526
#include <rtos/panic.h>
2627
#include <sof/ipc/msg.h>
@@ -51,30 +52,31 @@ LOG_MODULE_REGISTER(volume, CONFIG_SOF_LOG_LEVEL);
5152
#if CONFIG_FORMAT_S16LE
5253
/**
5354
* \brief Used to find nearest zero crossing frame for 16 bit format.
54-
* \param[in,out] source Source buffer.
55+
* \param[in,out] source Source circular buffer view.
56+
* \param[in] channels Number of channels in the stream.
5557
* \param[in] frames Number of frames.
5658
* \param[in,out] prev_sum Previous sum of channel samples.
5759
*/
58-
static uint32_t vol_zc_get_s16(const struct audio_stream *source,
60+
static uint32_t vol_zc_get_s16(struct cir_buf_source *source, const int channels,
5961
uint32_t frames, int64_t *prev_sum)
6062
{
6163
uint32_t curr_frames = frames;
6264
int32_t sum;
63-
int16_t *x = audio_stream_get_rptr(source);
65+
const int16_t *x = source->ptr;
6466
int bytes;
6567
int nmax;
6668
int i, j, n;
67-
const int nch = audio_stream_get_channels(source);
68-
int remaining_samples = frames * nch;
69+
int remaining_samples = frames * channels;
6970

70-
x = audio_stream_wrap(source, x + remaining_samples - 1); /* Go to last channel */
71+
/* Go to last channel */
72+
x = cir_buf_wrap(x + remaining_samples - 1, source->buf_start, source->buf_end);
7173
while (remaining_samples) {
72-
bytes = audio_stream_rewind_bytes_without_wrap(source, x);
74+
bytes = cir_buf_bytes_without_wrap_rewind(x, source->buf_start);
7375
nmax = VOL_BYTES_TO_S16_SAMPLES(bytes) + 1;
7476
n = MIN(nmax, remaining_samples);
75-
for (i = 0; i < n; i += nch) {
77+
for (i = 0; i < n; i += channels) {
7678
sum = 0;
77-
for (j = 0; j < nch; j++) {
79+
for (j = 0; j < channels; j++) {
7880
sum += *x;
7981
x--;
8082
}
@@ -87,7 +89,7 @@ static uint32_t vol_zc_get_s16(const struct audio_stream *source,
8789
curr_frames--;
8890
}
8991
remaining_samples -= n;
90-
x = audio_stream_rewind_wrap(source, x);
92+
x = source_cir_buf_rewind_wrap(x, source->buf_start, source->buf_end);
9193
}
9294

9395
/* sign change not detected, process all samples */
@@ -99,30 +101,31 @@ static uint32_t vol_zc_get_s16(const struct audio_stream *source,
99101
#if CONFIG_FORMAT_S24LE
100102
/**
101103
* \brief Used to find nearest zero crossing frame for 24 in 32 bit format.
102-
* \param[in,out] source Source buffer.
104+
* \param[in,out] source Source circular buffer view.
105+
* \param[in] channels Number of channels in the stream.
103106
* \param[in] frames Number of frames.
104107
* \param[in,out] prev_sum Previous sum of channel samples.
105108
*/
106-
static uint32_t vol_zc_get_s24(const struct audio_stream *source,
109+
static uint32_t vol_zc_get_s24(struct cir_buf_source *source, const int channels,
107110
uint32_t frames, int64_t *prev_sum)
108111
{
109112
int64_t sum;
110113
uint32_t curr_frames = frames;
111-
int32_t *x = audio_stream_get_rptr(source);
114+
const int32_t *x = source->ptr;
112115
int bytes;
113116
int nmax;
114117
int i, j, n;
115-
const int nch = audio_stream_get_channels(source);
116-
int remaining_samples = frames * nch;
118+
int remaining_samples = frames * channels;
117119

118-
x = audio_stream_wrap(source, x + remaining_samples - 1); /* Go to last channel */
120+
/* Go to last channel */
121+
x = cir_buf_wrap(x + remaining_samples - 1, source->buf_start, source->buf_end);
119122
while (remaining_samples) {
120-
bytes = audio_stream_rewind_bytes_without_wrap(source, x);
123+
bytes = cir_buf_bytes_without_wrap_rewind(x, source->buf_start);
121124
nmax = VOL_BYTES_TO_S32_SAMPLES(bytes) + 1;
122125
n = MIN(nmax, remaining_samples);
123-
for (i = 0; i < n; i += nch) {
126+
for (i = 0; i < n; i += channels) {
124127
sum = 0;
125-
for (j = 0; j < nch; j++) {
128+
for (j = 0; j < channels; j++) {
126129
sum += sign_extend_s24(*x);
127130
x--;
128131
}
@@ -135,7 +138,7 @@ static uint32_t vol_zc_get_s24(const struct audio_stream *source,
135138
curr_frames--;
136139
}
137140
remaining_samples -= n;
138-
x = audio_stream_rewind_wrap(source, x);
141+
x = source_cir_buf_rewind_wrap(x, source->buf_start, source->buf_end);
139142
}
140143

141144
/* sign change not detected, process all samples */
@@ -147,30 +150,31 @@ static uint32_t vol_zc_get_s24(const struct audio_stream *source,
147150
#if CONFIG_FORMAT_S32LE
148151
/**
149152
* \brief Used to find nearest zero crossing frame for 32 bit format.
150-
* \param[in,out] source Source buffer.
153+
* \param[in,out] source Source circular buffer view.
154+
* \param[in] channels Number of channels in the stream.
151155
* \param[in] frames Number of frames.
152156
* \param[in,out] prev_sum Previous sum of channel samples.
153157
*/
154-
static uint32_t vol_zc_get_s32(const struct audio_stream *source,
158+
static uint32_t vol_zc_get_s32(struct cir_buf_source *source, const int channels,
155159
uint32_t frames, int64_t *prev_sum)
156160
{
157161
int64_t sum;
158162
uint32_t curr_frames = frames;
159-
int32_t *x = audio_stream_get_rptr(source);
163+
const int32_t *x = source->ptr;
160164
int bytes;
161165
int nmax;
162166
int i, j, n;
163-
const int nch = audio_stream_get_channels(source);
164-
int remaining_samples = frames * nch;
167+
int remaining_samples = frames * channels;
165168

166-
x = audio_stream_wrap(source, x + remaining_samples - 1); /* Go to last channel */
169+
/* Go to last channel */
170+
x = cir_buf_wrap(x + remaining_samples - 1, source->buf_start, source->buf_end);
167171
while (remaining_samples) {
168-
bytes = audio_stream_rewind_bytes_without_wrap(source, x);
172+
bytes = cir_buf_bytes_without_wrap_rewind(x, source->buf_start);
169173
nmax = VOL_BYTES_TO_S32_SAMPLES(bytes) + 1;
170174
n = MIN(nmax, remaining_samples);
171-
for (i = 0; i < n; i += nch) {
175+
for (i = 0; i < n; i += channels) {
172176
sum = 0;
173-
for (j = 0; j < nch; j++) {
177+
for (j = 0; j < channels; j++) {
174178
sum += *x;
175179
x--;
176180
}
@@ -183,7 +187,7 @@ static uint32_t vol_zc_get_s32(const struct audio_stream *source,
183187
curr_frames--;
184188
}
185189
remaining_samples -= n;
186-
x = audio_stream_rewind_wrap(source, x);
190+
x = source_cir_buf_rewind_wrap(x, source->buf_start, source->buf_end);
187191
}
188192

189193
/* sign change not detected, process all samples */
@@ -552,17 +556,46 @@ void volume_set_chan_unmute(struct processing_module *mod, int chan)
552556
* \return Error code.
553557
*/
554558
static int volume_process(struct processing_module *mod,
555-
struct input_stream_buffer *input_buffers, int num_input_buffers,
556-
struct output_stream_buffer *output_buffers, int num_output_buffers)
559+
struct sof_source **sources, int num_of_sources,
560+
struct sof_sink **sinks, int num_of_sinks)
557561
{
558562
struct vol_data *cd = module_get_private_data(mod);
559-
struct audio_stream *source = input_buffers[0].data;
560-
uint32_t avail_frames = input_buffers[0].size;
563+
struct sof_source *source = sources[0];
564+
struct sof_sink *sink = sinks[0];
565+
struct cir_buf_source source_buf;
566+
struct cir_buf_sink sink_buf;
567+
const int nch = cd->channels;
568+
size_t source_frame_bytes = source_get_frame_bytes(source);
569+
size_t sink_frame_bytes = sink_get_frame_bytes(sink);
570+
size_t source_bytes, sink_bytes, bytes;
571+
uint32_t avail_frames;
561572
uint32_t frames;
562573
int64_t prev_sum = 0;
574+
int ret;
563575

564576
comp_dbg(mod->dev, "entry");
565577

578+
avail_frames = source_sink_avail_frames_aligned(source, sink);
579+
if (!avail_frames)
580+
return 0;
581+
582+
source_bytes = avail_frames * source_frame_bytes;
583+
sink_bytes = avail_frames * sink_frame_bytes;
584+
585+
/* acquire source and sink buffers once for the whole available period */
586+
ret = source_get_data(source, source_bytes, &source_buf.ptr,
587+
&source_buf.buf_start, &bytes);
588+
if (ret < 0)
589+
return ret;
590+
source_buf.buf_end = (const char *)source_buf.buf_start + bytes;
591+
592+
ret = sink_get_buffer(sink, sink_bytes, &sink_buf.ptr, &sink_buf.buf_start, &bytes);
593+
if (ret < 0) {
594+
source_release_data(source, 0);
595+
return ret;
596+
}
597+
sink_buf.buf_end = (char *)sink_buf.buf_start + bytes;
598+
566599
while (avail_frames) {
567600
#if CONFIG_COMP_PEAK_VOL
568601
volume_update_current_vol_ipc4(cd);
@@ -572,19 +605,19 @@ static int volume_process(struct processing_module *mod,
572605
frames = avail_frames;
573606
} else if (cd->ramp_type == SOF_VOLUME_LINEAR_ZC) {
574607
/* with ZC ramping look for next ZC offset */
575-
frames = cd->zc_get(source, cd->vol_ramp_frames, &prev_sum);
608+
frames = cd->zc_get(&source_buf, nch, cd->vol_ramp_frames, &prev_sum);
576609
/* Align frames count to audio stream constraints. If it rounds to zero
577610
* round it up to smallest nonzero aligned frames count.
578611
*/
579-
frames = audio_stream_align_frames_round_nearest(source, frames);
612+
frames = source_align_frames_round_nearest(source, frames);
580613
if (!frames)
581-
frames = audio_stream_align_frames_round_up(source, 1);
614+
frames = source_align_frames_round_up(source, 1);
582615
} else {
583616
/* During volume ramp align the number of frames used in this
584617
* gain step. Align up since with low rates this would typically
585618
* become zero.
586619
*/
587-
frames = audio_stream_align_frames_round_up(source, cd->vol_ramp_frames);
620+
frames = source_align_frames_round_up(source, cd->vol_ramp_frames);
588621
}
589622

590623
/* Cancel the gain step for ZC or smaller ramp step if it exceeds
@@ -599,10 +632,22 @@ static int volume_process(struct processing_module *mod,
599632
}
600633

601634
/* copy and scale volume */
602-
cd->scale_vol(mod, &input_buffers[0], &output_buffers[0], frames, cd->attenuation);
635+
cd->scale_vol(mod, &source_buf, &sink_buf, frames, cd->attenuation);
636+
637+
/* advance the views by the processed frames */
638+
source_buf.ptr = cir_buf_wrap((const char *)source_buf.ptr +
639+
frames * source_frame_bytes,
640+
source_buf.buf_start, source_buf.buf_end);
641+
sink_buf.ptr = cir_buf_wrap((char *)sink_buf.ptr + frames * sink_frame_bytes,
642+
sink_buf.buf_start, sink_buf.buf_end);
603643

604644
avail_frames -= frames;
605645
}
646+
647+
/* commit the consumed and produced data */
648+
source_release_data(source, source_bytes);
649+
sink_commit_buffer(sink, sink_bytes);
650+
606651
#if CONFIG_COMP_PEAK_VOL
607652
cd->peak_cnt++;
608653
if (cd->peak_cnt == cd->peak_report_cnt) {
@@ -623,13 +668,13 @@ static int volume_process(struct processing_module *mod,
623668
* \param[in,out] dev Volume base component device.
624669
*/
625670
static vol_zc_func vol_get_zc_function(struct comp_dev *dev,
626-
struct comp_buffer *sinkb)
671+
struct sof_sink *sink)
627672
{
628673
int i;
629674

630675
/* map the zc function to frame format */
631676
for (i = 0; i < ARRAY_SIZE(zc_func_map); i++) {
632-
if (audio_stream_get_valid_fmt(&sinkb->stream) == zc_func_map[i].frame_fmt)
677+
if (sink_get_valid_fmt(sink) == zc_func_map[i].frame_fmt)
633678
return zc_func_map[i].func;
634679
}
635680

@@ -640,9 +685,9 @@ static vol_zc_func vol_get_zc_function(struct comp_dev *dev,
640685
* \brief Set volume frames alignment limit.
641686
* \param[in,out] source Structure pointer of source.
642687
*/
643-
static void volume_set_alignment(struct audio_stream *source)
688+
static void volume_set_alignment(struct sof_source *source)
644689
{
645-
const int channels = audio_stream_get_channels(source);
690+
const int channels = source_get_channels(source);
646691

647692
/* The source buffer in HiFi5 processing version needs 16 bytes alignment. The
648693
* macro SOF_FRAME_BYTE_ALIGN is set in common.h to the requirement align.
@@ -662,14 +707,14 @@ static void volume_set_alignment(struct audio_stream *source)
662707
* frame align need to be 4, 2, 1, 2, ...
663708
*/
664709
#if SOF_USE_HIFI(5, VOLUME)
665-
const int n = (audio_stream_get_valid_fmt(source) == SOF_IPC_FRAME_S16_LE) ? 8 : 4;
710+
const int n = (source_get_valid_fmt(source) == SOF_IPC_FRAME_S16_LE) ? 8 : 4;
666711
#else
667-
const int n = (audio_stream_get_valid_fmt(source) == SOF_IPC_FRAME_S16_LE) ? 4 : 2;
712+
const int n = (source_get_valid_fmt(source) == SOF_IPC_FRAME_S16_LE) ? 4 : 2;
668713
#endif
669714

670715
const uint32_t frame_align_req = (uint32_t)(n / gcd(n, channels));
671716

672-
audio_stream_set_align(byte_align, frame_align_req, source);
717+
source_set_alignment_constants(source, byte_align, frame_align_req);
673718
}
674719

675720
/**
@@ -688,32 +733,28 @@ static int volume_prepare(struct processing_module *mod,
688733
struct vol_data *cd = module_get_private_data(mod);
689734
struct module_data *md = &mod->priv;
690735
struct comp_dev *dev = mod->dev;
691-
struct comp_buffer *sourceb, *sinkb;
692736
uint32_t sink_period_bytes;
693737
int ret;
694738
int i;
695739

696740
comp_dbg(dev, "entry");
697741

698742
/* volume component will only ever have 1 sink and source buffer */
699-
sinkb = comp_dev_get_first_data_consumer(dev);
700-
sourceb = comp_dev_get_first_data_producer(dev);
701-
if (!sourceb || !sinkb) {
743+
if (num_of_sources < 1 || num_of_sinks < 1 ) {
702744
comp_err(dev, "no source or sink buffer");
703745
return -ENOTCONN;
704746
}
705747

706748
ret = volume_peak_prepare(cd, mod);
707749

708-
volume_set_alignment(&sourceb->stream);
750+
volume_set_alignment(sources[0]);
709751

710752
/* get sink period bytes */
711-
sink_period_bytes = audio_stream_period_bytes(&sinkb->stream,
712-
dev->frames);
753+
sink_period_bytes = dev->frames * sink_get_frame_bytes(sinks[0]);
713754

714-
if (audio_stream_get_size(&sinkb->stream) < sink_period_bytes) {
715-
comp_err(dev, "sink buffer size %d is insufficient < %d",
716-
audio_stream_get_size(&sinkb->stream), sink_period_bytes);
755+
if (sink_get_free_size(sinks[0]) < sink_period_bytes) {
756+
comp_err(dev, "sink buffer size %zu is insufficient < %u",
757+
sink_get_free_size(sinks[0]), sink_period_bytes);
717758
ret = -ENOMEM;
718759
goto err;
719760
}
@@ -727,7 +768,7 @@ static int volume_prepare(struct processing_module *mod,
727768
goto err;
728769
}
729770

730-
cd->zc_get = vol_get_zc_function(dev, sinkb);
771+
cd->zc_get = vol_get_zc_function(dev, sinks[0]);
731772
if (!cd->zc_get) {
732773
comp_err(dev, "invalid cd->zc_get");
733774
ret = -EINVAL;
@@ -742,14 +783,14 @@ static int volume_prepare(struct processing_module *mod,
742783
*/
743784
cd->ramp_finished = false;
744785

745-
cd->channels = audio_stream_get_channels(&sinkb->stream);
786+
cd->channels = sink_get_channels(sinks[0]);
746787
if (cd->channels > SOF_IPC_MAX_CHANNELS) {
747788
ret = -EINVAL;
748789
goto err;
749790
}
750791

751792
cd->sample_rate_inv = (int32_t)(1000LL * INT32_MAX /
752-
audio_stream_get_rate(&sinkb->stream));
793+
sink_get_rate(sinks[0]));
753794

754795
for (i = 0; i < cd->channels; i++) {
755796
cd->volume[i] = cd->vol_min;
@@ -808,7 +849,7 @@ static int volume_free(struct processing_module *mod)
808849
static const struct module_interface volume_interface = {
809850
.init = volume_init,
810851
.prepare = volume_prepare,
811-
.process_audio_stream = volume_process,
852+
.process = volume_process,
812853
.set_configuration = volume_set_config,
813854
.get_configuration = volume_get_config,
814855
.reset = volume_reset,
@@ -819,7 +860,7 @@ static const struct module_interface volume_interface = {
819860
static const struct module_interface gain_interface = {
820861
.init = volume_init,
821862
.prepare = volume_prepare,
822-
.process_audio_stream = volume_process,
863+
.process = volume_process,
823864
.set_configuration = volume_set_config,
824865
.get_configuration = volume_get_config,
825866
.reset = volume_reset,

0 commit comments

Comments
 (0)