Initial Commit
This commit is contained in:
115
thirdparty/miniaudio-0.11.24/examples/custom_decoder.c
vendored
Normal file
115
thirdparty/miniaudio-0.11.24/examples/custom_decoder.c
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Demonstrates how to implement a custom decoder.
|
||||
|
||||
This example implements two custom decoders:
|
||||
|
||||
* Vorbis via libvorbis
|
||||
* Opus via libopus
|
||||
|
||||
A custom decoder must implement a data source. In this example, the libvorbis data source is called
|
||||
`ma_libvorbis` and the Opus data source is called `ma_libopus`. These two objects are compatible
|
||||
with the `ma_data_source` APIs and can be taken straight from this example and used in real code.
|
||||
|
||||
The custom decoding data sources (`ma_libvorbis` and `ma_libopus` in this example) are connected to
|
||||
the decoder via the decoder config (`ma_decoder_config`). You need to implement a vtable for each
|
||||
of your custom decoders. See `ma_decoding_backend_vtable` for the functions you need to implement.
|
||||
The `onInitFile`, `onInitFileW` and `onInitMemory` functions are optional.
|
||||
*/
|
||||
#include "../miniaudio.c"
|
||||
#include "../extras/decoders/libvorbis/miniaudio_libvorbis.c"
|
||||
#include "../extras/decoders/libopus/miniaudio_libopus.c"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
{
|
||||
ma_data_source* pDataSource = (ma_data_source*)pDevice->pUserData;
|
||||
if (pDataSource == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ma_data_source_read_pcm_frames(pDataSource, pOutput, frameCount, NULL);
|
||||
|
||||
(void)pInput;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
ma_result result;
|
||||
ma_decoder_config decoderConfig;
|
||||
ma_decoder decoder;
|
||||
ma_device_config deviceConfig;
|
||||
ma_device device;
|
||||
ma_format format;
|
||||
ma_uint32 channels;
|
||||
ma_uint32 sampleRate;
|
||||
|
||||
/*
|
||||
Add your custom backend vtables here. The order in the array defines the order of priority. The
|
||||
vtables will be passed in via the decoder config.
|
||||
*/
|
||||
ma_decoding_backend_vtable* pCustomBackendVTables[] =
|
||||
{
|
||||
ma_decoding_backend_libvorbis,
|
||||
ma_decoding_backend_libopus
|
||||
};
|
||||
|
||||
|
||||
if (argc < 2) {
|
||||
printf("No input file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the decoder. */
|
||||
decoderConfig = ma_decoder_config_init_default();
|
||||
decoderConfig.pCustomBackendUserData = NULL; /* None of our decoders require user data, so this can be set to null. */
|
||||
decoderConfig.ppCustomBackendVTables = pCustomBackendVTables;
|
||||
decoderConfig.customBackendCount = sizeof(pCustomBackendVTables) / sizeof(pCustomBackendVTables[0]);
|
||||
|
||||
result = ma_decoder_init_file(argv[1], &decoderConfig, &decoder);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to initialize decoder.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ma_data_source_set_looping(&decoder, MA_TRUE);
|
||||
|
||||
|
||||
/* Initialize the device. */
|
||||
result = ma_data_source_get_data_format(&decoder, &format, &channels, &sampleRate, NULL, 0);
|
||||
if (result != MA_SUCCESS) {
|
||||
printf("Failed to retrieve decoder data format.");
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -1;
|
||||
}
|
||||
|
||||
deviceConfig = ma_device_config_init(ma_device_type_playback);
|
||||
deviceConfig.playback.format = format;
|
||||
deviceConfig.playback.channels = channels;
|
||||
deviceConfig.sampleRate = sampleRate;
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
deviceConfig.pUserData = &decoder;
|
||||
|
||||
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("Failed to open playback device.\n");
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Press Enter to quit...");
|
||||
getchar();
|
||||
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user