Alsa: Combining Type "Dsnoop" with Type "Fifo"

I am trying to get my Linux audio system to handle audio via ALSA. These are the requirements

  1. Handle echo cancellation - I am using , following the steps mentioned and it works independently without a problem
  2. Divide the echo canceled stream to 2
  3. One going into a noise-canceling plugin again works independently, the audio output of this is used by a different program
  4. The other to a compressor, the audio output of this will be the default device

Problem

I am facing problems in using "dsnoop" to share/divide the audio stream into two. When dsnoop plugins' slave is set to be a FIFO it throws an error.

executed:

sudo arecord -D default -f cd defRecording.wav -c 1 -r 32000

error:

ALSA lib pcm_direct.c:1809:(_snd_pcm_direct_get_slave_ipc_offset) Invalid type 'fifo' for slave PCM

arecord: main:828: audio open error: Invalid argument

This is the current asound.conf settings

asound.conf

pcm.!default {
    type asym
    playback.pcm "playback"
    capture.pcm "capture"
}

pcm.playback {
    type plug
    slave.pcm "eci"
}

# Stream Output 1: Final
pcm.capture {
    type plug
    slave.pcm "compressor"
}

# Stream Output 2: Final
pcm.capture2 {
    type plug
    slave.pcm "werman"
}

# Stream output 2: Noise Cancellation
pcm.werman {
    type ladspa
    slave.pcm "array";
    path "/usr/lib/ladspa";
    plugins [{
        label noise_suppressor_mono
        input {
            # VAD Threshold %
            controls [ 1  ]
        }
    }]
}

# Stream output 1: Compressor
pcm.compressor {
    type ladspa
    slave.pcm "array";
    path "/usr/lib/ladspa";
    plugins [{
        label dysonCompress
        input {
            #peak limit, release time, fast ratio, ratio
            controls [0 1 0.5 0.99]
        }
    }]
}

# Used to share the record device
pcm.array {
    type dsnoop
    slave {
        pcm "eco"
        channels 1
    }
    ipc_key 666666
}

# Writes audio coming from any sort of player to ec.input, this is read by the echo
# cancellation software.
pcm.eci {
    type plug
    slave {
        format S16_LE
        rate 32000
        channels 1
        pcm {
            type file
            slave.pcm null
            file "/tmp/ec.input"
            format "raw"
        }
    }
}

# Read FIFO output which contains echo cancelled audio
pcm.eco {
    type plug
    slave.pcm {
        type fifo
        infile "/tmp/ec.output"
        rate 32000
        format S16_LE
        channels 1
    }
    #ipc_key 666666
}

Note: eco is used to read the FIFO file which contains the echo canceled audio coming in from cancellation software. This software's input is hw:0 and records audio directly from the microphone, and then processes and passes this over to ec.output

Dsnoop works well when the slave.pcm is a hardware device but as soon as I point to something else it fails. Is there a workaround or any other solution to tackle this problem?

1 Answer

Dsnoop can only have a hardware slave so it can not take in a FIFO plugin as an input. To solve this, I made the echo cancellation software output data into 2 different FIFO files and then read that via ALSA.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.

Share this article
Twitter Facebook Pinterest