Skip to content
Open
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
168 changes: 102 additions & 66 deletions src/audio/rtnr/rtnr.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sof/audio/format.h>
#include <sof/audio/pipeline.h>
#include <sof/audio/rtnr/rtnr.h>
#include <sof/audio/sink_source_utils.h>
#include <sof/common.h>
#include <rtos/panic.h>
#include <sof/ipc/msg.h>
Expand Down Expand Up @@ -305,8 +306,8 @@ static int rtnr_free(struct processing_module *mod)
}

/* Check component audio stream parameters */
static int rtnr_check_params(struct processing_module *mod, struct audio_stream *source,
struct audio_stream *sink)
static int rtnr_check_params(struct processing_module *mod, struct sof_source *source,
struct sof_sink *sink)
{
struct comp_dev *dev = mod->dev;
struct comp_data *cd = module_get_private_data(mod);
Expand All @@ -315,11 +316,11 @@ static int rtnr_check_params(struct processing_module *mod, struct audio_stream
comp_info(dev, "entry");

/* set source/sink_frames/rate */
cd->source_rate = audio_stream_get_rate(source);
cd->sink_rate = audio_stream_get_rate(sink);
cd->sources_stream[0].rate = audio_stream_get_rate(source);
cd->sink_stream.rate = audio_stream_get_rate(sink);
channels_valid = audio_stream_get_channels(source) == audio_stream_get_channels(sink);
cd->source_rate = source_get_rate(source);
cd->sink_rate = sink_get_rate(sink);
cd->sources_stream[0].rate = cd->source_rate;
cd->sink_stream.rate = cd->sink_rate;
channels_valid = source_get_channels(source) == sink_get_channels(sink);

if (!cd->sink_rate) {
comp_err(dev, "rtnr_nr_params(), zero sink rate");
Expand All @@ -346,14 +347,18 @@ static int rtnr_check_params(struct processing_module *mod, struct audio_stream
}

/* set source/sink stream channels */
cd->sources_stream[0].channels = audio_stream_get_channels(source);
cd->sink_stream.channels = audio_stream_get_channels(sink);
cd->sources_stream[0].channels = source_get_channels(source);
cd->sink_stream.channels = sink_get_channels(sink);

/* set source/sink stream overrun/underrun permitted */
cd->sources_stream[0].overrun_permitted = audio_stream_get_overrun(source);
cd->sink_stream.overrun_permitted = audio_stream_get_overrun(sink);
cd->sources_stream[0].underrun_permitted = audio_stream_get_underrun(source);
cd->sink_stream.underrun_permitted = audio_stream_get_underrun(sink);
/*
* Set source/sink stream overrun/underrun permitted. The sink/source API exposes only
* the direction-relevant flag (a reader can underrun, a writer can overrun); the
* cross-direction flags have no getter and are hardcoded to false.
*/
cd->sources_stream[0].overrun_permitted = false;
cd->sink_stream.overrun_permitted = sink_get_overrun(sink);
cd->sources_stream[0].underrun_permitted = source_get_underrun(source);
cd->sink_stream.underrun_permitted = false;

return 0;
}
Expand Down Expand Up @@ -691,41 +696,76 @@ static int rtnr_set_config(struct processing_module *mod, uint32_t param_id,
#endif
}

void rtnr_copy_from_sof_stream(struct audio_stream_rtnr *dst, struct audio_stream *src)
/*
* Acquire the source's circular buffer and describe it for the RTNR library, which does its
* own circular-buffer arithmetic. It needs the buffer base/end address, the read pointer and
* the number of bytes to process this cycle. Only the acquired bytes are reported as available
* (with the write pointer placed at the end of that window), so the library processes exactly
* the amount released afterwards and never more than the sink can accept.
*/
static int rtnr_source_get_stream(struct audio_stream_rtnr *dst, struct sof_source *source,
size_t bytes)
{
const void *data_ptr, *buf_start;
size_t buf_size;
int ret;

ret = source_get_data(source, bytes, &data_ptr, &buf_start, &buf_size);
if (ret)
return ret;

dst->size = audio_stream_get_size(src);
dst->avail = audio_stream_get_avail(src);
dst->free = audio_stream_get_free(src);
dst->w_ptr = audio_stream_get_wptr(src);
dst->r_ptr = audio_stream_get_rptr(src);
dst->addr = audio_stream_get_addr(src);
dst->end_addr = audio_stream_get_end_addr(src);
dst->addr = (void *)buf_start;
dst->end_addr = (char *)buf_start + buf_size;
dst->size = buf_size;
dst->r_ptr = (void *)data_ptr;
dst->avail = bytes;
dst->free = buf_size - bytes;
Comment thread
softwarecki marked this conversation as resolved.
dst->w_ptr = cir_buf_wrap((char *)data_ptr + bytes, dst->addr, dst->end_addr);

return 0;
}

void rtnr_copy_to_sof_stream(struct audio_stream *dst, struct audio_stream_rtnr *src)
/*
* Acquire the sink's circular buffer and describe it for the RTNR library. See
* rtnr_source_get_stream(); here data_ptr is the write pointer, only the acquired bytes are
* reported as free and the read pointer is placed at the end of that window.
*/
static int rtnr_sink_get_stream(struct audio_stream_rtnr *dst, struct sof_sink *sink,
size_t bytes)
{
audio_stream_set_size(dst, src->size);
audio_stream_set_avail(dst, src->avail);
audio_stream_set_free(dst, src->free);
audio_stream_set_wptr(dst, src->w_ptr);
audio_stream_set_rptr(dst, src->r_ptr);
audio_stream_set_addr(dst, src->addr);
audio_stream_set_end_addr(dst, src->end_addr);
void *data_ptr, *buf_start;
size_t buf_size;
int ret;

ret = sink_get_buffer(sink, bytes, &data_ptr, &buf_start, &buf_size);
if (ret)
return ret;

dst->addr = buf_start;
dst->end_addr = (char *)buf_start + buf_size;
dst->size = buf_size;
dst->w_ptr = data_ptr;
dst->free = bytes;
dst->avail = buf_size - bytes;
Comment thread
softwarecki marked this conversation as resolved.
dst->r_ptr = cir_buf_wrap((char *)data_ptr + bytes, dst->addr, dst->end_addr);

return 0;
}

/* copy and process stream data from source to sink buffers */
static int rtnr_process(struct processing_module *mod,
struct input_stream_buffer *input_buffers, int num_input_buffers,
struct output_stream_buffer *output_buffers, int num_output_buffers)
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks)
{
struct comp_dev *dev = mod->dev;
struct audio_stream *source = input_buffers[0].data;
struct audio_stream *sink = output_buffers[0].data;
int frames = input_buffers[0].size;
struct comp_data *cd = module_get_private_data(mod);
struct sof_source *source = sources[0];
struct sof_sink *sink = sinks[0];
size_t src_frame_bytes = source_get_frame_bytes(source);
size_t snk_frame_bytes = sink_get_frame_bytes(sink);
struct audio_stream_rtnr *sources_stream[RTNR_MAX_SOURCES];
struct audio_stream_rtnr *sink_stream = &cd->sink_stream;
struct comp_dev *dev = mod->dev;
uint32_t frames;
int32_t i;
int ret;

Expand All @@ -741,18 +781,25 @@ static int rtnr_process(struct processing_module *mod,
comp_dbg(dev, "rtnr_copy()");

/* put empty data into output queue*/
RTKMA_API_First_Copy(cd->rtk_agl, cd->source_rate, audio_stream_get_channels(source));
RTKMA_API_First_Copy(cd->rtk_agl, cd->source_rate, source_get_channels(source));

frames = MIN(source_get_data_frames_available(source), sink_get_free_frames(sink));
if (!frames)
return 0;

comp_dbg(dev, "rtnr_copy() frames = %d", frames);
comp_dbg(dev, "rtnr_copy() frames = %u", frames);
if (cd->process_enable) {
/* Run processing function */

/* copy required data from sof audio stream to RTNR audio stream */
rtnr_copy_from_sof_stream(sources_stream[0], source);
rtnr_copy_from_sof_stream(sink_stream, sink);
/* acquire the source/sink circular buffers and describe them for the library */
ret = rtnr_source_get_stream(sources_stream[0], source, frames * src_frame_bytes);
if (ret)
return ret;

ret = rtnr_sink_get_stream(sink_stream, sink, frames * snk_frame_bytes);
if (ret) {
source_release_data(source, 0);
return ret;
}

/*
* Processing function uses an array of pointers to source streams
Expand All @@ -766,38 +813,30 @@ static int rtnr_process(struct processing_module *mod,
*/
RTKMA_API_Process(cd->rtk_agl, 0, cd->source_rate, MicNum);

/* copy required data from RTNR audio stream to sof audio stream */
rtnr_copy_to_sof_stream(source, sources_stream[0]);
rtnr_copy_to_sof_stream(sink, sink_stream);

source_release_data(source, frames * src_frame_bytes);
sink_commit_buffer(sink, frames * snk_frame_bytes);
} else {
comp_dbg(dev, "rtnr_copy() passthrough");

audio_stream_copy(source, 0, sink, 0, frames * audio_stream_get_channels(source));
return source_to_sink_copy(source, sink, true, frames * src_frame_bytes);
}

/* Track consume and produce */
module_update_buffer_position(&input_buffers[0], &output_buffers[0], frames);
return 0;
}

#if CONFIG_IPC_MAJOR_4
static void rtnr_params(struct processing_module *mod)
static void rtnr_params(struct processing_module *mod, struct sof_source *source,
struct sof_sink *sink)
{
struct sof_ipc_stream_params *params = mod->stream_params;
struct comp_buffer *sinkb, *sourceb;
struct comp_dev *dev = mod->dev;

ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params);
component_set_nearest_period_frames(dev, params->rate);

/* The caller has checked validity of source and sink buffers */

sourceb = comp_dev_get_first_data_producer(dev);
ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt);

sinkb = comp_dev_get_first_data_consumer(dev);
ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt);
ipc4_update_source_format(source, &mod->priv.cfg.base_cfg.audio_fmt);
ipc4_update_sink_format(sink, &mod->priv.cfg.base_cfg.audio_fmt);
}
#endif

