diff --git a/miniaudio.h b/miniaudio.h index 5cd5fb8e..b87fc431 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -19577,7 +19577,7 @@ BACKENDS #if defined(__OpenBSD__) /* <-- Change this to "#if defined(MA_BSD)" to enable sndio on all BSD flavors. */ #define MA_SUPPORT_SNDIO /* sndio is only supported on OpenBSD for now. May be expanded later if there's demand. */ #endif - #if defined(__NetBSD__) || defined(__OpenBSD__) + #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(MA_SUN) #define MA_SUPPORT_AUDIO4 /* Only support audio(4) on platforms with known support. */ #endif #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(MA_LINUX) && !defined(MA_ANDROID) @@ -41181,6 +41181,8 @@ static ma_result ma_context_init__audio4(ma_context* pContext, const void* pCont const ma_context_config_audio4* pContextConfigAudio4 = (const ma_context_config_audio4*)pContextBackendConfig; ma_context_config_audio4 defaultConfigAudio4; + + if (pContextConfigAudio4 == NULL) { defaultConfigAudio4 = ma_context_config_audio4_init(); pContextConfigAudio4 = &defaultConfigAudio4; @@ -41348,12 +41350,30 @@ static ma_format ma_format_from_prinfo__audio4(struct audio_prinfo* prinfo) return ma_format_from_encoding__audio4(prinfo->encoding, prinfo->precision); } -static ma_format ma_best_format_from_fd__audio4(int fd, ma_format preferredFormat) +#if !defined(MA_SUN) +static ma_format ma_best_format_from_fd__audio4(int fd, ma_format preferredFormat, ma_device_type deviceType) { + #if defined(MA_SUN) + audio_info_t info; + + (void)preferredFormat; + + if (ioctl(fd, AUDIO_GETINFO, &info) < 0) { + return ma_format_unknown; + } + + if (deviceType == ma_device_type_playback) { + return ma_format_from_encoding__audio4(info.play.encoding, info.play.precision); + } else { + return ma_format_from_encoding__audio4(info.record.encoding, info.record.precision); + } + #else audio_encoding_t encoding; ma_uint32 iFormat; int counter = 0; + (void)deviceType; + /* First check to see if the preferred format is supported. */ if (preferredFormat != ma_format_unknown) { counter = 0; @@ -41393,10 +41413,12 @@ static ma_format ma_best_format_from_fd__audio4(int fd, ma_format preferredForma counter += 1; } } + #endif /* Getting here means not appropriate format was found. */ return ma_format_unknown; } +#endif /* !defined(MA_SUN) */ #else static ma_format ma_format_from_swpar__audio4(struct audio_swpar* par) { @@ -41446,7 +41468,6 @@ static ma_result ma_context_get_device_info_from_fd__audio4(int fd, int deviceIn #if !defined(MA_AUDIO4_USE_NEW_API) { audio_info_t fdInfo; - int counter = 0; ma_uint32 channels; ma_uint32 sampleRate; @@ -41470,23 +41491,34 @@ static ma_result ma_context_get_device_info_from_fd__audio4(int fd, int deviceIn /* Supported formats. We get this by looking at the encodings. */ pDeviceInfo->nativeDataFormatCount = 0; - for (;;) { - audio_encoding_t encoding; - ma_format format; - - MA_ZERO_OBJECT(&encoding); - encoding.index = counter; - if (ioctl(fd, AUDIO_GETENC, &encoding) < 0) { - break; - } - - format = ma_format_from_encoding__audio4(encoding.encoding, encoding.precision); - if (format != ma_format_unknown) { - ma_device_info_add_native_data_format(pDeviceInfo, format, channels, channels, sampleRate, sampleRate); - } - - counter += 1; + #if defined(MA_SUN) + { + /* Just reporting s16 here. */ + ma_device_info_add_native_data_format(pDeviceInfo, ma_format_s16, channels, channels, sampleRate, sampleRate); } + #else + { + int counter = 0; + + for (;;) { + audio_encoding_t encoding; + ma_format format; + + MA_ZERO_OBJECT(&encoding); + encoding.index = counter; + if (ioctl(fd, AUDIO_GETENC, &encoding) < 0) { + break; + } + + format = ma_format_from_encoding__audio4(encoding.encoding, encoding.precision); + if (format != ma_format_unknown) { + ma_device_info_add_native_data_format(pDeviceInfo, format, channels, channels, sampleRate, sampleRate); + } + + counter += 1; + } + } + #endif } #else { @@ -41800,26 +41832,42 @@ static ma_result ma_device_init_fd__audio4(ma_device* pDevice, ma_device_descrip /* We get the driver to do as much of the data conversion as possible. */ if (deviceType == ma_device_type_capture) { + #if defined(MA_SUN) + ma_encoding_from_format__audio4(ma_format_s16, &fdInfo.record.encoding, &fdInfo.record.precision); + #else fdInfo.mode = AUMODE_RECORD; - ma_encoding_from_format__audio4(ma_best_format_from_fd__audio4(fd, pDescriptor->format), &fdInfo.record.encoding, &fdInfo.record.precision); + ma_encoding_from_format__audio4(ma_best_format_from_fd__audio4(fd, pDescriptor->format, ma_device_type_capture), &fdInfo.record.encoding, &fdInfo.record.precision); + #endif if (pDescriptor->channels != 0) { - fdInfo.record.channels = ma_clamp(pDescriptor->channels, 1, 12); /* From the documentation: `channels` ranges from 1 to 12. */ + #if defined(MA_SUN) + fdInfo.record.channels = ma_clamp(pDescriptor->channels, 1, 2); + #else + fdInfo.record.channels = ma_clamp(pDescriptor->channels, 1, 12); /* From the documentation for NetBSD: `channels` ranges from 1 to 12. */ + #endif } if (pDescriptor->sampleRate != 0) { - fdInfo.record.sample_rate = ma_clamp(pDescriptor->sampleRate, 1000, 192000); /* From the documentation: `frequency` ranges from 1000Hz to 192000Hz. (They mean `sample_rate` instead of `frequency`.) */ + fdInfo.record.sample_rate = ma_clamp(pDescriptor->sampleRate, 1000, 192000); /* From the documentation for NetBSD: `frequency` ranges from 1000Hz to 192000Hz. (They mean `sample_rate` instead of `frequency`.) */ } } else { + #if defined(MA_SUN) + ma_encoding_from_format__audio4(ma_format_s16, &fdInfo.play.encoding, &fdInfo.play.precision); + #else fdInfo.mode = AUMODE_PLAY; - ma_encoding_from_format__audio4(ma_best_format_from_fd__audio4(fd, pDescriptor->format), &fdInfo.play.encoding, &fdInfo.play.precision); + ma_encoding_from_format__audio4(ma_best_format_from_fd__audio4(fd, pDescriptor->format, ma_device_type_playback), &fdInfo.play.encoding, &fdInfo.play.precision); + #endif if (pDescriptor->channels != 0) { - fdInfo.play.channels = ma_clamp(pDescriptor->channels, 1, 12); /* From the documentation: `channels` ranges from 1 to 12. */ + #if defined(MA_SUN) + fdInfo.play.channels = ma_clamp(pDescriptor->channels, 1, 2); + #else + fdInfo.play.channels = ma_clamp(pDescriptor->channels, 1, 12); /* From the documentation for NetBSD: `channels` ranges from 1 to 12. */ + #endif } if (pDescriptor->sampleRate != 0) { - fdInfo.play.sample_rate = ma_clamp(pDescriptor->sampleRate, 1000, 192000); /* From the documentation: `frequency` ranges from 1000Hz to 192000Hz. (They mean `sample_rate` instead of `frequency`.) */ + fdInfo.play.sample_rate = ma_clamp(pDescriptor->sampleRate, 1000, 192000); /* From the documentation for NetBSD: `frequency` ranges from 1000Hz to 192000Hz. (They mean `sample_rate` instead of `frequency`.) */ } } @@ -41852,11 +41900,24 @@ static ma_result ma_device_init_fd__audio4(ma_device* pDevice, ma_device_descrip } /* Buffer. */ + internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, internalSampleRate); + + #if defined(MA_SUN) + { + /* + No good way to query the buffer size. From the Oracle docs: https://web.archive.org/web/20260128053127/https://docs.oracle.com/cd/E19683-01/817-0669/6mgf1n1ba/index.html + + The play.buffer_size field is currently not supported. + + We're just going to assume the requested buffer size and move on. Not much else I can think of. + */ + internalPeriods = 2; + internalPeriodSizeInFrames = ma_clamp(internalPeriodSizeInFrames, 256, 8192); + } + #else { ma_uint32 internalPeriodSizeInBytes; - internalPeriodSizeInFrames = ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptor, internalSampleRate); - internalPeriodSizeInBytes = internalPeriodSizeInFrames * ma_get_bytes_per_frame(internalFormat, internalChannels); if (internalPeriodSizeInBytes < 16) { internalPeriodSizeInBytes = 16; @@ -41881,6 +41942,7 @@ static ma_result ma_device_init_fd__audio4(ma_device* pDevice, ma_device_descrip internalPeriods = fdInfo.hiwat; internalPeriodSizeInFrames = fdInfo.blocksize / ma_get_bytes_per_frame(internalFormat, internalChannels); } + #endif } #else { @@ -42161,10 +42223,19 @@ static ma_result ma_device_stop_fd__audio4(ma_device* pDevice, int fd) #if !defined(MA_AUDIO4_USE_NEW_API) { - if (ioctl(fd, AUDIO_FLUSH, 0) < 0) { - ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to stop device. AUDIO_FLUSH failed."); - return ma_result_from_errno(errno); + #if defined(MA_SUN) + { + /* There is no flush here for Solaris, but we could use the I_FLUSH stream ioctl with FLUSHR for capture?I have no way to test - leaving that to the community. */ + (void)pDevice; } + #else + { + if (ioctl(fd, AUDIO_FLUSH, 0) < 0) { + ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[audio4] Failed to stop device. AUDIO_FLUSH failed."); + return ma_result_from_errno(errno); + } + } + #endif } #else {