Commit aba41c9e authored by David Reid's avatar David Reid

Add release notes for version 0.10.

parent 2e1958ff
...@@ -8,136 +8,114 @@ https://github.com/dr-soft/miniaudio ...@@ -8,136 +8,114 @@ https://github.com/dr-soft/miniaudio
*/ */
/* /*
MAJOR CHANGES IN VERSION 0.9 RELEASE NOTES - VERSION 0.10
============================ ============================
Version 0.9 includes major API changes, centered mostly around full-duplex and the rebrand to "miniaudio". Before I go into Version 0.10 includes major API changes and refactoring, mostly concerned with the data conversion system. Data conversion
detail about the major changes I would like to apologize. I know it's annoying dealing with breaking API changes, but I think is performed internally to convert audio data between the format requested when initializing the `ma_device` object and the
it's best to get these changes out of the way now while the library is still relatively young and unknown. format of the internal device used by the backend. The same applies to the `ma_decoder` object. The previous design has
several design flaws and missing features which necessitated a complete redesign.
There's been a lot of refactoring with this release so there's a good chance a few bugs have been introduced. I apologize in
advance for this. You may want to hold off on upgrading for the short term if you're worried. If mini_al v0.8.14 works for
you, and you don't need full-duplex support, you can avoid upgrading (though you won't be getting future bug fixes).
Changes to Data Conversion
--------------------------
The previous data conversion system used callbacks to deliver input data for conversion. This design works well in some
specific situations, but in other situations it has some major readability and maintenance issues. The decision was made to
replace this with a more iterative approach where you just pass in a pointer to the input data directly rather than dealing
with a callback.
Rebranding to "miniaudio" The following are the data conversion APIs that have been removed and their replacements:
-------------------------
The decision was made to rename mini_al to miniaudio. Don't worry, it's the same project. The reason for this is simple:
1) Having the word "audio" in the title makes it immediately clear that the library is related to audio; and - ma_format_converter -> ma_convert_pcm_frames_format()
2) I don't like the look of the underscore. - ma_channel_router -> ma_channel_converter
- ma_src -> ma_resampler
- ma_pcm_converter -> ma_data_converter
This rebrand has necessitated a change in namespace from "mal" to "ma". I know this is annoying, and I apologize, but it's The previous conversion APIs accepted a callback in their configs. There are no longer any callbacks to deal with. Instead you
better to get this out of the road now rather than later. Also, since there are necessary API changes for full-duplex support just pass the data into the `*_process_pcm_frames()` function as a pointer to a buffer.
I think it's better to just get the namespace change over and done with at the same time as the full-duplex changes. I'm hoping
this will be the last of the major API changes. Fingers crossed!
The implementation define is now "#define MINIAUDIO_IMPLEMENTATION". You can also use "#define MA_IMPLEMENTATION" if that's The simplest aspect of data conversion is sample format conversion. To convert between two formats, just call
your preference. `ma_convert_pcm_frames_format()`. Channel conversion is also simple which you can do with `ma_channel_router` via
`ma_channel_router_process_pcm_frames().
Resampling is more complicated because the number of output frames that are processed is different to the number of input
frames that are consumed. When you call `ma_resampler_process_pcm_frames()` you need to pass in the number of input frames
available for processing and the number of output frames you want to output. Upon returning they will receive the number of
input frames that were consumed and the number of output frames that were generated.
Full-Duplex Support The `ma_data_converter` API is a wrapper around format, channel and sample rate conversion and handles all of the data
------------------- conversion you'll need which probably makes it the best option if you need to do data conversion.
The major feature added to version 0.9 is full-duplex. This has necessitated a few API changes.
1) The data callback has now changed. Previously there was one type of callback for playback and another for capture. I wanted In addition to changes to the API design, a few other changes have been made to the data conversion pipeline:
to avoid a third callback just for full-duplex so the decision was made to break this API and unify the callbacks. Now,
there is just one callback which is the same for all three modes (playback, capture, duplex). The new callback looks like
the following:
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount); - The sinc resampler has been removed. This was completely broken and never actually worked properly.
- The linear resampler can now uses low-pass filtering to remove aliasing. The quality of the low-pass filter can be
controlled via the resampler config with the `lpcCount` option, which has a maximum value of MA_MAX_RESAMPLER_LPF_FILTERS.
- Data conversion now supports s16 natively which runs through a fixed point pipeline. Previously everything needed to be
converted to floating point before processing, whereas now both s16 and f32 are natively supported. Other formats still
require conversion to either s16 or f32 prior to processing, however `ma_data_converter` will handle this for you.
This callback allows you to move data straight out of the input buffer and into the output buffer in full-duplex mode. In
playback-only mode, pInput will be null. Likewise, pOutput will be null in capture-only mode. The sample count is no longer
returned from the callback since it's not necessary for miniaudio anymore.
2) The device config needed to change in order to support full-duplex. Full-duplex requires the ability to allow the client Custom Memory Allocators
to choose a different PCM format for the playback and capture sides. The old ma_device_config object simply did not allow ------------------------
this and needed to change. With these changes you now specify the device ID, format, channels, channel map and share mode miniaudio has always supported macro level customization to memory allocation via MA_MALLOC, MA_REALLOC and MA_FREE, however
on a per-playback and per-capture basis (see example below). The sample rate must be the same for playback and capture. some scenarios require more flexibility by allowing a user data pointer to be passed to the custom allocation routines. Support
for this has been added to version 0.10 via the `ma_allocation_callbacks` structure. Anything making use of heap allocations
has been updated to accept this new structure.
Since the device config API has changed I have also decided to take the opportunity to simplify device initialization. Now, The `ma_device_config` structure has been updated with a new member called `allocationCallbacks`. Leaving this set to it's
the device ID, device type and callback user data are set in the config. ma_device_init() is now simplified down to taking defaults returned by `ma_device_config_init()` will cause it to use defaults. Likewise, The `ma_decoder_config` structure has
just the context, device config and a pointer to the device object being initialized. The rationale for this change is that been updated in the same way, and leaving everything as-is after `ma_decoder_config_init()` will cause it to use defaults.
it just makes more sense to me that these are set as part of the config like everything else.
Example device initialization: The following APIs have been updated to take a pointer to a `ma_allocation_callbacks` object. Setting this parameter to NULL
will cause it to use defaults. Otherwise they will use the relevant callback in the structure.
ma_device_config config = ma_device_config_init(ma_device_type_duplex); // Or ma_device_type_playback or ma_device_type_capture. - ma_malloc()
config.playback.pDeviceID = &myPlaybackDeviceID; // Or NULL for the default playback device. - ma_realloc()
config.playback.format = ma_format_f32; - ma_free()
config.playback.channels = 2; - ma_aligned_malloc()
config.capture.pDeviceID = &myCaptureDeviceID; // Or NULL for the default capture device. - ma_aligned_free()
config.capture.format = ma_format_s16; - ma_rb_init() / ma_rb_init_ex()
config.capture.channels = 1; - ma_pcm_rb_init() / ma_pcm_rb_init_ex()
config.sampleRate = 44100;
config.dataCallback = data_callback;
config.pUserData = &myUserData;
result = ma_device_init(&myContext, &config, &device); Note that you can continue to use MA_MALLOC, MA_REALLOC and MA_FREE as per normal. These will continue to be used by default if
if (result != MA_SUCCESS) { you do not specify custom allocation callbacks.
... handle error ...
}
Note that the "onDataCallback" member of ma_device_config has been renamed to "dataCallback". Also, "onStopCallback" has
been renamed to "stopCallback".
This is the first pass for full-duplex and there is a known bug. You will hear crackling on the following backends when sample Other API Changes
rate conversion is required for the playback device: -----------------
- Core Audio Other less major API changes have also been made in version 0.10.
- JACK
- AAudio
- OpenSL
- WebAudio
In addition to the above, not all platforms have been absolutely thoroughly tested simply because I lack the hardware for such `ma_sine_wave_read_f32()` and `ma_sine_wave_read_f32_ex()` have been removed and replaced with `ma_sine_wave_process_pcm_frames()`
thorough testing. If you experience a bug, an issue report on GitHub or an email would be greatly appreciated (and a sample which supports outputting PCM frames in any format (specified by a parameter).
program that reproduces the issue if possible).
`ma_convert_frames()` and `ma_convert_frames_ex()` have been changed. Both of these functions now take a new parameter called
`frameCountOut` which specifies the size of the output buffer in PCM frames. This has been added for safety. In addition to this,
the parameters for `ma_convert_frames_ex()` have changed to take a pointer to a `ma_data_converter_config` object to specify the
input and output formats to convert between. This was done to make it make it more flexible, to prevent the parameter list
getting too long, and to prevent API breakage whenever a new conversion property is added.
Other API Changes
-----------------
In addition to the above, the following API changes have been made:
- The log callback is no longer passed to ma_context_config_init(). Instead you need to set it manually after initialization. Biquad and Low-Pass Filters
- The onLogCallback member of ma_context_config has been renamed to "logCallback". ---------------------------
- The log callback now takes a logLevel parameter. The new callback looks like: void log_callback(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message) A generic biquad filter has been added. This is used via the `ma_biquad` API. The biquad filter is used as the basis for the
- You can use ma_log_level_to_string() to convert the logLevel to human readable text if you want to log it. low-pass filter. The biquad filter supports 32-bit floating point samples which runs on a floating point pipeline and 16-bit
- Some APIs have been renamed: signed integer samples which runs on a 32-bit fixed point pipeline. Both formats use transposed direct form 2.
- mal_decoder_read() -> ma_decoder_read_pcm_frames()
- mal_decoder_seek_to_frame() -> ma_decoder_seek_to_pcm_frame() The low-pass filter is just a biquad filter. By itself it's a second order low-pass filter, but it can be extended to higher
- mal_sine_wave_read() -> ma_sine_wave_read_f32() orders by chaining low-pass filters together. Low-pass filtering is achieved via the `ma_lpf` API. Since the low-pass filter
- mal_sine_wave_read_ex() -> ma_sine_wave_read_f32_ex() is just a biquad filter, it supports both 32-bit floating point and 16-bit signed integer formats.
- Some APIs have been removed:
- mal_device_get_buffer_size_in_bytes()
- mal_device_set_recv_callback()
- mal_device_set_send_callback()
- mal_src_set_input_sample_rate()
- mal_src_set_output_sample_rate()
- Error codes have been rearranged. If you're a binding maintainer you will need to update.
- The ma_backend enums have been rearranged to priority order. The rationale for this is to simplify automatic backend selection
and to make it easier to see the priority. If you're a binding maintainer you will need to update.
- ma_dsp has been renamed to ma_pcm_converter. The rationale for this change is that I'm expecting "ma_dsp" to conflict with
some future planned high-level APIs.
- For functions that take a pointer/count combo, such as ma_decoder_read_pcm_frames(), the parameter order has changed so that
the pointer comes before the count. The rationale for this is to keep it consistent with things like memcpy().
Miscellaneous Changes Miscellaneous Changes
--------------------- ---------------------
The following miscellaneous changes have also been made. Internal functions have all been made static where possible. If you get warnings about unused functions, please submit a bug
report.
- The AAudio backend has been added for Android 8 and above. This is Android's new "High-Performance Audio" API. (For the
record, this is one of the nicest audio APIs out there, just behind the BSD audio APIs). The `ma_device` structure is no longer defined as being aligned to MA_SIMD_ALIGNMENT. This resulted in a possible crash when
- The WebAudio backend has been added. This is based on ScriptProcessorNode. This removes the need for SDL. allocating a `ma_device` object on the heap, but not aligning it to MA_SIMD_ALIGNMENT. This crash would happen due to the
- The SDL and OpenAL backends have been removed. These were originally implemented to add support for platforms for which miniaudio compiler seeing the alignment specified on the structure and assuming it was always aligned as such and thinking it was safe
was not explicitly supported. These are no longer needed and have therefore been removed. to emit alignment-dependant SIMD instructions. Since miniaudio's philosophy is for things to just work, this has been removed
- Device initialization now fails if the requested share mode is not supported. If you ask for exclusive mode, you either get an from all structures.
exclusive mode device, or an error. The rationale for this change is to give the client more control over how to handle cases
when the desired shared mode is unavailable.
- A lock-free ring buffer API has been added. There are two varients of this. "ma_rb" operates on bytes, whereas "ma_pcm_rb"
operates on PCM frames.
- The library is now licensed as a choice of Public Domain (Unlicense) _or_ MIT-0 (No Attribution) which is the same as MIT, but
removes the attribution requirement. The rationale for this is to support countries that don't recognize public domain.
*/ */
/* /*
...@@ -36519,6 +36497,139 @@ ma_uint64 ma_sine_wave_read_pcm_frames(ma_sine_wave* pSineWave, void* pFramesOut ...@@ -36519,6 +36497,139 @@ ma_uint64 ma_sine_wave_read_pcm_frames(ma_sine_wave* pSineWave, void* pFramesOut
#endif /* MINIAUDIO_IMPLEMENTATION */ #endif /* MINIAUDIO_IMPLEMENTATION */
/*
MAJOR CHANGES IN VERSION 0.9
============================
Version 0.9 includes major API changes, centered mostly around full-duplex and the rebrand to "miniaudio". Before I go into
detail about the major changes I would like to apologize. I know it's annoying dealing with breaking API changes, but I think
it's best to get these changes out of the way now while the library is still relatively young and unknown.
There's been a lot of refactoring with this release so there's a good chance a few bugs have been introduced. I apologize in
advance for this. You may want to hold off on upgrading for the short term if you're worried. If mini_al v0.8.14 works for
you, and you don't need full-duplex support, you can avoid upgrading (though you won't be getting future bug fixes).
Rebranding to "miniaudio"
-------------------------
The decision was made to rename mini_al to miniaudio. Don't worry, it's the same project. The reason for this is simple:
1) Having the word "audio" in the title makes it immediately clear that the library is related to audio; and
2) I don't like the look of the underscore.
This rebrand has necessitated a change in namespace from "mal" to "ma". I know this is annoying, and I apologize, but it's
better to get this out of the road now rather than later. Also, since there are necessary API changes for full-duplex support
I think it's better to just get the namespace change over and done with at the same time as the full-duplex changes. I'm hoping
this will be the last of the major API changes. Fingers crossed!
The implementation define is now "#define MINIAUDIO_IMPLEMENTATION". You can also use "#define MA_IMPLEMENTATION" if that's
your preference.
Full-Duplex Support
-------------------
The major feature added to version 0.9 is full-duplex. This has necessitated a few API changes.
1) The data callback has now changed. Previously there was one type of callback for playback and another for capture. I wanted
to avoid a third callback just for full-duplex so the decision was made to break this API and unify the callbacks. Now,
there is just one callback which is the same for all three modes (playback, capture, duplex). The new callback looks like
the following:
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
This callback allows you to move data straight out of the input buffer and into the output buffer in full-duplex mode. In
playback-only mode, pInput will be null. Likewise, pOutput will be null in capture-only mode. The sample count is no longer
returned from the callback since it's not necessary for miniaudio anymore.
2) The device config needed to change in order to support full-duplex. Full-duplex requires the ability to allow the client
to choose a different PCM format for the playback and capture sides. The old ma_device_config object simply did not allow
this and needed to change. With these changes you now specify the device ID, format, channels, channel map and share mode
on a per-playback and per-capture basis (see example below). The sample rate must be the same for playback and capture.
Since the device config API has changed I have also decided to take the opportunity to simplify device initialization. Now,
the device ID, device type and callback user data are set in the config. ma_device_init() is now simplified down to taking
just the context, device config and a pointer to the device object being initialized. The rationale for this change is that
it just makes more sense to me that these are set as part of the config like everything else.
Example device initialization:
ma_device_config config = ma_device_config_init(ma_device_type_duplex); // Or ma_device_type_playback or ma_device_type_capture.
config.playback.pDeviceID = &myPlaybackDeviceID; // Or NULL for the default playback device.
config.playback.format = ma_format_f32;
config.playback.channels = 2;
config.capture.pDeviceID = &myCaptureDeviceID; // Or NULL for the default capture device.
config.capture.format = ma_format_s16;
config.capture.channels = 1;
config.sampleRate = 44100;
config.dataCallback = data_callback;
config.pUserData = &myUserData;
result = ma_device_init(&myContext, &config, &device);
if (result != MA_SUCCESS) {
... handle error ...
}
Note that the "onDataCallback" member of ma_device_config has been renamed to "dataCallback". Also, "onStopCallback" has
been renamed to "stopCallback".
This is the first pass for full-duplex and there is a known bug. You will hear crackling on the following backends when sample
rate conversion is required for the playback device:
- Core Audio
- JACK
- AAudio
- OpenSL
- WebAudio
In addition to the above, not all platforms have been absolutely thoroughly tested simply because I lack the hardware for such
thorough testing. If you experience a bug, an issue report on GitHub or an email would be greatly appreciated (and a sample
program that reproduces the issue if possible).
Other API Changes
-----------------
In addition to the above, the following API changes have been made:
- The log callback is no longer passed to ma_context_config_init(). Instead you need to set it manually after initialization.
- The onLogCallback member of ma_context_config has been renamed to "logCallback".
- The log callback now takes a logLevel parameter. The new callback looks like: void log_callback(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message)
- You can use ma_log_level_to_string() to convert the logLevel to human readable text if you want to log it.
- Some APIs have been renamed:
- mal_decoder_read() -> ma_decoder_read_pcm_frames()
- mal_decoder_seek_to_frame() -> ma_decoder_seek_to_pcm_frame()
- mal_sine_wave_read() -> ma_sine_wave_read_f32()
- mal_sine_wave_read_ex() -> ma_sine_wave_read_f32_ex()
- Some APIs have been removed:
- mal_device_get_buffer_size_in_bytes()
- mal_device_set_recv_callback()
- mal_device_set_send_callback()
- mal_src_set_input_sample_rate()
- mal_src_set_output_sample_rate()
- Error codes have been rearranged. If you're a binding maintainer you will need to update.
- The ma_backend enums have been rearranged to priority order. The rationale for this is to simplify automatic backend selection
and to make it easier to see the priority. If you're a binding maintainer you will need to update.
- ma_dsp has been renamed to ma_pcm_converter. The rationale for this change is that I'm expecting "ma_dsp" to conflict with
some future planned high-level APIs.
- For functions that take a pointer/count combo, such as ma_decoder_read_pcm_frames(), the parameter order has changed so that
the pointer comes before the count. The rationale for this is to keep it consistent with things like memcpy().
Miscellaneous Changes
---------------------
The following miscellaneous changes have also been made.
- The AAudio backend has been added for Android 8 and above. This is Android's new "High-Performance Audio" API. (For the
record, this is one of the nicest audio APIs out there, just behind the BSD audio APIs).
- The WebAudio backend has been added. This is based on ScriptProcessorNode. This removes the need for SDL.
- The SDL and OpenAL backends have been removed. These were originally implemented to add support for platforms for which miniaudio
was not explicitly supported. These are no longer needed and have therefore been removed.
- Device initialization now fails if the requested share mode is not supported. If you ask for exclusive mode, you either get an
exclusive mode device, or an error. The rationale for this change is to give the client more control over how to handle cases
when the desired shared mode is unavailable.
- A lock-free ring buffer API has been added. There are two varients of this. "ma_rb" operates on bytes, whereas "ma_pcm_rb"
operates on PCM frames.
- The library is now licensed as a choice of Public Domain (Unlicense) _or_ MIT-0 (No Attribution) which is the same as MIT, but
removes the attribution requirement. The rationale for this is to support countries that don't recognize public domain.
*/
/* /*
REVISION HISTORY REVISION HISTORY
================ ================
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