Last active
July 4, 2022 11:22
-
-
Save chadmed/2c772c8fdac8280cb17846388203a213 to your computer and use it in GitHub Desktop.
j314s-alsa-notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# File written by chadmed <[email protected]> | |
# This file is organised from top to bottom as sound enters ALSA from user space. | |
# Set up device and set default for Pulse, PipeWire, JACK, etc. | |
# XXX: doesn't work reliably with PipeWire for some reason. | |
pcm.!default { | |
type plug | |
slave.pcm pass6 | |
} | |
ctl.!default { | |
type hw | |
card 0 | |
} | |
# We need to copy the L and R signal to 6 channels, each corresponding with a | |
# driver in the array. We use the assignments from the ASoC driver for | |
# simplicity. This must be a plug device for LADSPA to work properly. | |
pcm.pass6 { | |
type plug | |
slave.pcm filters | |
slave.channels 6 | |
ttable { | |
0.0 = 1 | |
0.2 = 1 | |
0.4 = 1 | |
1.1 = 1 | |
1.3 = 1 | |
1.5 = 1 | |
} | |
} | |
# The six channels are then routed into this PCM, which applies our filters | |
# accordng to the crossover network I determined. | |
pcm.filters { | |
type ladspa | |
slave.pcm dumbplug | |
path "/usr/lib/ladspa" | |
channels 6 | |
plugins { | |
# HPFs on the tweeters | |
0 { | |
label hpf | |
policy none | |
input.bindings.2 "Input"; | |
output.bindings.2 "Output"; | |
input { | |
controls [ 2000 ] | |
} | |
} | |
1 { | |
label hpf | |
policy none | |
input.bindings.3 "Input"; | |
output.bindings.3 "Output"; | |
input { | |
controls [ 2000 ] | |
} | |
} | |
# LPFs on the main woofers | |
2 { | |
label lpf | |
policy none | |
input.bindings.0 "Input"; | |
output.bindings.0 "Output"; | |
input { | |
controls [ 2000 ] | |
} | |
} | |
3 { | |
label lpf | |
policy none | |
input.bindings.1 "Input"; | |
output.bindings.1 "Output"; | |
input { | |
controls [ 2000 ] | |
} | |
} | |
# HPFs on the "main" woofers | |
4 { | |
label hpf | |
policy none | |
input.bindings.0 "Input"; | |
output.bindings.0 "Output"; | |
input { | |
controls [ 80 ] | |
} | |
} | |
5 { | |
label hpf | |
policy none | |
input.bindings.1 "Input"; | |
output.bindings.1 "Output"; | |
input { | |
controls [ 80 ] | |
} | |
} | |
# LPFs on the "sub" woofers | |
6 { | |
label lpf | |
policy none | |
input.bindings.4 "Input"; | |
output.bindings.4 "Output"; | |
input { | |
controls [ 400 ] | |
} | |
} | |
7 { | |
label lpf | |
policy none | |
input.bindings.5 "Input"; | |
output.bindings.5 "Output"; | |
input { | |
controls [ 400 ] | |
} | |
} | |
# HPFs on the "sub" woofers | |
8 { | |
label hpf | |
policy none | |
input.bindings.5 "Input"; | |
output.bindings.5 "Output"; | |
input { | |
controls [ 80 ] | |
} | |
} | |
9 { | |
label hpf | |
policy none | |
input.bindings.4 "Input"; | |
output.bindings.4 "Output"; | |
input { | |
controls [ 80 ] | |
} | |
} | |
} | |
} | |
# LADSPA MUST have a plug device as its slave. This slave simply passes | |
# whatever it gets from LADSPA to the actual speaker array | |
pcm.dumbplug { | |
type plug | |
slave.pcm j314s-array | |
} | |
# It is in this device that we map the output of LADSPA 1:1 with the speakers | |
# on the machine. The coefficients are for fine tuning the volume of each | |
# driver. | |
pcm.j314s-array { | |
type route | |
slave outputs | |
ttable { | |
0.0 = 1 | |
2.2 = 0.75 | |
4.4 = 1 | |
1.1 = 1 | |
3.3 = 0.75 | |
5.5 = 1 | |
} | |
} | |
# This is the actual interface to the hardware. Do not change this. | |
pcm_slave.outputs { | |
pcm "hw:0,0" | |
channels 6 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
macOS does two very interesting things to the audio signal. Firstly, it EQs away | |
almost all of the real low end below ~80-100Hz. This is actually a great idea, | |
since doing so stops the machine vibrating, which under Linux gave me a headache | |
after about 5 minutes of playing around with FIRs in Carla. It also clarifies the | |
sound big time. | |
The second thing it does is significantly boost the low mids. This is a very | |
common trick in consumer sound equipment. Consumers "like" the illusion of | |
fullness and richness, but this all this does is make things muddier. The real | |
shame here is that it's not even needed, these speakers sound quite excellent with | |
nothing more than basic crossovers and per-driver volume tuning in a routing | |
matrix. | |
Given that whatever processing macOS applies to the speakers actually hinders | |
their performance, I reccommend that we do not attempt to copy it. Rather, | |
whatever FIRs/IIRs we end up applying should be based on a series of parameters | |
I have experimentally determined to maximise the natural performance of this | |
extremely high quality speaker array. The quick version: | |
a) bandpass on drivers 4 and 5 of 80-400 Hz | |
b) bandpass on drivers 0 and 1 of 80-2000 Hz | |
c) high pass on drivers 2 and 3 set at 2000 Hz | |
d) linear coefficient of 0.75 applied to drivers 2 and 3 | |
e) -3 dB at 550 Hz, Q = 2.75, applied directly to the stereo signal | |
f) no cross mixing for stereo separation, it's not needed | |
For the why and how of these values, read on. | |
A SCIENCE-ADJACENT EXPERIMENT | |
----------------------------- | |
I have experimentally determined that these parameters result in the most | |
natural-sounding audio direct from ALSA. /etc/asound.conf included in this | |
Gist for reference. I am a scientist by trade and I simply could not live | |
with myself if I did not publish my findings properly, so for your perusal | |
here is a vaguely scientific writeup on what I did. | |
EQUIPMENT | |
--------- | |
The source music used for this experiment consisted of: | |
Kenny G - Breathless (whole album) [CD :: 16/44.1 FLAC] | |
DALI - ムーンライト伝説 (track) [CD :: 16/44.1 FLAC] | |
Sade - No Ordinary Love (track) [24/192 ALAC] | |
Aqua - Doctor Jones (track) [CD :: 16/44.1 FLAC] | |
Horii Katsumi Project - Sky Cruisin' (album) [CD :: 16/44.1 FLAC] | |
George Gershwin (rec. Royal Phil. Orch.) - Rhapsody In Blue [24/96 ALAC] | |
Michael Jackson - Off The Wall (album) [LP :: 24/96 FLAC] | |
花江夏樹 - 青春は残酷じゃない (track) [YouTube (garbage)] | |
角松敏生 - On The City Shore (album) [LP :: 24/192 FLAC] | |
Kelly Bailey - Half-Life 2 Original Sountrack (album) [CD :: 16/44.1 FLAC] | |
菊池桃子 - Adventure (album) [LP :: 24/192 FLAC] | |
ABBA - Arrival (album) [LP :: 24/192 FLAC] | |
These tracks and albums were chosen to ensure that whatever parameters were | |
applied preserved the experience intended by the artists/engineers across many | |
genres and styles. (I'm also not going to sit here all day listening to | |
music I don't like) | |
All music samples were played through my home HiFi as a reference. Physical | |
formats specified above indicate the source of the digital transfers used | |
on the J314s. ALACs were sourced from Apple Music, and YouTube was sourced from | |
Google. As my digital rips were made on different equipment to what I have now, | |
I also used the physical copies as reference material to verify that the transfers | |
are of acceptable quality for this experiment. They are of marginally lower | |
quality than I would have liked, but any differences were noted and accounted | |
for. | |
Reference Setup | |
------------------ | |
Speakers: | |
Richter Wizard S6 (3-way floorstanders) | |
Amp: | |
Yamaha A-S2200 | |
Digital Signal Chain: | |
J314s MacBook Pro (CoreAudio) feeds | |
Schiit Hel 2 (24/192) line level output feeds | |
Yamaha amp line in | |
Physical Sources: | |
LP: Denon DP-47F w/ Ortofon 2M Blue cartridge/stylus | |
CD: Onkyo 6-CD carousel (using builtin DAC) | |
Test Machine | |
------------- | |
J314s running the Asahi reference distro plus Plasma under Wayland. | |
Vanilla PulseAudio feeding a custom ALSA device as per the included asound.conf. | |
PA daemon manually set to 24/96 with resampling enabled to match the hardware. | |
All drivers were configured to 50% volume in alsamixer with no amp gain. | |
The ASoC driver seems to significantly overdrive the amps and causes wild | |
clipping above this. | |
METHODS | |
-------- | |
Testing was conducted in an A/B pattern. I would listen to the source material | |
for a while, mute it, then move over to the J314s under Linux and play the | |
corresponding audio file. Crossover values would be manually set in asound.conf, | |
PA restarted from the command line, and then the test continued until the values | |
below were determined to produce the nicest sound. | |
Additional testing consisted of applying IIRs to the stereo signal via | |
the LSP 32-band PEQ plugin in Carla. | |
RESULTS | |
-------- | |
The table below outlines the crossover network I landed on at the end of this | |
experiment. | |
Freq Range (Hz) | Drivers Note that frequencies below 80 Hz are filtered | |
----------------|--------- out of the signal. As discussed, this greatly | |
80-400 | 0 1 4 5 improves the sound clarity and stops the machine | |
400-2000 | 0 1 from vibrating. The cones are too small to | |
2000-20000 | 2 3 properly reproduce anything that low anyway. | |
Mixing coefficients are applied to each driver in order to balance | |
the sound profile. The tweeters are significantly louder than the woofers, and | |
so a 1:1 mix causes the sound to be harsh and aggressive. Using a linear | |
coefficient of 0.75 cuts virtually all harshness out of the sound and results | |
in a mostly flat sound profile with a very slight emphasis on the low end. The | |
woofers are all mixed at 1:1. | |
After applying these parameters via a series of chained PCM devices in | |
asound.conf, the speaker array sounds incredibly good, better than it | |
does in macOS in my opinion. | |
The array is fairly linear in response, with slight booming at 450-650 Hz and | |
harmonics thereof. This is fairly typical for laptop speaker arrays. These are | |
diminished with a -3 dB reduction at 550 Hz with Q = 2.25. | |
Additionally, stereo separation is fantastic even without any fancy cross | |
mixing as done by macOS. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## BEGIN NOTES ## | |
HOUSEKEEPING | |
All testing conducted with channels set to 40% in alsamixer, | |
with no amp gain. | |
Do NOT try to play sound with the speakers set to 100% in alsamixer, | |
you will fry the cones! | |
DRIVER MAPPINGS/ALSA QUIRKS | |
The speaker array as set up by the ASoC driver maps like | |
this on a J314s: | |
0: Left Woofer 1 | |
1: Right Woofer 1 | |
2: Left Tweeter | |
3: Right Tweeter | |
4: Left (Sub)Woofer 2 | |
5: Right (Sub)Woofer 2 | |
ALSA sets up the speaker array on the J314s as a 4.0 surround system, | |
with the RL and RR channels duplicated across the woofers like this: | |
2: Front Left | |
3: Front Right | |
0: Rear Left | |
1: Rear Right | |
4: Rear Left | |
5: Rear Right | |
Obviously this is not correct, but for us it does not matter, since | |
we can just tell ALSA to route FL and FR to all drivers, presenting | |
it to the rest of userspace as a stereo device. Surround sources | |
are downmixed appropriately. | |
SOUND CHECK | |
Testing reveals that drivers 4 and 5 are likely | |
only there to help with bass and sub bass. They | |
are extremely bad at reproducing frequencies above | |
~500Hz, and even with the help of the tweeters sound | |
rough/deep fried in the mids. Drivers 0 and 1 are obviously | |
intended to be the main woofers in the array. | |
If we weren't intending to mimic whatever macOS does, my ear-only | |
testing would have me setting up a xover network like this: | |
Freq Range (Hz) | Drivers | |
----------------|--------- | |
0-300 | 0 1 4 5 | |
300-6500 | 0 1 | |
6500-20000 | 2 3 | |
THIS TABLE IS WRONG: SEE UPDATE BELOW! | |
Figures based on typical {LP,BP,HP}F rolloff characteristics. | |
Using all 4 woofers below 300Hz moves more air than just using the | |
(sub)woofers alone. 3-way loudspeakers work like this conventionally. | |
The ttable in the j314s-array pcm device tries to compensate for the lack of | |
EQ right now by greatly reducing the volume of 4 and 5, and slightly reducing | |
the volume of 0 and 1 relative to 2 and 3. I have found this gives an acceptably | |
clear sound without being too bright or losing too much out of the mids. Bass is | |
nonexistent, though I suspect this is just because we have not applied appropriate | |
correction to overcome the machine's housing yet. | |
FIRs can be applied to a 6 channel slave PCM which would then feed the routing | |
table | |
## END NOTES ## |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That's just something I put there for the time being: https://github.com/povik/linux/blob/asahi-sound-wip/sound/soc/apple/macaudio.c#L487
I suppose the woofers are not "rear enough" to qualify...