2

To setup my USB soundcard for my Linux PC, I started to learn about ALSA and about writing configuration files. After much effort, I was able to write one and get it working. The following is my .asoundrc stored in my home folder:

pcm.!default {
    type plug
    slave {
       pcm "hw:1,0"
    }
}

ctl.!default {
    type hw
    card 1
}

pcm_slave.maudiomtrackeight1 {
    pcm "hw:1,0"
    channels 8
    rate 44100
    buffer_size 4096
    period_size 1024
}

pcm.outch1 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 0 ]
    hint.description "M-Audio M-Track Eight output/playback channel 1"
}

pcm.inch1 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 0 ]
    hint.description "M-Audio M-Track Eight input/capture channel 1"
}

pcm.outch2 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 1 ]
    hint.description "M-Audio M-Track Eight output/playback channel 2"
}

pcm.inch2 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 1 ]
    hint.description "M-Audio M-Track Eight input/capture channel 2"
}

pcm.outch3 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 2 ]
    hint.description "M-Audio M-Track Eight output/playback channel 3"
}

pcm.inch3 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 2 ]
    hint.description "M-Audio M-Track Eight input/capture channel 3"
}

pcm.outch4 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 3 ]
    hint.description "M-Audio M-Track Eight output/playback channel 4"
}

pcm.inch4 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 3 ]
    hint.description "M-Audio M-Track Eight input/capture channel 4"
}

pcm.outch5 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 4 ]
    hint.description "M-Audio M-Track Eight output/playback channel 5"
}

pcm.inch5 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 4 ]
    hint.description "M-Audio M-Track Eight input/capture channel 5"
}

pcm.outch6 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 5 ]
    hint.description "M-Audio M-Track Eight output/playback channel 6"
}

pcm.inch6 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 5 ]
    hint.description "M-Audio M-Track Eight input/capture channel 6"
}

pcm.outch7 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 6 ]
    hint.description "M-Audio M-Track Eight output/playback channel 7"
}

pcm.inch7 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 6 ]
    hint.description "M-Audio M-Track Eight input/capture channel 7"
}

pcm.outch8 {
    type dshare
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 7 ]
    hint.description "M-Audio M-Track Eight output/playback channel 8"
}

pcm.inch8 {
    type dsnoop
    ipc_key 1111
    slave maudiomtrackeight1
    bindings [ 7 ]
    hint.description "M-Audio M-Track Eight input/capture channel 8"
}

Though I was able to grasp most of the concepts, I was unable to understand the following:

  • channels : does it stand for audio channel numbers? Like if I'm gonna use mono or stereo? Say, if my soundcard has 8 input ports and 8 output ports on it, if I were to use mono configuration should I set a value of 16 - 8 inputs + 8 outputs or 8 - 8 input-output pairs (and in case I were to use stereo configuration, should I set a value of 8 - 4 inputs + 4 outputs or 4 - 4 input-output pairs)?
  • buffer_size : I don't know anything except that making these sizes smaller is needed to ensure lower latency. What exactly does this mean?
  • period_size : again this has to be related to latency?
  • bindings : are these the ones that maps channels to the ports? For mono configuration I used [ <index_number> ]. Can I use [ <index_number1> <index_number2> ] for stereo configuration and likewise?
  • ipc_key : I understand it is a given unique number, same for each PCM device defined from the same slave. Supposing I add a new soundcard detected as hw:2,0, and go ahead to define PCM devices in the same manner as above, I will have to assign a different value for this parameter there (say 2222) for each PCM device defined from the new slave?

I could try and experiment a bit to understand the rest, but still some stuffs couldn't be cleared. The fact that not many tutorials and lack of good official ALSA documentation is not helping the cause either. Can someone throw some light on this?

3

Partial answer:

First, let me say that very likely you don't need to write a configuration for your M-Track at all. In fact, the way you have set it up is what you don't want under most circumstances: You have made each channel a separate device. That means when you try to record, say, a band playing at the same time, it's possible to get random offsets between the channels (band members) because each channel is processes separately. So normally, you'd just record all 8 channel into separate tracks, and then you have them nicely synchronized and you can edit them.

The same holds if you just want to connect up your home Hi-Fi system for playing music: You want synchronous channels for left/right/center/subwoofer/rear etc., not separate devices.