Expand All @@ -807,20 +846,17 @@ static int rtnr_prepare(struct processing_module *mod,
{
struct comp_data *cd = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;
struct comp_buffer *sourceb, *sinkb;
int ret;

comp_dbg(dev, "entry");

sinkb = comp_dev_get_first_data_consumer(dev);
sourceb = comp_dev_get_first_data_producer(dev);
if (!sourceb || !sinkb) {
if (!num_of_sources || !num_of_sinks) {
comp_err(dev, "no source or sink buffer");
return -ENOTCONN;
}

#if CONFIG_IPC_MAJOR_4
rtnr_params(mod);
rtnr_params(mod, sources[0], sinks[0]);
#endif

/* Check config */
Expand All @@ -833,9 +869,9 @@ static int rtnr_prepare(struct processing_module *mod,
/* Initialize RTNR */

/* Get sink data format */
cd->sink_format = audio_stream_get_frm_fmt(&sinkb->stream);
cd->sink_stream.frame_fmt = audio_stream_get_frm_fmt(&sinkb->stream);
ret = rtnr_check_params(mod, &sourceb->stream, &sinkb->stream);
cd->sink_format = sink_get_frm_fmt(sinks[0]);
cd->sink_stream.frame_fmt = cd->sink_format;
ret = rtnr_check_params(mod, sources[0], sinks[0]);
if (ret)
goto err;

Expand Down Expand Up @@ -877,7 +913,7 @@ static int rtnr_reset(struct processing_module *mod)
static const struct module_interface rtnr_interface = {
.init = rtnr_init,
.prepare = rtnr_prepare,
.process_audio_stream = rtnr_process,
.process = rtnr_process,
.set_configuration = rtnr_set_config,
.get_configuration = rtnr_get_config,
.reset = rtnr_reset,
Expand Down
47 changes: 20 additions & 27 deletions src/audio/rtnr/rtnr_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,48 @@
#include <sof/audio/rtnr/rtklib/include/RTK_MA_API.h>
#include <sof/audio/audio_stream.h>
#include <rtos/alloc.h>
#include <stddef.h>
#include <stdint.h>

#define RTNR_STUB_CONTEXT_SIZE 42 /* Just some random size to allocate */

/*
* The stub replaces the proprietary RTNR library with a plain passthrough: the requested frames
* are copied straight from the source to the sink circular buffer, honouring wrap on both sides.
* It works directly on the audio_stream_rtnr descriptors filled in by the component.
*/
static void rtnr_stub_passthrough(struct audio_stream_rtnr **sources,
struct audio_stream_rtnr *sink, int frames, size_t sample_bytes)
{
struct audio_stream_rtnr *source = sources[0];

cir_buf_copy(source->r_ptr, source->addr, source->end_addr,
sink->w_ptr, sink->addr, sink->end_addr,
(size_t)frames * sink->channels * sample_bytes);
}

void RTKMA_API_S16_Default(void *Context, struct audio_stream_rtnr **sources,
struct audio_stream_rtnr *sink, int frames,
_Bool ref_active, int in_idx, int ref_idx,
int ref_32bits, int ref_shift)
{
struct audio_stream sof_source;
struct audio_stream sof_sink;

rtnr_copy_to_sof_stream(&sof_source, sources[0]);
rtnr_copy_to_sof_stream(&sof_sink, sink);
audio_stream_copy(&sof_source, 0, &sof_sink, 0,
frames * audio_stream_get_channels(&sof_sink));
rtnr_copy_from_sof_stream(sources[0], &sof_source);
rtnr_copy_from_sof_stream(sink, &sof_sink);
rtnr_stub_passthrough(sources, sink, frames, sizeof(int16_t));
}

void RTKMA_API_S24_Default(void *Context, struct audio_stream_rtnr **sources,
struct audio_stream_rtnr *sink, int frames,
_Bool ref_active, int in_idx, int ref_idx,
int ref_32bits, int ref_shift)
{
struct audio_stream sof_source;
struct audio_stream sof_sink;

rtnr_copy_to_sof_stream(&sof_source, sources[0]);
rtnr_copy_to_sof_stream(&sof_sink, sink);
audio_stream_copy(&sof_source, 0, &sof_sink, 0,
frames * audio_stream_get_channels(&sof_sink));
rtnr_copy_from_sof_stream(sources[0], &sof_source);
rtnr_copy_from_sof_stream(sink, &sof_sink);
rtnr_stub_passthrough(sources, sink, frames, sizeof(int32_t));
}

void RTKMA_API_S32_Default(void *Context, struct audio_stream_rtnr **sources,
struct audio_stream_rtnr *sink, int frames,
_Bool ref_active, int in_idx, int ref_idx,
int ref_32bits, int ref_shift)
{
struct audio_stream sof_source;
struct audio_stream sof_sink;

rtnr_copy_to_sof_stream(&sof_source, sources[0]);
rtnr_copy_to_sof_stream(&sof_sink, sink);
audio_stream_copy(&sof_source, 0, &sof_sink, 0,
frames * audio_stream_get_channels(&sof_sink));
rtnr_copy_from_sof_stream(sources[0], &sof_source);
rtnr_copy_from_sof_stream(sink, &sof_sink);
rtnr_stub_passthrough(sources, sink, frames, sizeof(int32_t));
}

void RTKMA_API_First_Copy(void *Context, int SampleRate, int MicCh)
Expand Down
4 changes: 0 additions & 4 deletions src/include/sof/audio/rtnr/rtnr.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,4 @@ void rtnr_printf(int a, int b, int c, int d, int e);
void *rtk_rballoc(unsigned int flags, unsigned int caps, unsigned int bytes);
void rtk_rfree(void *ptr);

/* For stub processing functions */
void rtnr_copy_from_sof_stream(struct audio_stream_rtnr *dst, struct audio_stream *src);
void rtnr_copy_to_sof_stream(struct audio_stream *dst, struct audio_stream_rtnr *src);

#endif /* __SOF_AUDIO_RTNR_RTNR_H__ */
Loading