direwolf speech espeak dwespeak.sh alsa resource busy

by matthew
0 comment

ugh. alsa!

Recently while working on a Microsat Ulari 7Watt VHF APRS device I found an issue with Direwolf and the ‘dwespeak.sh’ script. In my research I also noted Direwolf users on other platforms were also experiencing issues with Direwolf and espeak – in that case you may wish to skip down to the ‘.asoundrc’ section for Alsa specific information.

In the case of the Ulari Duo I found:

  • The ‘espeak-ng’ package needs to be installed
  • dwespeak.sh is not included in the direwolf packaging shipped with the distribution
  • Alsa needs a configuration tweak to enable ‘device sharing’ of the sound card.

To confirm the system is using alsa, use ‘arecord -l’ to list alsa devices. /dev/dsp should be missing too.

First, stop direwolf:

systemctl stop direwolf

now, espeak-ng needs to be installed:

apt-get update
apt-get install espeak-ng

next, you’ll need to place the following contents into /usr/bin/dwespeak.sh (if it does not already exist as in the case with direwolf in the armbian packaging).

!/bin/bash
chan=$1
msg=$2
sleep 1
espeak -v en-sc "$msg"

and update /etc/direwolf.conf so that the following line is present:

SPEECH dwespeak.sh

Next I ran into ‘espeak’ being unable to access the sound device. The problem is that Alsa (by default) on this armbian distribution needs to be configured to have a slave ‘asymed’ plug otherwise I would encounter ‘device or resource busy’ errors due to Direwolf having exclusive access of the sound device.

Add to ~/.asoundrc:

pcm.dmixer {
    type dmix
    ipc_key 1024
    slave {
        pcm "hw:0,0"
        period_time 0
        period_size 1024
        buffer_size 8192
        rate 48000
    }

    bindings {
        0 0
        1 1
    }
}

pcm.asymed {
    type asym
    playback.pcm "dmixer"
    capture.pcm "hw:0,0"
}

pcm.dsp0 {
    type plug
    slave.pcm "asymed"
}

pcm.!default {
    type plug
    slave.pcm "asymed"
}

pcm.default {
    type plug
    slave.pcm "asymed"
}

ctl.mixer0 {
    type hw
    card 0
}

(Note that the ‘rate’ parameter must match the ‘ARATE’ setting in /etc/direwolf.conf).

Now either run direwolf by hand:

direwolf -c /etc/direwolf.conf -X 1

or start the daemon

systemctl start direwolf

And Voila! Direwolf can now call espeak to transmit speech!

You may also like