The only circumstances I can think if where it makes sense to make separate devices is if for some reason each channel is connected to a loudspeaker in a different room, and you want to play different music through each of them.

Also, modern ALSA automatically provides dshare and dsnoop plugins on top of the hardware decice by default, so you don't need to specify them explicitely.

That said, here are the explanations:

  • channels: The number of channels that are simultaniously recorded/played. 1 for mono, 2 for stereo, 8 for your card. Input and output is counted separately, so for 8 input and 8 input channels you just say "8 channels". The way you setup your inch and outch devices requires a channels 1 entry for each.

  • bindings: map channels from the device the slave device is bound to to the channels on this device. Say you want to swap the left and right channel of the original device by putting a plugin on top, then you'd say bindings { 0 1 1 0 }.

  • ipc_key: dmix, dshare and dsnoop plugins allow multiple clients to communicate with a single source/sink. This communication is done via this key (IPC = Inter-Process Communication). So the key needs to be different for every plugin, no matter if you have several plugins for one soundcard or one plugin each for several soundcard, or you'll run into trouble.

  • buffer_size: Audio data is stored and transferred in so-called buffers, i.e. pieces of RAM for a number of samples. If you make this way high, lots of data will be stored before it is processed, so you increase latency. If you make it way low, the overhead of processing will prevent all data to be processed before the next data comes in or must go out, so you'll have audio drop out.

  • period_size: No idea.

All ALSA PCM plugins are also described here in detail.

Don't mess with buffer_size or period_size unless you really know what you are doing. If latency is important for you (e.g., if you want to use the computer for a live performance), the first thing to do is to make sure Pulseaudio is uninstalled, and use jackd for all things audio. Only if you still experience noticable latency problems, you can try different values for buffer_size.

  • This is as good as it can get. Probably, partial only because of period_size being left blank. So, bindings { 0 1 1 0 } is a fixed string for swapping left and right channels of a device or is constructed based on some logic? Also, my PCM devices all are defined with same ipc_key as 1111. Going by your explanation, if I use 1111 for dsnoop, I must use something else for dshare right? Is there a way to know the optimal buffer_size and period_size values? Or its done through trial and error only? – skrowten_hermit Mar 23 '17 at 11:20
  • 1
    No, you must use different keys for every single plugin. So inch1 gets 1001, inch2 gets 1002, outch1 get 2001 etc. See the link above for the the format of binding. For share, dmix etc. it's pairs of slave channel/client channel. As for buffer size, define "optimal". As I said: Too low and you'll loose audio. Too high and you'll get higher latency. Just leave it alone unless you really need to modify it, because either you get drop outs, or you have noticable latency. – dirkt Mar 23 '17 at 11:43
  • So, I need to modify my .asoundrc and assign different key for each of the plugins above and probably remove buffer_size and period_size completely from the definition to make the configuration more stable and efficient, right? – skrowten_hermit Mar 27 '17 at 3:36
  • 1
    If you insist on using this particular configuration, because for example you have connected each channel to a single speaker in a different room, yes. If you want a stable and efficient configuration for most other purposes, you'd just completely delete it and use the default configuration (play/record 8 channels at once, with default dsnoop/dshare on top). If you would tell me in what way you intend to use it, I could comment on the best configuration. – dirkt Mar 27 '17 at 5:46
  • I'm trying to play an audio file on 8 separate devices and record them (not necessarily at the same time always), making sure I use dedicated channels for each. – skrowten_hermit Mar 29 '17 at 4:01
0

This article has a short explanation of the relationship of buffers and periods:

A sound card has a hardware buffer that stores recorded samples. When the buffer is sufficiently full, it [the sound card?] generates an interrupt. The kernel sound driver then uses direct memory access (DMA) to transfer samples to an application buffer in memory. [...] The buffer can be quite large, and transferring it in one operation could result in unacceptable delays, called latency. To solve this, ALSA splits the buffer up into a series of periods (called fragments in OSS/Free) and transfers the data in units of a period.

It sounds like:

  • audio samples are stored in a buffer
  • the kernel copies audio samples from the buffer to application memory
  • the buffer could be too large to transfer in one copy (causing latency)
  • the buffer is instead copied in pieces, called periods

The article provides a diagram.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.