Skip to content

rtnr: Decouple switch-enable control from params blob#5616

Closed
johnylin76 wants to merge 1 commit into
mainfrom
main-rktr
Closed

rtnr: Decouple switch-enable control from params blob#5616
johnylin76 wants to merge 1 commit into
mainfrom
main-rktr

Conversation

@johnylin76
Copy link
Copy Markdown
Contributor

The ideal implementation for the feature component control is to have:

  • A switch-typed control for enabling/disabling the feature processing
  • A byte-typed control for the feature parameters

Typically the feature parameters should be set only once on DSP init. Updating
new parameters is supported but we should minimize such occurences. A decoupled
switch control provides the perfect solution to enable/disable the feature
without touching params, which is also less cost and error-prone.

Moreover, due to the security request there should be a bypass path under the
switch control, which routes around the feature library for audio samples as
the passthrough.

Hi Realtek folks,
Please help to verify this patch (I only verified the functionality of the switch control).
The example to set the switch value by UCM config:

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

You can also set/get via amixer for testing purposes:

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10'

The ideal implementation for the feature component control is to have:
 - A switch-typed control for enabling/disabling the feature processing
 - A byte-typed control for the feature parameters

Typically the feature parameters should be set only once on DSP init. Updating
new parameters is supported but we should minimize such occurences. A decoupled
switch control provides the perfect solution to enable/disable the feature
without touching params, which is also less cost and error-prone.

Moreover, due to the security request there should be a bypass path under the
switch control, which routes around the feature library for audio samples as
the passthrough.

Signed-off-by: Pin-chih Lin <johnylin@google.com>
@johnylin76
Copy link
Copy Markdown
Contributor Author

In the aspect of UCM, currently it requires the param blob setting per enabling/disabling. The On/Off.bin is 72 bytes and only one bit different between them.

SectionModifier."Internal Mic Noise Cancellation".0 {
        EnableSequence [
                cdev "hw:sofrt5682"
		cset-tlv "name='RTNR10.0 rtnr_bytes_10' /opt/rtnr/RTNR_On.bin"
        ]
        DisableSequence [
                cdev "hw:sofrt5682"
		cset-tlv "name='RTNR10.0 rtnr_bytes_10' /opt/rtnr/RTNR_Off.bin"
        ]
}

With this PR, we set the param blob once, and enable/disable the component via switch control:

SectionVerb {
	Value {
		FullySpecifiedUCM "1"
	}
	EnableSequence [
		cdev "hw:sofrt5682"
		cset-tlv "name='RTNR10.0 rtnr_bytes_10' /opt/rtnr/RTNR.bin"
        ]
}

SectionModifier."Internal Mic Noise Cancellation".0 {
        EnableSequence [
                cdev "hw:sofrt5682"
		cset "name='RTNR10.0 rtnr_enable_10' on"
        ]
        DisableSequence [
                cdev "hw:sofrt5682"
		cset "name='RTNR10.0 rtnr_enable_10' off"
        ]
}

