aboutsummaryrefslogtreecommitdiff
path: root/pd/src/s_audio_alsa.c
diff options
context:
space:
mode:
authorMiller Puckette <millerpuckette@users.sourceforge.net>2008-12-08 20:14:40 +0000
committerMiller Puckette <millerpuckette@users.sourceforge.net>2008-12-08 20:14:40 +0000
commit22c0a77781368cddcbd273009d3c55a765e9200a (patch)
tree61f2117cf389f34d3702d364bb12c741bb505e8d /pd/src/s_audio_alsa.c
parenta798f231a5d048cb9126003b856281d508946703 (diff)
0.42-0test06
svn path=/trunk/; revision=10432
Diffstat (limited to 'pd/src/s_audio_alsa.c')
-rw-r--r--pd/src/s_audio_alsa.c73
1 files changed, 66 insertions, 7 deletions
diff --git a/pd/src/s_audio_alsa.c b/pd/src/s_audio_alsa.c
index 6733182d..a5034c8d 100644
--- a/pd/src/s_audio_alsa.c
+++ b/pd/src/s_audio_alsa.c
@@ -25,6 +25,7 @@
#include <sched.h>
#include <sys/mman.h>
#include "s_audio_alsa.h"
+#include <endian.h>
/* Defines */
#define DEBUG(x) x
@@ -117,17 +118,33 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate,
if (err < 0)
return (-1);
check_error(err, "snd_pcm_hw_params_set_access");
+#if 0 /* enable this to print out which formats are available */
+ {
+ int i;
+ for (i = 0; i <= SND_PCM_FORMAT_LAST; i++)
+ fprintf(stderr, "%d -> %d\n",
+ i, snd_pcm_hw_params_test_format(dev->a_handle, hw_params, i));
+ }
+#endif
/* Try to set 32 bit format first */
err = snd_pcm_hw_params_set_format(dev->a_handle,
hw_params, SND_PCM_FORMAT_S32);
if (err < 0)
{
/* fprintf(stderr,
- "PD-ALSA: 32 bit format not available - using 16\n"); */
+ "PD-ALSA: 32 bit format not available - trying 24\n"); */
err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params,
- SND_PCM_FORMAT_S16);
- check_error(err, "snd_pcm_hw_params_set_format");
- dev->a_sampwidth = 2;
+ SND_PCM_FORMAT_S24_3LE);
+ if (err < 0)
+ {
+ /* fprintf(stderr,
+ "PD-ALSA: 32/24 bit format not available - using 16\n"); */
+ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params,
+ SND_PCM_FORMAT_S16);
+ check_error(err, "snd_pcm_hw_params_set_format");
+ dev->a_sampwidth = 2;
+ }
+ else dev->a_sampwidth = 3;
}
else dev->a_sampwidth = 4;
@@ -426,17 +443,42 @@ int alsa_send_dacs(void)
if (alsa_outdev[iodev].a_sampwidth == 4)
{
for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE)
- for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--;
+ for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--;
j += thisdevchans, fp2++)
{
float s1 = *fp2 * INT32_MAX;
((t_alsa_sample32 *)alsa_snd_buf)[j] = CLIP32(s1);
}
for (; i < thisdevchans; i++, ch++)
- for (j = ch, k = DEFDACBLKSIZE; k--; j += thisdevchans)
+ for (j = i, k = DEFDACBLKSIZE; k--; j += thisdevchans)
((t_alsa_sample32 *)alsa_snd_buf)[j] = 0;
}
- else
+ else if (alsa_outdev[iodev].a_sampwidth == 3)
+ {
+ for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE)
+ for (j = i, k = DEFDACBLKSIZE, fp2 = fp1; k--;
+ j += thisdevchans, fp2++)
+ {
+ int s = *fp2 * 8388352.;
+ if (s > 8388351)
+ s = 8388351;
+ else if (s < -8388351)
+ s = -8388351;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ ((char *)(alsa_snd_buf))[3*j] = (s & 255);
+ ((char *)(alsa_snd_buf))[3*j+1] = ((s>>8) & 255);
+ ((char *)(alsa_snd_buf))[3*j+2] = ((s>>16) & 255);
+#else
+ fprintf(stderr("big endian 24-bit not supported");
+#endif
+ }
+ for (; i < thisdevchans; i++, ch++)
+ for (j = i, k = DEFDACBLKSIZE; k--; j += thisdevchans)
+ ((char *)(alsa_snd_buf))[3*j] =
+ ((char *)(alsa_snd_buf))[3*j+1] =
+ ((char *)(alsa_snd_buf))[3*j+2] = 0;
+ }
+ else /* 16 bit samples */
{
for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE)
for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--;
@@ -525,6 +567,23 @@ int alsa_send_dacs(void)
* (1./ INT32_MAX);
}
}
+ else if (alsa_indev[iodev].a_sampwidth == 3)
+ {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE)
+ {
+ for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--;
+ j += thisdevchans, fp2++)
+ *fp2 = ((float) (
+ (((unsigned char *)alsa_snd_buf)[3*j] << 8)
+ | (((unsigned char *)alsa_snd_buf)[3*j+1] << 16)
+ | (((unsigned char *)alsa_snd_buf)[3*j+2] << 24)))
+ * (1./ INT32_MAX);
+ }
+#else
+ fprintf(stderr("big endian 24-bit not supported");
+#endif
+ }
else
{
for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE)