mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-30 12:14:03 +02:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea205fb7b0 | |||
| 26c11a7771 | |||
| 870ac8a22c | |||
| a1ea4438ee | |||
| 902c19d6ab | |||
| 64f14070a7 | |||
| 6d20ccb701 | |||
| 96ac03f184 | |||
| e913a6d1aa | |||
| de706d44b8 | |||
| 2bf7e03777 | |||
| ae25dbcdac | |||
| 4326fad97a | |||
| 937cd9c16c | |||
| d1f3715a08 | |||
| 9fe0970e20 | |||
| a74c2c78d9 | |||
| 189beb67fa | |||
| 7384bde372 |
+10
-2
@@ -1,8 +1,16 @@
|
||||
v0.11.15 - TBD
|
||||
==============
|
||||
v0.11.16 - 2023-05-15
|
||||
=====================
|
||||
* Fix a memory leak with `ma_sound_init_copy()`.
|
||||
* Improve performance of `ma_sound_init_*()` when using the `ASYNC | DECODE` flag combination.
|
||||
|
||||
|
||||
v0.11.15 - 2023-04-30
|
||||
=====================
|
||||
* Fix a bug where initialization of a duplex device fails on some backends.
|
||||
* Fix a bug in ma_gainer where smoothing isn't applied correctly thus resulting in glitching.
|
||||
* Add support for volume smoothing to sounds when changing the volume with `ma_sound_set_volume()`. To use this, you must configure it via the `volumeSmoothTimeInPCMFrames` member of ma_sound_config and use `ma_sound_init_ex()` to initialize your sound. Smoothing is disabled by default.
|
||||
* WASAPI: Fix a possible buffer overrun when initializing a device.
|
||||
* WASAPI: Make device initialization more robust by improving the handling of the querying of the internal data format.
|
||||
|
||||
|
||||
v0.11.14 - 2023-03-29
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<h4 align="center">A single file library for audio playback and capture.</h4>
|
||||
<h4 align="center">An audio playback and capture library in a single source file.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/9vpqbjU"><img src="https://img.shields.io/discord/712952679415939085?label=discord&logo=discord&style=flat-square" alt="discord"></a>
|
||||
@@ -12,14 +12,39 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#features">Features</a> -
|
||||
<a href="#examples">Examples</a> -
|
||||
<a href="#building">Building</a> -
|
||||
<a href="#documentation">Documentation</a> -
|
||||
<a href="#supported-platforms">Supported Platforms</a> -
|
||||
<a href="#backends">Backends</a> -
|
||||
<a href="#major-features">Major Features</a> -
|
||||
<a href="#building">Building</a>
|
||||
<a href="#license">License</a>
|
||||
</p>
|
||||
|
||||
miniaudio is written in C with no dependencies except the standard library and should compile clean on all major
|
||||
compilers without the need to install any additional development packages. All major desktop and mobile platforms
|
||||
are supported.
|
||||
|
||||
|
||||
Features
|
||||
========
|
||||
- Simple build system with no external dependencies.
|
||||
- Simple and flexible API.
|
||||
- Low-level API for direct access to raw audio data.
|
||||
- High-level API for sound management, mixing, effects and optional 3D spatialization.
|
||||
- Flexible node graph system for advanced mixing and effect processing.
|
||||
- Resource management for loading sound files.
|
||||
- Decoding, with built-in support for WAV, FLAC and MP3, in addition to being able to plug in custom decoders.
|
||||
- Encoding (WAV only).
|
||||
- Data conversion.
|
||||
- Resampling, including custom resamplers.
|
||||
- Channel mapping.
|
||||
- Basic generation of waveforms and noise.
|
||||
- Basic effects and filters.
|
||||
|
||||
Refer to the [Programming Manual](https://miniaud.io/docs/manual/) for a more complete description of
|
||||
available features in miniaudio.
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
@@ -27,27 +52,21 @@ This example shows one way to play a sound using the high level API.
|
||||
|
||||
```c
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "../miniaudio.h"
|
||||
#include "miniaudio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main()
|
||||
{
|
||||
ma_result result;
|
||||
ma_engine engine;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("No input file.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = ma_engine_init(NULL, &engine);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize audio engine.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ma_engine_play_sound(&engine, argv[1], NULL);
|
||||
ma_engine_play_sound(&engine, "sound.wav", NULL);
|
||||
|
||||
printf("Press Enter to quit...");
|
||||
getchar();
|
||||
@@ -62,7 +81,7 @@ This example shows how to decode and play a sound using the low level API.
|
||||
|
||||
```c
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "../miniaudio.h"
|
||||
#include "miniaudio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -128,6 +147,34 @@ int main(int argc, char** argv)
|
||||
More examples can be found in the [examples](examples) folder or online here: https://miniaud.io/docs/examples/
|
||||
|
||||
|
||||
Building
|
||||
========
|
||||
Do the following in one source file:
|
||||
```c
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
```
|
||||
Then just compile. There's no need to install any dependencies. On Windows and macOS there's no need to link
|
||||
to anything. On Linux just link to `-lpthread`, `-lm` and `-ldl`. On BSD just link to `-lpthread` and `-lm`.
|
||||
On iOS you need to compile as Objective-C.
|
||||
|
||||
If you get errors about undefined references to `__sync_val_compare_and_swap_8`, `__atomic_load_8`, etc. you
|
||||
need to link with `-latomic`.
|
||||
|
||||
If you prefer separate .h and .c files, you can find a split version of miniaudio in the extras/miniaudio_split
|
||||
folder. From here you can use miniaudio as a traditional .c and .h library - just add miniaudio.c to your source
|
||||
tree like any other source file and include miniaudio.h like a normal header. If you prefer compiling as a
|
||||
single translation unit (AKA unity builds), you can just #include the .c file in your main source file:
|
||||
```c
|
||||
#include "miniaudio.c"
|
||||
```
|
||||
Note that the split version is auto-generated using a tool and is based on the main file in the root directory.
|
||||
If you want to contribute, please make the change in the main file.
|
||||
|
||||
ABI compatibility is not guaranteed between versions so take care if compiling as a DLL/SO. The suggested way
|
||||
to integrate miniaudio is by adding it directly to your source tree.
|
||||
|
||||
|
||||
Documentation
|
||||
=============
|
||||
Online documentation can be found here: https://miniaud.io/docs/
|
||||
@@ -139,17 +186,20 @@ documentation is generated from this in-code documentation.
|
||||
|
||||
Supported Platforms
|
||||
===================
|
||||
- Windows, UWP
|
||||
- Windows
|
||||
- macOS, iOS
|
||||
- Linux
|
||||
- BSD
|
||||
- FreeBSD / OpenBSD / NetBSD
|
||||
- Android
|
||||
- Raspberry Pi
|
||||
- Emscripten / HTML5
|
||||
|
||||
miniaudio should compile clean on other platforms, but it will not include any support for playback or capture
|
||||
by default. To support that, you would need to implement a custom backend. You can do this without needing to
|
||||
modify the miniaudio source code. See the [custom_backend](examples/custom_backend.c) example.
|
||||
|
||||
Backends
|
||||
========
|
||||
--------
|
||||
- WASAPI
|
||||
- DirectSound
|
||||
- WinMM
|
||||
@@ -167,80 +217,6 @@ Backends
|
||||
- Custom
|
||||
|
||||
|
||||
Major Features
|
||||
==============
|
||||
- Your choice of either public domain or [MIT No Attribution](https://github.com/aws/mit-0).
|
||||
- Entirely contained within a single file for easy integration into your source tree.
|
||||
- No external dependencies except for the C standard library and backend libraries.
|
||||
- Written in C and compilable as C++, enabling miniaudio to work on almost all compilers.
|
||||
- Supports all major desktop and mobile platforms, with multiple backends for maximum compatibility.
|
||||
- A low level API with direct access to the raw audio data.
|
||||
- A high level API with sound management and effects, including 3D spatialization.
|
||||
- Supports playback, capture, full-duplex and loopback (WASAPI only).
|
||||
- Device enumeration for connecting to specific devices, not just defaults.
|
||||
- Connect to multiple devices at once.
|
||||
- Shared and exclusive mode on supported backends.
|
||||
- Resource management for loading and streaming sounds.
|
||||
- A node graph system for advanced mixing and effect processing.
|
||||
- Data conversion (sample format conversion, channel conversion and resampling).
|
||||
- Filters.
|
||||
- Biquads
|
||||
- Low-pass (first, second and high order)
|
||||
- High-pass (first, second and high order)
|
||||
- Band-pass (second and high order)
|
||||
- Effects.
|
||||
- Delay/Echo
|
||||
- Spatializer
|
||||
- Stereo Pan
|
||||
- Waveform generation (sine, square, triangle, sawtooth).
|
||||
- Noise generation (white, pink, Brownian).
|
||||
- Decoding
|
||||
- WAV
|
||||
- FLAC
|
||||
- MP3
|
||||
- Vorbis via stb_vorbis (not built in - must be included separately).
|
||||
- Custom
|
||||
- Encoding
|
||||
- WAV
|
||||
|
||||
Refer to the [Programming Manual](https://miniaud.io/docs/manual/) for a more complete description of
|
||||
available features in miniaudio.
|
||||
|
||||
|
||||
Building
|
||||
========
|
||||
Do the following in one source file:
|
||||
```c
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
```
|
||||
Then just compile. There's no need to install any dependencies. On Windows and macOS there's no need to link
|
||||
to anything. On Linux just link to -lpthread, -lm and -ldl. On BSD just link to -lpthread and -lm. On iOS you
|
||||
need to compile as Objective-C.
|
||||
|
||||
If you prefer separate .h and .c files, you can find a split version of miniaudio in the extras/miniaudio_split
|
||||
folder. From here you can use miniaudio as a traditional .c and .h library - just add miniaudio.c to your source
|
||||
tree like any other source file and include miniaudio.h like a normal header. If you prefer compiling as a
|
||||
single translation unit (AKA unity builds), you can just #include the .c file in your main source file:
|
||||
```c
|
||||
#include "miniaudio.c"
|
||||
```
|
||||
Note that the split version is auto-generated using a tool and is based on the main file in the root directory.
|
||||
If you want to contribute, please make the change in the main file.
|
||||
|
||||
Vorbis Decoding
|
||||
---------------
|
||||
Vorbis decoding is enabled via stb_vorbis. To use it, you need to include the header section of stb_vorbis
|
||||
before the implementation of miniaudio. You can enable Vorbis by doing the following:
|
||||
|
||||
```c
|
||||
#define STB_VORBIS_HEADER_ONLY
|
||||
#include "extras/stb_vorbis.c" /* Enables Vorbis decoding. */
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
|
||||
/* stb_vorbis implementation must come after the implementation of miniaudio. */
|
||||
#undef STB_VORBIS_HEADER_ONLY
|
||||
#include "extras/stb_vorbis.c"
|
||||
```
|
||||
License
|
||||
=======
|
||||
Your choice of either public domain or [MIT No Attribution](https://github.com/aws/mit-0).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||
miniaudio - v0.11.15 - 2023-04-30
|
||||
miniaudio - v0.11.16 - 2023-05-15
|
||||
|
||||
David Reid - mackron@gmail.com
|
||||
|
||||
@@ -7101,22 +7101,22 @@ MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
|
||||
|
||||
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
|
||||
#if !defined(WINAPI_FAMILY) || (defined(WINAPI_FAMILY) && (defined(WINAPI_FAMILY_DESKTOP_APP) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
handle = (ma_handle)LoadLibraryA(filename);
|
||||
#ifdef MA_WIN32
|
||||
/* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
|
||||
#if !defined(MA_WIN32_UWP)
|
||||
handle = (ma_handle)LoadLibraryA(filename);
|
||||
#else
|
||||
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
|
||||
WCHAR filenameW[4096];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
|
||||
handle = NULL;
|
||||
} else {
|
||||
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
|
||||
WCHAR filenameW[4096];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
|
||||
handle = NULL;
|
||||
} else {
|
||||
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
|
||||
}
|
||||
handle = (ma_handle)dlopen(filename, RTLD_NOW);
|
||||
#endif
|
||||
#else
|
||||
handle = (ma_handle)dlopen(filename, RTLD_NOW);
|
||||
#endif
|
||||
|
||||
/*
|
||||
I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
|
||||
@@ -7139,11 +7139,11 @@ MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
|
||||
MA_API void ma_dlclose(ma_context* pContext, ma_handle handle)
|
||||
{
|
||||
#ifndef MA_NO_RUNTIME_LINKING
|
||||
#ifdef _WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose((void*)handle);
|
||||
#endif
|
||||
#ifdef MA_WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose((void*)handle);
|
||||
#endif
|
||||
|
||||
(void)pContext;
|
||||
#else
|
||||
@@ -8466,7 +8466,7 @@ WIN32 COMMON
|
||||
|
||||
*******************************************************************************/
|
||||
#if defined(MA_WIN32)
|
||||
#if defined(MA_WIN32_DESKTOP)
|
||||
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
|
||||
#define ma_CoInitializeEx(pContext, pvReserved, dwCoInit) ((pContext->win32.CoInitializeEx) ? ((MA_PFN_CoInitializeEx)pContext->win32.CoInitializeEx)(pvReserved, dwCoInit) : ((MA_PFN_CoInitialize)pContext->win32.CoInitialize)(pvReserved))
|
||||
#define ma_CoUninitialize(pContext) ((MA_PFN_CoUninitialize)pContext->win32.CoUninitialize)()
|
||||
#define ma_CoCreateInstance(pContext, rclsid, pUnkOuter, dwClsContext, riid, ppv) ((MA_PFN_CoCreateInstance)pContext->win32.CoCreateInstance)(rclsid, pUnkOuter, dwClsContext, riid, ppv)
|
||||
@@ -9526,13 +9526,9 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged
|
||||
/*ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "IMMNotificationClient_OnDefaultDeviceChanged(dataFlow=%d, role=%d, pDefaultDeviceID=%S)\n", dataFlow, role, (pDefaultDeviceID != NULL) ? pDefaultDeviceID : L"(NULL)");*/
|
||||
#endif
|
||||
|
||||
/* We only ever use the eConsole role in miniaudio. */
|
||||
if (role != ma_eConsole) {
|
||||
ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Stream rerouting: role != eConsole\n");
|
||||
return S_OK;
|
||||
}
|
||||
(void)role;
|
||||
|
||||
/* We only care about devices with the same data flow and role as the current device. */
|
||||
/* We only care about devices with the same data flow as the current device. */
|
||||
if ((pThis->pDevice->type == ma_device_type_playback && dataFlow != ma_eRender) ||
|
||||
(pThis->pDevice->type == ma_device_type_capture && dataFlow != ma_eCapture) ||
|
||||
(pThis->pDevice->type == ma_device_type_loopback && dataFlow != ma_eRender)) {
|
||||
@@ -11577,7 +11573,7 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
|
||||
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex || pDevice->type == ma_device_type_loopback) {
|
||||
hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture);
|
||||
if (FAILED(hr)) {
|
||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device.");
|
||||
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device. HRESULT = %d.", (int)hr);
|
||||
return ma_result_from_HRESULT(hr);
|
||||
}
|
||||
|
||||
@@ -11587,7 +11583,7 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
|
||||
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
|
||||
hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
|
||||
if (FAILED(hr)) {
|
||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device.");
|
||||
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device. HRESULT = %d.", (int)hr);
|
||||
return ma_result_from_HRESULT(hr);
|
||||
}
|
||||
|
||||
@@ -29618,11 +29614,15 @@ static ma_bool32 ma_device__is_initialized(ma_device* pDevice)
|
||||
static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
|
||||
{
|
||||
/* For some reason UWP complains when CoUninitialize() is called. I'm just not going to call it on UWP. */
|
||||
#ifdef MA_WIN32_DESKTOP
|
||||
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
|
||||
ma_CoUninitialize(pContext);
|
||||
ma_dlclose(pContext, pContext->win32.hUser32DLL);
|
||||
|
||||
#if defined(MA_WIN32_DESKTOP)
|
||||
ma_dlclose(pContext, pContext->win32.hUser32DLL);
|
||||
ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
|
||||
#endif
|
||||
|
||||
ma_dlclose(pContext, pContext->win32.hOle32DLL);
|
||||
ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
|
||||
#else
|
||||
(void)pContext;
|
||||
#endif
|
||||
@@ -29632,7 +29632,29 @@ static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
|
||||
|
||||
static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
|
||||
{
|
||||
#ifdef MA_WIN32_DESKTOP
|
||||
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
|
||||
#if defined(MA_WIN32_DESKTOP)
|
||||
/* User32.dll */
|
||||
pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
|
||||
if (pContext->win32.hUser32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
|
||||
pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
|
||||
|
||||
|
||||
/* Advapi32.dll */
|
||||
pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
|
||||
if (pContext->win32.hAdvapi32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
|
||||
pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
|
||||
pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
|
||||
#endif
|
||||
|
||||
/* Ole32.dll */
|
||||
pContext->win32.hOle32DLL = ma_dlopen(pContext, "ole32.dll");
|
||||
if (pContext->win32.hOle32DLL == NULL) {
|
||||
@@ -29646,27 +29668,6 @@ static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
|
||||
pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoTaskMemFree");
|
||||
pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "PropVariantClear");
|
||||
pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "StringFromGUID2");
|
||||
|
||||
|
||||
/* User32.dll */
|
||||
pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
|
||||
if (pContext->win32.hUser32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
|
||||
pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
|
||||
|
||||
|
||||
/* Advapi32.dll */
|
||||
pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
|
||||
if (pContext->win32.hAdvapi32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
|
||||
pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
|
||||
pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
|
||||
#else
|
||||
(void)pContext; /* Unused. */
|
||||
#endif
|
||||
@@ -56583,7 +56584,12 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
|
||||
job.data.resourceManager.loadDataBufferNode.pInitFence = pInitFence;
|
||||
job.data.resourceManager.loadDataBufferNode.pDoneFence = pDoneFence;
|
||||
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
result = ma_job_process(&job);
|
||||
} else {
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
}
|
||||
|
||||
if (result != MA_SUCCESS) {
|
||||
/* Failed to post job. Probably ran out of memory. */
|
||||
ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER_NODE job. %s.\n", ma_result_description(result));
|
||||
@@ -56596,12 +56602,13 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
|
||||
if (pDoneFence != NULL) { ma_fence_release(pDoneFence); }
|
||||
|
||||
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
ma_resource_manager_inline_notification_init(pResourceManager, pInitNotification);
|
||||
ma_resource_manager_inline_notification_uninit(pInitNotification);
|
||||
} else {
|
||||
/* These will have been freed by the job thread, but with WAIT_INIT they will already have happend sinced the job has already been handled. */
|
||||
ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
|
||||
ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
|
||||
}
|
||||
|
||||
ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
|
||||
ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
|
||||
|
||||
ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBufferNode);
|
||||
ma_free(pDataBufferNode, &pResourceManager->config.allocationCallbacks);
|
||||
|
||||
@@ -57040,7 +57047,13 @@ static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_ma
|
||||
job.data.resourceManager.loadDataBuffer.loopPointEndInPCMFrames = pConfig->loopPointEndInPCMFrames;
|
||||
job.data.resourceManager.loadDataBuffer.isLooping = pConfig->isLooping;
|
||||
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
/* If we need to wait for initialization to complete we can just process the job in place. */
|
||||
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
result = ma_job_process(&job);
|
||||
} else {
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
}
|
||||
|
||||
if (result != MA_SUCCESS) {
|
||||
/* We failed to post the job. Most likely there isn't enough room in the queue's buffer. */
|
||||
ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER job. %s.\n", ma_result_description(result));
|
||||
@@ -58739,6 +58752,12 @@ done:
|
||||
|
||||
/* Increment the node's execution pointer so that the next jobs can be processed. This is how we keep decoding of pages in-order. */
|
||||
c89atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1);
|
||||
|
||||
/* A busy result should be considered successful from the point of view of the job system. */
|
||||
if (result == MA_BUSY) {
|
||||
result = MA_SUCCESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -64090,7 +64109,7 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
|
||||
|
||||
/*
|
||||
We need to make a clone of the data source. If the data source is not a data buffer (i.e. a stream)
|
||||
the this will fail.
|
||||
this will fail.
|
||||
*/
|
||||
pSound->pResourceManagerDataSource = (ma_resource_manager_data_source*)ma_malloc(sizeof(*pSound->pResourceManagerDataSource), &pEngine->allocationCallbacks);
|
||||
if (pSound->pResourceManagerDataSource == NULL) {
|
||||
@@ -64118,6 +64137,9 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Make sure the sound is marked as the owner of the data source or else it will never get uninitialized. */
|
||||
pSound->ownsDataSource = MA_TRUE;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||
miniaudio - v0.11.15 - 2023-04-30
|
||||
miniaudio - v0.11.16 - 2023-05-15
|
||||
|
||||
David Reid - mackron@gmail.com
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
|
||||
#define MA_VERSION_MAJOR 0
|
||||
#define MA_VERSION_MINOR 11
|
||||
#define MA_VERSION_REVISION 15
|
||||
#define MA_VERSION_REVISION 16
|
||||
#define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
+84
-62
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
|
||||
miniaudio - v0.11.15 - 2023-04-30
|
||||
miniaudio - v0.11.16 - 2023-05-15
|
||||
|
||||
David Reid - mackron@gmail.com
|
||||
|
||||
@@ -3722,7 +3722,7 @@ extern "C" {
|
||||
|
||||
#define MA_VERSION_MAJOR 0
|
||||
#define MA_VERSION_MINOR 11
|
||||
#define MA_VERSION_REVISION 15
|
||||
#define MA_VERSION_REVISION 16
|
||||
#define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
@@ -18455,22 +18455,22 @@ MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
|
||||
|
||||
ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_DEBUG, "Loading library: %s\n", filename);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
|
||||
#if !defined(WINAPI_FAMILY) || (defined(WINAPI_FAMILY) && (defined(WINAPI_FAMILY_DESKTOP_APP) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||
handle = (ma_handle)LoadLibraryA(filename);
|
||||
#ifdef MA_WIN32
|
||||
/* From MSDN: Desktop applications cannot use LoadPackagedLibrary; if a desktop application calls this function it fails with APPMODEL_ERROR_NO_PACKAGE.*/
|
||||
#if !defined(MA_WIN32_UWP)
|
||||
handle = (ma_handle)LoadLibraryA(filename);
|
||||
#else
|
||||
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
|
||||
WCHAR filenameW[4096];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
|
||||
handle = NULL;
|
||||
} else {
|
||||
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
/* *sigh* It appears there is no ANSI version of LoadPackagedLibrary()... */
|
||||
WCHAR filenameW[4096];
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, sizeof(filenameW)) == 0) {
|
||||
handle = NULL;
|
||||
} else {
|
||||
handle = (ma_handle)LoadPackagedLibrary(filenameW, 0);
|
||||
}
|
||||
handle = (ma_handle)dlopen(filename, RTLD_NOW);
|
||||
#endif
|
||||
#else
|
||||
handle = (ma_handle)dlopen(filename, RTLD_NOW);
|
||||
#endif
|
||||
|
||||
/*
|
||||
I'm not considering failure to load a library an error nor a warning because seamlessly falling through to a lower-priority
|
||||
@@ -18493,11 +18493,11 @@ MA_API ma_handle ma_dlopen(ma_context* pContext, const char* filename)
|
||||
MA_API void ma_dlclose(ma_context* pContext, ma_handle handle)
|
||||
{
|
||||
#ifndef MA_NO_RUNTIME_LINKING
|
||||
#ifdef _WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose((void*)handle);
|
||||
#endif
|
||||
#ifdef MA_WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose((void*)handle);
|
||||
#endif
|
||||
|
||||
(void)pContext;
|
||||
#else
|
||||
@@ -19820,7 +19820,7 @@ WIN32 COMMON
|
||||
|
||||
*******************************************************************************/
|
||||
#if defined(MA_WIN32)
|
||||
#if defined(MA_WIN32_DESKTOP)
|
||||
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
|
||||
#define ma_CoInitializeEx(pContext, pvReserved, dwCoInit) ((pContext->win32.CoInitializeEx) ? ((MA_PFN_CoInitializeEx)pContext->win32.CoInitializeEx)(pvReserved, dwCoInit) : ((MA_PFN_CoInitialize)pContext->win32.CoInitialize)(pvReserved))
|
||||
#define ma_CoUninitialize(pContext) ((MA_PFN_CoUninitialize)pContext->win32.CoUninitialize)()
|
||||
#define ma_CoCreateInstance(pContext, rclsid, pUnkOuter, dwClsContext, riid, ppv) ((MA_PFN_CoCreateInstance)pContext->win32.CoCreateInstance)(rclsid, pUnkOuter, dwClsContext, riid, ppv)
|
||||
@@ -20880,13 +20880,9 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDefaultDeviceChanged
|
||||
/*ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "IMMNotificationClient_OnDefaultDeviceChanged(dataFlow=%d, role=%d, pDefaultDeviceID=%S)\n", dataFlow, role, (pDefaultDeviceID != NULL) ? pDefaultDeviceID : L"(NULL)");*/
|
||||
#endif
|
||||
|
||||
/* We only ever use the eConsole role in miniaudio. */
|
||||
if (role != ma_eConsole) {
|
||||
ma_log_postf(ma_device_get_log(pThis->pDevice), MA_LOG_LEVEL_DEBUG, "[WASAPI] Stream rerouting: role != eConsole\n");
|
||||
return S_OK;
|
||||
}
|
||||
(void)role;
|
||||
|
||||
/* We only care about devices with the same data flow and role as the current device. */
|
||||
/* We only care about devices with the same data flow as the current device. */
|
||||
if ((pThis->pDevice->type == ma_device_type_playback && dataFlow != ma_eRender) ||
|
||||
(pThis->pDevice->type == ma_device_type_capture && dataFlow != ma_eCapture) ||
|
||||
(pThis->pDevice->type == ma_device_type_loopback && dataFlow != ma_eRender)) {
|
||||
@@ -22931,7 +22927,7 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
|
||||
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex || pDevice->type == ma_device_type_loopback) {
|
||||
hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientCapture);
|
||||
if (FAILED(hr)) {
|
||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device.");
|
||||
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal capture device. HRESULT = %d.", (int)hr);
|
||||
return ma_result_from_HRESULT(hr);
|
||||
}
|
||||
|
||||
@@ -22941,7 +22937,7 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
|
||||
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
|
||||
hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
|
||||
if (FAILED(hr)) {
|
||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device.");
|
||||
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device. HRESULT = %d.", (int)hr);
|
||||
return ma_result_from_HRESULT(hr);
|
||||
}
|
||||
|
||||
@@ -40972,11 +40968,15 @@ static ma_bool32 ma_device__is_initialized(ma_device* pDevice)
|
||||
static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
|
||||
{
|
||||
/* For some reason UWP complains when CoUninitialize() is called. I'm just not going to call it on UWP. */
|
||||
#ifdef MA_WIN32_DESKTOP
|
||||
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
|
||||
ma_CoUninitialize(pContext);
|
||||
ma_dlclose(pContext, pContext->win32.hUser32DLL);
|
||||
|
||||
#if defined(MA_WIN32_DESKTOP)
|
||||
ma_dlclose(pContext, pContext->win32.hUser32DLL);
|
||||
ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
|
||||
#endif
|
||||
|
||||
ma_dlclose(pContext, pContext->win32.hOle32DLL);
|
||||
ma_dlclose(pContext, pContext->win32.hAdvapi32DLL);
|
||||
#else
|
||||
(void)pContext;
|
||||
#endif
|
||||
@@ -40986,7 +40986,29 @@ static ma_result ma_context_uninit_backend_apis__win32(ma_context* pContext)
|
||||
|
||||
static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
|
||||
{
|
||||
#ifdef MA_WIN32_DESKTOP
|
||||
#if defined(MA_WIN32_DESKTOP) || defined(MA_WIN32_GDK)
|
||||
#if defined(MA_WIN32_DESKTOP)
|
||||
/* User32.dll */
|
||||
pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
|
||||
if (pContext->win32.hUser32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
|
||||
pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
|
||||
|
||||
|
||||
/* Advapi32.dll */
|
||||
pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
|
||||
if (pContext->win32.hAdvapi32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
|
||||
pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
|
||||
pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
|
||||
#endif
|
||||
|
||||
/* Ole32.dll */
|
||||
pContext->win32.hOle32DLL = ma_dlopen(pContext, "ole32.dll");
|
||||
if (pContext->win32.hOle32DLL == NULL) {
|
||||
@@ -41000,27 +41022,6 @@ static ma_result ma_context_init_backend_apis__win32(ma_context* pContext)
|
||||
pContext->win32.CoTaskMemFree = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "CoTaskMemFree");
|
||||
pContext->win32.PropVariantClear = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "PropVariantClear");
|
||||
pContext->win32.StringFromGUID2 = (ma_proc)ma_dlsym(pContext, pContext->win32.hOle32DLL, "StringFromGUID2");
|
||||
|
||||
|
||||
/* User32.dll */
|
||||
pContext->win32.hUser32DLL = ma_dlopen(pContext, "user32.dll");
|
||||
if (pContext->win32.hUser32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.GetForegroundWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetForegroundWindow");
|
||||
pContext->win32.GetDesktopWindow = (ma_proc)ma_dlsym(pContext, pContext->win32.hUser32DLL, "GetDesktopWindow");
|
||||
|
||||
|
||||
/* Advapi32.dll */
|
||||
pContext->win32.hAdvapi32DLL = ma_dlopen(pContext, "advapi32.dll");
|
||||
if (pContext->win32.hAdvapi32DLL == NULL) {
|
||||
return MA_FAILED_TO_INIT_BACKEND;
|
||||
}
|
||||
|
||||
pContext->win32.RegOpenKeyExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegOpenKeyExA");
|
||||
pContext->win32.RegCloseKey = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegCloseKey");
|
||||
pContext->win32.RegQueryValueExA = (ma_proc)ma_dlsym(pContext, pContext->win32.hAdvapi32DLL, "RegQueryValueExA");
|
||||
#else
|
||||
(void)pContext; /* Unused. */
|
||||
#endif
|
||||
@@ -67937,7 +67938,12 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
|
||||
job.data.resourceManager.loadDataBufferNode.pInitFence = pInitFence;
|
||||
job.data.resourceManager.loadDataBufferNode.pDoneFence = pDoneFence;
|
||||
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
result = ma_job_process(&job);
|
||||
} else {
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
}
|
||||
|
||||
if (result != MA_SUCCESS) {
|
||||
/* Failed to post job. Probably ran out of memory. */
|
||||
ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER_NODE job. %s.\n", ma_result_description(result));
|
||||
@@ -67950,12 +67956,13 @@ static ma_result ma_resource_manager_data_buffer_node_acquire_critical_section(m
|
||||
if (pDoneFence != NULL) { ma_fence_release(pDoneFence); }
|
||||
|
||||
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
ma_resource_manager_inline_notification_init(pResourceManager, pInitNotification);
|
||||
ma_resource_manager_inline_notification_uninit(pInitNotification);
|
||||
} else {
|
||||
/* These will have been freed by the job thread, but with WAIT_INIT they will already have happend sinced the job has already been handled. */
|
||||
ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
|
||||
ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
|
||||
}
|
||||
|
||||
ma_free(pFilePathCopy, &pResourceManager->config.allocationCallbacks);
|
||||
ma_free(pFilePathWCopy, &pResourceManager->config.allocationCallbacks);
|
||||
|
||||
ma_resource_manager_data_buffer_node_remove(pResourceManager, pDataBufferNode);
|
||||
ma_free(pDataBufferNode, &pResourceManager->config.allocationCallbacks);
|
||||
|
||||
@@ -68394,7 +68401,13 @@ static ma_result ma_resource_manager_data_buffer_init_ex_internal(ma_resource_ma
|
||||
job.data.resourceManager.loadDataBuffer.loopPointEndInPCMFrames = pConfig->loopPointEndInPCMFrames;
|
||||
job.data.resourceManager.loadDataBuffer.isLooping = pConfig->isLooping;
|
||||
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
/* If we need to wait for initialization to complete we can just process the job in place. */
|
||||
if ((flags & MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT) != 0) {
|
||||
result = ma_job_process(&job);
|
||||
} else {
|
||||
result = ma_resource_manager_post_job(pResourceManager, &job);
|
||||
}
|
||||
|
||||
if (result != MA_SUCCESS) {
|
||||
/* We failed to post the job. Most likely there isn't enough room in the queue's buffer. */
|
||||
ma_log_postf(ma_resource_manager_get_log(pResourceManager), MA_LOG_LEVEL_ERROR, "Failed to post MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER job. %s.\n", ma_result_description(result));
|
||||
@@ -70093,6 +70106,12 @@ done:
|
||||
|
||||
/* Increment the node's execution pointer so that the next jobs can be processed. This is how we keep decoding of pages in-order. */
|
||||
c89atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1);
|
||||
|
||||
/* A busy result should be considered successful from the point of view of the job system. */
|
||||
if (result == MA_BUSY) {
|
||||
result = MA_SUCCESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -75444,7 +75463,7 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
|
||||
|
||||
/*
|
||||
We need to make a clone of the data source. If the data source is not a data buffer (i.e. a stream)
|
||||
the this will fail.
|
||||
this will fail.
|
||||
*/
|
||||
pSound->pResourceManagerDataSource = (ma_resource_manager_data_source*)ma_malloc(sizeof(*pSound->pResourceManagerDataSource), &pEngine->allocationCallbacks);
|
||||
if (pSound->pResourceManagerDataSource == NULL) {
|
||||
@@ -75472,6 +75491,9 @@ MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistin
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Make sure the sound is marked as the owner of the data source or else it will never get uninitialized. */
|
||||
pSound->ownsDataSource = MA_TRUE;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user