[raudio] Add function to get list audio of devices

This commit is contained in:
AllMeatball 2026-07-28 22:10:05 -05:00
commit 793688e8c9
2 changed files with 127 additions and 0 deletions

View file

@ -47,6 +47,9 @@
* - Mixing channels support
* - Raw audio context support
*
* Levi Spencer (github: @AllMeatball) (July. 2026)
* - Audio device listing (playback and capture)
*
*
* LICENSE: zlib/libpng
*
@ -378,6 +381,12 @@ struct rAudioProcessor {
rAudioProcessor *prev; // Previous audio processor on the list
};
// Audio device id abstraction struct
// NOTE: This could do more in the future, other than storing ma_device_id.
struct rAudioDeviceID {
ma_device_id id;
};
#define AudioBuffer rAudioBuffer // WARNING: Renamed to avoid symbol collision with CoreAudio (macOS) AudioBuffer type
// Audio data context
@ -567,6 +576,95 @@ float GetMasterVolume(void)
return volume;
}
// Get list of all audio devices (playback and capture)
bool GetAudioDeviceList(AudioDeviceList *devices)
{
ma_device_info *playbackDevices = NULL;
ma_uint32 playbackDevicesCount = 0;
ma_device_info *captureDevices = NULL;
ma_uint32 captureDevicesCount = 0;
ma_result result = ma_context_get_devices(&AUDIO.System.context, &playbackDevices, &playbackDevicesCount, &captureDevices, &captureDevicesCount);
// ma_context_get_devices has failed, log that it did so and return false.
if (result != MA_SUCCESS) {
TRACELOG(LOG_WARNING, "AUDIO: Failed to get list of audio devices");
return false;
}
// Allocate list of devices.
devices->playbackDevices = RL_CALLOC( playbackDevicesCount, sizeof(AudioDevice) );
devices->captureDevices = RL_CALLOC( captureDevicesCount, sizeof(AudioDevice) );
if (!devices->playbackDevices || !devices->captureDevices) {
TRACELOG(LOG_WARNING, "AUDIO: Failed to get list of audio devices");
return false;
}
devices->playbackDevicesCount = playbackDevicesCount;
devices->captureDevicesCount = captureDevicesCount;
// Add playback devices.
for (unsigned int i = 0; i < playbackDevicesCount; i++)
{
ma_device_info device = playbackDevices[i];
rAudioDeviceID *id = RL_MALLOC(sizeof(rAudioDeviceID));
id->id = device.id;
devices->playbackDevices[i] = (AudioDevice){
.id = id,
.name = StringDuplicate(device.name),
.type = AUDIODEVICE_PLAYBACK,
.isDefault = device.isDefault == MA_TRUE,
};
}
// Add capture devices.
for (unsigned int i = 0; i < captureDevicesCount; i++)
{
ma_device_info device = captureDevices[i];
rAudioDeviceID *id = RL_MALLOC(sizeof(rAudioDeviceID));
id->id = device.id;
devices->playbackDevices[i] = (AudioDevice){
.id = id,
.name = StringDuplicate(device.name),
.type = AUDIODEVICE_CAPTURE,
.isDefault = device.isDefault == MA_TRUE,
};
}
return true;
}
// Unload audio device list
void UnloadAudioDeviceList(AudioDeviceList devices)
{
for (unsigned int i = 0; i < devices.playbackDevicesCount; i++)
{
AudioDevice device = devices.playbackDevices[i];
RL_FREE(device.id);
RL_FREE(device.name);
}
for (unsigned int i = 0; i < devices.captureDevicesCount; i++)
{
AudioDevice device = devices.captureDevices[i];
RL_FREE(device.id);
RL_FREE(device.name);
}
RL_FREE(devices.playbackDevices);
RL_FREE(devices.captureDevices);
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Audio Buffer management
//----------------------------------------------------------------------------------

View file

@ -474,6 +474,26 @@ typedef struct Wave {
// NOTE: Actual structs are defined internally in raudio module
typedef struct rAudioBuffer rAudioBuffer;
typedef struct rAudioProcessor rAudioProcessor;
typedef struct rAudioDeviceID rAudioDeviceID;
// Audio device, playback or capture
typedef struct AudioDevice {
rAudioDeviceID *id; // Pointer interal audio device id
char *name; // Audio device name (e.g. Ryzen HD Audio Controller)
unsigned int type; // Audio device type (see AudioDeviceType)
bool isDefault; // If this audio device is default this should be set as true
} AudioDevice;
// Audio device list, contains both playback and capture devices (see AudioDevice)
typedef struct AudioDeviceList {
unsigned int playbackDevicesCount; // Playback device entries count
AudioDevice *playbackDevices; // Playback device entries
unsigned int captureDevicesCount; // Capture device entries count
AudioDevice *captureDevices; // Capture device entries
} AudioDeviceList;
// AudioStream, custom audio stream
typedef struct AudioStream {
@ -963,6 +983,13 @@ typedef enum {
NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles
} NPatchLayout;
// Audio device type
typedef enum {
AUDIODEVICE_UNKNOWN = 0, // Unknown or unspecified
AUDIODEVICE_PLAYBACK, // Playback device (e.g. speakers, headphones etc.)
AUDIODEVICE_CAPTURE // Capture device (e.g. microphones, voice changers etc.)
} AudioDeviceType;
// Callbacks to hook some internal functions
// WARNING: These callbacks are intended for advanced users
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
@ -1680,6 +1707,8 @@ RLAPI void CloseAudioDevice(void); // Close t
RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
RLAPI void SetMasterVolume(float volume); // Set master volume (listener)
RLAPI float GetMasterVolume(void); // Get master volume (listener)
RLAPI bool GetAudioDeviceList(AudioDeviceList *devices); // Get list of all audio devices (playback and capture)
RLAPI void UnloadAudioDeviceList(AudioDeviceList devices); // Unload audio device list
// Wave/Sound loading/unloading functions
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file