Closed marcan closed 2 weeks ago
Useful resources from TI:
How could we use I/V sense:
Bonus points for the latter two: hwmon and power subsystem reporting of average power draw.
I believe second option is the most sane. Userspace support like in (3) requires some form of integrity assurance as well, since the kernel will have to first take a handshake to ensure that protection-enabled software is being ran, as well as having a watchdog to check the userspace process every (milliseconds interval I think?), which will require messy API between kernel and userspace audio. Also this closes the way for using native ALSA without a sound server.
However if we limit safety with a power monitoring in kernel, this ensures protection in a more confident fashion. I believe the algorithm might make its way into ASoC subsystem, as it should be pretty much universal and it's the kernel job to drive hardware and protect it. I might try to develop various algorithmic solutions once some data is obtained.
This is the security measure like a circuit breaker, not the operational mode. So kernel is only responsible for essentially cutting power off the amp by toggling hw mute on when something goes wrong. However, userspace still holds the responsibility for impulse response filters for quality sound and prevention of overcurrent. This protection should only get tripped when userspace bugs out or is misconfigured.
Also, nobody forbids us to actually do both for best power and safety combo. Kernel both keeps an eye at monitoring parameters to shut amps down if there's a risk and streams that data into userspace. PipeWire (we mainly target it for now) tries to avoid fault mode and muting, it adjusts the volume and (maybe) filters to ensure the correct current. But still, kernel makes the thing safe even if we break PW, misconfigure it, cause bugs etc. So no watchdog/authentication handshake needed.
That's all fine and good, but as I said in the first sentence of the thread, let's keep this issue about the research. We've already covered the obvious bases as far as possible implementations, and any further discussion is pointless until we actually find out what we need to do to keep the speakers in a safe operating envelope.
Okay, so I did a bit of recon in macOS and it turns out this stuff is all out in the open in plist files. I think we can afford to look at this (the speaker limits are facts about the hardware, so not copyrightable).
/System/Library/Audio/Tunings/AID<id>
has all the DSP chains and speaker protection parameters, where <id> is /product/audio.acoustic-id
from the ADT. For example, the speaker protection model for the M2 air (AID13) is in AID13/DSP/Strips/aid13-aufx-spp3-appl.plist
. Snippet from the tweeter temperature model:
<key>SpeakerName</key>
<string>LT</string>
<key>SpeakerGroup</key>
<integer>1</integer>
<key>IgnoreTelemetry</key>
<false/>
<key>OL_thermal</key>
<dict>
<key>Rshunt</key>
<real>0</real>
<key>Reb_ref</key>
<real>3.72</real>
<key>Rampout</key>
<integer>0</integer>
<key>T_sett_vc</key>
<real>104.9</real>
<key>tau_Tvc</key>
<real>3.9</real>
<key>T_sett_mg</key>
<real>129.5</real>
<key>tau_Tmg</key>
<integer>70</integer>
<key>ThermalFFSpeedupFactor</key>
<real>0.25</real>
<key>HardTempLimitHeadroom</key>
<real>10</real>
<key>TemperatureLimit</key>
<integer>140</integer>
</dict>
The ADT also contains /product/audio.speaker-thiele-small
, which is a thing. That blob structure roughly decodes like this:
02 00 5e 04
00000000 860f f10a 00000000 00000000 0000 30417073
'spA0'
00000000 610f f10a 00000000 00000000 0000 31417073 'spA1'
00000000 e60d f10a 00000000 00000000 0000 34417073 'spA4'
00000000 ba0d f10a 00000000 00000000 0000 35417073 'spA5'
97f3 checksum?
The parameters are each 16 bits it seems. The first one that has data is DC resistance in milliohms. The second one is called 't' judging by some strings, and I'm not sure what it is (but it doesn't look individually calibrated?)
If we only care about DC resistance for the safety model, the amp chips can measure that (and I was planning on adding that feature for experimentation), so it might be preferable to just have the driver/protection daemon do a measurement at startup and avoid having to drag around calibration data from the ADT (which could be out of date anyway, if the user has done a non-official speaker replacement).
Okay, so let's do a bit of math. Assuming a constant resistance (which isn't true but it'll do for now), with the amp at 15.5 dBV, and input at -2dBFS, that's 13.5 dBV = 4.73 Vrms, current at 3.72Ω is 1.27 A. Almost exactly 6 W I was pumping into each tweeter.
We have τ_Tvc = 3.9 and τ_Tmg = 70, and I think T_sett_vc=104.9 and T_sett_mg=129.5 are the thermal resistances in °C/W. That means that, if I'm mental mathing right, the tweeter voice coil would've reached >600°C after a few seconds, give or take (and longer as the magnet heats up).
Yeah, no wonder I cooked it.
Given both thermal resistances and max temp, the long term average power (= maximum safe kernel level cap) is on the order of 0.5W or so, 12 times lower than what I have. That's a little over 10 dB lower, add 2 for the signal headroom, you end up at 3.5 dBV max safe output. The lowest we can go for the amp gain is 11 dBV, so that means we need to cap the DVC at -7.5 dB or so on top.
I sure hope I screwed up the math somewhere, because otherwise that's a ridiculously small safe volume limit to put in the kernel.
More resources: https://liu.diva-portal.org/smash/get/diva2:954210/FULLTEXT01.pdf
In particular,
vs. these keys:
<key>PilotAmplHi_dB</key>
<integer>-30</integer>
<key>PilotAmplLo_dB</key>
<integer>-40</integer>
<key>PilotUpperThres</key>
<integer>90</integer>
<key>PilotLowerThres</key>
<real>80</real>
<key>PilotDecayTime</key>
<real>0.05</real>
<key>PilotFreq</key>
<real>43.0664</real>
... make me think whatever Apple engineers came up with this were reading that same paper.
Okay, so let's do a bit of math. Assuming a constant resistance (which isn't true but it'll do for now), with the amp at 15.5 dBV, and input at -2dBFS, that's 13.5 dBV = 4.73 Vrms, current at 3.72Ω is 1.27 A. Almost exactly 6 W I was pumping into each tweeter.
Checks out for me. (Including crosschecking with the amp datasheet but assuming 3.72 ohms is right.)
We have τ_Tvc = 3.9 and τ_Tmg = 70, and I think T_sett_vc=104.9 and T_sett_mg=129.5 are the thermal resistances in °C/W. That means that, if I'm mental mathing right, the tweeter voice coil would've reached >600°C after a few seconds, give or take (and longer as the magnet heats up).
So the steady state temperature difference should be power times the thermal resistance, giving the 600 degrees, hmm. How sure are we about the units? Also what about the taus? If they are in joules per degree, that would take a bit of time to heat up.
The taus would be in seconds, since they are time constants. So after 3.9 seconds you'd be ~62% of the way to the target. Hence my 40-second sweeps should've effectively reached the new steady state temperature for the voice coil vs. magnet system (the magnet itself would only be part of the way up, since its time constant is 70)
As for the units, strings from the DSP plugin say:
speakerType A: VoiceCoil: DC resistance [Ohms]
speakerType A: VoiceCoil: thermal resistance [C/Watt]
speakerType A: Magnet: thermal resistance [C/Watt]
speakerType A: Voice Coil: thermal time constant [s]
speakerType A: Magnet: thermal time constant [s]
speakerType A: Ambient temperature, [C]
speakerType A: Temperature limit [C]
speakerType A: Attack time
speakerType A: Release time
speakerType A: Temperature hard limit headroom [C]
Of course, I can't know whether those map 1:1 to the parameters in the plist, but it would be weird if they don't.
OK, convinces me
Oh yeah, and this math is for sine waves, but a square wave has 1.414 times the RMS voltage, and therefore delivers 2 times the power. Assuming the amp definition of output gains is for sine waves, that means we need another factor of 2 (3dB) in our safety calculation (this is the I Won The Loudness War safety factor ;) - and this checks out, since the song is ~+3dB LUFS!).
Also, since coil resistance increases with temperature, it wouldn't actually hit 600°C. With the tempco from the plist, you get 2x resistance at ~285°C, so let's say equilibrium at 300°C or so. That's ~soldering temperature, which also checks out with the damage not being an instant open circuit. High enough to solidly melt the plastic, low enough that the coil itself probably survived (though might've partially shorted out).
So, before I go to sleep, let's see how badly I abused the woofers. 3.9Ω, same amp settings, so 1.21 A and about 5.7W.
Those have a T_sett_vc of 32.1, so 183°C plus ambient, call it 200°C. Due to the tempco, equilibrium is more like at +126°C, where resistance is 45% higher. That's ~150°C with ambient. Max temperature is... 140°C.
Checks out. I abused them but not too badly. Which means the existing kernel limit is actually not too shabby for the woofers. -2dB for the signal, -3dB for square waves, -1dB so we don't actually exceed 140°C, let's say -6dB would get us into 100% safe territory.
Honestly? They're loud enough, -6dB is usable, and if I put them first in the channel map no-userspace playback will default to the woofers. So I'm actually tempted to enable audio for this model, putting a crazy cap on the tweeters but just -6dB on the woofers, and at least then people can start playing around with userspace and get some audio.
Ah, but we need to consider the magnet temp too, that's 20°C/W. Let's round that up to same as the voice coil, and call it 2x in total. So -3dB on top of the prior calculation, for sustained power safety.
The parameters are each 16 bits it seems. The first one that has data is DC resistance in milliohms. The second one is called 't' judging by some strings, and I'm not sure what it is (but it doesn't look individually calibrated?)
My guess would be 't' refers to Qt (or Qts), which is maybe the most relevant Thielle-Small parameter. What's the value of the 't' parameter?
The parameters are each 16 bits it seems. The first one that has data is DC resistance in milliohms. The second one is called 't' judging by some strings, and I'm not sure what it is (but it doesn't look individually calibrated?)
My guess would be 't' refers to Qt (or Qts), which is maybe the most relevant Thielle-Small parameter. What's the value of the 't' parameter?
After going through the speaker protection model stuff, I'm pretty sure it's temperature at which the DC resistance was measured. For this laptop it's 2801 for all speakers (28.01°C). It doesn't make much sense for a Thiele-Small parameter to be the same for woofers and tweeters, and temperature makes sense since it gives you the reference point for the DC impedance vs. temperature curve, which allows you to calculate voice coil temperature given that and the tempco (which is in the speaker protection profile).
Makes sense -- except that temperature is not part of the Thielle-Small parameter set.
Turns out this all works pretty much as expected. J314 tweeter voice coil temperature (blue) vs. model estimate (orange). Green is the magnet temperature estimate. The woofer model is a bit worse, but not much.
Now we just need to implement this in the production daemon, and take a guess as to what a good temperature governor model is (since it's not entirely clear what Apple does here exactly).
Could you maybe give a status update? Thanks :)
@hackgrid I have an unfounded theory that that this will be a surprise feature drop, along with the official fedora distro release coming at some point later this month
@DavidBuchanan314 That would be very nice. The next fedora release is scheduled to be released on 06.11.
But can you please answer the question how you come to the assumption that the speaker support could be included in the fedora release?
@marcan and everyone else, i would like to thank you for the great work. Can you say anything about how to support to move forward on the problem with the speaker? For me it is the last piece of the puzzle to be able to use Linux more or less productively on the Macbook. I assume some others feel the same way as I do.
If you follow the IRC channels and Linas last webcam videos, you get the impression it is coming soon.
Markus @.***> schrieb am Fr., 29. Sept. 2023, 07:56:
@DavidBuchanan314 https://github.com/DavidBuchanan314 That would be very nice. The next fedora release is scheduled to be released on 06.11.
But can you please answer the question how you come to the assumption that the speaker support could be included in the fedora release?
@marcan https://github.com/marcan and everyone else, i would like to thank you for the great work. Can you say anything about how to support to move forward on the problem with the speaker? For me it is the last piece of the puzzle to be able to use Linux more or less productively on the Macbook. I assume some others feel the same way as I do.
— Reply to this email directly, view it on GitHub https://github.com/AsahiLinux/linux/issues/53#issuecomment-1740350734, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAANGLH3MSMAGSO7ECEU4Q3X4ZPIPANCNFSM6AAAAAAQLBVQ2U . You are receiving this because you were mentioned.Message ID: @.***>
@Markus-Be I don't have any evidence, hence "unfounded theory". I am reading tea leaves. It would be pointless to speculate any further.
Nevertheless, I'm in the mood to write a bunch of pointless words, so here goes. It is my understanding that most of the speaker-related research has been completed, and the remaining work required is "just" integrating it all. Given that Fedora is the new flagship asahi distro, that's where I expect to see it integrated first. Given that both Fedora and Asahi have high quality standards, I'd expect speaker support out-of-the-box in an "official" release.
Estimating software engineering progress is famously impossible, so when that official release arrives is anyone's guess.
This is done.
Opening this to track the ongoing research into the safety envelope of the speakers (focusing mostly on testing; we can open other threads to discuss potential solutions once we have more data on what's needed).
The first target is an M2 MacBook Air, which is interesting because:
Initial testing done with povik's latest audio branch, including volume caps and tweeter HPF. Configured as follows:
No VISENSE support yet, that's in the works.
Testing using a sine sweep, 10-20kHz, 40 seconds, volume 0.8 (~-2dB). Initial testing was ad-hoc since I was not expecting damage this quickly, but a couple sweeps from Linux were enough to destroy the left tweeter and possibly damage the right one.
The failure mode for the tweeters seems to be a severe drop in volume, except for a small band of improved reproduction (that varies). My theory is that this is thermal damage, i.e. the tweeter melted itself and seized up. Left: dead tweeter; right: possibly-damaged but still functional tweeter.
In addition, there is rattling, which can be identified by the presence of sub harmonics. See the band in the middle of this sweep of the right tweeter:
It's not clear whether I actually damaged the woofers during this test. More controlled testing will follow. For now, my conclusion is that the tweeters are the major damage risk, and that damage occurs fairly quickly, even with just 40-second sweeps. If this is thermal, that suggests even short-term power excursions are dangerous.
After the initial testing, a follow-up with I Won The Loudness War successfully killed the right tweeter in the same way as the left one. I am sending the machine in for repairs.
Next steps:
For Linux testing:
A priori, it would seem that we have to set the tweeter amp gain much lower than we do now.
Bonus points once most of the work is done: