Besserer Stereo-zu-5.1-Upmix unter Linux/ALSA/.asoundrc
Letztens habe ich herausgefunden, wie man einen perfekten Upmix eines Stereo-Signals zu einem Surround-Signal unter Windows hinbekommt.
Das Gleiche wollte ich auch unter Linux erreichen, allerdings ist dies deutlich komplizierter und nur durch das Editieren einer Textdatei namens .asoundrc zu bewerkstelligen. Allerdings hat man damit auch viel mehr Möglichkeiten, wenn man das richtig anstellt! đ
Ich wollte 6 AnwendungsfÀlle behandeln:
- Alle Quellen werden standardmĂ€Ăig behandelt. Mono, Stereo, Surround gehen zu den entsprechenden Lautsprechern. Das ist einfach, denn so verhĂ€lt sich ALSA normalerweise.
- Eine Stereo-Quelle mit 2 KanÀlen wird auf 6 KanÀle hochgemixt
- Eine Surround-Quelle mit 6 KanÀlen wird genutzt, die zwei FrontkanÀle (Stereo) werden jedoch zusÀtzlich an den Subwoofer gesendet.
- FĂŒr alle 3 Situationen gibt es einen LautstĂ€rkeregler.
- Ein Extra-AufnahmgerĂ€t fĂŒr eine (Mono-)Webcam wird benötigt.
- All das sollte auch ĂŒber OSS laufen.
Update 24.08.2014: Tobias hat mich auf das FreeSurround-Plugin hingewiesen, welches das Upmixen von Stereoquellen sehr viel einfacher macht. Ich habe das in meine .asoundrc mit eingebaut. Danke dafĂŒr! đ
Warum Nummer 3? Weil einige Filme (besonders welche aus den 80ern) schlecht abgemischt sind und entweder einen viel zu schwachen Basskanal haben oder einen, der völlig still ist. Da ich keinen VerstĂ€rker habe, kann ich nur einen Kanal an meinen Sub senden und der frisst ihn dann. Die alte Schule, ich weiĂ.
Die Lösung ist fast perfekt – momentan kriegt mein Subwoofer noch den gesamten Frequenzbereich ab, was manchmal etwas unschön klingt – mein nĂ€chstes Ziel wird sein, einen Frequenzfilter ĂŒber LADSPA in diese Konfigurationsdatei mit einzubauen, um den perfekten Sound hinzubekommen.
Okay, hier ist sie – kopiere diese Datei in dein Home-Verzeichnis als .asoundrc und kommentiere das GerĂ€t das du nutzen will (im Abschnitt “pcm.duplex”) einfach aus:
#StandardgerĂ€t festlegen via "aplay -l" #Meine CM6206 ist hw2:0 pcm.snd_card { type hw card 2 device 0 } #StandardkontrollgerĂ€t festlegen ctl.snd_card { type hw card 2 device 0 } #Der folgende Abschnitt erstellt einen "Master"-Regler #Meine C-Media-Karte hat keinen, also ist es nĂŒtzlich. #Wenn deine Soundkarte kein MĂŒll ist und bereits einen hat, #wĂ€hle: slave.pcm "duplex" #und entferne den pcm.softvol-Teil pcm.!default { type plug slave.pcm "softvol" } pcm.softvol { type softvol slave { #leitet die Ausgabe an duplex weiter (anstatt "hw:2,0"): pcm "duplex" } control { name "Master" card 2 } } #Dies ist der wichtige Teil, in dem du entscheiden musst. #Willst du Upmix, Stereo oder was anderes? pcm.duplex { type asym # --Dies ist fĂŒr das FreeSurround ALSA-Plugin von hier:-- # http://micosphere.free.fr/freesurround-alsa/downloads.html # Dieses Plugin nimmt dir alle Entscheidungen ab. # playback.pcm "freesurround" # --Die folgenden Methoden sind traditionell-- # Stereo wird zu 6 KanĂ€len hochgemixt # Vorne links und Vorne rechts werden dupliziert auf # alle anderen playback.pcm "upmix" # Wenn deine Quelle 6 KanĂ€le hat, wĂ€hle dmixer: # playback.pcm "dmixer" # Wenn deine Quelle 6 KanĂ€le und einen miesen Basskanal hat, # nimm dies. Links und Rechts gehen an den Subwoofer # ohne die anderen KanĂ€le zu beeinflussen # playback.pcm "51withsub" # Stereo-AufnahmegerĂ€t capture.pcm "dsnooper" # Mono-(Webcam-)AufnahmegerĂ€t # capture.pcm "webcam" } # dmixer ist die zentrale Stelle die alles an die # richtigen Lautspr. schickt, festgelegt in "pcm.duplex" pcm.dmixer { type dmix ipc_key 1024 ipc_perm 0666 slave.pcm "snd_card" slave { period_time 0 period_size 1024 buffer_size 4096 channels 6 } bindings { 0 0 1 1 2 2 3 3 4 4 5 5 } } #Dies kontrolliert das AufnahmegerĂ€t. Es ist nur Stereo und #braucht deshalb nichts Besonderes. pcm.dsnooper { type dsnoop ipc_key 2048 ipc_perm 0666 slave.pcm "snd_card" slave { period_time 0 period_size 1024 buffer_size 4096 channels 2 } bindings { 0 0 1 1 } } #Meine Mono-Webcam braucht dies fĂŒr Skype pcm.webcam { type dsnoop ipc_key 4096 ipc_perm 0666 slave.pcm "hw:3,0" #cam gefunden via aplay -l slave { channels 1 } bindings { 0 0 } } # Dies ist fĂŒr das FreeSurround ALSA plugin von hier: # http://micosphere.free.fr/freesurround-alsa/downloads.html pcm.freesurround { type freesurround slave.pcm "snd_card" #surround51 for built-in default } # Hier sind meine festgelegten Routings. # Jeder Lautsprecher kann zu einem anderen # geroutet werden, Signale können gemischt werden etc. pcm.upmix { type route slave.pcm dmixer slave.channels 6 ttable.0.0 1 #links ttable.1.1 1 #rechts ttable.0.2 0.5 #halb links zum center ttable.1.2 0.5 #halb rechts zum center ttable.0.3 0.5 #halb links zum sub ttable.1.3 0.5 #halb rechts zum sub ttable.0.4 1 #links zu hinten links ttable.1.5 1 #rechts zu hinten rechts } pcm.51withsub { type route slave.pcm dmixer slave.channels 6 ttable.0.0 1 #links ttable.1.1 1 #rechts ttable.2.2 1 #center # ttable.3.3 1 #sub ttable.4.4 1 #hinten links ttable.5.5 1 #hinten rechts # halb links und halb rechts zum sub ttable.0.3 0.5 ttable.1.3 0.5 } #Altes Zeug: FĂŒr OSS-KompatibilitĂ€t mit aoss-Wrapper: pcm.dsp0 { type plug slave.pcm "!default" }
This is awesome! Thank you.
I just made the switch from my Windows 7 to Linux Mint 16.
There is one difference though:
“Speaker Fill” on the Hardware does some calculation and only mixes sound on L [AND] R to Center. Like a logical AND, you can only hear what is on both speakers and this way – in our real world – in the center.
Also, it routes sound only to the surround speakers, if it is not present on the opposite speaker. kinda like: L [AND NOT] R goes to SurroundLeft and likewise. This way, left-panned sounds will feel like behind you, which is also very natural.
Is there a way to achive this behavior? It is pure maths and logic, but I have no idea how to get this into a plugin or .asoundrc
Thanks for your great work! I’m looking forward to your answer, gerne auch auf deutsch đ
(See also my StackExchange Thread in the URL Field)
Hi,
I kinda incorporated that in a cheap way in the upmix section:
ttable.0.0 1 #left
ttable.1.1 1 #right
ttable.0.2 1 #left to center
ttable.1.3 1 #right to sub
ttable.0.4 0.5 #left to rear left
ttable.1.4 0.5 #right to rear left
ttable.0.5 0.5 #left to rear right
ttable.1.5 0.5 #right to rear right
}
You can at least modify that in a way that you only get front left to rear left or you can mix the two front channels into center where I chose to send the left channel to the center and the right one to the subwoofer. That would be something like this:
ttable.0.0 1 #left
ttable.1.1 1 #right
ttable.0.2 0.5 #half left to center
ttable.1.2 0.5 #half right to center
ttable.0.3 0.5 #half left to sub
ttable.1.3 0.5 #half right to sub
ttable.0.4 1 #left to rear left
ttable.1.5 1 #right to rear right
}
If you want to compare two channels and only send things to one channel that are not present on the other channel you can only achieve that with a LADSPA plugin. If anyone ever wrote such a plugin, I don’t know of that (yet). I’m still figuring out how to use a low-pass filter in there, so I’m not that “into” the topic of LADSPA myself. Good luck! đ
If you want real surround you can do this with freesurround ALSA plugin
http://micosphere.free.fr/?lang=en
That plugin is awesome! Thanks đ
I had trouble building it on Slackware, because it uses /usr/lib64 for ALSA. Changed all references in the Makefile from /usr/lib to /usr/lib64 and now it runs.
I made the following changes in my asoundrc:
1. In the “pcm.duplex” section I added a new line:
playback.pcm "freesurround"
2. I added a new section to start up FreeSound:
pcm.freesurround {
type freesurround
slave.pcm "snd_card" #surround51 for built-in default
}
That’s it! It works like a charme and using this way we can also retain the software volume control.