@cujomalainey cujomalainey requested a review from MingJenTai March 29, 2022 20:57
# "RTNR 0" has 2 sink period and 2 source periods
W_RTNR(0, PIPELINE_FORMAT, 2, DAI_PERIODS, SCHEDULE_CORE, LIST(` ', "DEF_RTNR_BYTES"))
W_RTNR(0, PIPELINE_FORMAT, 2, DAI_PERIODS, SCHEDULE_CORE,
LIST(` ', "DEF_RTNR_BYTES"),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

if this is the only purpose of the bytes control I would suggest we just remove it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Could you rephrase for me? I think both bytes and switch control are still required, aren't they?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sampling rate is also part of the bytes control.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry I get more confused. The comment at line 71

# "RTNR 0" has 2 sink period and 2 source periods

has no relation to bytes control. "sink period" and "source period" are the 3rd and 4th arguments of W_RTNR.
line 73 is the 6th argument for bytes-control, line 74 is the 7th argument for switch-control (mixer). Both of them are required for W_RTNR (refer to m4/rtnr.m4)

Comment thread src/audio/rtnr/rtnr.c

comp_dbg(dev, "rtnr_copy()");

ret = cd->rtnr_copy_func(dev);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just return the function call

Comment thread src/audio/rtnr/rtnr.c
comp_info(dev, "rtnr_prepare(), passthrough mode");
cd->rtnr_copy_func = rtnr_passthrough;
cd->rtnr_func = NULL;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@johnylin76 Thanks for the PR!
@cujomalainey Do we have to support toggling on/off on-the-fly during recording? If so I think we should move this part to rtnr_set_value() since copy function is assigned before recording and couldn't be changed on-the-fly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Toggling on/off on-the-fly during recording should be supported. The fact is that it will be handled on CRAS side.
The input device node (e.g. iternal microphone) will be closed and then re-opened transiently while NR state is toggled.

In the aspect of SOF side, RTNR, when the state is being toggled, it will be triggered to stop (comp_reset) and then start (comp_prepare, comp_trigger). So, it is sufficient to make the config and state update just during comp_prepare.

And here I mean is for the toggle of the real use cases, not including the toggle by amixer command because it will not be across CRAS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the description. For developers like us this might be helpful for debugging. Would there be a chance that sof+RTNR is running on the device without NS UI integrated in the OS?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Some components would add a config-changed check in comp_copy(), for example:
https://github.com/thesofproject/sof/blob/main/src/audio/eq_iir/eq_iir.c#L825
which makes it able to "dynamically" update config on-the-fly. This is for config blob

I am not sure for switch-typed value change, with the concern that whether the setter (comp_cmd) and the getter (comp_copy) are synchronized. The former is from IPC while the latter is from scheduler. To be honest I am not sure whether the config blob had handled synchronization either.
@singalsu hi Seppo could you help to comment on this?

Copy link
Copy Markdown
Collaborator

@singalsu singalsu Apr 26, 2022

Choose a reason for hiding this comment

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

There's no controls synchronization in the framework from cmd() to copy(). If a control could create a hazard if it changes in the middle of processing the component should implement some two phase control change. The binary blob is updated in two steps by the model handler so it doesn't need work in the component side. Except if @jsarha 's new single blob feature (for very large ones) is used.

@fuyuntsuo
Copy link
Copy Markdown
Contributor

@johnylin76 @cujomalainey AFAIK there is a fuzzer stress testing binary control widget. Is it same for switch control widget?

Comment thread src/audio/rtnr/rtnr.c
* requires, instead of the default one.
* Please move to rtnr_prepare().
*/
/* Check config */
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is because RTNR requires a default sample rate while creating instance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If so I would suggest to defer RTKMA_API_Context_Create() to rtnr_params(), where we could get the sample rate from source and sink buffer without config blob, unless the required sample rate is neither of them. Even so, I am still of the opinion against fetching config in rtnr_new(). Could we use a constant value for the default sample rate?
@cujomalainey WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we simply instantiate on the first call to params and then only recreate as needed if the next params call has a different rate?

@MingJenTai
Copy link
Copy Markdown
Contributor

Hi @cujomalainey and @johnylin76,

I've tested this patch and it works well on my device. With some modifications, I created another PR #5618 that should complete the proposed feature.

Thanks!

@cujomalainey
Copy link
Copy Markdown
Contributor

Lets continue on #5618

MingJenTai added a commit to MingJenTai/sof that referenced this pull request Apr 29, 2022
This PR is based on thesofproject#5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func
MingJenTai added a commit to MingJenTai/sof that referenced this pull request Apr 30, 2022
This PR is based on thesofproject#5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func
MingJenTai added a commit to MingJenTai/sof that referenced this pull request Apr 30, 2022
This PR is based on thesofproject#5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func
lgirdwood pushed a commit that referenced this pull request May 3, 2022
This PR is based on #5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func
MingJenTai added a commit to MingJenTai/sof that referenced this pull request May 11, 2022
This PR is based on thesofproject#5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func

Cherry-picked from: 2e6bfbe
afq984 pushed a commit that referenced this pull request May 13, 2022
This PR is based on #5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func

Cherry-picked from: 2e6bfbe
MingJenTai added a commit to MingJenTai/sof that referenced this pull request May 19, 2022
This PR is based on thesofproject#5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func

Cherry-picked from 2e6bfbe
MingJenTai added a commit to MingJenTai/sof that referenced this pull request May 19, 2022
This PR is based on thesofproject#5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func

Cherry-picked from 2e6bfbe
mwasko pushed a commit that referenced this pull request May 27, 2022
This PR is based on #5616

It decouples the switch-typed control for enabling/disabling from the
control bytes.

Previously, control blobs should be sent from userspace to to toggle
RTNR on/off.
With this PR, RTNR can be toggled by setting the UCM switch value.

cset "name='RTNR10.0 rtnr_enable_10' off"
cset "name='RTNR10.0 rtnr_enable_10' on"

or from command line

amixer -c0 cset name='RTNR10.0 rtnr_enable_10' 1
amixer -c0 cget name='RTNR10.0 rtnr_enable_10' 0

Signed-off-by: Pin-chih Lin <johnylin@google.com>
Signed-off-by: Ming Jen Tai <mingjen_tai@realtek.com>

merge copy_func

Cherry-picked from 2e6bfbe
@johnylin76 johnylin76 deleted the main-rktr branch June 30, 2022 03:43
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.

5 participants