Commit 35af204e authored by David Reid's avatar David Reid

Clean up whitespace.

parent 5d0705b3
...@@ -73,7 +73,7 @@ mal_uint32 on_send_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, ...@@ -73,7 +73,7 @@ mal_uint32 on_send_frames_to_device(mal_device* pDevice, mal_uint32 frameCount,
if (pWav == NULL) { if (pWav == NULL) {
return 0; return 0;
} }
return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels; return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels;
} }
...@@ -93,12 +93,12 @@ int main(int argc, char** argv) ...@@ -93,12 +93,12 @@ int main(int argc, char** argv)
mal_context context; mal_context context;
if (mal_context_init(NULL, 0, NULL, &context) != MAL_SUCCESS) { if (mal_context_init(NULL, 0, NULL, &context) != MAL_SUCCESS) {
printf("Failed to initialize context.\n"); printf("Failed to initialize context.\n");
drwav_uninit(&wav); drwav_uninit(&wav);
return -3; return -3;
} }
mal_device_config config = mal_device_config_init_playback(mal_format_s16, wav.channels, wav.sampleRate, on_send_frames_to_device); mal_device_config config = mal_device_config_init_playback(mal_format_s16, wav.channels, wav.sampleRate, on_send_frames_to_device);
mal_device device; mal_device device;
if (mal_device_init(&context, mal_device_type_playback, NULL, &config, &wav, &device) != MAL_SUCCESS) { if (mal_device_init(&context, mal_device_type_playback, NULL, &config, &wav, &device) != MAL_SUCCESS) {
printf("Failed to open playback device.\n"); printf("Failed to open playback device.\n");
...@@ -114,14 +114,14 @@ int main(int argc, char** argv) ...@@ -114,14 +114,14 @@ int main(int argc, char** argv)
drwav_uninit(&wav); drwav_uninit(&wav);
return -5; return -5;
} }
printf("Press Enter to quit..."); printf("Press Enter to quit...");
getchar(); getchar();
mal_device_uninit(&device); mal_device_uninit(&device);
mal_context_uninit(&context); mal_context_uninit(&context);
drwav_uninit(&wav); drwav_uninit(&wav);
return 0; return 0;
} }
``` ```
......
...@@ -81,9 +81,9 @@ int main(int argc, char** argv) ...@@ -81,9 +81,9 @@ int main(int argc, char** argv)
} }
printf("Playback Devices (%d)\n", playbackDeviceCount); printf("Playback Devices (%d)\n", playbackDeviceCount);
for (mal_uint32 iDevice = 0; iDevice < playbackDeviceCount; ++iDevice) { for (mal_uint32 iDevice = 0; iDevice < playbackDeviceCount; ++iDevice) {
printf(" %u: %s\n", iDevice, pPlaybackDeviceInfos[iDevice].name); printf(" %u: %s\n", iDevice, pPlaybackDeviceInfos[iDevice].name);
} }
printf("\n"); printf("\n");
...@@ -103,9 +103,9 @@ int main(int argc, char** argv) ...@@ -103,9 +103,9 @@ int main(int argc, char** argv)
} }
printf("Capture Devices (%d)\n", captureDeviceCount); printf("Capture Devices (%d)\n", captureDeviceCount);
for (mal_uint32 iDevice = 0; iDevice < captureDeviceCount; ++iDevice) { for (mal_uint32 iDevice = 0; iDevice < captureDeviceCount; ++iDevice) {
printf(" %u: %s\n", iDevice, pCaptureDeviceInfos[iDevice].name); printf(" %u: %s\n", iDevice, pCaptureDeviceInfos[iDevice].name);
} }
// Open the device. // Open the device.
...@@ -169,10 +169,10 @@ int main(int argc, char** argv) ...@@ -169,10 +169,10 @@ int main(int argc, char** argv)
printf("Press Enter to quit..."); printf("Press Enter to quit...");
getchar(); getchar();
mal_device_uninit(&playbackDevice); mal_device_uninit(&playbackDevice);
mal_context_uninit(&context); mal_context_uninit(&context);
return 0; return 0;
} }
...@@ -22,96 +22,96 @@ ...@@ -22,96 +22,96 @@
mal_uint32 on_send_flac_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples) mal_uint32 on_send_flac_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
{ {
drflac* pFlac = (drflac*)pDevice->pUserData; drflac* pFlac = (drflac*)pDevice->pUserData;
if (pFlac == NULL) { if (pFlac == NULL) {
return 0; return 0;
} }
return (mal_uint32)drflac_read_s16(pFlac, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels; return (mal_uint32)drflac_read_s16(pFlac, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels;
} }
mal_uint32 on_send_wav_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples) mal_uint32 on_send_wav_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
{ {
drwav* pWav = (drwav*)pDevice->pUserData; drwav* pWav = (drwav*)pDevice->pUserData;
if (pWav == NULL) { if (pWav == NULL) {
return 0; return 0;
} }
return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels; return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels;
} }
mal_uint32 on_send_vorbis_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples) mal_uint32 on_send_vorbis_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
{ {
stb_vorbis* pVorbis = (stb_vorbis*)pDevice->pUserData; stb_vorbis* pVorbis = (stb_vorbis*)pDevice->pUserData;
if (pVorbis == NULL) { if (pVorbis == NULL) {
return 0; return 0;
} }
return (mal_uint32)stb_vorbis_get_samples_short_interleaved(pVorbis, pDevice->channels, (short*)pSamples, frameCount * pDevice->channels) / pDevice->channels; return (mal_uint32)stb_vorbis_get_samples_short_interleaved(pVorbis, pDevice->channels, (short*)pSamples, frameCount * pDevice->channels) / pDevice->channels;
} }
mal_uint32 on_send_mod_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples) mal_uint32 on_send_mod_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
{ {
jar_mod_context_t* pMod = (jar_mod_context_t*)pDevice->pUserData; jar_mod_context_t* pMod = (jar_mod_context_t*)pDevice->pUserData;
if (pMod == NULL) { if (pMod == NULL) {
return 0; return 0;
} }
jar_mod_fillbuffer(pMod, (mal_int16*)pSamples, frameCount, 0); jar_mod_fillbuffer(pMod, (mal_int16*)pSamples, frameCount, 0);
return frameCount; return frameCount;
} }
mal_uint32 on_send_xm_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples) mal_uint32 on_send_xm_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
{ {
jar_xm_context_t* pXM = (jar_xm_context_t*)pDevice->pUserData; jar_xm_context_t* pXM = (jar_xm_context_t*)pDevice->pUserData;
if (pXM == NULL) { if (pXM == NULL) {
return 0; return 0;
} }
jar_xm_generate_samples_16bit(pXM, (short*)pSamples, frameCount); jar_xm_generate_samples_16bit(pXM, (short*)pSamples, frameCount);
return frameCount; return frameCount;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int exitcode = 0; int exitcode = 0;
if (argc < 2) { if (argc < 2) {
printf("No input file."); printf("No input file.");
return -1; return -1;
} }
enum { UNK, FLAC, WAV, VORBIS, MOD, XM } type = UNK; enum { UNK, FLAC, WAV, VORBIS, MOD, XM } type = UNK;
jar_mod_context_t mod; jar_mod_context_t mod;
jar_mod_init(&mod); jar_mod_init(&mod);
jar_xm_context_t *xm = 0; jar_xm_context_t *xm = 0;
drflac* flac = NULL; drflac* flac = NULL;
drwav* wav = NULL; drwav* wav = NULL;
stb_vorbis* vorbis = NULL; stb_vorbis* vorbis = NULL;
if ( type == UNK && (flac = drflac_open_file(argv[1])) != NULL) type = FLAC; if ( type == UNK && (flac = drflac_open_file(argv[1])) != NULL) type = FLAC;
if ( type == UNK && (wav = drwav_open_file(argv[1])) != NULL) type = WAV; if ( type == UNK && (wav = drwav_open_file(argv[1])) != NULL) type = WAV;
if ( type == UNK && (vorbis = stb_vorbis_open_filename(argv[1], NULL, NULL)) != NULL) type = VORBIS; if ( type == UNK && (vorbis = stb_vorbis_open_filename(argv[1], NULL, NULL)) != NULL) type = VORBIS;
if ( type == UNK && (jar_xm_create_context_from_file(&xm, 48000, argv[1]) == 0)) type = XM; if ( type == UNK && (jar_xm_create_context_from_file(&xm, 48000, argv[1]) == 0)) type = XM;
if ( type == UNK && (jar_mod_load_file(&mod, argv[1]) != 0) ) type = MOD; if ( type == UNK && (jar_mod_load_file(&mod, argv[1]) != 0) ) type = MOD;
if( type == UNK ) { if( type == UNK ) {
printf("Not a valid input file."); printf("Not a valid input file.");
exitcode = -2; exitcode = -2;
goto end; goto end;
} }
mal_context context; mal_context context;
if (mal_context_init(NULL, 0, NULL, &context) != MAL_SUCCESS) { if (mal_context_init(NULL, 0, NULL, &context) != MAL_SUCCESS) {
printf("Failed to initialize context."); printf("Failed to initialize context.");
exitcode = -3; exitcode = -3;
goto end; goto end;
} }
void* pUserData = NULL; void* pUserData = NULL;
mal_device_config config; mal_device_config config;
switch (type) switch (type)
{ {
case FLAC: case FLAC:
...@@ -140,34 +140,34 @@ int main(int argc, char** argv) ...@@ -140,34 +140,34 @@ int main(int argc, char** argv)
break; break;
} }
mal_device device; mal_device device;
if (mal_device_init(&context, mal_device_type_playback, NULL, &config, pUserData, &device) != MAL_SUCCESS) { if (mal_device_init(&context, mal_device_type_playback, NULL, &config, pUserData, &device) != MAL_SUCCESS) {
printf("Failed to open playback device."); printf("Failed to open playback device.");
mal_context_uninit(&context); mal_context_uninit(&context);
exitcode = -4; exitcode = -4;
goto end; goto end;
} }
if (mal_device_start(&device) != MAL_SUCCESS) { if (mal_device_start(&device) != MAL_SUCCESS) {
printf("Failed to start playback device.\n"); printf("Failed to start playback device.\n");
mal_device_uninit(&device); mal_device_uninit(&device);
mal_context_uninit(&context); mal_context_uninit(&context);
exitcode = -4; exitcode = -4;
goto end; goto end;
} }
printf("Press Enter to quit..."); printf("Press Enter to quit...");
getchar(); getchar();
mal_device_uninit(&device); mal_device_uninit(&device);
mal_context_uninit(&context); mal_context_uninit(&context);
end:; end:;
drflac_close(flac); drflac_close(flac);
drwav_close(wav); drwav_close(wav);
stb_vorbis_close(vorbis); stb_vorbis_close(vorbis);
jar_mod_unload(&mod); jar_mod_unload(&mod);
if(xm) jar_xm_free_context(xm); if(xm) jar_xm_free_context(xm);
return exitcode; return exitcode;
} }
...@@ -15,7 +15,7 @@ mal_uint32 playbackSample = 0; ...@@ -15,7 +15,7 @@ mal_uint32 playbackSample = 0;
void on_recv_frames(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples) void on_recv_frames(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples)
{ {
mal_uint32 sampleCount = frameCount * pDevice->channels; mal_uint32 sampleCount = frameCount * pDevice->channels;
mal_uint32 newCapturedSampleCount = capturedSampleCount + sampleCount; mal_uint32 newCapturedSampleCount = capturedSampleCount + sampleCount;
mal_int16* pNewCapturedSamples = (mal_int16*)realloc(pCapturedSamples, newCapturedSampleCount * sizeof(mal_int16)); mal_int16* pNewCapturedSamples = (mal_int16*)realloc(pCapturedSamples, newCapturedSampleCount * sizeof(mal_int16));
if (pNewCapturedSamples == NULL) { if (pNewCapturedSamples == NULL) {
...@@ -74,8 +74,8 @@ int main() ...@@ -74,8 +74,8 @@ int main()
getchar(); getchar();
mal_device_uninit(&captureDevice); mal_device_uninit(&captureDevice);
printf("Playing...\n"); printf("Playing...\n");
mal_device playbackDevice; mal_device playbackDevice;
......
...@@ -14,40 +14,40 @@ int main(int argc, char** argv) ...@@ -14,40 +14,40 @@ int main(int argc, char** argv)
return -2; return -2;
} }
mal_device_info infos[32]; mal_device_info infos[32];
mal_uint32 infoCount = sizeof(infos) / sizeof(infos[0]); mal_uint32 infoCount = sizeof(infos) / sizeof(infos[0]);
// Playback devices. // Playback devices.
mal_result result = mal_enumerate_devices(&context, mal_device_type_playback, &infoCount, infos); mal_result result = mal_enumerate_devices(&context, mal_device_type_playback, &infoCount, infos);
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
printf("Failed to enumerate playback devices."); printf("Failed to enumerate playback devices.");
mal_context_uninit(&context); mal_context_uninit(&context);
return -3; return -3;
} }
printf("Playback Devices\n"); printf("Playback Devices\n");
for (mal_uint32 iDevice = 0; iDevice < infoCount; ++iDevice) { for (mal_uint32 iDevice = 0; iDevice < infoCount; ++iDevice) {
printf(" %u: %s\n", iDevice, infos[iDevice].name); printf(" %u: %s\n", iDevice, infos[iDevice].name);
} }
printf("\n"); printf("\n");
// Capture devices. // Capture devices.
result = mal_enumerate_devices(&context, mal_device_type_capture, &infoCount, infos); result = mal_enumerate_devices(&context, mal_device_type_capture, &infoCount, infos);
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
printf("Failed to enumerate capture devices."); printf("Failed to enumerate capture devices.");
mal_context_uninit(&context); mal_context_uninit(&context);
return -4; return -4;
} }
printf("Capture Devices\n"); printf("Capture Devices\n");
for (mal_uint32 iDevice = 0; iDevice < infoCount; ++iDevice) { for (mal_uint32 iDevice = 0; iDevice < infoCount; ++iDevice) {
printf(" %u: %s\n", iDevice, infos[iDevice].name); printf(" %u: %s\n", iDevice, infos[iDevice].name);
} }
mal_context_uninit(&context); mal_context_uninit(&context);
return 0; return 0;
} }
...@@ -13,7 +13,7 @@ mal_uint32 on_send_frames_to_device(mal_device* pDevice, mal_uint32 frameCount, ...@@ -13,7 +13,7 @@ mal_uint32 on_send_frames_to_device(mal_device* pDevice, mal_uint32 frameCount,
if (pWav == NULL) { if (pWav == NULL) {
return 0; return 0;
} }
return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels; return (mal_uint32)drwav_read_s16(pWav, frameCount * pDevice->channels, (mal_int16*)pSamples) / pDevice->channels;
} }
...@@ -33,12 +33,12 @@ int main(int argc, char** argv) ...@@ -33,12 +33,12 @@ int main(int argc, char** argv)
mal_context context; mal_context context;
if (mal_context_init(NULL, 0, NULL, &context) != MAL_SUCCESS) { if (mal_context_init(NULL, 0, NULL, &context) != MAL_SUCCESS) {
printf("Failed to initialize context.\n"); printf("Failed to initialize context.\n");
drwav_uninit(&wav); drwav_uninit(&wav);
return -3; return -3;
} }
mal_device_config config = mal_device_config_init_playback(mal_format_s16, wav.channels, wav.sampleRate, on_send_frames_to_device); mal_device_config config = mal_device_config_init_playback(mal_format_s16, wav.channels, wav.sampleRate, on_send_frames_to_device);
mal_device device; mal_device device;
if (mal_device_init(&context, mal_device_type_playback, NULL, &config, &wav, &device) != MAL_SUCCESS) { if (mal_device_init(&context, mal_device_type_playback, NULL, &config, &wav, &device) != MAL_SUCCESS) {
printf("Failed to open playback device.\n"); printf("Failed to open playback device.\n");
...@@ -54,13 +54,13 @@ int main(int argc, char** argv) ...@@ -54,13 +54,13 @@ int main(int argc, char** argv)
drwav_uninit(&wav); drwav_uninit(&wav);
return -5; return -5;
} }
printf("Press Enter to quit..."); printf("Press Enter to quit...");
getchar(); getchar();
mal_device_uninit(&device); mal_device_uninit(&device);
mal_context_uninit(&context); mal_context_uninit(&context);
drwav_uninit(&wav); drwav_uninit(&wav);
return 0; return 0;
} }
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
// ---------------- // ----------------
// mal_uint32 on_send_samples(mal_device* pDevice, mal_uint32 frameCount, void* pSamples) // mal_uint32 on_send_samples(mal_device* pDevice, mal_uint32 frameCount, void* pSamples)
// { // {
// // This callback is set at initialization time and will be called when a playback device needs more // // This callback is set at initialization time and will be called when a playback device needs more
// // data. You need to write as many frames as you can to pSamples (but no more than frameCount) and // // data. You need to write as many frames as you can to pSamples (but no more than frameCount) and
// // then return the number of frames you wrote. // // then return the number of frames you wrote.
// // // //
...@@ -212,11 +212,11 @@ extern "C" { ...@@ -212,11 +212,11 @@ extern "C" {
// Some backends are only supported on certain platforms. // Some backends are only supported on certain platforms.
#if defined(MAL_WIN32) #if defined(MAL_WIN32)
#define MAL_SUPPORT_WASAPI #define MAL_SUPPORT_WASAPI
#if defined(MAL_WIN32_DESKTOP) // DirectSound and WinMM backends are only supported on desktop's. #if defined(MAL_WIN32_DESKTOP) // DirectSound and WinMM backends are only supported on desktop's.
#define MAL_SUPPORT_DSOUND #define MAL_SUPPORT_DSOUND
#define MAL_SUPPORT_WINMM #define MAL_SUPPORT_WINMM
#endif #endif
// Don't support WASAPI on older versions of MSVC for now. // Don't support WASAPI on older versions of MSVC for now.
#if defined(_MSC_VER) #if defined(_MSC_VER)
...@@ -228,20 +228,20 @@ extern "C" { ...@@ -228,20 +228,20 @@ extern "C" {
#endif #endif
#endif #endif
#if defined(MAL_UNIX) #if defined(MAL_UNIX)
#if defined(MAL_LINUX) #if defined(MAL_LINUX)
#if !defined(MAL_ANDROID) // ALSA is not supported on Android. #if !defined(MAL_ANDROID) // ALSA is not supported on Android.
#define MAL_SUPPORT_ALSA #define MAL_SUPPORT_ALSA
#endif #endif
#endif #endif
#if defined(MAL_APPLE) #if defined(MAL_APPLE)
#define MAL_SUPPORT_COREAUDIO #define MAL_SUPPORT_COREAUDIO
#endif #endif
#if defined(MAL_ANDROID) #if defined(MAL_ANDROID)
#define MAL_SUPPORT_OPENSL #define MAL_SUPPORT_OPENSL
#endif #endif
#if !defined(MAL_LINUX) && !defined(MAL_APPLE) && !defined(MAL_ANDROID) && !defined(MAL_EMSCRIPTEN) #if !defined(MAL_LINUX) && !defined(MAL_APPLE) && !defined(MAL_ANDROID) && !defined(MAL_EMSCRIPTEN)
#define MAL_SUPPORT_OSS #define MAL_SUPPORT_OSS
#endif #endif
#endif #endif
#define MAL_SUPPORT_SDL // All platforms support SDL. #define MAL_SUPPORT_SDL // All platforms support SDL.
...@@ -260,13 +260,13 @@ extern "C" { ...@@ -260,13 +260,13 @@ extern "C" {
#define MAL_ENABLE_DSOUND #define MAL_ENABLE_DSOUND
#endif #endif
#if !defined(MAL_NO_WINMM) && defined(MAL_SUPPORT_WINMM) #if !defined(MAL_NO_WINMM) && defined(MAL_SUPPORT_WINMM)
#define MAL_ENABLE_WINMM #define MAL_ENABLE_WINMM
#endif #endif
#if !defined(MAL_NO_ALSA) && defined(MAL_SUPPORT_ALSA) #if !defined(MAL_NO_ALSA) && defined(MAL_SUPPORT_ALSA)
#define MAL_ENABLE_ALSA #define MAL_ENABLE_ALSA
#endif #endif
#if !defined(MAL_NO_COREAUDIO) && defined(MAL_SUPPORT_COREAUDIO) #if !defined(MAL_NO_COREAUDIO) && defined(MAL_SUPPORT_COREAUDIO)
#define MAL_ENABLE_COREAUDIO #define MAL_ENABLE_COREAUDIO
#endif #endif
#if !defined(MAL_NO_OSS) && defined(MAL_SUPPORT_OSS) #if !defined(MAL_NO_OSS) && defined(MAL_SUPPORT_OSS)
#define MAL_ENABLE_OSS #define MAL_ENABLE_OSS
...@@ -444,8 +444,8 @@ typedef int mal_result; ...@@ -444,8 +444,8 @@ typedef int mal_result;
#define MAL_FAILED_TO_INIT_BACKEND -15 #define MAL_FAILED_TO_INIT_BACKEND -15
#define MAL_FAILED_TO_READ_DATA_FROM_CLIENT -16 #define MAL_FAILED_TO_READ_DATA_FROM_CLIENT -16
#define MAL_FAILED_TO_READ_DATA_FROM_DEVICE -17 #define MAL_FAILED_TO_READ_DATA_FROM_DEVICE -17
#define MAL_FAILED_TO_SEND_DATA_TO_CLIENT -18 #define MAL_FAILED_TO_SEND_DATA_TO_CLIENT -18
#define MAL_FAILED_TO_SEND_DATA_TO_DEVICE -19 #define MAL_FAILED_TO_SEND_DATA_TO_DEVICE -19
#define MAL_FAILED_TO_OPEN_BACKEND_DEVICE -20 #define MAL_FAILED_TO_OPEN_BACKEND_DEVICE -20
#define MAL_FAILED_TO_START_BACKEND_DEVICE -21 #define MAL_FAILED_TO_START_BACKEND_DEVICE -21
#define MAL_FAILED_TO_STOP_BACKEND_DEVICE -22 #define MAL_FAILED_TO_STOP_BACKEND_DEVICE -22
...@@ -525,16 +525,16 @@ typedef union ...@@ -525,16 +525,16 @@ typedef union
mal_uint8 dsound[16]; // DirectSound uses a GUID for identification. mal_uint8 dsound[16]; // DirectSound uses a GUID for identification.
#endif #endif
#ifdef MAL_SUPPORT_WINMM #ifdef MAL_SUPPORT_WINMM
/*UINT_PTR*/ mal_uint32 winmm; // When creating a device, WinMM expects a Win32 UINT_PTR for device identification. In practice it's actually just a UINT. /*UINT_PTR*/ mal_uint32 winmm; // When creating a device, WinMM expects a Win32 UINT_PTR for device identification. In practice it's actually just a UINT.
#endif #endif
#ifdef MAL_SUPPORT_ALSA #ifdef MAL_SUPPORT_ALSA
char alsa[256]; // ALSA uses a name string for identification. char alsa[256]; // ALSA uses a name string for identification.
#endif #endif
#ifdef MAL_SUPPORT_COREAUDIO #ifdef MAL_SUPPORT_COREAUDIO
// TODO: Implement me. // TODO: Implement me.
#endif #endif
#ifdef MAL_SUPPORT_OSS #ifdef MAL_SUPPORT_OSS
char oss[64]; // "dev/dsp0", etc. "dev/dsp" for the default device. char oss[64]; // "dev/dsp0", etc. "dev/dsp" for the default device.
#endif #endif
#ifdef MAL_SUPPORT_OPENSL #ifdef MAL_SUPPORT_OPENSL
mal_uint32 opensl; // OpenSL|ES uses a 32-bit unsigned integer for identification. mal_uint32 opensl; // OpenSL|ES uses a 32-bit unsigned integer for identification.
...@@ -546,7 +546,7 @@ typedef union ...@@ -546,7 +546,7 @@ typedef union
int sdl; // SDL devices are identified with an index. int sdl; // SDL devices are identified with an index.
#endif #endif
#ifdef MAL_SUPPORT_NULL #ifdef MAL_SUPPORT_NULL
int nullbackend; // Always 0. int nullbackend; // Always 0.
#endif #endif
} mal_device_id; } mal_device_id;
...@@ -690,8 +690,8 @@ struct mal_context ...@@ -690,8 +690,8 @@ struct mal_context
} dsound; } dsound;
#endif #endif
#ifdef MAL_SUPPORT_WINMM #ifdef MAL_SUPPORT_WINMM
struct struct
{ {
/*HMODULE*/ mal_handle hWinMM; /*HMODULE*/ mal_handle hWinMM;
mal_proc waveOutGetNumDevs; mal_proc waveOutGetNumDevs;
mal_proc waveOutGetDevCapsA; mal_proc waveOutGetDevCapsA;
...@@ -710,7 +710,7 @@ struct mal_context ...@@ -710,7 +710,7 @@ struct mal_context
mal_proc waveInAddBuffer; mal_proc waveInAddBuffer;
mal_proc waveInStart; mal_proc waveInStart;
mal_proc waveInReset; mal_proc waveInReset;
} winmm; } winmm;
#endif #endif
#ifdef MAL_SUPPORT_ALSA #ifdef MAL_SUPPORT_ALSA
struct struct
...@@ -765,17 +765,17 @@ struct mal_context ...@@ -765,17 +765,17 @@ struct mal_context
} alsa; } alsa;
#endif #endif
#ifdef MAL_SUPPORT_COREAUDIO #ifdef MAL_SUPPORT_COREAUDIO
struct struct
{ {
int _unused; int _unused;
} coreaudio; } coreaudio;
#endif #endif
#ifdef MAL_SUPPORT_OSS #ifdef MAL_SUPPORT_OSS
struct struct
{ {
int versionMajor; int versionMajor;
int versionMinor; int versionMinor;
} oss; } oss;
#endif #endif
#ifdef MAL_SUPPORT_OPENSL #ifdef MAL_SUPPORT_OPENSL
struct struct
...@@ -997,8 +997,8 @@ struct mal_device ...@@ -997,8 +997,8 @@ struct mal_device
} dsound; } dsound;
#endif #endif
#ifdef MAL_SUPPORT_WINMM #ifdef MAL_SUPPORT_WINMM
struct struct
{ {
/*HWAVEOUT, HWAVEIN*/ mal_handle hDevice; /*HWAVEOUT, HWAVEIN*/ mal_handle hDevice;
/*HANDLE*/ mal_handle hEvent; /*HANDLE*/ mal_handle hEvent;
mal_uint32 fragmentSizeInFrames; mal_uint32 fragmentSizeInFrames;
...@@ -1008,7 +1008,7 @@ struct mal_device ...@@ -1008,7 +1008,7 @@ struct mal_device
mal_uint8* pIntermediaryBuffer; mal_uint8* pIntermediaryBuffer;
mal_uint8* _pHeapData; // Used internally and is used for the heap allocated data for the intermediary buffer and the WAVEHDR structures. mal_uint8* _pHeapData; // Used internally and is used for the heap allocated data for the intermediary buffer and the WAVEHDR structures.
mal_bool32 breakFromMainLoop; mal_bool32 breakFromMainLoop;
} winmm; } winmm;
#endif #endif
#ifdef MAL_SUPPORT_ALSA #ifdef MAL_SUPPORT_ALSA
struct struct
...@@ -1020,19 +1020,19 @@ struct mal_device ...@@ -1020,19 +1020,19 @@ struct mal_device
} alsa; } alsa;
#endif #endif
#ifdef MAL_SUPPORT_COREAUDIO #ifdef MAL_SUPPORT_COREAUDIO
struct struct
{ {
int _unused; int _unused;
} coreaudio; } coreaudio;
#endif #endif
#ifdef MAL_SUPPORT_OSS #ifdef MAL_SUPPORT_OSS
struct struct
{ {
int fd; int fd;
mal_uint32 fragmentSizeInFrames; mal_uint32 fragmentSizeInFrames;
mal_bool32 breakFromMainLoop; mal_bool32 breakFromMainLoop;
void* pIntermediaryBuffer; void* pIntermediaryBuffer;
} oss; } oss;
#endif #endif
#ifdef MAL_SUPPORT_OPENSL #ifdef MAL_SUPPORT_OPENSL
struct struct
...@@ -2498,7 +2498,7 @@ static mal_result mal_post_error(mal_device* pDevice, const char* message, mal_r ...@@ -2498,7 +2498,7 @@ static mal_result mal_post_error(mal_device* pDevice, const char* message, mal_r
#if !defined(MAL_ANDROID) #if !defined(MAL_ANDROID)
static void mal_get_default_channel_mapping(mal_backend backend, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS]) static void mal_get_default_channel_mapping(mal_backend backend, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS])
{ {
if (channels == 1) { // Mono if (channels == 1) { // Mono
channelMap[0] = MAL_CHANNEL_FRONT_CENTER; channelMap[0] = MAL_CHANNEL_FRONT_CENTER;
} else if (channels == 2) { // Stereo } else if (channels == 2) { // Stereo
channelMap[0] = MAL_CHANNEL_FRONT_LEFT; channelMap[0] = MAL_CHANNEL_FRONT_LEFT;
...@@ -2519,48 +2519,48 @@ static void mal_get_default_channel_mapping(mal_backend backend, mal_uint32 chan ...@@ -2519,48 +2519,48 @@ static void mal_get_default_channel_mapping(mal_backend backend, mal_uint32 chan
channelMap[3] = MAL_CHANNEL_SIDE_RIGHT; channelMap[3] = MAL_CHANNEL_SIDE_RIGHT;
channelMap[4] = MAL_CHANNEL_LFE; channelMap[4] = MAL_CHANNEL_LFE;
} else if (channels >= 6) { // 5.1 } else if (channels >= 6) { // 5.1
// Some backends use different default layouts. // Some backends use different default layouts.
if (backend == mal_backend_wasapi || backend == mal_backend_dsound || backend == mal_backend_winmm || backend == mal_backend_oss) { if (backend == mal_backend_wasapi || backend == mal_backend_dsound || backend == mal_backend_winmm || backend == mal_backend_oss) {
channelMap[0] = MAL_CHANNEL_FRONT_LEFT; channelMap[0] = MAL_CHANNEL_FRONT_LEFT;
channelMap[1] = MAL_CHANNEL_FRONT_RIGHT; channelMap[1] = MAL_CHANNEL_FRONT_RIGHT;
channelMap[2] = MAL_CHANNEL_FRONT_CENTER; channelMap[2] = MAL_CHANNEL_FRONT_CENTER;
channelMap[3] = MAL_CHANNEL_LFE; channelMap[3] = MAL_CHANNEL_LFE;
channelMap[4] = MAL_CHANNEL_SIDE_LEFT; channelMap[4] = MAL_CHANNEL_SIDE_LEFT;
channelMap[5] = MAL_CHANNEL_SIDE_RIGHT; channelMap[5] = MAL_CHANNEL_SIDE_RIGHT;
} else { } else {
channelMap[0] = MAL_CHANNEL_FRONT_LEFT; channelMap[0] = MAL_CHANNEL_FRONT_LEFT;
channelMap[1] = MAL_CHANNEL_FRONT_RIGHT; channelMap[1] = MAL_CHANNEL_FRONT_RIGHT;
channelMap[2] = MAL_CHANNEL_SIDE_LEFT; channelMap[2] = MAL_CHANNEL_SIDE_LEFT;
channelMap[3] = MAL_CHANNEL_SIDE_RIGHT; channelMap[3] = MAL_CHANNEL_SIDE_RIGHT;
channelMap[4] = MAL_CHANNEL_FRONT_CENTER; channelMap[4] = MAL_CHANNEL_FRONT_CENTER;
channelMap[5] = MAL_CHANNEL_LFE; channelMap[5] = MAL_CHANNEL_LFE;
} }
if (channels == 7) { // Not sure about this one. if (channels == 7) { // Not sure about this one.
channelMap[6] = MAL_CHANNEL_BACK_CENTER; channelMap[6] = MAL_CHANNEL_BACK_CENTER;
} else { } else {
// I don't know what mapping to use in this case, but I'm making it upwards compatible with 7.1. Good luck! // I don't know what mapping to use in this case, but I'm making it upwards compatible with 7.1. Good luck!
mal_assert(channels >= 8); mal_assert(channels >= 8);
channelMap[6] = MAL_CHANNEL_BACK_LEFT; channelMap[6] = MAL_CHANNEL_BACK_LEFT;
channelMap[7] = MAL_CHANNEL_BACK_RIGHT; channelMap[7] = MAL_CHANNEL_BACK_RIGHT;
// Beyond 7.1 I'm just guessing... // Beyond 7.1 I'm just guessing...
if (channels == 9) { if (channels == 9) {
channelMap[8] = MAL_CHANNEL_BACK_CENTER; channelMap[8] = MAL_CHANNEL_BACK_CENTER;
} else if (channels == 10) { } else if (channels == 10) {
channelMap[8] = MAL_CHANNEL_FRONT_LEFT_CENTER; channelMap[8] = MAL_CHANNEL_FRONT_LEFT_CENTER;
channelMap[9] = MAL_CHANNEL_FRONT_RIGHT_CENTER; channelMap[9] = MAL_CHANNEL_FRONT_RIGHT_CENTER;
} else if (channels == 11) { } else if (channels == 11) {
channelMap[ 8] = MAL_CHANNEL_FRONT_LEFT_CENTER; channelMap[ 8] = MAL_CHANNEL_FRONT_LEFT_CENTER;
channelMap[ 9] = MAL_CHANNEL_FRONT_RIGHT_CENTER; channelMap[ 9] = MAL_CHANNEL_FRONT_RIGHT_CENTER;
channelMap[10] = MAL_CHANNEL_BACK_CENTER; channelMap[10] = MAL_CHANNEL_BACK_CENTER;
} else { } else {
mal_assert(channels >= 12); mal_assert(channels >= 12);
for (mal_uint8 iChannel = 11; iChannel < channels && iChannel < MAL_MAX_CHANNELS; ++iChannel) { for (mal_uint8 iChannel = 11; iChannel < channels && iChannel < MAL_MAX_CHANNELS; ++iChannel) {
channelMap[iChannel] = iChannel + 1; channelMap[iChannel] = iChannel + 1;
} }
} }
} }
} }
} }
#endif #endif
...@@ -2748,7 +2748,7 @@ static mal_result mal_context__try_get_device_name_by_id(mal_context* pContext, ...@@ -2748,7 +2748,7 @@ static mal_result mal_context__try_get_device_name_by_id(mal_context* pContext,
#ifdef MAL_HAS_COREAUDIO #ifdef MAL_HAS_COREAUDIO
case mal_backend_coreaudio case mal_backend_coreaudio
{ {
// TODO: Implement me. // TODO: Implement me.
} break; } break;
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
...@@ -3123,24 +3123,24 @@ static DWORD mal_channel_id_to_win32(DWORD id) ...@@ -3123,24 +3123,24 @@ static DWORD mal_channel_id_to_win32(DWORD id)
{ {
switch (id) switch (id)
{ {
case MAL_CHANNEL_FRONT_LEFT: return SPEAKER_FRONT_LEFT; case MAL_CHANNEL_FRONT_LEFT: return SPEAKER_FRONT_LEFT;
case MAL_CHANNEL_FRONT_RIGHT: return SPEAKER_FRONT_RIGHT; case MAL_CHANNEL_FRONT_RIGHT: return SPEAKER_FRONT_RIGHT;
case MAL_CHANNEL_FRONT_CENTER: return SPEAKER_FRONT_CENTER; case MAL_CHANNEL_FRONT_CENTER: return SPEAKER_FRONT_CENTER;
case MAL_CHANNEL_LFE: return SPEAKER_LOW_FREQUENCY; case MAL_CHANNEL_LFE: return SPEAKER_LOW_FREQUENCY;
case MAL_CHANNEL_BACK_LEFT: return SPEAKER_BACK_LEFT; case MAL_CHANNEL_BACK_LEFT: return SPEAKER_BACK_LEFT;
case MAL_CHANNEL_BACK_RIGHT: return SPEAKER_BACK_RIGHT; case MAL_CHANNEL_BACK_RIGHT: return SPEAKER_BACK_RIGHT;
case MAL_CHANNEL_FRONT_LEFT_CENTER: return SPEAKER_FRONT_LEFT_OF_CENTER; case MAL_CHANNEL_FRONT_LEFT_CENTER: return SPEAKER_FRONT_LEFT_OF_CENTER;
case MAL_CHANNEL_FRONT_RIGHT_CENTER: return SPEAKER_FRONT_RIGHT_OF_CENTER; case MAL_CHANNEL_FRONT_RIGHT_CENTER: return SPEAKER_FRONT_RIGHT_OF_CENTER;
case MAL_CHANNEL_BACK_CENTER: return SPEAKER_BACK_CENTER; case MAL_CHANNEL_BACK_CENTER: return SPEAKER_BACK_CENTER;
case MAL_CHANNEL_SIDE_LEFT: return SPEAKER_SIDE_LEFT; case MAL_CHANNEL_SIDE_LEFT: return SPEAKER_SIDE_LEFT;
case MAL_CHANNEL_SIDE_RIGHT: return SPEAKER_SIDE_RIGHT; case MAL_CHANNEL_SIDE_RIGHT: return SPEAKER_SIDE_RIGHT;
case MAL_CHANNEL_TOP_CENTER: return SPEAKER_TOP_CENTER; case MAL_CHANNEL_TOP_CENTER: return SPEAKER_TOP_CENTER;
case MAL_CHANNEL_TOP_FRONT_LEFT: return SPEAKER_TOP_FRONT_LEFT; case MAL_CHANNEL_TOP_FRONT_LEFT: return SPEAKER_TOP_FRONT_LEFT;
case MAL_CHANNEL_TOP_FRONT_CENTER: return SPEAKER_TOP_FRONT_CENTER; case MAL_CHANNEL_TOP_FRONT_CENTER: return SPEAKER_TOP_FRONT_CENTER;
case MAL_CHANNEL_TOP_FRONT_RIGHT: return SPEAKER_TOP_FRONT_RIGHT; case MAL_CHANNEL_TOP_FRONT_RIGHT: return SPEAKER_TOP_FRONT_RIGHT;
case MAL_CHANNEL_TOP_BACK_LEFT: return SPEAKER_TOP_BACK_LEFT; case MAL_CHANNEL_TOP_BACK_LEFT: return SPEAKER_TOP_BACK_LEFT;
case MAL_CHANNEL_TOP_BACK_CENTER: return SPEAKER_TOP_BACK_CENTER; case MAL_CHANNEL_TOP_BACK_CENTER: return SPEAKER_TOP_BACK_CENTER;
case MAL_CHANNEL_TOP_BACK_RIGHT: return SPEAKER_TOP_BACK_RIGHT; case MAL_CHANNEL_TOP_BACK_RIGHT: return SPEAKER_TOP_BACK_RIGHT;
default: return 0; default: return 0;
} }
} }
...@@ -3692,7 +3692,7 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type ...@@ -3692,7 +3692,7 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
iid = g_malIID_DEVINTERFACE_AUDIO_CAPTURE; iid = g_malIID_DEVINTERFACE_AUDIO_CAPTURE;
} }
} }
LPOLESTR iidStr; LPOLESTR iidStr;
hr = StringFromIID(iid, &iidStr); hr = StringFromIID(iid, &iidStr);
if (FAILED(hr)) { if (FAILED(hr)) {
...@@ -3890,7 +3890,7 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type ...@@ -3890,7 +3890,7 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
goto done; goto done;
} }
if (shareMode == AUDCLNT_SHAREMODE_SHARED) { if (shareMode == AUDCLNT_SHAREMODE_SHARED) {
pDevice->exclusiveMode = MAL_FALSE; pDevice->exclusiveMode = MAL_FALSE;
} else /*if (shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE)*/ { } else /*if (shareMode == AUDCLNT_SHAREMODE_EXCLUSIVE)*/ {
...@@ -3916,7 +3916,7 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type ...@@ -3916,7 +3916,7 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
errorMsg = "[WASAPI] Failed to create stop event for main loop break notification.", result = MAL_FAILED_TO_CREATE_EVENT; errorMsg = "[WASAPI] Failed to create stop event for main loop break notification.", result = MAL_FAILED_TO_CREATE_EVENT;
goto done; goto done;
} }
result = MAL_SUCCESS; result = MAL_SUCCESS;
done: done:
...@@ -4045,10 +4045,10 @@ static mal_uint32 mal_device__wait_for_frames__wasapi(mal_device* pDevice) ...@@ -4045,10 +4045,10 @@ static mal_uint32 mal_device__wait_for_frames__wasapi(mal_device* pDevice)
} }
// Break from the main loop if the device isn't started anymore. Likely what's happened is the application // Break from the main loop if the device isn't started anymore. Likely what's happened is the application
// has requested that the device be stopped. // has requested that the device be stopped.
if (!mal_device_is_started(pDevice)) { if (!mal_device_is_started(pDevice)) {
break; break;
} }
mal_uint32 framesAvailable = mal_device__get_available_frames__wasapi(pDevice); mal_uint32 framesAvailable = mal_device__get_available_frames__wasapi(pDevice);
if (framesAvailable > 0) { if (framesAvailable > 0) {
...@@ -4135,7 +4135,7 @@ static mal_result mal_device__main_loop__wasapi(mal_device* pDevice) ...@@ -4135,7 +4135,7 @@ static mal_result mal_device__main_loop__wasapi(mal_device* pDevice)
#ifdef MAL_HAS_DSOUND #ifdef MAL_HAS_DSOUND
#include <dsound.h> #include <dsound.h>
#if 0 // MAL_GUID_NULL is not currently used, but leaving it here in case I need to add it back again. #if 0 // MAL_GUID_NULL is not currently used, but leaving it here in case I need to add it back again.
static GUID MAL_GUID_NULL = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; static GUID MAL_GUID_NULL = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
#endif #endif
static GUID MAL_GUID_IID_DirectSoundNotify = {0xb0210783, 0x89cd, 0x11d0, {0xaf, 0x08, 0x00, 0xa0, 0xc9, 0x25, 0xcd, 0x16}}; static GUID MAL_GUID_IID_DirectSoundNotify = {0xb0210783, 0x89cd, 0x11d0, {0xaf, 0x08, 0x00, 0xa0, 0xc9, 0x25, 0xcd, 0x16}};
...@@ -4815,9 +4815,9 @@ mal_result mal_context_init__winmm(mal_context* pContext) ...@@ -4815,9 +4815,9 @@ mal_result mal_context_init__winmm(mal_context* pContext)
pContext->winmm.waveInPrepareHeader = mal_dlsym(pContext->winmm.hWinMM, "waveInPrepareHeader"); pContext->winmm.waveInPrepareHeader = mal_dlsym(pContext->winmm.hWinMM, "waveInPrepareHeader");
pContext->winmm.waveInUnprepareHeader = mal_dlsym(pContext->winmm.hWinMM, "waveInUnprepareHeader"); pContext->winmm.waveInUnprepareHeader = mal_dlsym(pContext->winmm.hWinMM, "waveInUnprepareHeader");
pContext->winmm.waveInAddBuffer = mal_dlsym(pContext->winmm.hWinMM, "waveInAddBuffer"); pContext->winmm.waveInAddBuffer = mal_dlsym(pContext->winmm.hWinMM, "waveInAddBuffer");
pContext->winmm.waveInStart = mal_dlsym(pContext->winmm.hWinMM, "waveInStart"); pContext->winmm.waveInStart = mal_dlsym(pContext->winmm.hWinMM, "waveInStart");
pContext->winmm.waveInReset = mal_dlsym(pContext->winmm.hWinMM, "waveInReset"); pContext->winmm.waveInReset = mal_dlsym(pContext->winmm.hWinMM, "waveInReset");
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -4878,7 +4878,7 @@ static mal_result mal_enumerate_devices__winmm(mal_context* pContext, mal_device ...@@ -4878,7 +4878,7 @@ static mal_result mal_enumerate_devices__winmm(mal_context* pContext, mal_device
} }
} }
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -5109,7 +5109,7 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type ...@@ -5109,7 +5109,7 @@ static mal_result mal_device_init__winmm(mal_context* pContext, mal_device_type
formatChannels = 2; formatChannels = 2;
formatSampleRate = 96000; formatSampleRate = 96000;
} break; } break;
default: default:
{ {
errorMsg = "[WinMM] The internal device does not support any of the standard formats.", errorCode = MAL_ERROR; // <-- Should never hit this. errorMsg = "[WinMM] The internal device does not support any of the standard formats.", errorCode = MAL_ERROR; // <-- Should never hit this.
goto on_error; goto on_error;
...@@ -5336,7 +5336,7 @@ static mal_result mal_device__stop_backend__winmm(mal_device* pDevice) ...@@ -5336,7 +5336,7 @@ static mal_result mal_device__stop_backend__winmm(mal_device* pDevice)
if (resultMM != MMSYSERR_NOERROR) { if (resultMM != MMSYSERR_NOERROR) {
mal_post_error(pDevice, "[WinMM] WARNING: Failed to reset capture device.", mal_result_from_MMRESULT(resultMM)); mal_post_error(pDevice, "[WinMM] WARNING: Failed to reset capture device.", mal_result_from_MMRESULT(resultMM));
} }
// Unprepare all WAVEHDR structures. // Unprepare all WAVEHDR structures.
for (mal_uint32 i = 0; i < pDevice->periods; ++i) { for (mal_uint32 i = 0; i < pDevice->periods; ++i) {
resultMM = ((MAL_PFN_waveInUnprepareHeader)pDevice->pContext->winmm.waveInUnprepareHeader)((HWAVEIN)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR)); resultMM = ((MAL_PFN_waveInUnprepareHeader)pDevice->pContext->winmm.waveInUnprepareHeader)((HWAVEIN)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR));
...@@ -5373,10 +5373,10 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice) ...@@ -5373,10 +5373,10 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice)
} }
// Break from the main loop if the device isn't started anymore. Likely what's happened is the application // Break from the main loop if the device isn't started anymore. Likely what's happened is the application
// has requested that the device be stopped. // has requested that the device be stopped.
if (!mal_device_is_started(pDevice)) { if (!mal_device_is_started(pDevice)) {
break; break;
} }
// Any headers that are marked as done need to be handled. We start by processing the completed blocks. Then we reset the event // Any headers that are marked as done need to be handled. We start by processing the completed blocks. Then we reset the event
// and then write or add replacement buffers to the device. // and then write or add replacement buffers to the device.
...@@ -5388,7 +5388,7 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice) ...@@ -5388,7 +5388,7 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice)
} }
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
// Playback. // Playback.
MMRESULT resultMM = ((MAL_PFN_waveOutUnprepareHeader)pDevice->pContext->winmm.waveOutUnprepareHeader)((HWAVEOUT)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR)); MMRESULT resultMM = ((MAL_PFN_waveOutUnprepareHeader)pDevice->pContext->winmm.waveOutUnprepareHeader)((HWAVEOUT)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) { if (resultMM != MMSYSERR_NOERROR) {
mal_post_error(pDevice, "[WinMM] Failed to unprepare header for playback device in preparation for sending a new block of data to the device for playback.", mal_result_from_MMRESULT(resultMM)); mal_post_error(pDevice, "[WinMM] Failed to unprepare header for playback device in preparation for sending a new block of data to the device for playback.", mal_result_from_MMRESULT(resultMM));
...@@ -5401,16 +5401,16 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice) ...@@ -5401,16 +5401,16 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice)
((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwFlags = 0L; ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwFlags = 0L;
((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwLoops = 0L; ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwLoops = 0L;
((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwUser = 1; // <-- Used in the next section to identify the buffers that needs to be re-written to the device. ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwUser = 1; // <-- Used in the next section to identify the buffers that needs to be re-written to the device.
mal_device__read_frames_from_client(pDevice, pDevice->winmm.fragmentSizeInFrames, ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].lpData); mal_device__read_frames_from_client(pDevice, pDevice->winmm.fragmentSizeInFrames, ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].lpData);
resultMM = ((MAL_PFN_waveOutPrepareHeader)pDevice->pContext->winmm.waveOutPrepareHeader)((HWAVEOUT)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR)); resultMM = ((MAL_PFN_waveOutPrepareHeader)pDevice->pContext->winmm.waveOutPrepareHeader)((HWAVEOUT)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) { if (resultMM != MMSYSERR_NOERROR) {
mal_post_error(pDevice, "[WinMM] Failed to prepare header for playback device in preparation for sending a new block of data to the device for playback.", mal_result_from_MMRESULT(resultMM)); mal_post_error(pDevice, "[WinMM] Failed to prepare header for playback device in preparation for sending a new block of data to the device for playback.", mal_result_from_MMRESULT(resultMM));
break; break;
} }
} else { } else {
// Capture. // Capture.
mal_uint32 framesCaptured = (mal_uint32)(((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwBytesRecorded) / pDevice->internalChannels / mal_get_sample_size_in_bytes(pDevice->internalFormat); mal_uint32 framesCaptured = (mal_uint32)(((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwBytesRecorded) / pDevice->internalChannels / mal_get_sample_size_in_bytes(pDevice->internalFormat);
if (framesCaptured > 0) { if (framesCaptured > 0) {
mal_device__send_frames_to_client(pDevice, framesCaptured, ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].lpData); mal_device__send_frames_to_client(pDevice, framesCaptured, ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].lpData);
} }
...@@ -5433,7 +5433,7 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice) ...@@ -5433,7 +5433,7 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice)
mal_post_error(pDevice, "[WinMM] Failed to prepare header for capture device in preparation for adding a new capture buffer for the device.", mal_result_from_MMRESULT(resultMM)); mal_post_error(pDevice, "[WinMM] Failed to prepare header for capture device in preparation for adding a new capture buffer for the device.", mal_result_from_MMRESULT(resultMM));
break; break;
} }
} }
pDevice->winmm.iNextHeader = (pDevice->winmm.iNextHeader + 1) % pDevice->periods; pDevice->winmm.iNextHeader = (pDevice->winmm.iNextHeader + 1) % pDevice->periods;
} }
...@@ -5447,23 +5447,23 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice) ...@@ -5447,23 +5447,23 @@ static mal_result mal_device__main_loop__winmm(mal_device* pDevice)
((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwUser = 0; ((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i].dwUser = 0;
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
// Playback. // Playback.
MMRESULT resultMM = ((MAL_PFN_waveOutWrite)pDevice->pContext->winmm.waveOutWrite)((HWAVEOUT)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR)); MMRESULT resultMM = ((MAL_PFN_waveOutWrite)pDevice->pContext->winmm.waveOutWrite)((HWAVEOUT)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) { if (resultMM != MMSYSERR_NOERROR) {
mal_post_error(pDevice, "[WinMM] Failed to write data to the internal playback device.", mal_result_from_MMRESULT(resultMM)); mal_post_error(pDevice, "[WinMM] Failed to write data to the internal playback device.", mal_result_from_MMRESULT(resultMM));
break; break;
} }
} else { } else {
// Capture. // Capture.
MMRESULT resultMM = ((MAL_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR)); MMRESULT resultMM = ((MAL_PFN_waveInAddBuffer)pDevice->pContext->winmm.waveInAddBuffer)((HWAVEIN)pDevice->winmm.hDevice, &((LPWAVEHDR)pDevice->winmm.pWAVEHDR)[i], sizeof(WAVEHDR));
if (resultMM != MMSYSERR_NOERROR) { if (resultMM != MMSYSERR_NOERROR) {
mal_post_error(pDevice, "[WinMM] Failed to add new capture buffer to the internal capture device.", mal_result_from_MMRESULT(resultMM)); mal_post_error(pDevice, "[WinMM] Failed to add new capture buffer to the internal capture device.", mal_result_from_MMRESULT(resultMM));
break; break;
} }
} }
} }
} }
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -5611,7 +5611,7 @@ mal_channel mal_convert_alsa_channel_position_to_mal_channel(unsigned int alsaCh ...@@ -5611,7 +5611,7 @@ mal_channel mal_convert_alsa_channel_position_to_mal_channel(unsigned int alsaCh
case SND_CHMAP_TRC: return MAL_CHANNEL_TOP_BACK_CENTER; case SND_CHMAP_TRC: return MAL_CHANNEL_TOP_BACK_CENTER;
default: break; default: break;
} }
return 0; return 0;
} }
...@@ -5976,7 +5976,7 @@ static mal_bool32 mal_is_device_name_in_hw_format__alsa(const char* hwid) ...@@ -5976,7 +5976,7 @@ static mal_bool32 mal_is_device_name_in_hw_format__alsa(const char* hwid)
} }
hwid += 3; hwid += 3;
int commaPos; int commaPos;
const char* dev = mal_find_char(hwid, ',', &commaPos); const char* dev = mal_find_char(hwid, ',', &commaPos);
if (dev == NULL) { if (dev == NULL) {
...@@ -6045,7 +6045,7 @@ static int mal_convert_device_name_to_hw_format__alsa(mal_context* pContext, cha ...@@ -6045,7 +6045,7 @@ static int mal_convert_device_name_to_hw_format__alsa(mal_context* pContext, cha
//printf("TESTING: CARD=%s,DEV=%s\n", card, dev); //printf("TESTING: CARD=%s,DEV=%s\n", card, dev);
// Construction. // Construction.
dst[0] = 'h'; dst[1] = 'w'; dst[2] = ':'; dst[0] = 'h'; dst[1] = 'w'; dst[2] = ':';
if (mal_itoa_s(cardIndex, dst+3, dstSize-3, 10) != 0) { if (mal_itoa_s(cardIndex, dst+3, dstSize-3, 10) != 0) {
...@@ -6112,7 +6112,7 @@ static mal_result mal_enumerate_devices__alsa(mal_context* pContext, mal_device_ ...@@ -6112,7 +6112,7 @@ static mal_result mal_enumerate_devices__alsa(mal_context* pContext, mal_device_
} }
} }
if (includeThisDevice) { if (includeThisDevice) {
#if 0 #if 0
...@@ -6198,7 +6198,7 @@ static mal_result mal_enumerate_devices__alsa(mal_context* pContext, mal_device_ ...@@ -6198,7 +6198,7 @@ static mal_result mal_enumerate_devices__alsa(mal_context* pContext, mal_device_
mal_strcpy_s(pInfo->name, sizeof(pInfo->name), DESC); mal_strcpy_s(pInfo->name, sizeof(pInfo->name), DESC);
} }
} }
pInfo += 1; pInfo += 1;
infoSize -= 1; infoSize -= 1;
*pCount += 1; *pCount += 1;
...@@ -6343,7 +6343,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -6343,7 +6343,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
// We may need to scale the size of the buffer depending on the device. // We may need to scale the size of the buffer depending on the device.
if (pDevice->usingDefaultBufferSize) { if (pDevice->usingDefaultBufferSize) {
float bufferSizeScale = 1; float bufferSizeScale = 1;
snd_pcm_info_t* pInfo = (snd_pcm_info_t*)alloca(((mal_snd_pcm_info_sizeof)pContext->alsa.snd_pcm_info_sizeof)()); snd_pcm_info_t* pInfo = (snd_pcm_info_t*)alloca(((mal_snd_pcm_info_sizeof)pContext->alsa.snd_pcm_info_sizeof)());
mal_zero_memory(pInfo, ((mal_snd_pcm_info_sizeof)pContext->alsa.snd_pcm_info_sizeof)()); mal_zero_memory(pInfo, ((mal_snd_pcm_info_sizeof)pContext->alsa.snd_pcm_info_sizeof)());
...@@ -6518,15 +6518,15 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -6518,15 +6518,15 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
} }
pDevice->bufferSizeInFrames = actualBufferSize; pDevice->bufferSizeInFrames = actualBufferSize;
// Apply hardware parameters. // Apply hardware parameters.
if (((mal_snd_pcm_hw_params_proc)pContext->alsa.snd_pcm_hw_params)((snd_pcm_t*)pDevice->alsa.pPCM, pHWParams) < 0) { if (((mal_snd_pcm_hw_params_proc)pContext->alsa.snd_pcm_hw_params)((snd_pcm_t*)pDevice->alsa.pPCM, pHWParams) < 0) {
mal_device_uninit__alsa(pDevice); mal_device_uninit__alsa(pDevice);
return mal_post_error(pDevice, "[ALSA] Failed to set hardware parameters. snd_pcm_hw_params() failed.", MAL_ALSA_FAILED_TO_SET_HW_PARAMS); return mal_post_error(pDevice, "[ALSA] Failed to set hardware parameters. snd_pcm_hw_params() failed.", MAL_ALSA_FAILED_TO_SET_HW_PARAMS);
} }
// Software parameters. // Software parameters.
snd_pcm_sw_params_t* pSWParams = (snd_pcm_sw_params_t*)alloca(((mal_snd_pcm_sw_params_sizeof_proc)pContext->alsa.snd_pcm_sw_params_sizeof)()); snd_pcm_sw_params_t* pSWParams = (snd_pcm_sw_params_t*)alloca(((mal_snd_pcm_sw_params_sizeof_proc)pContext->alsa.snd_pcm_sw_params_sizeof)());
...@@ -6564,8 +6564,8 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -6564,8 +6564,8 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
return mal_post_error(pDevice, "[ALSA] Failed to allocate memory for intermediary buffer.", MAL_OUT_OF_MEMORY); return mal_post_error(pDevice, "[ALSA] Failed to allocate memory for intermediary buffer.", MAL_OUT_OF_MEMORY);
} }
} }
// Grab the internal channel map. For now we're not going to bother trying to change the channel map and // Grab the internal channel map. For now we're not going to bother trying to change the channel map and
// instead just do it ourselves. // instead just do it ourselves.
...@@ -6580,7 +6580,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -6580,7 +6580,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
} else { } else {
// Excess channels use defaults. Do an initial fill with defaults, overwrite the first pChmap->channels, validate to ensure there are no duplicate // Excess channels use defaults. Do an initial fill with defaults, overwrite the first pChmap->channels, validate to ensure there are no duplicate
// channels. If validation fails, fall back to defaults. // channels. If validation fails, fall back to defaults.
// Fill with defaults. // Fill with defaults.
mal_get_default_channel_mapping(pDevice->pContext->backend, pDevice->internalChannels, pDevice->internalChannelMap); mal_get_default_channel_mapping(pDevice->pContext->backend, pDevice->internalChannels, pDevice->internalChannelMap);
...@@ -6602,7 +6602,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t ...@@ -6602,7 +6602,7 @@ static mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type t
// If our channel map is invalid, fall back to defaults. // If our channel map is invalid, fall back to defaults.
if (!isValid) { if (!isValid) {
mal_get_default_channel_mapping(pDevice->pContext->backend, pDevice->internalChannels, pDevice->internalChannelMap); mal_get_default_channel_mapping(pDevice->pContext->backend, pDevice->internalChannels, pDevice->internalChannelMap);
} }
} }
...@@ -6699,37 +6699,37 @@ static mal_result mal_device__main_loop__alsa(mal_device* pDevice) ...@@ -6699,37 +6699,37 @@ static mal_result mal_device__main_loop__alsa(mal_device* pDevice)
int mal_open_temp_device__oss() int mal_open_temp_device__oss()
{ {
// The OSS sample code uses "/dev/mixer" as the device for getting system properties so I'm going to do the same. // The OSS sample code uses "/dev/mixer" as the device for getting system properties so I'm going to do the same.
int fd = open("/dev/mixer", O_RDONLY, 0); int fd = open("/dev/mixer", O_RDONLY, 0);
if (fd >= 0) { if (fd >= 0) {
return fd; return fd;
} }
return -1; return -1;
} }
mal_result mal_context_init__oss(mal_context* pContext) mal_result mal_context_init__oss(mal_context* pContext)
{ {
mal_assert(pContext != NULL); mal_assert(pContext != NULL);
// Try opening a temporary device first so we can get version information. This is closed at the end. // Try opening a temporary device first so we can get version information. This is closed at the end.
int fd = mal_open_temp_device__oss(); int fd = mal_open_temp_device__oss();
if (fd == -1) { if (fd == -1) {
return mal_context_post_error(pContext, NULL, "[OSS] Failed to open temporary device for retrieving system properties.", MAL_NO_BACKEND); // Looks liks OSS isn't installed, or there are no available devices. return mal_context_post_error(pContext, NULL, "[OSS] Failed to open temporary device for retrieving system properties.", MAL_NO_BACKEND); // Looks liks OSS isn't installed, or there are no available devices.
} }
// Grab the OSS version. // Grab the OSS version.
int ossVersion = 0; int ossVersion = 0;
int result = ioctl(fd, OSS_GETVERSION, &ossVersion); int result = ioctl(fd, OSS_GETVERSION, &ossVersion);
if (result == -1) { if (result == -1) {
close(fd); close(fd);
return mal_context_post_error(pContext, NULL, "[OSS] Failed to retrieve OSS version.", MAL_NO_BACKEND); return mal_context_post_error(pContext, NULL, "[OSS] Failed to retrieve OSS version.", MAL_NO_BACKEND);
} }
pContext->oss.versionMajor = ((ossVersion & 0xFF0000) >> 16); pContext->oss.versionMajor = ((ossVersion & 0xFF0000) >> 16);
pContext->oss.versionMinor = ((ossVersion & 0x00FF00) >> 8); pContext->oss.versionMinor = ((ossVersion & 0x00FF00) >> 8);
close(fd); close(fd);
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -6749,41 +6749,41 @@ static mal_result mal_enumerate_devices__oss(mal_context* pContext, mal_device_t ...@@ -6749,41 +6749,41 @@ static mal_result mal_enumerate_devices__oss(mal_context* pContext, mal_device_t
mal_uint32 infoSize = *pCount; mal_uint32 infoSize = *pCount;
*pCount = 0; *pCount = 0;
// The object returned by SNDCTL_SYSINFO will have the information we're after. // The object returned by SNDCTL_SYSINFO will have the information we're after.
int fd = mal_open_temp_device__oss(); int fd = mal_open_temp_device__oss();
if (fd == -1) { if (fd == -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(fd, 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(fd, SNDCTL_AUDIOINFO, &ai);
if (result != -1) { if (result != -1) {
mal_bool32 includeThisDevice = MAL_FALSE; mal_bool32 includeThisDevice = MAL_FALSE;
if (type == mal_device_type_playback && (ai.caps & PCM_CAP_OUTPUT) != 0) { if (type == mal_device_type_playback && (ai.caps & PCM_CAP_OUTPUT) != 0) {
includeThisDevice = MAL_TRUE; includeThisDevice = MAL_TRUE;
} else if (type == mal_device_type_capture && (ai.caps & PCM_CAP_INPUT) != 0) { } else if (type == mal_device_type_capture && (ai.caps & PCM_CAP_INPUT) != 0) {
includeThisDevice = MAL_TRUE; includeThisDevice = MAL_TRUE;
} }
if (includeThisDevice) { if (includeThisDevice) {
if (ai.devnode[0] != '\0') { // <-- Can be blank, according to documentation. if (ai.devnode[0] != '\0') { // <-- Can be blank, according to documentation.
if (pInfo != NULL) { if (pInfo != NULL) {
if (infoSize > 0) { if (infoSize > 0) {
mal_strncpy_s(pInfo->id.oss, sizeof(pInfo->id.oss), ai.devnode, (size_t)-1); mal_strncpy_s(pInfo->id.oss, sizeof(pInfo->id.oss), ai.devnode, (size_t)-1);
// The human readable device name should be in the "ai.handle" variable, but it can // The human readable device name should be in the "ai.handle" variable, but it can
// sometimes be empty in which case we just fall back to "ai.name" which is less user // sometimes be empty in which case we just fall back to "ai.name" which is less user
// friendly, but usually has a value. // friendly, but usually has a value.
if (ai.handle[0] != '\0') { if (ai.handle[0] != '\0') {
mal_strncpy_s(pInfo->name, sizeof(pInfo->name), ai.handle, (size_t)-1); mal_strncpy_s(pInfo->name, sizeof(pInfo->name), ai.handle, (size_t)-1);
} else { } else {
mal_strncpy_s(pInfo->name, sizeof(pInfo->name), ai.name, (size_t)-1); mal_strncpy_s(pInfo->name, sizeof(pInfo->name), ai.name, (size_t)-1);
} }
pInfo += 1; pInfo += 1;
infoSize -= 1; infoSize -= 1;
...@@ -6792,29 +6792,29 @@ static mal_result mal_enumerate_devices__oss(mal_context* pContext, mal_device_t ...@@ -6792,29 +6792,29 @@ static mal_result mal_enumerate_devices__oss(mal_context* pContext, mal_device_t
} else { } else {
*pCount += 1; *pCount += 1;
} }
} }
} }
} }
} }
} else { } else {
// Failed to retrieve the system information. Just return a default device for both playback and capture. // Failed to retrieve the system information. Just return a default device for both playback and capture.
if (pInfo != NULL) { if (pInfo != NULL) {
if (infoSize > 0) { if (infoSize > 0) {
mal_strncpy_s(pInfo[0].id.oss, sizeof(pInfo[0].id.oss), "/dev/dsp", (size_t)-1); mal_strncpy_s(pInfo[0].id.oss, sizeof(pInfo[0].id.oss), "/dev/dsp", (size_t)-1);
if (type == mal_device_type_playback) { if (type == mal_device_type_playback) {
mal_strncpy_s(pInfo[0].name, sizeof(pInfo[0].name), "Default Playback Device", (size_t)-1); mal_strncpy_s(pInfo[0].name, sizeof(pInfo[0].name), "Default Playback Device", (size_t)-1);
} else { } else {
mal_strncpy_s(pInfo[0].name, sizeof(pInfo[0].name), "Default Capture Device", (size_t)-1); mal_strncpy_s(pInfo[0].name, sizeof(pInfo[0].name), "Default Capture Device", (size_t)-1);
} }
*pCount = 1; *pCount = 1;
} }
} else { } else {
*pCount = 1; *pCount = 1;
} }
} }
close(fd); close(fd);
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -6822,8 +6822,8 @@ static void mal_device_uninit__oss(mal_device* pDevice) ...@@ -6822,8 +6822,8 @@ static void mal_device_uninit__oss(mal_device* pDevice)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
close(pDevice->oss.fd); close(pDevice->oss.fd);
mal_free(pDevice->oss.pIntermediaryBuffer); mal_free(pDevice->oss.pIntermediaryBuffer);
} }
static mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal_device_id* pDeviceID, const mal_device_config* pConfig, mal_device* pDevice) static mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, mal_device_id* pDeviceID, const mal_device_config* pConfig, mal_device* pDevice)
...@@ -6833,111 +6833,111 @@ static mal_result mal_device_init__oss(mal_context* pContext, mal_device_type ty ...@@ -6833,111 +6833,111 @@ static mal_result mal_device_init__oss(mal_context* pContext, mal_device_type ty
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
mal_zero_object(&pDevice->oss); mal_zero_object(&pDevice->oss);
char deviceName[64]; char deviceName[64];
if (pDeviceID != NULL) { if (pDeviceID != NULL) {
mal_strncpy_s(deviceName, sizeof(deviceName), pDeviceID->oss, (size_t)-1); mal_strncpy_s(deviceName, sizeof(deviceName), pDeviceID->oss, (size_t)-1);
} else { } else {
mal_strncpy_s(deviceName, sizeof(deviceName), "/dev/dsp", (size_t)-1); 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); pDevice->oss.fd = open(deviceName, (type == mal_device_type_playback) ? O_WRONLY : O_RDONLY, 0);
if (pDevice->oss.fd == -1) { 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);
} }
// The OSS documantation is very clear about the order we should be initializing the device's properties: // The OSS documantation is very clear about the order we should be initializing the device's properties:
// 1) Format // 1) Format
// 2) Channels // 2) Channels
// 3) Sample rate. // 3) Sample rate.
// Format. // Format.
int ossFormat = AFMT_U8; int ossFormat = AFMT_U8;
switch (pDevice->format) { switch (pDevice->format) {
case mal_format_s16: ossFormat = AFMT_S16_LE; break; case mal_format_s16: ossFormat = AFMT_S16_LE; break;
case mal_format_s24: ossFormat = AFMT_S32_LE; break; case mal_format_s24: ossFormat = AFMT_S32_LE; break;
case mal_format_s32: ossFormat = AFMT_S32_LE; break; case mal_format_s32: ossFormat = AFMT_S32_LE; break;
case mal_format_f32: ossFormat = AFMT_S32_LE; break; case mal_format_f32: ossFormat = AFMT_S32_LE; break;
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 result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFMT, &ossFormat);
if (result == -1) { if (result == -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);
} }
switch (ossFormat) { switch (ossFormat) {
case AFMT_U8: pDevice->internalFormat = mal_format_u8; break; case AFMT_U8: pDevice->internalFormat = mal_format_u8; break;
case AFMT_S16_LE: pDevice->internalFormat = mal_format_s16; break; case AFMT_S16_LE: pDevice->internalFormat = mal_format_s16; break;
case AFMT_S32_LE: pDevice->internalFormat = mal_format_s32; break; case AFMT_S32_LE: pDevice->internalFormat = mal_format_s32; break;
default: mal_post_error(pDevice, "[OSS] The device's internal format is not supported by mini_al.", MAL_FORMAT_NOT_SUPPORTED); default: mal_post_error(pDevice, "[OSS] The device's internal format is not supported by mini_al.", MAL_FORMAT_NOT_SUPPORTED);
} }
// Channels. // Channels.
int ossChannels = (int)pConfig->channels; int ossChannels = (int)pConfig->channels;
result = ioctl(pDevice->oss.fd, SNDCTL_DSP_CHANNELS, &ossChannels); result = ioctl(pDevice->oss.fd, SNDCTL_DSP_CHANNELS, &ossChannels);
if (result == -1) { if (result == -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);
} }
pDevice->internalChannels = ossChannels; pDevice->internalChannels = ossChannels;
// Sample rate. // Sample rate.
int ossSampleRate = (int)pConfig->sampleRate; int ossSampleRate = (int)pConfig->sampleRate;
result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SPEED, &ossSampleRate); result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SPEED, &ossSampleRate);
if (result == -1) { if (result == -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);
} }
pDevice->sampleRate = ossSampleRate;
pDevice->sampleRate = ossSampleRate;
// The documentation says that the fragment settings should be set as soon as possible, but I'm not sure if
// it should be done before or after format/channels/rate.
//
// OSS wants the fragment size in bytes and a power of 2. When setting, we specify the power, not the actual
// value.
mal_uint32 fragmentSizeInBytes = mal_round_to_power_of_2(pDevice->bufferSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat));
if (fragmentSizeInBytes < 16) {
fragmentSizeInBytes = 16;
}
// The documentation says that the fragment settings should be set as soon as possible, but I'm not sure if mal_uint32 ossFragmentSizePower = 4;
// it should be done before or after format/channels/rate. fragmentSizeInBytes >>= 4;
// while (fragmentSizeInBytes >>= 1) {
// OSS wants the fragment size in bytes and a power of 2. When setting, we specify the power, not the actual ossFragmentSizePower += 1;
// value. }
mal_uint32 fragmentSizeInBytes = mal_round_to_power_of_2(pDevice->bufferSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat));
if (fragmentSizeInBytes < 16) {
fragmentSizeInBytes = 16;
}
mal_uint32 ossFragmentSizePower = 4; int ossFragment = (int)((pDevice->periods << 16) | ossFragmentSizePower);
fragmentSizeInBytes >>= 4; result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFRAGMENT, &ossFragment);
while (fragmentSizeInBytes >>= 1) { if (result == -1) {
ossFragmentSizePower += 1; close(pDevice->oss.fd);
} return mal_post_error(pDevice, "[OSS] Failed to set fragment size and period count.", MAL_FORMAT_NOT_SUPPORTED);
}
int ossFragment = (int)((pDevice->periods << 16) | ossFragmentSizePower); int actualFragmentSizeInBytes = 1 << (ossFragment & 0xFFFF);
result = ioctl(pDevice->oss.fd, SNDCTL_DSP_SETFRAGMENT, &ossFragment); pDevice->oss.fragmentSizeInFrames = actualFragmentSizeInBytes / mal_get_sample_size_in_bytes(pDevice->internalFormat) / pDevice->internalChannels;
if (result == -1) {
close(pDevice->oss.fd);
return mal_post_error(pDevice, "[OSS] Failed to set fragment size and period count.", MAL_FORMAT_NOT_SUPPORTED);
}
int actualFragmentSizeInBytes = 1 << (ossFragment & 0xFFFF); pDevice->periods = (mal_uint32)(ossFragment >> 16);
pDevice->oss.fragmentSizeInFrames = actualFragmentSizeInBytes / mal_get_sample_size_in_bytes(pDevice->internalFormat) / pDevice->internalChannels; pDevice->bufferSizeInFrames = (mal_uint32)(pDevice->oss.fragmentSizeInFrames * pDevice->periods);
pDevice->periods = (mal_uint32)(ossFragment >> 16);
pDevice->bufferSizeInFrames = (mal_uint32)(pDevice->oss.fragmentSizeInFrames * pDevice->periods);
// Set the internal channel map. Not sure if this can be queried. For now just using our default assumptions.
// Set the internal channel map. Not sure if this can be queried. For now just using our default assumptions. mal_get_default_channel_mapping(pDevice->pContext->backend, pDevice->internalChannels, pDevice->internalChannelMap);
mal_get_default_channel_mapping(pDevice->pContext->backend, pDevice->internalChannels, pDevice->internalChannelMap);
// When not using MMAP mode, we need to use an intermediary buffer for the client <-> device transfer. We do // When not using MMAP mode, we need to use an intermediary buffer for the client <-> device transfer. We do
// everything by the size of a fragment. // everything by the size of a fragment.
pDevice->oss.pIntermediaryBuffer = mal_malloc(fragmentSizeInBytes); pDevice->oss.pIntermediaryBuffer = mal_malloc(fragmentSizeInBytes);
if (pDevice->oss.pIntermediaryBuffer == NULL) { if (pDevice->oss.pIntermediaryBuffer == NULL) {
close(pDevice->oss.fd); close(pDevice->oss.fd);
return mal_post_error(pDevice, "[OSS] Failed to allocate memory for intermediary buffer.", MAL_OUT_OF_MEMORY); return mal_post_error(pDevice, "[OSS] Failed to allocate memory for intermediary buffer.", MAL_OUT_OF_MEMORY);
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -6947,21 +6947,21 @@ static mal_result mal_device__start_backend__oss(mal_device* pDevice) ...@@ -6947,21 +6947,21 @@ static mal_result mal_device__start_backend__oss(mal_device* pDevice)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
// The device is started by the next calls to read() and write(). For playback it's simple - just read // The device is started by the next calls to read() and write(). For playback it's simple - just read
// data from the client, then write it to the device with write() which will in turn start the device. // data from the client, then write it to the device with write() which will in turn start the device.
// For capture it's a bit less intuitive - we do nothing (it'll be started automatically by the first // For capture it's a bit less intuitive - we do nothing (it'll be started automatically by the first
// call to read(). // call to read().
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
// Playback. // Playback.
mal_device__read_frames_from_client(pDevice, pDevice->oss.fragmentSizeInFrames, pDevice->oss.pIntermediaryBuffer); mal_device__read_frames_from_client(pDevice, pDevice->oss.fragmentSizeInFrames, pDevice->oss.pIntermediaryBuffer);
int bytesWritten = write(pDevice->oss.fd, pDevice->oss.pIntermediaryBuffer, pDevice->oss.fragmentSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat)); int bytesWritten = write(pDevice->oss.fd, pDevice->oss.pIntermediaryBuffer, pDevice->oss.fragmentSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat));
if (bytesWritten == -1) { if (bytesWritten == -1) {
return mal_post_error(pDevice, "[OSS] Failed to send initial chunk of data to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE); return mal_post_error(pDevice, "[OSS] Failed to send initial chunk of data to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE);
} }
} else { } else {
// Capture. Do nothing. // Capture. Do nothing.
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -6970,21 +6970,21 @@ static mal_result mal_device__stop_backend__oss(mal_device* pDevice) ...@@ -6970,21 +6970,21 @@ static mal_result mal_device__stop_backend__oss(mal_device* pDevice)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
// We want to use SNDCTL_DSP_HALT. From the documentation: // We want to use SNDCTL_DSP_HALT. From the documentation:
// //
// In multithreaded applications SNDCTL_DSP_HALT (SNDCTL_DSP_RESET) must only be called by the thread // In multithreaded applications SNDCTL_DSP_HALT (SNDCTL_DSP_RESET) must only be called by the thread
// that actually reads/writes the audio device. It must not be called by some master thread to kill the // that actually reads/writes the audio device. It must not be called by some master thread to kill the
// audio thread. The audio thread will not stop or get any kind of notification that the device was // audio thread. The audio thread will not stop or get any kind of notification that the device was
// stopped by the master thread. The device gets stopped but the next read or write call will silently // stopped by the master thread. The device gets stopped but the next read or write call will silently
// restart the device. // restart the device.
// //
// This is actually safe in our case, because this function is only ever called from within our worker // This is actually safe in our case, because this function is only ever called from within our worker
// thread anyway. Just keep this in mind, though... // thread anyway. Just keep this in mind, though...
int result = ioctl(pDevice->oss.fd, SNDCTL_DSP_HALT, 0); int result = ioctl(pDevice->oss.fd, SNDCTL_DSP_HALT, 0);
if (result == -1) { if (result == -1) {
return mal_post_error(pDevice, "[OSS] Failed to stop device. SNDCTL_DSP_HALT failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE); return mal_post_error(pDevice, "[OSS] Failed to stop device. SNDCTL_DSP_HALT failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE);
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -6993,7 +6993,7 @@ static mal_result mal_device__break_main_loop__oss(mal_device* pDevice) ...@@ -6993,7 +6993,7 @@ static mal_result mal_device__break_main_loop__oss(mal_device* pDevice)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
pDevice->oss.breakFromMainLoop = MAL_TRUE; pDevice->oss.breakFromMainLoop = MAL_TRUE;
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -7001,33 +7001,33 @@ static mal_result mal_device__main_loop__oss(mal_device* pDevice) ...@@ -7001,33 +7001,33 @@ static mal_result mal_device__main_loop__oss(mal_device* pDevice)
{ {
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
pDevice->oss.breakFromMainLoop = MAL_FALSE; pDevice->oss.breakFromMainLoop = MAL_FALSE;
while (!pDevice->oss.breakFromMainLoop) { while (!pDevice->oss.breakFromMainLoop) {
// Break from the main loop if the device isn't started anymore. Likely what's happened is the application // Break from the main loop if the device isn't started anymore. Likely what's happened is the application
// has requested that the device be stopped. // has requested that the device be stopped.
if (!mal_device_is_started(pDevice)) { if (!mal_device_is_started(pDevice)) {
break; break;
} }
if (pDevice->type == mal_device_type_playback) { if (pDevice->type == mal_device_type_playback) {
// Playback. // Playback.
mal_device__read_frames_from_client(pDevice, pDevice->oss.fragmentSizeInFrames, pDevice->oss.pIntermediaryBuffer); mal_device__read_frames_from_client(pDevice, pDevice->oss.fragmentSizeInFrames, pDevice->oss.pIntermediaryBuffer);
int bytesWritten = write(pDevice->oss.fd, pDevice->oss.pIntermediaryBuffer, pDevice->oss.fragmentSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat)); int bytesWritten = write(pDevice->oss.fd, pDevice->oss.pIntermediaryBuffer, pDevice->oss.fragmentSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat));
if (bytesWritten < 0) { if (bytesWritten < 0) {
return mal_post_error(pDevice, "[OSS] Failed to send data from the client to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE); return mal_post_error(pDevice, "[OSS] Failed to send data from the client to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE);
} }
} else { } else {
// Capture. // Capture.
int bytesRead = read(pDevice->oss.fd, pDevice->oss.pIntermediaryBuffer, pDevice->oss.fragmentSizeInFrames * mal_get_sample_size_in_bytes(pDevice->internalFormat)); int bytesRead = read(pDevice->oss.fd, pDevice->oss.pIntermediaryBuffer, pDevice->oss.fragmentSizeInFrames * mal_get_sample_size_in_bytes(pDevice->internalFormat));
if (bytesRead < 0) { if (bytesRead < 0) {
return mal_post_error(pDevice, "[OSS] Failed to read data from the device to be sent to the client.", MAL_FAILED_TO_READ_DATA_FROM_DEVICE); return mal_post_error(pDevice, "[OSS] Failed to read data from the device to be sent to the client.", MAL_FAILED_TO_READ_DATA_FROM_DEVICE);
} }
mal_uint32 framesRead = (mal_uint32)bytesRead / pDevice->internalChannels / mal_get_sample_size_in_bytes(pDevice->internalFormat); mal_uint32 framesRead = (mal_uint32)bytesRead / pDevice->internalChannels / mal_get_sample_size_in_bytes(pDevice->internalFormat);
mal_device__send_frames_to_client(pDevice, framesRead, pDevice->oss.pIntermediaryBuffer); mal_device__send_frames_to_client(pDevice, framesRead, pDevice->oss.pIntermediaryBuffer);
} }
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -7077,24 +7077,24 @@ static SLuint32 mal_channel_id_to_opensl(mal_uint8 id) ...@@ -7077,24 +7077,24 @@ static SLuint32 mal_channel_id_to_opensl(mal_uint8 id)
{ {
switch (id) switch (id)
{ {
case MAL_CHANNEL_FRONT_LEFT: return SL_SPEAKER_FRONT_LEFT; case MAL_CHANNEL_FRONT_LEFT: return SL_SPEAKER_FRONT_LEFT;
case MAL_CHANNEL_FRONT_RIGHT: return SL_SPEAKER_FRONT_RIGHT; case MAL_CHANNEL_FRONT_RIGHT: return SL_SPEAKER_FRONT_RIGHT;
case MAL_CHANNEL_FRONT_CENTER: return SL_SPEAKER_FRONT_CENTER; case MAL_CHANNEL_FRONT_CENTER: return SL_SPEAKER_FRONT_CENTER;
case MAL_CHANNEL_LFE: return SL_SPEAKER_LOW_FREQUENCY; case MAL_CHANNEL_LFE: return SL_SPEAKER_LOW_FREQUENCY;
case MAL_CHANNEL_BACK_LEFT: return SL_SPEAKER_BACK_LEFT; case MAL_CHANNEL_BACK_LEFT: return SL_SPEAKER_BACK_LEFT;
case MAL_CHANNEL_BACK_RIGHT: return SL_SPEAKER_BACK_RIGHT; case MAL_CHANNEL_BACK_RIGHT: return SL_SPEAKER_BACK_RIGHT;
case MAL_CHANNEL_FRONT_LEFT_CENTER: return SL_SPEAKER_FRONT_LEFT_OF_CENTER; case MAL_CHANNEL_FRONT_LEFT_CENTER: return SL_SPEAKER_FRONT_LEFT_OF_CENTER;
case MAL_CHANNEL_FRONT_RIGHT_CENTER: return SL_SPEAKER_FRONT_RIGHT_OF_CENTER; case MAL_CHANNEL_FRONT_RIGHT_CENTER: return SL_SPEAKER_FRONT_RIGHT_OF_CENTER;
case MAL_CHANNEL_BACK_CENTER: return SL_SPEAKER_BACK_CENTER; case MAL_CHANNEL_BACK_CENTER: return SL_SPEAKER_BACK_CENTER;
case MAL_CHANNEL_SIDE_LEFT: return SL_SPEAKER_SIDE_LEFT; case MAL_CHANNEL_SIDE_LEFT: return SL_SPEAKER_SIDE_LEFT;
case MAL_CHANNEL_SIDE_RIGHT: return SL_SPEAKER_SIDE_RIGHT; case MAL_CHANNEL_SIDE_RIGHT: return SL_SPEAKER_SIDE_RIGHT;
case MAL_CHANNEL_TOP_CENTER: return SL_SPEAKER_TOP_CENTER; case MAL_CHANNEL_TOP_CENTER: return SL_SPEAKER_TOP_CENTER;
case MAL_CHANNEL_TOP_FRONT_LEFT: return SL_SPEAKER_TOP_FRONT_LEFT; case MAL_CHANNEL_TOP_FRONT_LEFT: return SL_SPEAKER_TOP_FRONT_LEFT;
case MAL_CHANNEL_TOP_FRONT_CENTER: return SL_SPEAKER_TOP_FRONT_CENTER; case MAL_CHANNEL_TOP_FRONT_CENTER: return SL_SPEAKER_TOP_FRONT_CENTER;
case MAL_CHANNEL_TOP_FRONT_RIGHT: return SL_SPEAKER_TOP_FRONT_RIGHT; case MAL_CHANNEL_TOP_FRONT_RIGHT: return SL_SPEAKER_TOP_FRONT_RIGHT;
case MAL_CHANNEL_TOP_BACK_LEFT: return SL_SPEAKER_TOP_BACK_LEFT; case MAL_CHANNEL_TOP_BACK_LEFT: return SL_SPEAKER_TOP_BACK_LEFT;
case MAL_CHANNEL_TOP_BACK_CENTER: return SL_SPEAKER_TOP_BACK_CENTER; case MAL_CHANNEL_TOP_BACK_CENTER: return SL_SPEAKER_TOP_BACK_CENTER;
case MAL_CHANNEL_TOP_BACK_RIGHT: return SL_SPEAKER_TOP_BACK_RIGHT; case MAL_CHANNEL_TOP_BACK_RIGHT: return SL_SPEAKER_TOP_BACK_RIGHT;
default: return 0; default: return 0;
} }
} }
...@@ -7380,7 +7380,7 @@ static void mal_device_uninit__opensl(mal_device* pDevice) ...@@ -7380,7 +7380,7 @@ static void mal_device_uninit__opensl(mal_device* pDevice)
} }
mal_free(pDevice->opensl.pBuffer); mal_free(pDevice->opensl.pBuffer);
// Uninit global data. // Uninit global data.
if (g_malOpenSLInitCounter > 0) { if (g_malOpenSLInitCounter > 0) {
...@@ -7916,10 +7916,10 @@ mal_result mal_context_init__openal(mal_context* pContext) ...@@ -7916,10 +7916,10 @@ mal_result mal_context_init__openal(mal_context* pContext)
#ifdef MAL_APPLE #ifdef MAL_APPLE
libName = "OpenAL.framework/OpenAL"; libName = "OpenAL.framework/OpenAL";
#endif #endif
if (libName == NULL) { if (libName == NULL) {
return MAL_NO_BACKEND; // Don't know what the library name is called. return MAL_NO_BACKEND; // Don't know what the library name is called.
} }
pContext->openal.hOpenAL = mal_dlopen(libName); pContext->openal.hOpenAL = mal_dlopen(libName);
...@@ -8097,7 +8097,7 @@ mal_result mal_context_init__openal(mal_context* pContext) ...@@ -8097,7 +8097,7 @@ mal_result mal_context_init__openal(mal_context* pContext)
pContext->openal.isEnumerationSupported = ((MAL_LPALCISEXTENSIONPRESENT)pContext->openal.alcIsExtensionPresent)(NULL, "ALC_ENUMERATION_EXT"); pContext->openal.isEnumerationSupported = ((MAL_LPALCISEXTENSIONPRESENT)pContext->openal.alcIsExtensionPresent)(NULL, "ALC_ENUMERATION_EXT");
pContext->openal.isFloat32Supported = ((MAL_LPALISEXTENSIONPRESENT)pContext->openal.alIsExtensionPresent)("AL_EXT_float32"); pContext->openal.isFloat32Supported = ((MAL_LPALISEXTENSIONPRESENT)pContext->openal.alIsExtensionPresent)("AL_EXT_float32");
pContext->openal.isMCFormatsSupported = ((MAL_LPALISEXTENSIONPRESENT)pContext->openal.alIsExtensionPresent)("AL_EXT_MCFORMATS"); pContext->openal.isMCFormatsSupported = ((MAL_LPALISEXTENSIONPRESENT)pContext->openal.alIsExtensionPresent)("AL_EXT_MCFORMATS");
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -8123,7 +8123,7 @@ mal_result mal_enumerate_devices__openal(mal_context* pContext, mal_device_type ...@@ -8123,7 +8123,7 @@ mal_result mal_enumerate_devices__openal(mal_context* pContext, mal_device_type
if (pDeviceNames == NULL) { if (pDeviceNames == NULL) {
return MAL_NO_DEVICE; return MAL_NO_DEVICE;
} }
// Each device is stored in pDeviceNames, separated by a null-terminator. The string itself is double-null-terminated. // Each device is stored in pDeviceNames, separated by a null-terminator. The string itself is double-null-terminated.
const mal_ALCchar* pNextDeviceName = pDeviceNames; const mal_ALCchar* pNextDeviceName = pDeviceNames;
while (pNextDeviceName[0] != '\0') { while (pNextDeviceName[0] != '\0') {
...@@ -8694,7 +8694,7 @@ mal_result mal_context_init__sdl(mal_context* pContext) ...@@ -8694,7 +8694,7 @@ mal_result mal_context_init__sdl(mal_context* pContext)
if (pContext->sdl.hSDL == NULL) { if (pContext->sdl.hSDL == NULL) {
return MAL_NO_BACKEND; // Couldn't find SDL2.dll, etc. Most likely it's not installed. return MAL_NO_BACKEND; // Couldn't find SDL2.dll, etc. Most likely it's not installed.
} }
pContext->sdl.SDL_InitSubSystem = mal_dlsym(pContext->sdl.hSDL, "SDL_InitSubSystem"); pContext->sdl.SDL_InitSubSystem = mal_dlsym(pContext->sdl.hSDL, "SDL_InitSubSystem");
pContext->sdl.SDL_QuitSubSystem = mal_dlsym(pContext->sdl.hSDL, "SDL_QuitSubSystem"); pContext->sdl.SDL_QuitSubSystem = mal_dlsym(pContext->sdl.hSDL, "SDL_QuitSubSystem");
pContext->sdl.SDL_CloseAudio = mal_dlsym(pContext->sdl.hSDL, "SDL_CloseAudio"); pContext->sdl.SDL_CloseAudio = mal_dlsym(pContext->sdl.hSDL, "SDL_CloseAudio");
...@@ -8737,7 +8737,7 @@ mal_result mal_context_init__sdl(mal_context* pContext) ...@@ -8737,7 +8737,7 @@ mal_result mal_context_init__sdl(mal_context* pContext)
if (resultSDL != 0) { if (resultSDL != 0) {
return MAL_ERROR; return MAL_ERROR;
} }
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -8991,9 +8991,9 @@ static mal_result mal_device__start_backend(mal_device* pDevice) ...@@ -8991,9 +8991,9 @@ static mal_result mal_device__start_backend(mal_device* pDevice)
} }
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
if (pDevice->pContext->backend == mal_backend_oss) { if (pDevice->pContext->backend == mal_backend_oss) {
result = mal_device__start_backend__oss(pDevice); result = mal_device__start_backend__oss(pDevice);
} }
#endif #endif
#ifdef MAL_HAS_OPENAL #ifdef MAL_HAS_OPENAL
if (pDevice->pContext->backend == mal_backend_openal) { if (pDevice->pContext->backend == mal_backend_openal) {
...@@ -9035,9 +9035,9 @@ static mal_result mal_device__stop_backend(mal_device* pDevice) ...@@ -9035,9 +9035,9 @@ static mal_result mal_device__stop_backend(mal_device* pDevice)
} }
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
if (pDevice->pContext->backend == mal_backend_oss) { if (pDevice->pContext->backend == mal_backend_oss) {
result = mal_device__stop_backend__oss(pDevice); result = mal_device__stop_backend__oss(pDevice);
} }
#endif #endif
#ifdef MAL_HAS_OPENAL #ifdef MAL_HAS_OPENAL
if (pDevice->pContext->backend == mal_backend_openal) { if (pDevice->pContext->backend == mal_backend_openal) {
...@@ -9079,9 +9079,9 @@ static mal_result mal_device__break_main_loop(mal_device* pDevice) ...@@ -9079,9 +9079,9 @@ static mal_result mal_device__break_main_loop(mal_device* pDevice)
} }
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
if (pDevice->pContext->backend == mal_backend_oss) { if (pDevice->pContext->backend == mal_backend_oss) {
result = mal_device__break_main_loop__oss(pDevice); result = mal_device__break_main_loop__oss(pDevice);
} }
#endif #endif
#ifdef MAL_HAS_OPENAL #ifdef MAL_HAS_OPENAL
if (pDevice->pContext->backend == mal_backend_openal) { if (pDevice->pContext->backend == mal_backend_openal) {
...@@ -9123,9 +9123,9 @@ static mal_result mal_device__main_loop(mal_device* pDevice) ...@@ -9123,9 +9123,9 @@ static mal_result mal_device__main_loop(mal_device* pDevice)
} }
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
if (pDevice->pContext->backend == mal_backend_oss) { if (pDevice->pContext->backend == mal_backend_oss) {
result = mal_device__main_loop__oss(pDevice); result = mal_device__main_loop__oss(pDevice);
} }
#endif #endif
#ifdef MAL_HAS_OPENAL #ifdef MAL_HAS_OPENAL
if (pDevice->pContext->backend == mal_backend_openal) { if (pDevice->pContext->backend == mal_backend_openal) {
...@@ -9145,7 +9145,7 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData) ...@@ -9145,7 +9145,7 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData)
{ {
mal_device* pDevice = (mal_device*)pData; mal_device* pDevice = (mal_device*)pData;
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
#ifdef MAL_WIN32 #ifdef MAL_WIN32
mal_CoInitializeEx(pDevice->pContext, NULL, 0); // 0 = COINIT_MULTITHREADED mal_CoInitializeEx(pDevice->pContext, NULL, 0); // 0 = COINIT_MULTITHREADED
#endif #endif
...@@ -9406,12 +9406,12 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, con ...@@ -9406,12 +9406,12 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, con
result = mal_context_init__alsa(pContext); result = mal_context_init__alsa(pContext);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
case mal_backend_oss: case mal_backend_oss:
{ {
result = mal_context_init__oss(pContext); result = mal_context_init__oss(pContext);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OPENSL #ifdef MAL_HAS_OPENSL
case mal_backend_opensl: case mal_backend_opensl:
{ {
...@@ -9454,7 +9454,7 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, con ...@@ -9454,7 +9454,7 @@ mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, con
mal_result mal_context_uninit(mal_context* pContext) mal_result mal_context_uninit(mal_context* pContext)
{ {
if (pContext == NULL) return MAL_INVALID_ARGS; if (pContext == NULL) return MAL_INVALID_ARGS;
switch (pContext->backend) { switch (pContext->backend) {
#ifdef MAL_HAS_WASAPI #ifdef MAL_HAS_WASAPI
case mal_backend_wasapi: case mal_backend_wasapi:
...@@ -9480,12 +9480,12 @@ mal_result mal_context_uninit(mal_context* pContext) ...@@ -9480,12 +9480,12 @@ mal_result mal_context_uninit(mal_context* pContext)
return mal_context_uninit__alsa(pContext); return mal_context_uninit__alsa(pContext);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
case mal_backend_oss: case mal_backend_oss:
{ {
return mal_context_uninit__oss(pContext); return mal_context_uninit__oss(pContext);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OPENSL #ifdef MAL_HAS_OPENSL
case mal_backend_opensl: case mal_backend_opensl:
{ {
...@@ -9556,12 +9556,12 @@ mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, ma ...@@ -9556,12 +9556,12 @@ mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, ma
return mal_enumerate_devices__alsa(pContext, type, pCount, pInfo); return mal_enumerate_devices__alsa(pContext, type, pCount, pInfo);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
case mal_backend_oss: case mal_backend_oss:
{ {
return mal_enumerate_devices__oss(pContext, type, pCount, pInfo); return mal_enumerate_devices__oss(pContext, type, pCount, pInfo);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OPENSL #ifdef MAL_HAS_OPENSL
case mal_backend_opensl: case mal_backend_opensl:
{ {
...@@ -9661,7 +9661,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi ...@@ -9661,7 +9661,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
pDevice->sampleRate = config.sampleRate; pDevice->sampleRate = config.sampleRate;
pDevice->bufferSizeInFrames = config.bufferSizeInFrames; pDevice->bufferSizeInFrames = config.bufferSizeInFrames;
pDevice->periods = config.periods; pDevice->periods = config.periods;
// The internal format, channel count and sample rate can be modified by the backend. // The internal format, channel count and sample rate can be modified by the backend.
pDevice->internalFormat = pDevice->format; pDevice->internalFormat = pDevice->format;
pDevice->internalChannels = pDevice->channels; pDevice->internalChannels = pDevice->channels;
...@@ -9721,12 +9721,12 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi ...@@ -9721,12 +9721,12 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
result = mal_device_init__alsa(pContext, type, pDeviceID, &config, pDevice); result = mal_device_init__alsa(pContext, type, pDeviceID, &config, pDevice);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
case mal_backend_oss: case mal_backend_oss:
{ {
result = mal_device_init__oss(pContext, type, pDeviceID, &config, pDevice); result = mal_device_init__oss(pContext, type, pDeviceID, &config, pDevice);
} break; } break;
#endif #endif
#ifdef MAL_HAS_OPENSL #ifdef MAL_HAS_OPENSL
case mal_backend_opensl: case mal_backend_opensl:
{ {
...@@ -9758,7 +9758,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi ...@@ -9758,7 +9758,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
return MAL_NO_BACKEND; // The error message will have been posted with mal_post_error() by the source of the error so don't bother calling it here. return MAL_NO_BACKEND; // The error message will have been posted with mal_post_error() by the source of the error so don't bother calling it here.
} }
// If the backend did not fill out a name for the device, try a generic method. // If the backend did not fill out a name for the device, try a generic method.
if (pDevice->name[0] == '\0') { if (pDevice->name[0] == '\0') {
...@@ -9807,7 +9807,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi ...@@ -9807,7 +9807,7 @@ mal_result mal_device_init(mal_context* pContext, mal_device_type type, mal_devi
mal_dsp_init(&dspConfig, mal_device__on_read_from_device, pDevice, &pDevice->dsp); mal_dsp_init(&dspConfig, mal_device__on_read_from_device, pDevice, &pDevice->dsp);
} }
// Some backends don't require the worker thread. // Some backends don't require the worker thread.
...@@ -9875,9 +9875,9 @@ void mal_device_uninit(mal_device* pDevice) ...@@ -9875,9 +9875,9 @@ void mal_device_uninit(mal_device* pDevice)
} }
#endif #endif
#ifdef MAL_HAS_OSS #ifdef MAL_HAS_OSS
if (pDevice->pContext->backend == mal_backend_oss) { if (pDevice->pContext->backend == mal_backend_oss) {
mal_device_uninit__oss(pDevice); mal_device_uninit__oss(pDevice);
} }
#endif #endif
#ifdef MAL_HAS_OPENSL #ifdef MAL_HAS_OPENSL
if (pDevice->pContext->backend == mal_backend_opensl) { if (pDevice->pContext->backend == mal_backend_opensl) {
...@@ -9925,7 +9925,7 @@ mal_result mal_device_start(mal_device* pDevice) ...@@ -9925,7 +9925,7 @@ mal_result mal_device_start(mal_device* pDevice)
{ {
if (pDevice == NULL) return mal_post_error(pDevice, "mal_device_start() called with invalid arguments (pDevice == NULL).", MAL_INVALID_ARGS); if (pDevice == NULL) return mal_post_error(pDevice, "mal_device_start() called with invalid arguments (pDevice == NULL).", MAL_INVALID_ARGS);
if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) return mal_post_error(pDevice, "mal_device_start() called for an uninitialized device.", MAL_DEVICE_NOT_INITIALIZED); if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) return mal_post_error(pDevice, "mal_device_start() called for an uninitialized device.", MAL_DEVICE_NOT_INITIALIZED);
mal_result result = MAL_ERROR; mal_result result = MAL_ERROR;
mal_mutex_lock(&pDevice->lock); mal_mutex_lock(&pDevice->lock);
{ {
...@@ -10394,11 +10394,11 @@ mal_uint32 mal_src_read_frames_linear(mal_src* pSRC, mal_uint32 frameCount, void ...@@ -10394,11 +10394,11 @@ mal_uint32 mal_src_read_frames_linear(mal_src* pSRC, mal_uint32 frameCount, void
pSRC->linear.isPrevFramesLoaded = MAL_FALSE; pSRC->linear.isPrevFramesLoaded = MAL_FALSE;
} }
} }
break; break;
} }
} }
mal_pcm_convert(pFramesOut, pSRC->config.formatOut, pFrame, mal_format_f32, 1 * pSRC->config.channels); mal_pcm_convert(pFramesOut, pSRC->config.formatOut, pFrame, mal_format_f32, 1 * pSRC->config.channels);
pFramesOut = (mal_uint8*)pFramesOut + (1 * pSRC->config.channels * mal_get_sample_size_in_bytes(pSRC->config.formatOut)); pFramesOut = (mal_uint8*)pFramesOut + (1 * pSRC->config.channels * mal_get_sample_size_in_bytes(pSRC->config.formatOut));
...@@ -10702,7 +10702,7 @@ static void mal_dsp_mix_channels__dec(float* pFramesOut, mal_uint32 channelsOut, ...@@ -10702,7 +10702,7 @@ static void mal_dsp_mix_channels__dec(float* pFramesOut, mal_uint32 channelsOut,
} }
} }
} else { } else {
// Blend mode is where we just use simple averaging to blend based on spacial locality. // Blend mode is where we just use simple averaging to blend based on spacial locality.
if (channelsOut == 1) { if (channelsOut == 1) {
for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) { for (mal_uint32 iFrame = 0; iFrame < frameCount; ++iFrame) {
float total = 0; float total = 0;
...@@ -11039,7 +11039,7 @@ mal_uint32 mal_dsp_read_frames_ex(mal_dsp* pDSP, mal_uint32 frameCount, void* pF ...@@ -11039,7 +11039,7 @@ mal_uint32 mal_dsp_read_frames_ex(mal_dsp* pDSP, mal_uint32 frameCount, void* pF
if (framesRead == 0) { if (framesRead == 0) {
break; break;
} }
// Channel mixing. The input format must be in f32 which may require a conversion. // Channel mixing. The input format must be in f32 which may require a conversion.
if (pDSP->config.channelsIn != pDSP->config.channelsOut) { if (pDSP->config.channelsIn != pDSP->config.channelsOut) {
...@@ -11061,7 +11061,7 @@ mal_uint32 mal_dsp_read_frames_ex(mal_dsp* pDSP, mal_uint32 frameCount, void* pF ...@@ -11061,7 +11061,7 @@ mal_uint32 mal_dsp_read_frames_ex(mal_dsp* pDSP, mal_uint32 frameCount, void* pF
mal_rearrange_channels(pFrames[iFrames] + (i * pDSP->config.channelsOut * mal_get_sample_size_in_bytes(pFramesFormat[iFrames])), pDSP->config.channelsOut, pDSP->channelShuffleTable, pFramesFormat[iFrames]); mal_rearrange_channels(pFrames[iFrames] + (i * pDSP->config.channelsOut * mal_get_sample_size_in_bytes(pFramesFormat[iFrames])), pDSP->config.channelsOut, pDSP->channelShuffleTable, pFramesFormat[iFrames]);
} }
} }
// Final conversion to output format. // Final conversion to output format.
mal_pcm_convert(pFramesOut, pDSP->config.formatOut, pFrames[iFrames], pFramesFormat[iFrames], framesRead * pDSP->config.channelsOut); mal_pcm_convert(pFramesOut, pDSP->config.formatOut, pFrames[iFrames], pFramesFormat[iFrames], framesRead * pDSP->config.channelsOut);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment