portaudio: In the OSS hostapi, support additional sample formats.
While here, adjust some hacks around differences between NetBSD ossaudio and OSSv4: It turns out the problem was Audacity attempting to initialize with an absurdly high sample rate. When a sample rate that's outside the range of the kernel's maximum of 192000 is passed to SNDCTL_DSP_SPEED, -1 was returned (until my commits today). This is a violation of the OSSv4 spec in NetBSD. The spec states that if an unsupported sample rate is requested, a supported one should be picked and returned.
This commit is contained in:
parent
71513315a1
commit
869c35d13f
3 changed files with 85 additions and 33 deletions
|
@ -1,8 +1,8 @@
|
||||||
# $NetBSD: Makefile,v 1.28 2019/12/02 10:08:20 nia Exp $
|
# $NetBSD: Makefile,v 1.29 2020/04/15 17:12:14 nia Exp $
|
||||||
|
|
||||||
DISTNAME= pa_stable_v190600_20161030
|
DISTNAME= pa_stable_v190600_20161030
|
||||||
PKGNAME= ${DISTNAME:S/^pa_stable_v/portaudio-/1:S/_/./g}
|
PKGNAME= ${DISTNAME:S/^pa_stable_v/portaudio-/1:S/_/./g}
|
||||||
PKGREVISION= 2
|
PKGREVISION= 3
|
||||||
CATEGORIES= audio
|
CATEGORIES= audio
|
||||||
MASTER_SITES= http://www.portaudio.com/archives/
|
MASTER_SITES= http://www.portaudio.com/archives/
|
||||||
EXTRACT_SUFX= .tgz
|
EXTRACT_SUFX= .tgz
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
$NetBSD: distinfo,v 1.20 2019/11/24 13:15:15 nia Exp $
|
$NetBSD: distinfo,v 1.21 2020/04/15 17:12:14 nia Exp $
|
||||||
|
|
||||||
SHA1 (pa_stable_v190600_20161030.tgz) = 56c596bba820d90df7d057d8f6a0ec6bf9ab82e8
|
SHA1 (pa_stable_v190600_20161030.tgz) = 56c596bba820d90df7d057d8f6a0ec6bf9ab82e8
|
||||||
RMD160 (pa_stable_v190600_20161030.tgz) = e6e5cd3f3cb7469aa17549c189e445d573567e13
|
RMD160 (pa_stable_v190600_20161030.tgz) = e6e5cd3f3cb7469aa17549c189e445d573567e13
|
||||||
|
@ -11,4 +11,4 @@ SHA1 (patch-src_common_pa__front.c) = cdddb6f537f803b55873ad6bfa936a6bff47556d
|
||||||
SHA1 (patch-src_common_pa__stream.c) = 58e6ab2a61957208973a59be2f1140abc922f360
|
SHA1 (patch-src_common_pa__stream.c) = 58e6ab2a61957208973a59be2f1140abc922f360
|
||||||
SHA1 (patch-src_common_pa__stream.h) = 94781a9ae79ea1340eea8caadc106416c019cf74
|
SHA1 (patch-src_common_pa__stream.h) = 94781a9ae79ea1340eea8caadc106416c019cf74
|
||||||
SHA1 (patch-src_hostapi_alsa_pa__linux__alsa.c) = 6ddbeca36be30153f9c6c316c2fb78c06bbbf05d
|
SHA1 (patch-src_hostapi_alsa_pa__linux__alsa.c) = 6ddbeca36be30153f9c6c316c2fb78c06bbbf05d
|
||||||
SHA1 (patch-src_hostapi_oss_pa__unix__oss.c) = 47678cab04dfd5c221bd15e2c8af741bca2d843c
|
SHA1 (patch-src_hostapi_oss_pa__unix__oss.c) = 572c48f64104e22e7ae49acc54a26e549e381b5b
|
||||||
|
|
|
@ -1,40 +1,92 @@
|
||||||
$NetBSD: patch-src_hostapi_oss_pa__unix__oss.c,v 1.3 2019/11/24 13:15:15 nia Exp $
|
$NetBSD: patch-src_hostapi_oss_pa__unix__oss.c,v 1.4 2020/04/15 17:12:14 nia Exp $
|
||||||
|
|
||||||
Remove some rather pointless assertions that are incompatible with NetBSD's OSS
|
- Add 24-bit and 32-bit sample formats.
|
||||||
emulation layer.
|
- NetBSD-specific changes to make this map better to the emulation layer:
|
||||||
|
We don't need to initialize the stream by writing silence, etc.
|
||||||
Don't write an endless stream of silence when preparing the stream and don't try to
|
PaOssStream_WaitForFrames hangs forever unless disabled, this may be a bug.
|
||||||
use OSS in non-blocking mode or poll it on NetBSD, this is unsupported.
|
- Add features needed to make portmixer work with audacity.
|
||||||
|
|
||||||
Add features needed to make portmixer work with audacity.
|
|
||||||
|
|
||||||
--- src/hostapi/oss/pa_unix_oss.c.orig 2016-10-30 01:23:04.000000000 +0000
|
--- src/hostapi/oss/pa_unix_oss.c.orig 2016-10-30 01:23:04.000000000 +0000
|
||||||
+++ src/hostapi/oss/pa_unix_oss.c
|
+++ src/hostapi/oss/pa_unix_oss.c
|
||||||
@@ -1040,23 +1040,13 @@ static PaError PaOssStreamComponent_Conf
|
@@ -65,7 +65,7 @@
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SOUNDCARD_H
|
||||||
|
# include <sys/soundcard.h>
|
||||||
|
-# ifdef __NetBSD__
|
||||||
|
+# if defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
|
# define DEVICE_NAME_BASE "/dev/audio"
|
||||||
|
# else
|
||||||
|
# define DEVICE_NAME_BASE "/dev/dsp"
|
||||||
|
@@ -417,7 +417,12 @@ static PaError QueryDirection( const cha
|
||||||
|
/* Get supported sample rate closest to 44100 Hz */
|
||||||
|
if( *defaultSampleRate < 0 )
|
||||||
|
{
|
||||||
|
+#ifdef __NetBSD__
|
||||||
|
+ /* Less likely to require in-kernel conversion. */
|
||||||
|
+ sr = 48000;
|
||||||
|
+#else
|
||||||
|
sr = 44100;
|
||||||
|
+#endif
|
||||||
|
ENSURE_( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ), paUnanticipatedHostError );
|
||||||
|
|
||||||
|
*defaultSampleRate = sr;
|
||||||
|
@@ -938,6 +943,16 @@ static PaError Pa2OssFormat( PaSampleFor
|
||||||
|
case paInt16:
|
||||||
|
*ossFormat = AFMT_S16_NE;
|
||||||
|
break;
|
||||||
|
+#ifdef AFMT_S24_NE
|
||||||
|
+ case paInt24:
|
||||||
|
+ *ossFormat = AFMT_S24_NE;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
+#ifdef AFMT_S32_NE
|
||||||
|
+ case paInt32:
|
||||||
|
+ *ossFormat = AFMT_S32_NE;
|
||||||
|
+ break;
|
||||||
|
+#endif
|
||||||
|
default:
|
||||||
|
return paInternalError; /* This shouldn't happen */
|
||||||
|
}
|
||||||
|
@@ -961,6 +976,14 @@ static PaError GetAvailableFormats( PaOs
|
||||||
|
frmts |= paInt8;
|
||||||
|
if( mask & AFMT_S16_NE )
|
||||||
|
frmts |= paInt16;
|
||||||
|
+#ifdef AFMT_S24_NE
|
||||||
|
+ if( mask & AFMT_S24_NE )
|
||||||
|
+ frmts |= paInt24;
|
||||||
|
+#endif
|
||||||
|
+#ifdef AFMT_S32_NE
|
||||||
|
+ if( mask & AFMT_S32_NE )
|
||||||
|
+ frmts |= paInt32;
|
||||||
|
+#endif
|
||||||
|
else
|
||||||
|
result = paSampleFormatNotSupported;
|
||||||
|
|
||||||
|
@@ -1040,12 +1063,23 @@ static PaError PaOssStreamComponent_Conf
|
||||||
PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) );
|
PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) );
|
||||||
nativeFormat = temp;
|
nativeFormat = temp;
|
||||||
ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError );
|
ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError );
|
||||||
- PA_UNLESS( temp == nativeFormat, paInternalError );
|
+ PA_DEBUG(("%s: Wanted %d, selected format was %d\n", __FUNCTION__, nativeFormat, temp ));
|
||||||
|
PA_UNLESS( temp == nativeFormat, paInternalError );
|
||||||
|
|
||||||
/* try to set the number of channels */
|
/* try to set the number of channels */
|
||||||
ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported ); /* XXX: Should be paInvalidChannelCount? */
|
ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported ); /* XXX: Should be paInvalidChannelCount? */
|
||||||
- /* It's possible that the minimum number of host channels is greater than what the user requested */
|
+#ifndef __NetBSD__
|
||||||
- PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount );
|
/* It's possible that the minimum number of host channels is greater than what the user requested */
|
||||||
|
+ /* On NetBSD it's possible that the number is less than what the user requested, e.g. if the device is a mono mic */
|
||||||
|
PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount );
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifdef __NetBSD__
|
||||||
|
+ /* Make the sample rate conform to hard kernel limits */
|
||||||
|
+ /* This can likely be removed after NetBSD 10... SNDCTL_DSP_SPEED should never return an error code. */
|
||||||
|
+ sr = sr > 192000 ? 192000 : sr;
|
||||||
|
+ sr = sr < 1000 ? 1000 : sr;
|
||||||
|
+#endif
|
||||||
|
|
||||||
/* try to set the sample rate */
|
/* try to set the sample rate */
|
||||||
ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate );
|
ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate );
|
||||||
|
@@ -1477,6 +1511,7 @@ static PaError PaOssStream_Prepare( PaOs
|
||||||
- /* reject if there's no sample rate within 1% of the one requested */
|
|
||||||
- if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 )
|
|
||||||
- {
|
|
||||||
- PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));
|
|
||||||
- PA_ENSURE( paInvalidSampleRate );
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
ENSURE_( ioctl( component->fd, streamMode == StreamMode_In ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &bufInfo ),
|
|
||||||
paUnanticipatedHostError );
|
|
||||||
component->numBufs = bufInfo.fragstotal;
|
|
||||||
@@ -1477,6 +1467,7 @@ static PaError PaOssStream_Prepare( PaOs
|
|
||||||
size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback );
|
size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback );
|
||||||
memset( stream->playback->buffer, 0, bufSz );
|
memset( stream->playback->buffer, 0, bufSz );
|
||||||
|
|
||||||
|
@ -42,7 +94,7 @@ Add features needed to make portmixer work with audacity.
|
||||||
/* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer
|
/* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer
|
||||||
* OSS will complain. */
|
* OSS will complain. */
|
||||||
PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) );
|
PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) );
|
||||||
@@ -1486,6 +1477,7 @@ static PaError PaOssStream_Prepare( PaOs
|
@@ -1486,6 +1521,7 @@ static PaError PaOssStream_Prepare( PaOs
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) );
|
PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) );
|
||||||
|
@ -50,7 +102,7 @@ Add features needed to make portmixer work with audacity.
|
||||||
}
|
}
|
||||||
|
|
||||||
if( stream->sharedDevice )
|
if( stream->sharedDevice )
|
||||||
@@ -1652,6 +1644,7 @@ static void *PaOSS_AudioThreadProc( void
|
@@ -1652,6 +1688,7 @@ static void *PaOSS_AudioThreadProc( void
|
||||||
callbackResult = paComplete;
|
callbackResult = paComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +110,7 @@ Add features needed to make portmixer work with audacity.
|
||||||
/* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless
|
/* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless
|
||||||
* the stream has been recently started, we will have to go right ahead and read/write in blocking
|
* the stream has been recently started, we will have to go right ahead and read/write in blocking
|
||||||
* fashion to trigger operation. Therefore we begin with processing one host buffer before we switch
|
* fashion to trigger operation. Therefore we begin with processing one host buffer before we switch
|
||||||
@@ -1667,6 +1660,9 @@ static void *PaOSS_AudioThreadProc( void
|
@@ -1667,6 +1704,9 @@ static void *PaOSS_AudioThreadProc( void
|
||||||
{
|
{
|
||||||
framesAvail = stream->framesPerHostBuffer;
|
framesAvail = stream->framesPerHostBuffer;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +120,7 @@ Add features needed to make portmixer work with audacity.
|
||||||
|
|
||||||
while( framesAvail > 0 )
|
while( framesAvail > 0 )
|
||||||
{
|
{
|
||||||
@@ -1749,11 +1745,13 @@ static void *PaOSS_AudioThreadProc( void
|
@@ -1749,11 +1789,13 @@ static void *PaOSS_AudioThreadProc( void
|
||||||
|
|
||||||
if( initiateProcessing || !triggered )
|
if( initiateProcessing || !triggered )
|
||||||
{
|
{
|
||||||
|
@ -82,7 +134,7 @@ Add features needed to make portmixer work with audacity.
|
||||||
|
|
||||||
initiateProcessing = 0;
|
initiateProcessing = 0;
|
||||||
sem_post( &stream->semaphore );
|
sem_post( &stream->semaphore );
|
||||||
@@ -2043,3 +2041,26 @@ error:
|
@@ -2043,3 +2085,26 @@ error:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue