pkgsrc/audio/libao/patches/patch-src_plugins_sun_ao__sun.c
2020-06-05 10:08:35 +00:00

100 lines
2.7 KiB
C

$NetBSD: patch-src_plugins_sun_ao__sun.c,v 1.3 2020/06/05 10:08:35 nia Exp $
- Fix device selection on NetBSD.
- Support 24-bit playback on NetBSD.
--- src/plugins/sun/ao_sun.c.orig 2016-11-14 08:03:30.000000000 +0000
+++ src/plugins/sun/ao_sun.c
@@ -78,6 +78,9 @@ typedef struct ao_sun_internal {
char *dev;
int id;
int fd;
+ int linear24;
+ void *convbuf;
+ size_t convbuf_sz;
} ao_sun_internal;
@@ -160,7 +163,11 @@ int ao_plugin_open(ao_device *device, ao
if(internal->dev==NULL){
char buf[80];
- sprintf(buf,"/dev/sound/%d",internal->id);
+#ifndef __sun
+ snprintf(buf,sizeof(buf),"/dev/audio%d",internal->id);
+#else
+ snprintf(buf,sizeof(buf),"/dev/sound/%d",internal->id);
+#endif
internal->dev=strdup(buf);
}
@@ -172,7 +179,12 @@ int ao_plugin_open(ao_device *device, ao
info.mode = AUMODE_PLAY;
#endif
info.play.encoding = AUDIO_ENCODING_SLINEAR;
- info.play.precision = format->bits;
+ if (format->bits == 24) {
+ info.play.precision = 32;
+ internal->linear24 = 1;
+ } else {
+ info.play.precision = format->bits;
+ }
info.play.sample_rate = format->rate;
info.play.channels = device->output_channels;
@@ -198,8 +210,46 @@ int ao_plugin_play(ao_device *device, co
uint_32 num_bytes)
{
ao_sun_internal *internal = (ao_sun_internal *) device->internal;
+ void *out;
+
+ /* convert 24-bit linear to 32-bit linear for NetBSD compat */
+ if (internal->linear24) {
+ unsigned char *srcp = (unsigned char *)output_samples;
+ size_t nsamples = num_bytes / 3;
+ size_t bufsz = nsamples * 4;
+ sint_32 *outp, temp;
+
+ if (internal->convbuf_sz < bufsz) {
+ internal->convbuf = realloc(internal->convbuf, bufsz);
+ if (!internal->convbuf)
+ return 1;
+ internal->convbuf_sz = bufsz;
+ }
+ outp = internal->convbuf;
+ if (device->driver_byte_format != AO_FMT_BIG) {
+ while (nsamples--) {
+ temp = (((sint_32)srcp[0]) << 8);
+ temp = temp | (((sint_32)srcp[1]) << 16);
+ temp = temp | (((sint_32)srcp[2]) << 24);
+ *(outp++) = temp;
+ srcp += 3;
+ }
+ } else {
+ while (nsamples--) {
+ temp = (((sint_32)srcp[0]) << 24);
+ temp = temp | (((sint_32)srcp[1]) << 16);
+ temp = temp | (((sint_32)srcp[2]) << 8);
+ *(outp++) = temp;
+ srcp += 3;
+ }
+ }
+ num_bytes = bufsz;
+ out = internal->convbuf;
+ } else {
+ out = (void *)output_samples;
+ }
- if (write(internal->fd, output_samples, num_bytes) < 0)
+ if (write(internal->fd, out, num_bytes) < 0)
return 0;
else
return 1;
@@ -224,6 +274,7 @@ void ao_plugin_device_clear(ao_device *d
if(internal->dev)
free(internal->dev);
+ free(internal->convbuf);
free(internal);
device->internal=NULL;
}