Skip to content

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:

  1. Alle Quellen werden standardmäßig behandelt. Mono, Stereo, Surround gehen zu den entsprechenden Lautsprechern. Das ist einfach, denn so verhält sich ALSA normalerweise.
  2. Eine Stereo-Quelle mit 2 Kanälen wird auf 6 Kanäle hochgemixt
  3. Eine Surround-Quelle mit 6 Kanälen wird genutzt, die zwei Frontkanäle (Stereo) werden jedoch zusätzlich an den Subwoofer gesendet.
  4. Für alle 3 Situationen gibt es einen Lautstärkeregler.
  5. Ein Extra-Aufnahmgerät für eine (Mono-)Webcam wird benötigt.
  6. 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"
}

Dieser Beitrag hat 6 Kommentare

  1. 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)

    1. 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! 🙂

    1. 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.

  2. Can’t get it to work – bummer. Exactly the point keeps me from using Linux for years. I just can’t get the upmix to work. Is there possibly a tutorial for beginners under Ubuntu 20.x

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

An den Anfang scrollen