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

UCM2: Intel: sof-hda-dsp: Control SOF processing from UCM #419

Conversation

singalsu
Copy link
Contributor

This is a set of patches to control with UCMv2 audio processing in Sound Open Firmware (SOF). The settings are generic, mostly pass-through mode, except for speaker where a generic high-pass filter and DRC boost are applied.

All the filters can be set up with a bespoke tuned version per product for a better audio experience.

}
}

Macro.headphone.SofControl "endpoint=Headphone drcswitch=off"
Copy link
Member

Choose a reason for hiding this comment

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

Please, try to keep only this line in SectionDevice."Headphones" subtree. The subtrees should be merged, so there is no requirement to redefine the whole block again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change works,

SectionDevice."Headphones" {
	Macro.headphone.SofControl "endpoint=Headphone drcswitch=off"
}

}
}

Macro.speaker.SofControl "endpoint=Speaker drcswitch=on"
Copy link
Member

Choose a reason for hiding this comment

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

Just this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But here, both of these fail. @perexg What is the correct way?

SectionDevice."Speaker" {
        Macro.speaker.SofControl "endpoint=Speaker drcswitch=on"
}

If.spk {
	Condition {
		Type ControlExists
		Control "name='Speaker Playback Switch'"
	}
	True.SectionDevice."Speaker" {
               Macro.speaker.SofControl "endpoint=Speaker drcswitch=on"
        }
}

The speaker controls are not set, there's no print Speaker happening to /tmp/alsa-ucm.txt and I see in /var/log/syslog message " wireplumber[3991]: Failed to enable ucm device Speaker".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pereg Sorry for noise, again my bad. In my testing version I had device specific customization in place but needed EQ blobs were not in place. I should get this now working!

@@ -0,0 +1,7 @@
# How to build

These blobs were exported with example_fir_eq.m tool from
Copy link
Member

Choose a reason for hiding this comment

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

I would probably create one more level for those blobs like ucm2/blobs/sof/....

True.Define {
SOFIPCVer "ipc4"
BlobPath "${ConfTopDir}/sof/${var:SOFIPCVer}"
PostMixerAnalogPlaybackIIRBytes "Post Mixer Analog Playback IIR Eq bytes"
Copy link
Member

Choose a reason for hiding this comment

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

This can be more simplified. Just define the different values here and use another If to use those values (and execute the defines in the right order).

If.SOFPath {
  Condition { Type AlwaysTrue }
  True.Define {
    BlobPath "${ConfTopDir}/sof/${var:SOFIPCVer}"
      SpeakerIirBlob "${var:BlobPath}/eq_iir/highpass_100hz_0db_48khz.blob"
	      SpeakerFirBlob "${var:BlobPath}/eq_fir/pass.blob"
	      SpeakerDrcBlob "${var:BlobPath}/drc/speaker_default.blob"
	      HeadphoneIirBlob "${var:BlobPath}/eq_iir/pass.blob"
	      HeadphoneFirBlob "${var:BlobPath}/eq_fir/pass.blob"
	      HeadphoneDrcBlob "${var:BlobPath}/drc/passthrough.blob"
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks a lot for all the helpful suggestions! I hope to be able to share a new version next week some time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm trying this but I get "ALSA lib ucm_cond.c:378:(if_eval_one) condition block expected (If)". What could be wrong?

If.SOFIPCVer {
	Condition {
		Type ControlExists
		Control "name='Post Mixer Analog Playback IIR Eq bytes'"
	}
	True.Define {
	      SOFIPCVer "ipc4"
	      PostMixerAnalogPlaybackIIRBytes "Post Mixer Analog Playback IIR Eq bytes"
	      PostMixerAnalogPlaybackFIRBytes "Post Mixer Analog Playback FIR Eq bytes"
	      PostMixerAnalogPlaybackDRCBytes "Post Mixer Analog Playback DRC bytes"
	      PostMixerAnalogPlaybackDRCSwitch "Post Mixer Analog Playback DRC switch"
	}
	False.Define {
	      SOFIPCVer "ipc3"
	      PostMixerAnalogPlaybackIIRBytes "EQIIR1.0 eqiir_coef_1"
	      PostMixerAnalogPlaybackFIRBytes "EQFIR1.0 eqfir_coef_1"
	      PostMixerAnalogPlaybackDRCBytes "not available"
	      PostMixerAnalogPlaybackDRCSwitch "not available"
	}
}

If.SOFPath {
	Condition { Type AlwaysTrue }
	True.Define {
		BlobPath "${ConfTopDir}/blobs/sof/${var:SOFIPCVer}"
		SpeakerIirBlob "${var:BlobPath}/eq_iir/highpass_100hz_0db_48khz.blob"
		SpeakerFirBlob "${var:BlobPath}/eq_fir/pass.blob"
		SpeakerDrcBlob "${var:BlobPath}/drc/speaker_default.blob"
		HeadphoneIirBlob "${var:BlobPath}/eq_iir/pass.blob"
		HeadphoneFirBlob "${var:BlobPath}/eq_fir/pass.blob"
		HeadphoneDrcBlob "${var:BlobPath}/drc/passthrough.blob"
	}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@perexg Please ignore above question, it's correct. The problem is another fix later in not duplicating the entire speaker and headphone Ifs.

The example set contains passthrough configuration blobs with SOF IPC3
and IPC4 headers for DRC, FIR, and IIR. A few high-pass configurations
are added for IIR to be used e.g. for speakers. A DRC blob is added
that can be used to boost speaker playback loudness.

The blobs are all in binary format.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This example shows how to define IIR, FIR, and DRC processing for
speaker and headphone endpoints.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Copy link
Contributor

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

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

I tested an earlier version, but did another test with this version on a Intel IPC4 laptop. I tested specifying tuning blobs, switching between speaker and headphones, and also specifying the blob via a user config. All worked as advertise.

I can do a similar test when @singalsu you update the version.

EnableSequence [
cset-tlv "name='${var:PostMixerAnalogPlaybackIIRBytes}' ${var:EndpointIirBlob}"
cset-tlv "name='${var:PostMixerAnalogPlaybackFIRBytes}' ${var:EndpointFirBlob}"
#shell "/bin/echo '${var:__endpoint} ${var:EndpointIirBlob} ${var:EndpointFirBlob}' >> /tmp/alsa-ucm.txt"
Copy link
Contributor

Choose a reason for hiding this comment

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

I know it's not common to leave such commented-out code, but I did find these immensely useful when debugging and I could imagine these are useful for anyone who wants to add tuning for new laptop configurations later one. So if possible, +1 to leave these as examples.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the commented shell up before controls set to see the print before fails with them. There's now also a comment about use for debugging.

@singalsu singalsu force-pushed the intel_sof_hda_dsp_add_processing_control branch from 83907e1 to 261ff87 Compare May 31, 2024 10:23
@singalsu singalsu requested review from perexg and kv2019i May 31, 2024 10:26
Copy link
Contributor

@ujfalusi ujfalusi left a comment

Choose a reason for hiding this comment

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

@singalsu, this looks clean to my untrained eyes, I only have one nitpick and one question

}
}

# Merge this add to Headpones subtree in HDA/HiFi-analog.conf
Copy link
Contributor

Choose a reason for hiding this comment

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

Drop the 'add' from the comment

# Merge this to Speaker subtree in HDA/HiFi-analog.conf
SectionDevice."Speaker" {
Macro.speaker.SofControl "endpoint=Speaker drcswitch=on"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this create a "Speaker" Section Device when there is no Speaker, like on upx-i11?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the device will be always defined in this case. Move those lines to If block to use it only when the Speaker Playback Switch control exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks, it's fixed now!

Copy link
Member

@perexg perexg left a comment

Choose a reason for hiding this comment

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

Except the speaker block (missing condition) all looks really nice now.

This patch adds to Intel/sof-hda-dsp/HiFi.conf inclusion of
HiFi-sof.conf that by redefine of headphone and speaker handling
adds to UCM control of DRC and EQ SOF processing components.

The modified setting are applied in case of SOF processing
components' controls are detected. There is no change to operation
if no controls are present e.g. with legacy SOF topology.

If DRC control is found, it is assumed that also FIR and IIR
also exist. If there is no DRC but FIR is found, then it is assumed
that IIR also exists. This matches SOF FW builds for IPC3 (FIR, IIR)
and IPC4 (DRC, FIR, IIR). The controls names are different in IPC3
and IPC4 topologies. Also the configuration blobs differ.

The speaker mode is by default set up with 100 Hz high-pass IIR. The
DRC is set to a default speaker setting that boosts playback loudness.
The FIR is bypassed.

In the headphone mode all the processing is set to bypass and DRC
switch is set off.

The processing can be customized for products with UCM scripts placed
into blobs/sof/product_configs. The file path should be
<sys_vendor>/<product_name>.conf from DMI ID. An user configuration can
be similarly placed into blobs/sof/user_configs directory to e.g. avoid
it being overwritten by distribution.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
@singalsu singalsu force-pushed the intel_sof_hda_dsp_add_processing_control branch from 261ff87 to a50f7d9 Compare May 31, 2024 12:20
Copy link
Contributor

@ujfalusi ujfalusi left a comment

Choose a reason for hiding this comment

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

@singalsu, looks clean to me.

@perexg perexg closed this in 4502b17 May 31, 2024
perexg pushed a commit that referenced this pull request May 31, 2024
This example shows how to define IIR, FIR, and DRC processing for
speaker and headphone endpoints.

Closes: #419
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
perexg pushed a commit that referenced this pull request May 31, 2024
This patch adds to Intel/sof-hda-dsp/HiFi.conf inclusion of
HiFi-sof.conf that by redefine of headphone and speaker handling
adds to UCM control of DRC and EQ SOF processing components.

The modified setting are applied in case of SOF processing
components' controls are detected. There is no change to operation
if no controls are present e.g. with legacy SOF topology.

If DRC control is found, it is assumed that also FIR and IIR
also exist. If there is no DRC but FIR is found, then it is assumed
that IIR also exists. This matches SOF FW builds for IPC3 (FIR, IIR)
and IPC4 (DRC, FIR, IIR). The controls names are different in IPC3
and IPC4 topologies. Also the configuration blobs differ.

The speaker mode is by default set up with 100 Hz high-pass IIR. The
DRC is set to a default speaker setting that boosts playback loudness.
The FIR is bypassed.

In the headphone mode all the processing is set to bypass and DRC
switch is set off.

The processing can be customized for products with UCM scripts placed
into blobs/sof/product_configs. The file path should be
<sys_vendor>/<product_name>.conf from DMI ID. An user configuration can
be similarly placed into blobs/sof/user_configs directory to e.g. avoid
it being overwritten by distribution.

Closes: #419
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
@perexg
Copy link
Member

perexg commented May 31, 2024

Thanks. Applied now.

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.

4 participants