mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 00:34:03 +02:00
Merge branch 'dev' into dev-0.12
This commit is contained in:
+4
-1
@@ -1,6 +1,8 @@
|
||||
v0.11.22 - TBD
|
||||
=====================
|
||||
* Add `MA_SOUND_FLAG_LOOPING` and `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING` flags. These can be used to initialize sounds and resource managed data sources to loop by default. This is the recommended way to enable looping for streams. The `isLooping` config option in `ma_sound_config` and `ma_resource_manager_data_source_config` has been deprecated. If you are using those, you should switch to the new flag or else you'll get compiler errors when upgrading to a future version.
|
||||
* `ma_rb_commit_read()`, `ma_rb_commit_write()`, `ma_pcm_rb_commit_read()` and `ma_pcm_rb_commit_write()` no longer return `MA_AT_END`. The reason for this change is that there's no real notion of an "end" in a ring buffer which makes this result code confusing. In addition, it's possible for these functions to return something other than `MA_SUCCESS` when the operation completed successfully which adds to the confusion. The correct way to check if there is any more room in the ring buffer is to look at the frame count returned by `*rb_acquire_read/write()`.
|
||||
* The `ma_pcm_rb` data source implementation has been modified to pad output data with silence if there is not enough data in the ring buffer to fill the request. What this means is for an `ma_pcm_rb`, `ma_data_source_read_pcm_frames()` should no longer return a frame count of less than what you requested, and will therefore never return `MA_AT_END` which does not make sense for a ring buffer since it does not have the notion of an end. This change should make it much easier to use a ring buffer as the data source for a `ma_sound`.
|
||||
* Fix a bug relating to node detachment.
|
||||
* Fix a bug where amplification with `ma_device_set_master_volume()` does not work.
|
||||
* Fix a bug where sounds loaded with `MA_SOUND_FLAG_DECODE` do not loop.
|
||||
@@ -9,8 +11,9 @@ v0.11.22 - TBD
|
||||
* Web: Fix ScriptProcessorNode path when compiling with `--closure=1`. Note that the Audio Worklets path is not currently working due to the callback specified in `emscripten_create_wasm_audio_worklet_processor_async` never getting fired.
|
||||
* Web: Fix an error with the unlocked notification when compiling as C++.
|
||||
* Web: Fix a JavaScript error when initializing and then uninitializing a context before any interactivity.
|
||||
* AAudio: Fix an error where the device is silenced after rerouting. With this change, miniaudio will no longer give AAudio a hint to use your supplied period size which will therefore result in AAudio using its default latency configuration. If you want AAudio to try to use the period size you supply in the device config, which is the old behaviour, set `aaudio.allowSetBufferCapacity` to true in the device config. Note, however, if you do this you may end up with errors when rerouting between devices.
|
||||
* AAudio: The default minimum SDK version has been increased from 26 to 27 when enabling AAudio. If you need to support version 26, you can use `#define MA_AAUDIO_MIN_ANDROID_SDK_VERSION 26`.
|
||||
* AAudio: Fix ma_device_get_info() implementation
|
||||
* AAudio: Fix ma_device_get_info() implementation.
|
||||
* PulseAudio: Allow setting the channel map requested from PulseAudio in device configs
|
||||
|
||||
|
||||
|
||||
@@ -125,9 +125,6 @@ int main(int argc, char** argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make sure the sound is set to looping or else it'll stop if the ring buffer runs out of data. */
|
||||
ma_sound_set_looping(&sound, MA_TRUE);
|
||||
|
||||
/* Link the starting of the device and sound together. */
|
||||
ma_device_start(&device);
|
||||
ma_sound_start(&sound);
|
||||
|
||||
+56
-19
@@ -2919,7 +2919,7 @@ like the following:
|
||||
ma_resample_algorithm_linear);
|
||||
|
||||
ma_resampler resampler;
|
||||
ma_result result = ma_resampler_init(&config, &resampler);
|
||||
ma_result result = ma_resampler_init(&config, NULL, &resampler);
|
||||
if (result != MA_SUCCESS) {
|
||||
// An error occurred...
|
||||
}
|
||||
@@ -40117,6 +40117,10 @@ Web Audio Backend
|
||||
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 32)))
|
||||
#include <emscripten/webaudio.h>
|
||||
#define MA_SUPPORT_AUDIO_WORKLETS
|
||||
|
||||
#if (__EMSCRIPTEN_major__ > 3) || (__EMSCRIPTEN_major__ == 3 && (__EMSCRIPTEN_minor__ > 1 || (__EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 70)))
|
||||
#define MA_SUPPORT_AUDIO_WORKLETS_VARIABLE_BUFFER_SIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -40364,10 +40368,6 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const
|
||||
(void)paramCount;
|
||||
(void)pParams;
|
||||
|
||||
if (ma_device_get_state(pDevice) != ma_device_state_started) {
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
The Emscripten documentation says that it'll always be 128 frames being passed in. Hard coding it like that feels
|
||||
like a very bad idea to me. Even if it's hard coded in the backend, the API and documentation should always refer
|
||||
@@ -40376,7 +40376,20 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const
|
||||
Unfortunately the audio data is not interleaved so we'll need to convert it before we give the data to miniaudio
|
||||
for further processing.
|
||||
*/
|
||||
frameCount = 128;
|
||||
if (pDevice->type == ma_device_type_playback) {
|
||||
frameCount = pDevice->playback.internalPeriodSizeInFrames;
|
||||
} else {
|
||||
frameCount = pDevice->capture.internalPeriodSizeInFrames;
|
||||
}
|
||||
|
||||
if (ma_device_get_state(pDevice) != ma_device_state_started) {
|
||||
/* Fill the output buffer with zero to avoid a noise sound */
|
||||
for (int i = 0; i < outputCount; i += 1) {
|
||||
MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float));
|
||||
}
|
||||
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
if (inputCount > 0) {
|
||||
/* Input data needs to be interleaved before we hand it to the client. */
|
||||
@@ -40454,7 +40467,15 @@ static void ma_audio_worklet_processor_created__webaudio(EMSCRIPTEN_WEBAUDIO_T a
|
||||
Now that we know the channel count to use we can allocate the intermediary buffer. The
|
||||
intermediary buffer is used for interleaving and deinterleaving.
|
||||
*/
|
||||
intermediaryBufferSizeInFrames = 128;
|
||||
#if defined(MA_SUPPORT_AUDIO_WORKLETS_VARIABLE_BUFFER_SIZE)
|
||||
{
|
||||
intermediaryBufferSizeInFrames = (size_t)emscripten_audio_context_quantum_size(audioContext);
|
||||
}
|
||||
#else
|
||||
{
|
||||
intermediaryBufferSizeInFrames = 128;
|
||||
}
|
||||
#endif
|
||||
|
||||
pParameters->pDevice->webaudio.pIntermediaryBuffer = (float*)ma_malloc(intermediaryBufferSizeInFrames * (ma_uint32)channels * sizeof(float), &pParameters->pDevice->pContext->allocationCallbacks);
|
||||
if (pParameters->pDevice->webaudio.pIntermediaryBuffer == NULL) {
|
||||
@@ -56796,11 +56817,7 @@ MA_API ma_result ma_rb_commit_read(ma_rb* pRB, size_t sizeInBytes)
|
||||
|
||||
ma_atomic_exchange_32(&pRB->encodedReadOffset, ma_rb__construct_offset(newReadOffsetLoopFlag, newReadOffsetInBytes));
|
||||
|
||||
if (ma_rb_pointer_distance(pRB) == 0) {
|
||||
return MA_AT_END;
|
||||
} else {
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_rb_acquire_write(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut)
|
||||
@@ -56882,11 +56899,7 @@ MA_API ma_result ma_rb_commit_write(ma_rb* pRB, size_t sizeInBytes)
|
||||
|
||||
ma_atomic_exchange_32(&pRB->encodedWriteOffset, ma_rb__construct_offset(newWriteOffsetLoopFlag, newWriteOffsetInBytes));
|
||||
|
||||
if (ma_rb_pointer_distance(pRB) == 0) {
|
||||
return MA_AT_END;
|
||||
} else {
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
MA_API ma_result ma_rb_seek_read(ma_rb* pRB, size_t offsetInBytes)
|
||||
@@ -57109,6 +57122,16 @@ static ma_result ma_pcm_rb_data_source__on_read(ma_data_source* pDataSource, voi
|
||||
totalFramesRead += mappedFrameCount;
|
||||
}
|
||||
|
||||
/*
|
||||
There is no notion of an "end" in a ring buffer. If we didn't have enough data to fill the requested frame
|
||||
count we'll need to pad with silence. If we don't do this, totalFramesRead might equal 0 which will result
|
||||
in the data source layer at a higher level translating this to MA_AT_END which is incorrect for a ring buffer.
|
||||
*/
|
||||
if (totalFramesRead < frameCount) {
|
||||
ma_silence_pcm_frames(ma_offset_pcm_frames_ptr(pFramesOut, totalFramesRead, pRB->format, pRB->channels), (frameCount - totalFramesRead), pRB->format, pRB->channels);
|
||||
totalFramesRead = frameCount;
|
||||
}
|
||||
|
||||
*pFramesRead = totalFramesRead;
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
@@ -58250,6 +58273,13 @@ MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSo
|
||||
{
|
||||
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
|
||||
|
||||
if (pRangeBegInFrames != NULL) {
|
||||
*pRangeBegInFrames = 0;
|
||||
}
|
||||
if (pRangeEndInFrames != NULL) {
|
||||
*pRangeEndInFrames = 0;
|
||||
}
|
||||
|
||||
if (pDataSource == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -58294,6 +58324,13 @@ MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pD
|
||||
{
|
||||
const ma_data_source_base* pDataSourceBase = (const ma_data_source_base*)pDataSource;
|
||||
|
||||
if (pLoopBegInFrames != NULL) {
|
||||
*pLoopBegInFrames = 0;
|
||||
}
|
||||
if (pLoopEndInFrames != NULL) {
|
||||
*pLoopEndInFrames = 0;
|
||||
}
|
||||
|
||||
if (pDataSource == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -75351,8 +75388,8 @@ MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEng
|
||||
ma_allocation_callbacks_init_copy(&resourceManagerConfig.allocationCallbacks, &pEngine->allocationCallbacks);
|
||||
resourceManagerConfig.pVFS = engineConfig.pResourceManagerVFS;
|
||||
|
||||
/* The Emscripten build cannot use threads. */
|
||||
#if defined(MA_EMSCRIPTEN)
|
||||
/* The Emscripten build cannot use threads unless it's targeting pthreads. */
|
||||
#if defined(MA_EMSCRIPTEN) && !defined(__EMSCRIPTEN_PTHREADS__)
|
||||
{
|
||||
resourceManagerConfig.jobThreadCount = 0;
|
||||
resourceManagerConfig.flags |= MA_RESOURCE_MANAGER_FLAG_NO_THREADING;
|
||||
|
||||
@@ -172,8 +172,6 @@ int main(int argc, char** argv)
|
||||
int iarg;
|
||||
const char* pOutputFilePath;
|
||||
|
||||
print_usage();
|
||||
|
||||
/* Print help if requested. */
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
|
||||
@@ -236,19 +234,19 @@ int main(int argc, char** argv)
|
||||
result = ma_decoder_init_file(argv[1], &decoderConfig, &decoder);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to open input file. Check the file exists and the format is supported. Supported input formats:\n");
|
||||
#if defined(dr_opus_h)
|
||||
#if defined(ma_dr_opus_h)
|
||||
printf(" Opus\n");
|
||||
#endif
|
||||
#if defined(dr_mp3_h)
|
||||
#if defined(ma_dr_mp3_h)
|
||||
printf(" MP3\n");
|
||||
#endif
|
||||
#if defined(dr_flac_h)
|
||||
#if defined(ma_dr_flac_h)
|
||||
printf(" FLAC\n");
|
||||
#endif
|
||||
#if defined(STB_VORBIS_INCLUDE_STB_VORBIS_H)
|
||||
printf(" Vorbis\n");
|
||||
#endif
|
||||
#if defined(dr_wav_h)
|
||||
#if defined(ma_dr_wav_h)
|
||||
printf(" WAV\n");
|
||||
#endif
|
||||
return (int)result;
|
||||
|
||||
Reference in New Issue
Block a user