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 mini_al 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 mal_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. mal_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:
mal_device_config config = mal_device_config_init(mal_device_type_duplex); // Or mal_device_type_playback or mal_device_type_capture.
config.playback.pDeviceID = &myPlaybackDeviceID; // Or NULL for the default playback device.
config.playback.format = mal_format_f32;
config.playback.channels = 2;
config.capture.pDeviceID = &myCaptureDeviceID; // Or NULL for the default capture device.
config.capture.format = mal_format_s16;
config.capture.channels = 1;
config.sampleRate = 44100;
config.dataCallback = data_callback;
config.pUserData = &myUserData;
result = mal_device_init(&myContext, &config, &device);
if (result != MAL_SUCCESS) {
... handle error ...
}
Note that the "onDataCallback" member of mal_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 mal_context_config_init(). Instead you need to set it manually after initialization.
- The onLogCallback member of mal_context_config has been renamed to "logCallback".
- The log callback now takes a logLevel parameter. The new callback looks like: void log_callback(mal_context* pContext, mal_device* pDevice, mal_uint32 logLevel, const char* message)
- You can use mal_log_level_to_string() to convert the logLevel to human readable text if you want to log it.