Skip to content

Commit

Permalink
Use pulseaudio via ALSA as default audio backend
Browse files Browse the repository at this point in the history
We were previously accessing pulseaudio via OSS, but this worked very
badly.

By using the 'pulse' audio device we can work against pulseaudio by
default, and direct hardware access is still available for advanced
users who are willing to give Purr Data exclusive soundcard access.

The OSS and JACK backends are now disabled. Direct access to JACK
from inside Flatpak is unsupported and broken (see
#14) while
Pipewire support is not yet ready (see
#11).

Fixes #10
  • Loading branch information
ssssam committed Jul 20, 2020
1 parent 57501e1 commit 6088c35
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 1 deletion.
8 changes: 7 additions & 1 deletion net.purrdata.PurrData.yml
Expand Up @@ -40,12 +40,16 @@ modules:
- name: purr-data
buildsystem: autotools
subdir: pd/src
config-opts: [ '--disable-portaudio', '--enable-alsa', '--enable-oss', '--enable-jack' ]
config-opts: [ '--disable-portaudio', '--enable-alsa', '--disable-oss', '--disable-jack' ]
sources:
- type: git
url: https://github.com/agraef/purr-data/
tag: 2.12.0
commit: aeb24d8910da8ea5dc3bf3619e49d74f8e350cf7
- type: patch
path: patch/alsa-adddev.patch
- type: patch
path: patch/alsa-debug.patch
- type: patch
path: patch/gnu-make-parallel.patch
- type: patch
Expand Down Expand Up @@ -148,6 +152,8 @@ modules:
path: net.purrdata.PurrData.metainfo.xml
- type: file
path: default.settings
- type: patch
path: patch/flatpak-alsa-pulse.patch

cleanup:
- /include/*
Expand Down
70 changes: 70 additions & 0 deletions patch/alsa-adddev.patch
@@ -0,0 +1,70 @@
diff --git a/pd/src/s_audio_alsa.c b/pd/src/s_audio_alsa.c
index cb59b096..25eccd66 100644
--- a/pd/src/s_audio_alsa.c
+++ b/pd/src/s_audio_alsa.c
@@ -838,19 +838,29 @@ void alsa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
int maxndev, int devdescsize)
{
- int ndev = 0, cardno = -1, i, j;
+ int ndev = 0, cardno = -1;
*canmulti = 2; /* supports multiple devices */
+
+ /* First list devices from the -alsa-adddev command line arg */
+ for (ndev = 0; ndev < alsa_nnames; ndev++)
+ {
+ if (ndev >= maxndev)
+ break;
+ snprintf(indevlist + ndev * devdescsize, devdescsize, "%s",
+ alsa_names[ndev]);
+ snprintf(outdevlist + ndev * devdescsize, devdescsize, "%s",
+ alsa_names[ndev]);
+ }
+
+ /* Then query hardware devices from ALSA */
while (!snd_card_next(&cardno) && cardno >= 0)
{
snd_ctl_t *ctl;
snd_ctl_card_info_t *info = NULL;
char devname[80];
const char *desc;
- if (2 * ndev + 2 > maxndev)
+ if (ndev + 2 > maxndev)
break;
- /* apparently, "cardno" is just a counter; but check that here */
- if (ndev != cardno)
- fprintf(stderr, "oops: ALSA cards not reported in order?\n");
sprintf(devname, "hw:%d", cardno);
// fprintf(stderr, "\ntry %s...\n", devname);
if (snd_ctl_open(&ctl, devname, 0) >= 0)
@@ -865,23 +875,17 @@ void alsa_getdevs(char *indevlist, int *nindevs,
desc = "???";
}
/* fprintf(stderr, "name: %s\n", snd_ctl_card_info_get_name(info)); */
- sprintf(indevlist + 2*ndev * devdescsize, "%s (hardware)", desc);
- sprintf(indevlist + (2*ndev + 1) * devdescsize, "%s (plug-in)", desc);
- sprintf(outdevlist + 2*ndev * devdescsize, "%s (hardware)", desc);
- sprintf(outdevlist + (2*ndev + 1) * devdescsize, "%s (plug-in)", desc);
- ndev++;
+ sprintf(indevlist + ndev * devdescsize, "%s (hardware)", desc);
+ sprintf(indevlist + (ndev + 1) * devdescsize, "%s (plug-in)", desc);
+ sprintf(outdevlist + ndev * devdescsize, "%s (hardware)", desc);
+ sprintf(outdevlist + (ndev + 1) * devdescsize, "%s (plug-in)", desc);
+ ndev += 2;
if (info)
{
snd_ctl_card_info_free(info);
info = NULL;
}
}
- for (i = 0, j = 2*ndev; i < alsa_nnames; i++, j++)
- {
- if (j >= maxndev)
- break;
- snprintf(indevlist + j * devdescsize, devdescsize, "%s",
- alsa_names[i]);
- }
- *nindevs = *noutdevs = j;
+
+ *nindevs = *noutdevs = ndev;
}
77 changes: 77 additions & 0 deletions patch/alsa-debug.patch
@@ -0,0 +1,77 @@
diff --git a/pd/src/s_audio_alsa.c b/pd/src/s_audio_alsa.c
index cb59b096..beeb8129 100644
--- a/pd/src/s_audio_alsa.c
+++ b/pd/src/s_audio_alsa.c
@@ -169,7 +169,7 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate,
/* set the sampling rate */
err = snd_pcm_hw_params_set_rate_min(dev->a_handle, hw_params,
(unsigned int *)rate, 0);
- check_error(err, "snd_pcm_hw_params_set_rate_min (input)");
+ check_error(err, "snd_pcm_hw_params_set_rate_min");
#if 0
err = snd_pcm_hw_params_get_rate(hw_params, &subunitdir);
post("input sample rate %d", err);
@@ -185,7 +185,7 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate,
err = snd_pcm_hw_params_set_period_size_near(dev->a_handle,
hw_params, &tmp_snd_pcm_uframes, 0);
#endif
- check_error(err, "snd_pcm_hw_params_set_period_size_near (input)");
+ check_error(err, "snd_pcm_hw_params_set_period_size_near");

/* set the buffer size */
#ifdef ALSAAPI9
@@ -196,10 +196,10 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate,
err = snd_pcm_hw_params_set_buffer_size_near(dev->a_handle,
hw_params, &tmp_snd_pcm_uframes);
#endif
- check_error(err, "snd_pcm_hw_params_set_buffer_size_near (input)");
+ check_error(err, "snd_pcm_hw_params_set_buffer_size_near");

err = snd_pcm_hw_params(dev->a_handle, hw_params);
- check_error(err, "snd_pcm_hw_params (input)");
+ check_error(err, "snd_pcm_hw_params");

/* set up the buffer */
bufsizeforthis = DEFDACBLKSIZE * dev->a_sampwidth * *channels;
@@ -254,7 +254,7 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
alsa_numbertoname(audioindev[iodev], devname, 512);
err = snd_pcm_open(&alsa_indev[alsa_nindev].a_handle, devname,
SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
- check_error(err, "snd_pcm_open");
+ check_error(err, "snd_pcm_open (input)");
if (err < 0)
continue;
alsa_indev[alsa_nindev].a_devno = audioindev[iodev];
@@ -268,7 +268,7 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev,
alsa_numbertoname(audiooutdev[iodev], devname, 512);
err = snd_pcm_open(&alsa_outdev[alsa_noutdev].a_handle, devname,
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
- check_error(err, "snd_pcm_open");
+ check_error(err, "snd_pcm_open (output)");
if (err < 0)
continue;
alsa_outdev[alsa_noutdev].a_devno = audiooutdev[iodev];
@@ -421,7 +421,8 @@ int alsa_send_dacs(void)
callno++;
#endif

- alsa_checkiosync(); /* check I/O are in sync and data not late */
+ if (alsa_nindev > 0 && alsa_noutdev > 0)
+ alsa_checkiosync(); /* check I/O are in sync and data not late */

for (iodev = 0; iodev < alsa_nindev; iodev++)
{
@@ -746,10 +747,10 @@ static void alsa_checkiosync( void)
}
if (result < 0)
{
- post("output snd_pcm_delay failed: %s", snd_strerror(result));
- if (snd_pcm_status(alsa_outdev[iodev].a_handle,
+ post("input snd_pcm_delay failed: %s", snd_strerror(result));
+ if (snd_pcm_status(alsa_indev[iodev].a_handle,
alsa_status) < 0)
- post("output snd_pcm_status failed");
+ post("input snd_pcm_status failed");
else post("astate %d",
snd_pcm_status_get_state(alsa_status));
return;
24 changes: 24 additions & 0 deletions patch/flatpak-alsa-pulse.patch
@@ -0,0 +1,24 @@
commit 0c9930081862d95fd36e241b7350e83b2f514618
Author: Sam Thursfield <sam@afuera.me.uk>
Date: Mon Jul 20 11:43:22 2020 +0200

flatpak: Use pulseaudio via ALSA as default audio backend

We were previously accessing pulseaudio via OSS, but this worked very
badly.

By using the 'pulse' audio device we can work against pulseaudio by
default, and direct hardware access is still available for advanced
users who are willing to give Purr Data exclusive soundcard access.

Fixes https://github.com/flathub/net.purrdata.PurrData/issues/10

diff --git a/packages/linux_flatpak/pd-wrapper.sh b/packages/linux_flatpak/pd-wrapper.sh
index 541a195e..e056fa6c 100644
--- a/packages/linux_flatpak/pd-wrapper.sh
+++ b/packages/linux_flatpak/pd-wrapper.sh
@@ -1,3 +1,3 @@
#!/bin/sh

-padsp -n "Pure Data (Flatpak)" pd-l2ork -oss $@
+pd-l2ork -alsa -alsaadd pulse $@

0 comments on commit 6088c35

Please sign in to comment.