100 lines
2.7 KiB
C
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;
|
|
}
|