Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for OpenVino noise suppression model in the SOF plugin #8847

Merged
merged 10 commits into from
Feb 16, 2024

Conversation

ranj063
Copy link
Collaborator

@ranj063 ranj063 commented Feb 9, 2024

Introduce a new module that performs noise suppression. The module loads the noise suppression model using the OpenVino Runtime plugin, processes the input samples to produce output samples with clean speech. Currently, the module is hard-coded to compile the model to be run on the CPU only and will be extended for other devices like the NPU in the future.

To prevent the following with C++ compilation.
error: invalid conversion from ‘uint32_t’ {aka ‘unsigned int’} to ‘sof_ipc_frame’ [-fpermissive]

Signed-off-by: Ranjani Sridharan <[email protected]>
Add the missing return in the hw_free callback.

Signed-off-by: Ranjani Sridharan <[email protected]>
For now, only process widgets that don't need the basecfg extension are
supported.

Signed-off-by: Ranjani Sridharan <[email protected]>
Set both ibs/obs to be based on the ALSA period_size to make sure that the
intermediate buffers are large enough.

Signed-off-by: Ranjani Sridharan <[email protected]>
Set the host widget correctly and use the capture specific functions
during prepare/free.

Signed-off-by: Ranjani Sridharan <[email protected]>
This will be needed for the plugin voice PCM in preparation to add the
noise suppression module in the host pipeline.

Signed-off-by: Ranjani Sridharan <[email protected]>
/* hack for now to prevent compilation warning
* warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
*/
#define assert(cond) (void)(cond)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just as an idea - maybe you could use

#ifdef __cplusplus

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed it by changing the filename argument in __panic() to const char *

for (ch = 0; ch < NS_MAX_SOURCE_CHANNELS; ch++) {
/* split each channel samples and convert to floating point */
for (i = ch, j = 0; j < frame_count; i+=2,j++)
inp_wave_fp32[j] = (float)input_data[i] * scale;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no need to check input and output buffer for wrap? I can't see a module interface struct populate, but this is still legacy process type and not sink/source API, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, legacy process. Do you think sink/source makes more sense with this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as legacy is not deprecated should be no need. The sink/source API allows resources savings in DSP but it's not as critical on the host side. Also we don't yet have those savings implemented so currently there's no difference. The no-wrap check linear buffers will be a feature in sink/source API.

I was asking if it's ensured in plugin that buffers can be operated as linear even in legacy. It might work so too in FW but I'm not sure it's ensured. The components have still the samples/frame before wrap functions in use.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singalsu I've added the checks for input/output wrap now.

@ranj063 ranj063 force-pushed the plugin-noise-suppression branch 2 times, most recently from e3a6e2d to ca595ae Compare February 9, 2024 19:35
Make the filename argument be a const char * to avoid the following
warning with c++ compliation:
warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

Signed-off-by: Ranjani Sridharan <[email protected]>
@ranj063 ranj063 force-pushed the plugin-noise-suppression branch from ca595ae to 814a7de Compare February 9, 2024 22:29
Introduce a new module that performs noise suppression. The module loads
the noise suppression model using the OpenVino Runtime plugin, processes
the input samples to produce output samples with clean speech.
CUrrently, the module is hard-coded to compile the model to be run on
the CPU only and will be extended for other devices like the NPU in the
future.

Signed-off-by: Ranjani Sridharan <[email protected]>
Add the conf file for the OpenVino noise suppression module and
introduce the module in the capture path in the plugin topology when
noise suppression is enabled. ATM, only 16K capture is supported by the
model, so change the input/output rates for the host/dai modules in the
plugin capture pipeline.

Signed-off-by: Ranjani Sridharan <[email protected]>
Fix the stale instruction for install and add the steps for setting up
OpenVino/OpenCV to test the noise suppression model from the open model
zoo repository.

Signed-off-by: Ranjani Sridharan <[email protected]>
@ranj063 ranj063 force-pushed the plugin-noise-suppression branch from 814a7de to c790f60 Compare February 13, 2024 17:14
@ranj063 ranj063 requested review from singalsu and lyakh February 13, 2024 17:19
/* wrap if needed */
if (inp >= source->end_addr)
inp = (char *)source->addr +
((char *)inp - (char *)source->end_addr);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works but it's not efficient. The linear buffer can be filled in two steps with help from audio stream functions for samples or frames before wrap. We've fixed a lot of these during last year for better performance.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singalsu lets take this as an incremental fix. Can you give a pointer to good example code to copy.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's ok, this is not as consuming as read/write frag.

@dbaluta
Copy link
Collaborator

dbaluta commented Feb 14, 2024

@ranj063 do you have SOF running as an userspace plugin in ALSA? And this is an addition to that plugin for NS model?

@@ -365,7 +365,7 @@ static inline int audio_stream_set_params(struct audio_stream *buffer,
if (!params)
return -EINVAL;

buffer->runtime_stream_params.frame_fmt = params->frame_fmt;
buffer->runtime_stream_params.frame_fmt = (enum sof_ipc_frame)params->frame_fmt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch by G++, these should be fixed at source though, but sadly I dont think all C compilers allow this

diff --git a/src/include/ipc/stream.h b/src/include/ipc/stream.h
index c397f34a1..6466b2cbc 100644
--- a/src/include/ipc/stream.h
+++ b/src/include/ipc/stream.h
@@ -75,7 +75,7 @@ struct sof_ipc_stream_params {
        struct sof_ipc_hdr hdr;
        struct sof_ipc_host_buffer buffer;
        uint32_t direction;     /**< enum sof_ipc_stream_direction */
-       uint32_t frame_fmt;     /**< enum sof_ipc_frame */
+       enum sof_ipc_frame frame_fmt:32;        /**< enum sof_ipc_frame */
        uint32_t buffer_fmt;    /**< enum sof_ipc_buffer_format */
        uint32_t rate;
        uint16_t stream_tag;

/* wrap if needed */
if (inp >= source->end_addr)
inp = (char *)source->addr +
((char *)inp - (char *)source->end_addr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@singalsu lets take this as an incremental fix. Can you give a pointer to good example code to copy.

@lgirdwood
Copy link
Member

@ranj063 do you have SOF running as an userspace plugin in ALSA? And this is an addition to that plugin for NS model?

Yes. Exactly. Still all WIP code, not production ready yet.

# Noise suppression module
find_package(OpenVINO COMPONENTS Runtime)

if(OpenVINO_FOUND)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(OpenVINO_FOUND)
if(OpenVINO_FOUND)

Can you move the find_package() and if() to the parent CMakeLists.txt? This avoids the entire file being guarded.

@marc-hb
Copy link
Collaborator

marc-hb commented Feb 14, 2024

Wow, both ACE https://sof-ci.01.org/sofpr/PR8847/build2695/devicetest/index.html and CAVS https://sof-ci.01.org/sofpr/PR8847/build2696/devicetest/index.html are 100% green! This OpenVino stuff is miraculous, it fixes suspend/resume failures! :-D

@singalsu
Copy link
Collaborator

Wow, both ACE https://sof-ci.01.org/sofpr/PR8847/build2695/devicetest/index.html and CAVS https://sof-ci.01.org/sofpr/PR8847/build2696/devicetest/index.html are 100% green! This OpenVino stuff is miraculous, it fixes suspend/resume failures! :-D

A plugin build and run CI step would be good.

@ranj063
Copy link
Collaborator Author

ranj063 commented Feb 15, 2024

Wow, both ACE https://sof-ci.01.org/sofpr/PR8847/build2695/devicetest/index.html and CAVS https://sof-ci.01.org/sofpr/PR8847/build2696/devicetest/index.html are 100% green! This OpenVino stuff is miraculous, it fixes suspend/resume failures! :-D

aww i dont want to fix the find_package stuff now. I like all greens!

@kv2019i kv2019i merged commit 48462a4 into thesofproject:main Feb 16, 2024
38 of 44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants