Get the audio(4) backend compiling with Solaris.

I have not been able to figure out how to get audio working with my VM
so this is currently untested.
This commit is contained in:
David Reid
2026-01-28 16:20:09 +10:00
parent bbc7ad1921
commit 38e35935d7
+101 -30
View File
@@ -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
{