aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desiredata/src/s_audio_alsa.c197
-rw-r--r--desiredata/src/s_audio_alsa.h14
-rw-r--r--desiredata/src/s_audio_alsamm.c112
3 files changed, 159 insertions, 164 deletions
diff --git a/desiredata/src/s_audio_alsa.c b/desiredata/src/s_audio_alsa.c
index 21119641..0271e440 100644
--- a/desiredata/src/s_audio_alsa.c
+++ b/desiredata/src/s_audio_alsa.c
@@ -9,7 +9,7 @@
#include <alsa/asoundlib.h>
-#include "m_pd.h"
+#include "desire.h"
#include "s_stuff.h"
#include <errno.h>
#include <stdio.h>
@@ -51,11 +51,7 @@ static int alsa_snd_bufsize;
static int alsa_buf_samps;
static snd_pcm_status_t *alsa_status;
static int alsa_usemmap;
-
-t_alsa_dev alsa_indev[ALSA_MAXDEV];
-t_alsa_dev alsa_outdev[ALSA_MAXDEV];
-int alsa_nindev;
-int alsa_noutdev;
+t_alsa alsai,alsao;
static void check_error(int err, const char *why) {if (err<0) error("%s: %s", why, snd_strerror(err));}
@@ -177,57 +173,57 @@ int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int
nfrags = int(sys_schedadvance * (float)rate / (1e6 * frag_size));
/* save our belief as to ALSA's buffer size for later */
alsa_buf_samps = nfrags * frag_size;
- alsa_nindev = alsa_noutdev = 0;
+ alsai.ndev = alsao.ndev = 0;
alsa_jittermax = ALSA_DEFJITTERMAX;
if (sys_verbose) post("audio buffer set to %d", (int)(0.001 * sys_schedadvance));
- for (int iodev=0; iodev<naudioindev; iodev++) {
- alsa_numbertoname(audioindev[iodev], devname, 512);
- err = snd_pcm_open(&alsa_indev[alsa_nindev].a_handle, devname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
+ for (int i=0; i<naudioindev; i++) {
+ alsa_numbertoname(audioindev[i], devname, 512);
+ err = snd_pcm_open(&alsai.dev[alsai.ndev].a_handle, devname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
check_error(err, "snd_pcm_open (input)");
if (err<0) continue;
- alsa_indev[alsa_nindev].a_devno = audioindev[iodev];
- snd_pcm_nonblock(alsa_indev[alsa_nindev].a_handle, 1);
+ alsai.dev[alsai.ndev].a_devno = audioindev[i];
+ snd_pcm_nonblock(alsai.dev[alsai.ndev].a_handle, 1);
if (sys_verbose) post("opened input device name %s", devname);
- alsa_nindev++;
+ alsai.ndev++;
}
- for (int iodev=0; iodev<naudiooutdev; iodev++) {
- alsa_numbertoname(audiooutdev[iodev], devname, 512);
- err = snd_pcm_open(&alsa_outdev[alsa_noutdev].a_handle, devname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+ for (int i=0; i<naudiooutdev; i++) {
+ alsa_numbertoname(audiooutdev[i], devname, 512);
+ err = snd_pcm_open(&alsao.dev[alsao.ndev].a_handle, devname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
check_error(err, "snd_pcm_open (output)");
if (err<0) continue;
- alsa_outdev[alsa_noutdev].a_devno = audiooutdev[iodev];
- snd_pcm_nonblock(alsa_outdev[alsa_noutdev].a_handle, 1);
- alsa_noutdev++;
+ alsao.dev[alsao.ndev].a_devno = audiooutdev[i];
+ snd_pcm_nonblock(alsao.dev[alsao.ndev].a_handle, 1);
+ alsao.ndev++;
}
- if (!alsa_nindev && !alsa_noutdev) goto blewit;
+ if (!alsai.ndev && !alsao.ndev) goto blewit;
/* If all the open devices support mmap_noninterleaved, let's call Wini's code in s_audio_alsamm.c */
alsa_usemmap = 1;
- for (int iodev=0; iodev<alsa_nindev ; iodev++) if (!alsaio_canmmap(&alsa_indev [iodev])) alsa_usemmap = 0;
- for (int iodev=0; iodev<alsa_noutdev; iodev++) if (!alsaio_canmmap(&alsa_outdev[iodev])) alsa_usemmap = 0;
+ for (int i=0; i<alsai.ndev; i++) if (!alsaio_canmmap(&alsai.dev[i])) alsa_usemmap = 0;
+ for (int i=0; i<alsao.ndev; i++) if (!alsaio_canmmap(&alsao.dev[i])) alsa_usemmap = 0;
if (alsa_usemmap) {
post("using mmap audio interface");
if (alsamm_open_audio(rate)) goto blewit; else return 0;
}
- for (int iodev=0; iodev<alsa_nindev; iodev++) {
- int channels = chindev[iodev];
- if (alsaio_setup(&alsa_indev[iodev], 0, &channels, &rate, nfrags, frag_size) < 0) goto blewit;
+ for (int i=0; i<alsai.ndev; i++) {
+ int channels = chindev[i];
+ if (alsaio_setup(&alsai.dev[i], 0, &channels, &rate, nfrags, frag_size) < 0) goto blewit;
inchans += channels;
}
- for (int iodev=0; iodev<alsa_noutdev; iodev++) {
- int channels = choutdev[iodev];
- if (alsaio_setup(&alsa_outdev[iodev], 1, &channels, &rate, nfrags, frag_size) < 0) goto blewit;
+ for (int i=0; i<alsao.ndev; i++) {
+ int channels = choutdev[i];
+ if (alsaio_setup(&alsao.dev[i], 1, &channels, &rate, nfrags, frag_size) < 0) goto blewit;
outchans += channels;
}
if (!inchans && !outchans) goto blewit;
- for (int iodev=0; iodev<alsa_nindev ; iodev++) snd_pcm_prepare( alsa_indev[iodev].a_handle);
- for (int iodev=0; iodev<alsa_noutdev; iodev++) snd_pcm_prepare(alsa_outdev[iodev].a_handle);
- /* if duplex we can link the channels so they start together */
- for (int iodev=0; iodev<alsa_nindev; iodev++) {
- for (int dev2=0; dev2<alsa_noutdev; dev2++) {
- if (alsa_indev[iodev].a_devno == alsa_outdev[iodev].a_devno) {
- snd_pcm_link(alsa_indev[iodev].a_handle,alsa_outdev[iodev].a_handle);
+ for (int i=0; i<alsai.ndev; i++) snd_pcm_prepare(alsai.dev[i].a_handle);
+ for (int i=0; i<alsao.ndev; i++) snd_pcm_prepare(alsao.dev[i].a_handle);
+ /* if duplex we can link the channels so they start together; however j is not used, so wtf */
+ for (int i=0; i<alsai.ndev; i++) {
+ //for (int j=0; j<alsao.ndev; j++) {
+ if (alsai.dev[i].a_devno == alsao.dev[i].a_devno) {
+ snd_pcm_link(alsai.dev[i].a_handle,alsao.dev[i].a_handle);
}
- }
+ //}
}
/* allocate the status variables */
if (!alsa_status) {
@@ -239,12 +235,12 @@ int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int
if (outchans) {
i = (frag_size * nfrags)/sys_dacblocksize + 1;
while (i--) {
- for (int iodev=0; iodev<alsa_noutdev; iodev++)
- snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize);
+ for (int i=0; i<alsao.ndev; i++)
+ snd_pcm_writei(alsao.dev[i].a_handle, alsa_snd_buf, sys_dacblocksize);
}
} else if (inchans) {
- for (int iodev=0; iodev<alsa_nindev; iodev++)
- if ((err = snd_pcm_start(alsa_indev[iodev].a_handle)) < 0) check_error(err, "input start failed");
+ for (int i=0; i<alsai.ndev; i++)
+ if ((err = snd_pcm_start(alsai.dev[i].a_handle)) < 0) check_error(err, "input start failed");
}
return 0;
blewit:
@@ -257,15 +253,15 @@ blewit:
static void alsa_close_audio() {
int err;
if (alsa_usemmap) {alsamm_close_audio(); return;}
- for (int iodev=0; iodev<alsa_nindev; iodev++) {
- err = snd_pcm_close(alsa_indev[iodev].a_handle);
+ for (int i=0; i<alsai.ndev; i++) {
+ err = snd_pcm_close(alsai.dev[i].a_handle);
check_error(err, "snd_pcm_close (input)");
}
- for (int iodev=0; iodev<alsa_noutdev; iodev++) {
- err = snd_pcm_close(alsa_outdev[iodev].a_handle);
+ for (int i=0; i<alsao.ndev; i++) {
+ err = snd_pcm_close(alsao.dev[i].a_handle);
check_error(err, "snd_pcm_close (output)");
}
- alsa_nindev = alsa_noutdev = 0;
+ alsai.ndev = alsao.ndev = 0;
}
int alsa_send_dacs() {
@@ -276,11 +272,11 @@ int alsa_send_dacs() {
static double timenow;
double timelast;
t_sample *fp1, *fp2;
- int i, j, k, iodev, result, ch;
+ int j, k, iodev, result, ch;
int chansintogo, chansouttogo;
unsigned int transfersize;
if (alsa_usemmap) return alsamm_send_dacs();
- if (!alsa_nindev && !alsa_noutdev) return SENDDACS_NO;
+ if (!alsai.ndev && !alsao.ndev) return SENDDACS_NO;
chansintogo = sys_inchannels;
chansouttogo = sys_outchannels;
transfersize = sys_dacblocksize;
@@ -291,45 +287,50 @@ int alsa_send_dacs() {
callno++;
#endif
alsa_checkiosync(); /* check I/O are in sync and data not late */
- for (int iodev=0; iodev<alsa_nindev; iodev++) {
- snd_pcm_status(alsa_indev[iodev].a_handle, alsa_status);
+ for (int iodev=0; iodev<alsai.ndev; iodev++) {
+ snd_pcm_status(alsai.dev[iodev].a_handle, alsa_status);
if (snd_pcm_status_get_avail(alsa_status) < transfersize) return SENDDACS_NO;
}
- for (int iodev=0; iodev<alsa_noutdev; iodev++) {
- snd_pcm_status(alsa_outdev[iodev].a_handle, alsa_status);
+ for (int iodev=0; iodev<alsao.ndev; iodev++) {
+ snd_pcm_status(alsao.dev[iodev].a_handle, alsa_status);
if (snd_pcm_status_get_avail(alsa_status) < transfersize) return SENDDACS_NO;
}
/* do output */
fp1 = sys_soundout; ch = 0;
- for (int iodev=0; iodev<alsa_noutdev; iodev++) {
- int thisdevchans = alsa_outdev[iodev].a_channels;
- int chans = (chansouttogo < thisdevchans ? chansouttogo : thisdevchans);
+ for (int iodev=0; iodev<alsao.ndev; iodev++) {
+ int thisdevchans = alsao.dev[iodev].a_channels;
+ int chans = min(chansouttogo,thisdevchans);
chansouttogo -= chans;
- if (alsa_outdev[iodev].a_sampwidth == 4) {
- for (i = 0; i < chans; i++, ch++, fp1 += sys_dacblocksize)
- for (j = ch, k = sys_dacblocksize, fp2 = fp1; k--; j += thisdevchans, fp2++) {
- float s1 = *fp2 * INT32_MAX;
- ((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(int(s1));
+ int i;
+ if (alsao.dev[iodev].a_sampwidth == 4) {
+ for (i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) {
+ fp2 = fp1;
+ for (int j = ch, k = sys_dacblocksize; k--; j += thisdevchans, fp2++) {
+ float s1 = *fp2 * INT32_MAX;
+ ((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(int(s1));
+ }
}
- for (; i < thisdevchans; i++, ch++)
- for (j = ch, k = sys_dacblocksize; k--; j += thisdevchans) ((t_alsa_sample32 *)alsa_snd_buf)[j] = 0;
+ for (; i<thisdevchans; i++, ch++)
+ for (int j = ch, k = sys_dacblocksize; k--; j += thisdevchans) ((t_alsa_sample32 *)alsa_snd_buf)[j] = 0;
} else {
- for (i = 0; i < chans; i++, ch++, fp1 += sys_dacblocksize)
- for (j = ch, k = sys_dacblocksize, fp2 = fp1; k--; j += thisdevchans, fp2++) {
- int s = int(*fp2 * 32767.);
- if (s > 32767) s = 32767; else if (s < -32767) s = -32767;
- ((t_alsa_sample16 *)alsa_snd_buf)[j] = s;
+ for (i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) {
+ fp2=fp1;
+ for (int j=ch, k=sys_dacblocksize; k--; j += thisdevchans, fp2++) {
+ int s = int(*fp2 * 32767.);
+ if (s > 32767) s = 32767; else if (s < -32767) s = -32767;
+ ((t_alsa_sample16 *)alsa_snd_buf)[j] = s;
+ }
}
for (; i < thisdevchans; i++, ch++)
- for (j = ch, k = sys_dacblocksize; k--; j += thisdevchans) ((t_alsa_sample16 *)alsa_snd_buf)[j] = 0;
+ for (int j = ch, k = sys_dacblocksize; k--; j += thisdevchans) ((t_alsa_sample16 *)alsa_snd_buf)[j] = 0;
}
- result = snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, transfersize);
+ result = snd_pcm_writei(alsao.dev[iodev].a_handle, alsa_snd_buf, transfersize);
if (result != (int)transfersize) {
#ifdef DEBUG_ALSA_XFER
if (result >= 0 || errno == EAGAIN) post("ALSA: write returned %d of %d", result, transfersize);
else error("ALSA: write: %s", snd_strerror(errno));
post("inputcount %d, outputcount %d, outbufsize %d",
- inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsa_outdev[iodev].a_sampwidth * outchannels);
+ inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsao.dev[iodev].a_sampwidth * outchannels);
#endif
sys_log_error(ERR_DACSLEPT);
return SENDDACS_NO;
@@ -345,22 +346,22 @@ int alsa_send_dacs() {
}
}
/* do input */
- for (iodev = 0, fp1 = sys_soundin, ch = 0; iodev < alsa_nindev; iodev++) {
- int thisdevchans = alsa_indev[iodev].a_channels;
+ for (iodev = 0, fp1 = sys_soundin, ch = 0; iodev < alsai.ndev; iodev++) {
+ int thisdevchans = alsai.dev[iodev].a_channels;
int chans = (chansintogo < thisdevchans ? chansintogo : thisdevchans);
chansouttogo -= chans;
- result = snd_pcm_readi(alsa_indev[iodev].a_handle, alsa_snd_buf, transfersize);
+ result = snd_pcm_readi(alsai.dev[iodev].a_handle, alsa_snd_buf, transfersize);
if (result < (int)transfersize) {
#ifdef DEBUG_ALSA_XFER
if (result<0) error("snd_pcm_read %d %d: %s", callno, xferno, snd_strerror(errno));
else post("snd_pcm_read %d %d returned only %d", callno, xferno, result);
post("inputcount %d, outputcount %d, inbufsize %d",
- inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsa_indev[iodev].a_sampwidth * inchannels);
+ inputcount, outputcount, (ALSA_EXTRABUFFER + sys_advance_samples) * alsai.dev[iodev].a_sampwidth * inchannels);
#endif
sys_log_error(ERR_ADCSLEPT);
return SENDDACS_NO;
}
- if (alsa_indev[iodev].a_sampwidth == 4) {
+ if (alsai.dev[iodev].a_sampwidth == 4) {
for (int i=0; i<chans; i++, ch++, fp1 += sys_dacblocksize) {
for (j = ch, k = sys_dacblocksize, fp2 = fp1; k--; j += thisdevchans, fp2++)
*fp2 = (float) ((t_alsa_sample32 *)alsa_snd_buf)[j] * (1./ INT32_MAX);
@@ -385,18 +386,18 @@ int alsa_send_dacs() {
}
void alsa_printstate() {
- int result, iodev = 0;
+ int result, i=0;
snd_pcm_sframes_t indelay, outdelay;
if (sys_audioapi != API_ALSA) {
error("restart-audio: implemented for ALSA only.");
return;
}
if (sys_inchannels) {
- result = snd_pcm_delay(alsa_indev[iodev].a_handle, &indelay);
+ result = snd_pcm_delay(alsai.dev[i].a_handle, &indelay);
if (result<0) error("snd_pcm_delay 1 failed"); else post( "in delay %d", indelay);
}
if (sys_outchannels) {
- result = snd_pcm_delay(alsa_outdev[iodev].a_handle, &outdelay);
+ result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay);
if (result<0) error("snd_pcm_delay 2 failed"); else post("out delay %d", outdelay);
}
post("sum %d (%d mod 64)", indelay + outdelay, (indelay+outdelay)%64);
@@ -405,12 +406,12 @@ void alsa_printstate() {
void alsa_putzeros(int iodev, int n) {
- memset(alsa_snd_buf, 0, alsa_outdev[iodev].a_sampwidth * sys_dacblocksize * alsa_outdev[iodev].a_channels);
- for (int i=0; i<n; i++) snd_pcm_writei(alsa_outdev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize);
+ memset(alsa_snd_buf, 0, alsao.dev[iodev].a_sampwidth * sys_dacblocksize * alsao.dev[iodev].a_channels);
+ for (int i=0; i<n; i++) snd_pcm_writei(alsao.dev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize);
}
void alsa_getzeros(int iodev, int n) {
- for (int i=0; i<n; i++) snd_pcm_readi(alsa_indev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize);
+ for (int i=0; i<n; i++) snd_pcm_readi(alsai.dev[iodev].a_handle, alsa_snd_buf, sys_dacblocksize);
}
/* call this only if both input and output are open */
@@ -425,15 +426,15 @@ static void alsa_checkiosync() {
}
minphase = 0x7fffffff;
maxphase = -0x7fffffff;
- for (int iodev=0; iodev<alsa_noutdev; iodev++) {
- result = snd_pcm_delay(alsa_outdev[iodev].a_handle, &outdelay);
+ for (int i=0; i<alsao.ndev; i++) {
+ result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay);
if (result < 0) {
- snd_pcm_prepare(alsa_outdev[iodev].a_handle);
- result = snd_pcm_delay(alsa_outdev[iodev].a_handle, &outdelay);
+ snd_pcm_prepare(alsao.dev[i].a_handle);
+ result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay);
}
if (result<0) {
error("output snd_pcm_delay failed: %s", snd_strerror(result));
- if (snd_pcm_status(alsa_outdev[iodev].a_handle, alsa_status)<0) error("output snd_pcm_status failed");
+ if (snd_pcm_status(alsao.dev[i].a_handle, alsa_status)<0) error("output snd_pcm_status failed");
else post("astate %d", snd_pcm_status_get_state(alsa_status));
return;
}
@@ -443,15 +444,15 @@ static void alsa_checkiosync() {
if (outdelay < 0)
sys_log_error(ERR_DATALATE), alreadylogged = 1;
}
- for (int iodev=0; iodev<alsa_nindev; iodev++) {
- result = snd_pcm_delay(alsa_indev[iodev].a_handle, &thisphase);
+ for (int i=0; i<alsai.ndev; i++) {
+ result = snd_pcm_delay(alsai.dev[i].a_handle, &thisphase);
if (result < 0) {
- snd_pcm_prepare(alsa_indev[iodev].a_handle);
- result = snd_pcm_delay(alsa_indev[iodev].a_handle, &thisphase);
+ snd_pcm_prepare(alsai.dev[i].a_handle);
+ result = snd_pcm_delay(alsai.dev[i].a_handle, &thisphase);
}
if (result < 0) {
error("output snd_pcm_delay failed: %s", snd_strerror(result));
- if (snd_pcm_status(alsa_outdev[iodev].a_handle, alsa_status) < 0) error("output snd_pcm_status failed");
+ if (snd_pcm_status(alsao.dev[i].a_handle, alsa_status) < 0) error("output snd_pcm_status failed");
else post("astate %d", snd_pcm_status_get_state(alsa_status));
return;
}
@@ -463,22 +464,22 @@ static void alsa_checkiosync() {
we just ask that the spread be not more than 3/4 of a block. */
if (maxphase <= minphase + (alsa_jittermax * (sys_dacblocksize / 4))) break;
if (!alreadylogged) sys_log_error(ERR_RESYNC), alreadylogged = 1;
- for (int iodev=0; iodev<alsa_noutdev; iodev++) {
- result = snd_pcm_delay(alsa_outdev[iodev].a_handle, &outdelay);
+ for (int i=0; i<alsao.ndev; i++) {
+ result = snd_pcm_delay(alsao.dev[i].a_handle, &outdelay);
if (result < 0) break;
thisphase = alsa_buf_samps - outdelay;
if (thisphase > minphase + sys_dacblocksize) {
- alsa_putzeros(iodev, 1);
+ alsa_putzeros(i,1);
#if DEBUGSYNC
post("putz %d %d", (int)thisphase, (int)minphase);
#endif
}
}
- for (int iodev=0; iodev<alsa_nindev; iodev++) {
- result = snd_pcm_delay(alsa_indev[iodev].a_handle, &thisphase);
+ for (int i=0; i<alsai.ndev; i++) {
+ result = snd_pcm_delay(alsai.dev[i].a_handle, &thisphase);
if (result < 0) break;
if (thisphase > minphase + sys_dacblocksize) {
- alsa_getzeros(iodev, 1);
+ alsa_getzeros(i, 1);
#if DEBUGSYNC
post("getz %d %d", (int)thisphase, (int)minphase);
#endif
@@ -521,7 +522,7 @@ static void alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *n
snd_ctl_card_info_t *info;
char devname[80];
char *desc;
- if (2 * ndev + 2 > maxndev) break;
+ if (2*ndev + 2 > maxndev) break;
/* apparently, "cardno" is just a counter; but check that here */
if (ndev != cardno) post("oops: ALSA cards not reported in order?");
sprintf(devname, "hw:%d", cardno);
@@ -542,7 +543,7 @@ static void alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *n
ndev++;
free(desc);
}
- for (i = 0, j = 2*ndev; i < alsa_nnames; i++, j++) {
+ for (i=0, j=2*ndev; i<alsa_nnames; i++, j++) {
if (j >= maxndev) break;
snprintf(indevlist + j * devdescsize, devdescsize, "%s", alsa_names[i]);
}
diff --git a/desiredata/src/s_audio_alsa.h b/desiredata/src/s_audio_alsa.h
index 986bc1f5..4d67f78f 100644
--- a/desiredata/src/s_audio_alsa.h
+++ b/desiredata/src/s_audio_alsa.h
@@ -20,20 +20,20 @@ typedef int32_t t_alsa_sample32;
#define INT32_MAX 0x7fffffff
#endif
-typedef struct _alsa_dev
-{
+struct t_alsa_dev {
snd_pcm_t *a_handle;
int a_devno;
int a_sampwidth;
int a_channels;
char **a_addr;
int a_synced;
-} t_alsa_dev;
+};
-extern t_alsa_dev alsa_indev[ALSA_MAXDEV];
-extern t_alsa_dev alsa_outdev[ALSA_MAXDEV];
-extern int alsa_nindev;
-extern int alsa_noutdev;
+struct t_alsa {
+ t_alsa_dev dev[ALSA_MAXDEV];
+ int ndev;
+};
+extern t_alsa alsai, alsao;
int alsamm_open_audio(int rate);
void alsamm_close_audio(void);
diff --git a/desiredata/src/s_audio_alsamm.c b/desiredata/src/s_audio_alsamm.c
index 3a57691d..5ee76e3d 100644
--- a/desiredata/src/s_audio_alsamm.c
+++ b/desiredata/src/s_audio_alsamm.c
@@ -146,8 +146,8 @@ int alsamm_open_audio(int rate) {
/* first have a look which cards we can get and set up device infos for them */
/* init some structures */
for(int i=0; i<ALSA_MAXDEV;i++) {
- alsa_indev[i].a_synced=alsa_outdev[i].a_synced=0;
- alsa_indev[i].a_channels=alsa_outdev[i].a_channels=-1; /* query defaults */
+ alsai.dev[i].a_synced=alsao.dev[i].a_synced=0;
+ alsai.dev[i].a_channels=alsao.dev[i].a_channels=-1; /* query defaults */
}
alsamm_inchannels = 0;
alsamm_outchannels = 0;
@@ -167,36 +167,35 @@ int alsamm_open_audio(int rate) {
if(sys_verbose)
post("syschedadvance=%d us(%d Samples)so buffertime max should be this=%d"
"or sys_blocksize=%d (samples) to use buffersize=%d",
- sys_schedadvance,sys_advance_samples,alsamm_buffertime,
- sys_blocksize,alsamm_buffersize);
+ sys_schedadvance,sys_advance_samples,alsamm_buffertime,sys_blocksize,alsamm_buffersize);
alsamm_periods = 0; /* no one wants periods setting from command line ;-) */
- for (int i=0; i<alsa_noutdev;i++) {
- /* post("open audio out %d, of %lx, %d",i,&alsa_device[i], alsa_outdev[i].a_handle); */
+ for (int i=0; i<alsao.ndev;i++) {
+ /* post("open audio out %d, of %lx, %d",i,&alsa_device[i], alsao.dev[i].a_handle); */
try {
- CHK(set_hwparams(alsa_outdev[i].a_handle, hw_params, &(alsa_outdev[i].a_channels)));
- CHK(set_swparams(alsa_outdev[i].a_handle, sw_params,1));
- alsamm_outchannels += alsa_outdev[i].a_channels;
- alsa_outdev[i].a_addr = (char **)malloc(sizeof(char *)*alsa_outdev[i].a_channels);
- if(!alsa_outdev[i].a_addr) {error("playback device outaddr allocation error:"); continue;}
- memset(alsa_outdev[i].a_addr, 0, sizeof(char*) * alsa_outdev[i].a_channels);
- post("playback device with %d channels and buffer_time %d us opened", alsa_outdev[i].a_channels, alsamm_buffertime);
+ CHK(set_hwparams(alsao.dev[i].a_handle, hw_params, &(alsao.dev[i].a_channels)));
+ CHK(set_swparams(alsao.dev[i].a_handle, sw_params,1));
+ alsamm_outchannels += alsao.dev[i].a_channels;
+ alsao.dev[i].a_addr = (char **)malloc(sizeof(char *)*alsao.dev[i].a_channels);
+ if(!alsao.dev[i].a_addr) {error("playback device outaddr allocation error:"); continue;}
+ memset(alsao.dev[i].a_addr, 0, sizeof(char*) * alsao.dev[i].a_channels);
+ post("playback device with %d channels and buffer_time %d us opened", alsao.dev[i].a_channels, alsamm_buffertime);
} catch (AlsaError) {continue;}
}
- for (int i=0; i<alsa_nindev; i++) {
+ for (int i=0; i<alsai.ndev; i++) {
if(sys_verbose) post("capture card %d:--------------------",i);
- CHK(set_hwparams(alsa_indev[i].a_handle, hw_params, &(alsa_indev[i].a_channels)));
- alsamm_inchannels += alsa_indev[i].a_channels;
- CHK(set_swparams(alsa_indev[i].a_handle, sw_params,0));
- alsa_indev[i].a_addr = (char **)malloc(sizeof(char*)*alsa_indev[i].a_channels);
- if(!alsa_indev[i].a_addr) {error("capture device inaddr allocation error:"); continue;}
- memset(alsa_indev[i].a_addr, 0, sizeof(char*) * alsa_indev[i].a_channels);
- if(sys_verbose) post("capture device with %d channels and buffertime %d us opened", alsa_indev[i].a_channels,alsamm_buffertime);
+ CHK(set_hwparams(alsai.dev[i].a_handle, hw_params, &(alsai.dev[i].a_channels)));
+ alsamm_inchannels += alsai.dev[i].a_channels;
+ CHK(set_swparams(alsai.dev[i].a_handle, sw_params,0));
+ alsai.dev[i].a_addr = (char **)malloc(sizeof(char*)*alsai.dev[i].a_channels);
+ if(!alsai.dev[i].a_addr) {error("capture device inaddr allocation error:"); continue;}
+ memset(alsai.dev[i].a_addr, 0, sizeof(char*) * alsai.dev[i].a_channels);
+ if(sys_verbose) post("capture device with %d channels and buffertime %d us opened", alsai.dev[i].a_channels,alsamm_buffertime);
}
/* check for linked handles of input for each output*/
- for (int i=0; i<(alsa_noutdev < alsa_nindev ? alsa_noutdev:alsa_nindev); i++) {
- if (alsa_outdev[i].a_devno == alsa_indev[i].a_devno) {
- if ((err = snd_pcm_link(alsa_indev[i].a_handle, alsa_outdev[i].a_handle)) == 0) {
- alsa_indev[i].a_synced = alsa_outdev[i].a_synced = 1;
+ for (int i=0; i<(alsao.ndev < alsai.ndev ? alsao.ndev:alsai.ndev); i++) {
+ if (alsao.dev[i].a_devno == alsai.dev[i].a_devno) {
+ if ((err = snd_pcm_link(alsai.dev[i].a_handle, alsao.dev[i].a_handle)) == 0) {
+ alsai.dev[i].a_synced = alsao.dev[i].a_synced = 1;
if(sys_verbose) post("Linking in and outs of card %d",i);
} else error("could not link in and outs");
}
@@ -208,35 +207,35 @@ int alsamm_open_audio(int rate) {
if(sys_verbose) post("open_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns);
alsamm_xruns = dac_send = 0; /* reset debug */
/* start alsa in open or better in send_dacs once ??? we will see */
- for (int i=0;i<alsa_noutdev;i++) snd_pcm_dump(alsa_outdev[i].a_handle, alsa_stdout);
- for (int i=0;i<alsa_nindev;i++) snd_pcm_dump( alsa_indev[i].a_handle, alsa_stdout);
+ for (int i=0;i<alsao.ndev;i++) snd_pcm_dump(alsao.dev[i].a_handle, alsa_stdout);
+ for (int i=0;i<alsai.ndev;i++) snd_pcm_dump(alsai.dev[i].a_handle, alsa_stdout);
fflush(stdout);
}
sys_setchsr(alsamm_inchannels, alsamm_outchannels, alsamm_sr, sys_dacblocksize);
alsamm_start();
- /* report success */
+ /* report success */
return 0;
}
void alsamm_close_audio() {
if(debug&&sys_verbose) post("closing devices");
alsamm_stop();
- for (int i=0; i<alsa_noutdev; i++) {
+ for (int i=0; i<alsao.ndev; i++) {
//if(debug&&sys_verbose) post("unlink audio out %d, of %lx",i,used_outdevice[i]);
- if(alsa_outdev[i].a_synced != 0) {
- CHK(snd_pcm_unlink(alsa_outdev[i].a_handle));
- alsa_outdev[i].a_synced = 0;
+ if(alsao.dev[i].a_synced) {
+ CHK(snd_pcm_unlink(alsao.dev[i].a_handle));
+ alsao.dev[i].a_synced = 0;
}
- CHK(snd_pcm_close(alsa_outdev[i].a_handle));
- if(alsa_outdev[i].a_addr) {free(alsa_outdev[i].a_addr); alsa_outdev[i].a_addr=0;}
- alsa_outdev[i].a_channels = 0;
+ CHK(snd_pcm_close(alsao.dev[i].a_handle));
+ if(alsao.dev[i].a_addr) {free(alsao.dev[i].a_addr); alsao.dev[i].a_addr=0;}
+ alsao.dev[i].a_channels = 0;
}
- for (int i=0; i<alsa_nindev; i++) {
- CHK(snd_pcm_close(alsa_indev[i].a_handle));
- if(alsa_indev[i].a_addr) {free(alsa_indev[i].a_addr); alsa_indev[i].a_addr=0;}
- alsa_indev[i].a_channels = 0;
+ for (int i=0; i<alsai.ndev; i++) {
+ CHK(snd_pcm_close(alsai.dev[i].a_handle));
+ if(alsai.dev[i].a_addr) {free(alsai.dev[i].a_addr); alsai.dev[i].a_addr=0;}
+ alsai.dev[i].a_channels = 0;
}
- alsa_nindev = alsa_noutdev = 0;
+ alsai.ndev = alsao.ndev = 0;
if(debug) {
if(sys_verbose) post("close_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns);
alsamm_xruns = dac_send = 0;
@@ -407,9 +406,9 @@ static int alsamm_get_channels(snd_pcm_t *dev, snd_pcm_uframes_t *avail, snd_pcm
static void alsamm_start() {
int err = 0;
/* first prepare for in/out */
- for (int devno=0; devno<alsa_noutdev; devno++) {
+ for (int devno=0; devno<alsao.ndev; devno++) {
snd_pcm_uframes_t offset, avail;
- t_alsa_dev *dev = &alsa_outdev[devno];
+ t_alsa_dev *dev = &alsao.dev[devno];
/* snd_pcm_prepare also in xrun, but cannot harm here */
err = snd_pcm_prepare(dev->a_handle);
if (err<0) {check_error(err,"outcard prepare error for playback"); return;}
@@ -436,9 +435,9 @@ static void alsamm_start() {
err = snd_pcm_start (dev->a_handle);
if (err<0) check_error(err,"could not start playback");
}
- for (int devno=0; devno<alsa_nindev; devno++) {
+ for (int devno=0; devno<alsai.ndev; devno++) {
snd_pcm_uframes_t ioffset, iavail;
- t_alsa_dev *dev = &alsa_indev[devno];
+ t_alsa_dev *dev = &alsai.dev[devno];
/* if devices are synced then don't need to prepare; hopefully dma in aereas allready filled correct by the card */
if (dev->a_synced == 0) {
err = snd_pcm_prepare (dev->a_handle);
@@ -467,14 +466,12 @@ static void alsamm_start() {
}
static void alsamm_stop() {
- for (int devno=0; devno<alsa_nindev; devno++) {
- t_alsa_dev *dev = &alsa_indev[devno];
- if(sys_verbose) post("stop in device %d",devno);
+ for (int devno=0; devno<alsai.ndev; devno++) {
+ t_alsa_dev *dev = &alsai.dev[devno]; if(sys_verbose) post("stop in device %d",devno);
CH(snd_pcm_drop(dev->a_handle));
}
- for (int devno=0; devno<alsa_noutdev;devno++) {
- t_alsa_dev *dev = &alsa_outdev[devno];
- if(sys_verbose) post("stop out device %d",devno);
+ for (int devno=0; devno<alsao.ndev;devno++) {
+ t_alsa_dev *dev = &alsao.dev[devno]; if(sys_verbose) post("stop out device %d",devno);
CH(snd_pcm_drop(dev->a_handle));
}
if (debug) show_availist();
@@ -529,8 +526,8 @@ int alsamm_send_dacs() {
so we don't make a precheck of insamples here and let outsample check be the first of the first card. */
/* OUTPUT Transfer */
fpo = sys_soundout;
- for(devno = 0;devno < alsa_noutdev;devno++) {
- t_alsa_dev *dev = &alsa_outdev[devno];
+ for(devno = 0;devno < alsao.ndev;devno++) {
+ t_alsa_dev *dev = &alsao.dev[devno];
snd_pcm_t *out = dev->a_handle;
int ochannels =dev->a_channels;
/* how much samples available ??? */
@@ -603,17 +600,14 @@ int alsamm_send_dacs() {
fpo += ochannels*sys_dacblocksize;
}/* for devno */
fpi = sys_soundin; /* star first card first channel */
- for(devno = 0;devno < alsa_nindev;devno++) {
- t_alsa_dev *dev = &alsa_indev[devno];
+ for(devno = 0;devno < alsai.ndev;devno++) {
+ t_alsa_dev *dev = &alsai.dev[devno];
snd_pcm_t *in = dev->a_handle;
int ichannels = dev->a_channels;
iavail = snd_pcm_avail_update(in);
if (iavail < 0) {
err = xrun_recovery(in, iavail);
- if (err < 0) {
- check_error(err,"input avail update failed");
- return SENDDACS_NO;
- }
+ if (err < 0) {check_error(err,"input avail update failed"); return SENDDACS_NO;}
iavail=snd_pcm_avail_update(in);
}
state = snd_pcm_state(in);
@@ -664,7 +658,7 @@ int alsamm_send_dacs() {
size -= iframes;
}
fpi += ichannels*sys_dacblocksize;
- } /* for out devno < alsamm_outcards*/
+ } /* for out devno < alsamm_outcards */
if ((timenow = sys_getrealtime()) > (timelast + sleep_time)) {
if(debug && dac_send < 10 && sys_verbose)
post("slept %f > %f + %f (=%f)", timenow,timelast,sleep_time,(timelast + sleep_time));