mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-22 00:06:59 +02:00
OSS: Add support for retrieving detailed device info.
This commit is contained in:
@@ -62,7 +62,7 @@
|
|||||||
//
|
//
|
||||||
// Building for BSD
|
// Building for BSD
|
||||||
// ----------------
|
// ----------------
|
||||||
// The BSD build uses OSS. Requires linking to -lpthread. Also requires linking to -lossaudio on {Open,Net}BSD, but
|
// The BSD build uses OSS. Requires linking to -lpthread and -lm. Also requires linking to -lossaudio on {Open,Net}BSD, but
|
||||||
// not FreeBSD.
|
// not FreeBSD.
|
||||||
//
|
//
|
||||||
// Building for Android
|
// Building for Android
|
||||||
@@ -11835,6 +11835,29 @@ int mal_open_temp_device__oss()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mal_result mal_context_open_device__oss(mal_context* pContext, mal_device_type type, const mal_device_id* pDeviceID, int* pfd)
|
||||||
|
{
|
||||||
|
mal_assert(pContext != NULL);
|
||||||
|
mal_assert(pfd != NULL);
|
||||||
|
(void)pContext;
|
||||||
|
|
||||||
|
*pfd = -1;
|
||||||
|
|
||||||
|
char deviceName[64];
|
||||||
|
if (pDeviceID != NULL) {
|
||||||
|
mal_strncpy_s(deviceName, sizeof(deviceName), pDeviceID->oss, (size_t)-1);
|
||||||
|
} else {
|
||||||
|
mal_strncpy_s(deviceName, sizeof(deviceName), "/dev/dsp", (size_t)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*pfd = open(deviceName, (type == mal_device_type_playback) ? O_WRONLY : O_RDONLY, 0);
|
||||||
|
if (*pfd == -1) {
|
||||||
|
return MAL_FAILED_TO_OPEN_BACKEND_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MAL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
mal_bool32 mal_context_is_device_id_equal__oss(mal_context* pContext, const mal_device_id* pID0, const mal_device_id* pID1)
|
mal_bool32 mal_context_is_device_id_equal__oss(mal_context* pContext, const mal_device_id* pID0, const mal_device_id* pID1)
|
||||||
{
|
{
|
||||||
mal_assert(pContext != NULL);
|
mal_assert(pContext != NULL);
|
||||||
@@ -11923,18 +11946,18 @@ mal_result mal_context_get_device_info__oss(mal_context* pContext, mal_device_ty
|
|||||||
// If we get here it means we are _not_ using the default device.
|
// If we get here it means we are _not_ using the default device.
|
||||||
mal_bool32 foundDevice = MAL_FALSE;
|
mal_bool32 foundDevice = MAL_FALSE;
|
||||||
|
|
||||||
int fd = mal_open_temp_device__oss();
|
int fdTemp = mal_open_temp_device__oss();
|
||||||
if (fd == -1) {
|
if (fdTemp == -1) {
|
||||||
return mal_context_post_error(pContext, NULL, "[OSS] Failed to open a temporary device for retrieving system information used for device enumeration.", MAL_NO_BACKEND);
|
return mal_context_post_error(pContext, NULL, "[OSS] Failed to open a temporary device for retrieving system information used for device enumeration.", MAL_NO_BACKEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
oss_sysinfo si;
|
oss_sysinfo si;
|
||||||
int result = ioctl(fd, SNDCTL_SYSINFO, &si);
|
int result = ioctl(fdTemp, SNDCTL_SYSINFO, &si);
|
||||||
if (result != -1) {
|
if (result != -1) {
|
||||||
for (int iAudioDevice = 0; iAudioDevice < si.numaudios; ++iAudioDevice) {
|
for (int iAudioDevice = 0; iAudioDevice < si.numaudios; ++iAudioDevice) {
|
||||||
oss_audioinfo ai;
|
oss_audioinfo ai;
|
||||||
ai.dev = iAudioDevice;
|
ai.dev = iAudioDevice;
|
||||||
result = ioctl(fd, SNDCTL_AUDIOINFO, &ai);
|
result = ioctl(fdTemp, SNDCTL_AUDIOINFO, &ai);
|
||||||
if (result != -1) {
|
if (result != -1) {
|
||||||
if (mal_strcmp(ai.devnode, pDeviceID->oss) == 0) {
|
if (mal_strcmp(ai.devnode, pDeviceID->oss) == 0) {
|
||||||
// It has the same name, so now just confirm the type.
|
// It has the same name, so now just confirm the type.
|
||||||
@@ -11952,6 +11975,29 @@ mal_result mal_context_get_device_info__oss(mal_context* pContext, mal_device_ty
|
|||||||
mal_strncpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), ai.name, (size_t)-1);
|
mal_strncpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), ai.name, (size_t)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pDeviceInfo->minChannels = ai.min_channels;
|
||||||
|
pDeviceInfo->maxChannels = ai.max_channels;
|
||||||
|
pDeviceInfo->minSampleRate = ai.min_rate;
|
||||||
|
pDeviceInfo->maxSampleRate = ai.max_rate;
|
||||||
|
pDeviceInfo->formatCount = 0;
|
||||||
|
|
||||||
|
unsigned int formatMask;
|
||||||
|
if (deviceType == mal_device_type_playback) {
|
||||||
|
formatMask = ai.oformats;
|
||||||
|
} else {
|
||||||
|
formatMask = ai.iformats;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((formatMask & AFMT_U8) != 0) {
|
||||||
|
pDeviceInfo->formats[pDeviceInfo->formatCount++] = mal_format_u8;
|
||||||
|
}
|
||||||
|
if ((formatMask & AFMT_S16_LE) != 0) {
|
||||||
|
pDeviceInfo->formats[pDeviceInfo->formatCount++] = mal_format_s16;
|
||||||
|
}
|
||||||
|
if ((formatMask & AFMT_S32_LE) != 0) {
|
||||||
|
pDeviceInfo->formats[pDeviceInfo->formatCount++] = mal_format_s32;
|
||||||
|
}
|
||||||
|
|
||||||
foundDevice = MAL_TRUE;
|
foundDevice = MAL_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -11959,18 +12005,19 @@ mal_result mal_context_get_device_info__oss(mal_context* pContext, mal_device_ty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
close(fd);
|
close(fdTemp);
|
||||||
return mal_context_post_error(pContext, NULL, "[OSS] Failed to retrieve system information for device enumeration.", MAL_NO_BACKEND);
|
return mal_context_post_error(pContext, NULL, "[OSS] Failed to retrieve system information for device enumeration.", MAL_NO_BACKEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
close(fd);
|
close(fdTemp);
|
||||||
|
|
||||||
if (foundDevice) {
|
if (!foundDevice) {
|
||||||
return MAL_SUCCESS;
|
|
||||||
} else {
|
|
||||||
return MAL_NO_DEVICE;
|
return MAL_NO_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return MAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mal_result mal_context_init__oss(mal_context* pContext)
|
mal_result mal_context_init__oss(mal_context* pContext)
|
||||||
@@ -12026,15 +12073,8 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal
|
|||||||
mal_assert(pDevice != NULL);
|
mal_assert(pDevice != NULL);
|
||||||
mal_zero_object(&pDevice->oss);
|
mal_zero_object(&pDevice->oss);
|
||||||
|
|
||||||
char deviceName[64];
|
mal_result result = mal_context_open_device__oss(pContext, type, pDeviceID, &pDevice->oss.fd);
|
||||||
if (pDeviceID != NULL) {
|
if (result != MAL_SUCCESS) {
|
||||||
mal_strncpy_s(deviceName, sizeof(deviceName), pDeviceID->oss, (size_t)-1);
|
|
||||||
} else {
|
|
||||||
mal_strncpy_s(deviceName, sizeof(deviceName), "/dev/dsp", (size_t)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pDevice->oss.fd = open(deviceName, (type == mal_device_type_playback) ? O_WRONLY : O_RDONLY, 0);
|
|
||||||
if (pDevice->oss.fd == -1) {
|
|
||||||
return mal_post_error(pDevice, "[OSS] Failed to open device.", MAL_FAILED_TO_OPEN_BACKEND_DEVICE);
|
return mal_post_error(pDevice, "[OSS] Failed to open device.", MAL_FAILED_TO_OPEN_BACKEND_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12053,8 +12093,8 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal
|
|||||||
case mal_format_u8:
|
case mal_format_u8:
|
||||||
default: ossFormat = AFMT_U8; break;
|
default: ossFormat = AFMT_U8; break;
|
||||||
}
|
}
|
||||||
int result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFMT, &ossFormat);
|
int ossResult = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFMT, &ossFormat);
|
||||||
if (result == -1) {
|
if (ossResult == -1) {
|
||||||
close(pDevice->oss.fd);
|
close(pDevice->oss.fd);
|
||||||
return mal_post_error(pDevice, "[OSS] Failed to set format.", MAL_FORMAT_NOT_SUPPORTED);
|
return mal_post_error(pDevice, "[OSS] Failed to set format.", MAL_FORMAT_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
@@ -12069,8 +12109,8 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal
|
|||||||
|
|
||||||
// Channels.
|
// Channels.
|
||||||
int ossChannels = (int)pConfig->channels;
|
int ossChannels = (int)pConfig->channels;
|
||||||
result = ioctl(pDevice->oss.fd, SNDCTL_DSP_CHANNELS, &ossChannels);
|
ossResult = ioctl(pDevice->oss.fd, SNDCTL_DSP_CHANNELS, &ossChannels);
|
||||||
if (result == -1) {
|
if (ossResult == -1) {
|
||||||
close(pDevice->oss.fd);
|
close(pDevice->oss.fd);
|
||||||
return mal_post_error(pDevice, "[OSS] Failed to set channel count.", MAL_FORMAT_NOT_SUPPORTED);
|
return mal_post_error(pDevice, "[OSS] Failed to set channel count.", MAL_FORMAT_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
@@ -12080,8 +12120,8 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal
|
|||||||
|
|
||||||
// Sample rate.
|
// Sample rate.
|
||||||
int ossSampleRate = (int)pConfig->sampleRate;
|
int ossSampleRate = (int)pConfig->sampleRate;
|
||||||
result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SPEED, &ossSampleRate);
|
ossResult = ioctl(pDevice->oss.fd, SNDCTL_DSP_SPEED, &ossSampleRate);
|
||||||
if (result == -1) {
|
if (ossResult == -1) {
|
||||||
close(pDevice->oss.fd);
|
close(pDevice->oss.fd);
|
||||||
return mal_post_error(pDevice, "[OSS] Failed to set sample rate.", MAL_FORMAT_NOT_SUPPORTED);
|
return mal_post_error(pDevice, "[OSS] Failed to set sample rate.", MAL_FORMAT_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
@@ -12107,8 +12147,8 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ossFragment = (int)((pDevice->periods << 16) | ossFragmentSizePower);
|
int ossFragment = (int)((pDevice->periods << 16) | ossFragmentSizePower);
|
||||||
result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFRAGMENT, &ossFragment);
|
ossResult = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFRAGMENT, &ossFragment);
|
||||||
if (result == -1) {
|
if (ossResult == -1) {
|
||||||
close(pDevice->oss.fd);
|
close(pDevice->oss.fd);
|
||||||
return mal_post_error(pDevice, "[OSS] Failed to set fragment size and period count.", MAL_FORMAT_NOT_SUPPORTED);
|
return mal_post_error(pDevice, "[OSS] Failed to set fragment size and period count.", MAL_FORMAT_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
cc mal_test_0.c -o ./bin/mal_test_0 -Wall -lpthread
|
cc mal_test_0.c -o ./bin/mal_test_0 -Wall -lpthread -lm
|
||||||
c++ mal_test_0.cpp -o ./bin/mal_test_0_cpp -Wall -lpthread
|
c++ mal_test_0.cpp -o ./bin/mal_test_0_cpp -Wall -lpthread -lm
|
||||||
|
|||||||
Reference in New Issue
Block a user