Commit 96815f43 authored by David Reid's avatar David Reid

Simplify the format converter API.

parent d5549b37
......@@ -705,14 +705,14 @@ typedef struct
mal_stream_format streamFormatIn;
mal_stream_format streamFormatOut;
mal_dither_mode ditherMode;
mal_format_converter_read_proc onRead;
mal_format_converter_read_deinterleaved_proc onReadDeinterleaved;
void* pUserData;
} mal_format_converter_config;
struct mal_format_converter
{
mal_format_converter_config config;
mal_format_converter_read_proc onRead;
mal_format_converter_read_deinterleaved_proc onReadDeinterleaved;
void* pUserData;
void (* onConvertPCM)(void* dst, const void* src, mal_uint64 count, mal_dither_mode ditherMode);
void (* onInterleavePCM)(void* dst, const void** src, mal_uint64 frameCount, mal_uint32 channels);
void (* onDeinterleavePCM)(void** dst, const void* src, mal_uint64 frameCount, mal_uint32 channels);
......@@ -721,7 +721,6 @@ struct mal_format_converter
typedef struct mal_channel_router mal_channel_router;
//typedef mal_uint32 (* mal_channel_router_read_proc) (mal_channel_router* pRouter, mal_uint32 frameCount, void* pFramesOut, void* pUserData);
typedef mal_uint32 (* mal_channel_router_read_deinterleaved_proc)(mal_channel_router* pRouter, mal_uint32 frameCount, void** ppSamplesOut, void* pUserData);
typedef struct
......@@ -736,7 +735,6 @@ typedef struct
struct mal_channel_router
{
mal_channel_router_config config;
//mal_channel_router_read_proc onRead;
mal_channel_router_read_deinterleaved_proc onReadDeinterleaved;
void* pUserData;
mal_bool32 isPassthrough : 1;
......@@ -1838,10 +1836,7 @@ mal_bool32 mal_channel_map_contains_channel_position(mal_uint32 channels, const
///////////////////////////////////////////////////////////////////////////////
// Initializes a format converter.
mal_result mal_format_converter_init(const mal_format_converter_config* pConfig, mal_format_converter_read_proc onRead, void* pUserData, mal_format_converter* pConverter);
// Initializes a format converter when the input data is non-interleaved.
mal_result mal_format_converter_init_deinterleaved(const mal_format_converter_config* pConfig, mal_format_converter_read_deinterleaved_proc onRead, void* pUserData, mal_format_converter* pConverter);
mal_result mal_format_converter_init(const mal_format_converter_config* pConfig, mal_format_converter* pConverter);
// Reads data from the format converter as interleaved channels.
mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint64 frameCount, void* pFramesOut, void* pUserData);
......@@ -16731,7 +16726,7 @@ void mal_pcm_deinterleave_f32(void** dst, const void* src, mal_uint64 frameCount
mal_result mal_format_converter_init__common(const mal_format_converter_config* pConfig, void* pUserData, mal_format_converter* pConverter)
mal_result mal_format_converter_init(const mal_format_converter_config* pConfig, mal_format_converter* pConverter)
{
if (pConverter == NULL) {
return MAL_INVALID_ARGS;
......@@ -16743,7 +16738,6 @@ mal_result mal_format_converter_init__common(const mal_format_converter_config*
}
pConverter->config = *pConfig;
pConverter->pUserData = pUserData;
switch (pConfig->formatIn)
{
......@@ -16858,31 +16852,6 @@ mal_result mal_format_converter_init__common(const mal_format_converter_config*
return MAL_SUCCESS;
}
mal_result mal_format_converter_init(const mal_format_converter_config* pConfig, mal_format_converter_read_proc onRead, void* pUserData, mal_format_converter* pConverter)
{
mal_result result = mal_format_converter_init__common(pConfig, pUserData, pConverter);
if (result != MAL_SUCCESS) {
return result;
}
pConverter->onRead = onRead;
return MAL_SUCCESS;
}
mal_result mal_format_converter_init_deinterleaved(const mal_format_converter_config* pConfig, mal_format_converter_read_deinterleaved_proc onRead, void* pUserData, mal_format_converter* pConverter)
{
mal_result result = mal_format_converter_init__common(pConfig, pUserData, pConverter);
if (result != MAL_SUCCESS) {
return result;
}
pConverter->onReadDeinterleaved = onRead;
return MAL_SUCCESS;
}
mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint64 frameCount, void* pFramesOut, void* pUserData)
{
if (pConverter == NULL || pFramesOut == NULL) {
......@@ -16896,7 +16865,7 @@ mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint6
mal_uint32 frameSizeOut = sampleSizeOut * pConverter->config.channels;
mal_uint8* pNextFramesOut = (mal_uint8*)pFramesOut;
if (pConverter->onRead != NULL) {
if (pConverter->config.onRead != NULL) {
// Input data is interleaved.
if (pConverter->config.formatIn == pConverter->config.formatOut) {
// Pass through.
......@@ -16907,7 +16876,7 @@ mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint6
framesToReadRightNow = 0xFFFFFFFF;
}
mal_uint32 framesJustRead = (mal_uint32)pConverter->onRead(pConverter, (mal_uint32)framesToReadRightNow, pNextFramesOut, pUserData);
mal_uint32 framesJustRead = (mal_uint32)pConverter->config.onRead(pConverter, (mal_uint32)framesToReadRightNow, pNextFramesOut, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -16929,7 +16898,7 @@ mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint6
framesToReadRightNow = maxFramesToReadAtATime;
}
mal_uint32 framesJustRead = (mal_uint32)pConverter->onRead(pConverter, (mal_uint32)framesToReadRightNow, temp, pUserData);
mal_uint32 framesJustRead = (mal_uint32)pConverter->config.onRead(pConverter, (mal_uint32)framesToReadRightNow, temp, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -16963,7 +16932,7 @@ mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint6
if (pConverter->config.formatIn == pConverter->config.formatOut) {
// Only interleaving.
framesJustRead = (mal_uint32)pConverter->onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, ppTempSampleOfOutFormat, pUserData);
framesJustRead = (mal_uint32)pConverter->config.onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, ppTempSampleOfOutFormat, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -16977,7 +16946,7 @@ mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint6
}
framesJustRead = (mal_uint32)pConverter->onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, ppTempSampleOfInFormat, pUserData);
framesJustRead = (mal_uint32)pConverter->config.onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, ppTempSampleOfInFormat, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -17010,7 +16979,7 @@ mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConver
mal_uint8* ppNextSamplesOut[MAL_MAX_CHANNELS];
mal_copy_memory(ppNextSamplesOut, ppSamplesOut, sizeof(void*) * pConverter->config.channels);
if (pConverter->onRead != NULL) {
if (pConverter->config.onRead != NULL) {
// Input data is interleaved.
mal_uint8 tempSamplesOfOutFormat[MAL_MAX_CHANNELS * MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES * 128];
mal_assert(sizeof(tempSamplesOfOutFormat) <= 0xFFFFFFFF);
......@@ -17028,7 +16997,7 @@ mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConver
if (pConverter->config.formatIn == pConverter->config.formatOut) {
// Only de-interleaving.
framesJustRead = (mal_uint32)pConverter->onRead(pConverter, (mal_uint32)framesToReadRightNow, tempSamplesOfOutFormat, pUserData);
framesJustRead = (mal_uint32)pConverter->config.onRead(pConverter, (mal_uint32)framesToReadRightNow, tempSamplesOfOutFormat, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -17036,7 +17005,7 @@ mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConver
// De-interleaving + Conversion. Convert first, then de-interleave.
mal_uint8 tempSamplesOfInFormat[sizeof(tempSamplesOfOutFormat)];
framesJustRead = (mal_uint32)pConverter->onRead(pConverter, (mal_uint32)framesToReadRightNow, tempSamplesOfInFormat, pUserData);
framesJustRead = (mal_uint32)pConverter->config.onRead(pConverter, (mal_uint32)framesToReadRightNow, tempSamplesOfInFormat, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -17062,7 +17031,7 @@ mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConver
framesToReadRightNow = 0xFFFFFFFF;
}
mal_uint32 framesJustRead = (mal_uint32)pConverter->onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, (void**)ppNextSamplesOut, pUserData);
mal_uint32 framesJustRead = (mal_uint32)pConverter->config.onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, (void**)ppNextSamplesOut, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -17091,7 +17060,7 @@ mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConver
framesToReadRightNow = maxFramesToReadAtATime;
}
mal_uint32 framesJustRead = (mal_uint32)pConverter->onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, ppTemp, pUserData);
mal_uint32 framesJustRead = (mal_uint32)pConverter->config.onReadDeinterleaved(pConverter, (mal_uint32)framesToReadRightNow, ppTemp, pUserData);
if (framesJustRead == 0) {
break;
}
......@@ -18887,7 +18856,9 @@ mal_result mal_dsp_init(const mal_dsp_config* pConfig, mal_dsp_read_proc onRead,
preFormatConverterConfig.channels = pConfig->channelsIn;
preFormatConverterConfig.streamFormatIn = mal_stream_format_pcm;
preFormatConverterConfig.streamFormatOut = mal_stream_format_pcm;
result = mal_format_converter_init(&preFormatConverterConfig, mal_dsp__pre_format_converter_on_read, pDSP, &pDSP->formatConverterIn);
preFormatConverterConfig.onRead = mal_dsp__pre_format_converter_on_read;
preFormatConverterConfig.pUserData = pDSP;
result = mal_format_converter_init(&preFormatConverterConfig, &pDSP->formatConverterIn);
if (result != MAL_SUCCESS) {
return result;
}
......@@ -18903,14 +18874,14 @@ mal_result mal_dsp_init(const mal_dsp_config* pConfig, mal_dsp_read_proc onRead,
postFormatConverterConfig.channels = pConfig->channelsOut;
postFormatConverterConfig.streamFormatIn = mal_stream_format_pcm;
postFormatConverterConfig.streamFormatOut = mal_stream_format_pcm;
postFormatConverterConfig.onRead = mal_dsp__post_format_converter_on_read;
postFormatConverterConfig.onReadDeinterleaved = mal_dsp__post_format_converter_on_read_deinterleaved;
postFormatConverterConfig.pUserData = pDSP;
if (pDSP->isPreFormatConversionRequired) {
// Converting from an earlier stage in the pipeline which is always deinterleaved floating point.
postFormatConverterConfig.formatIn = mal_format_f32;
result = mal_format_converter_init_deinterleaved(&postFormatConverterConfig, mal_dsp__post_format_converter_on_read_deinterleaved, pDSP, &pDSP->formatConverterIn);
} else {
// Converting directly from the input client data.
result = mal_format_converter_init(&postFormatConverterConfig, mal_dsp__post_format_converter_on_read, pDSP, &pDSP->formatConverterIn);
}
result = mal_format_converter_init(&postFormatConverterConfig, &pDSP->formatConverterIn);
if (result != MAL_SUCCESS) {
return result;
}
......
......@@ -998,18 +998,23 @@ int do_format_converter_tests()
config.streamFormatIn = mal_stream_format_pcm;
config.streamFormatOut = mal_stream_format_pcm;
config.ditherMode = mal_dither_mode_none;
config.pUserData = &sineWave;
config.onRead = converter_test_interleaved_callback;
config.onReadDeinterleaved = NULL;
// Interleaved/Interleaved f32 to s16.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init(&config, converter_test_interleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
}
mal_int16 interleavedFrames[MAL_MAX_CHANNELS * 1024];
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1028,7 +1033,7 @@ int do_format_converter_tests()
// Interleaved/Deinterleaved f32 to s16.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init(&config, converter_test_interleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
......@@ -1040,7 +1045,7 @@ int do_format_converter_tests()
ppDeinterleavedFrames[iChannel] = &deinterleavedFrames[iChannel];
}
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1062,17 +1067,21 @@ int do_format_converter_tests()
}
}
config.onRead = NULL;
config.onReadDeinterleaved = converter_test_deinterleaved_callback;
// Deinterleaved/Interleaved f32 to s16.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init_deinterleaved(&config, converter_test_deinterleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
}
mal_int16 interleavedFrames[MAL_MAX_CHANNELS * 1024];
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1091,7 +1100,7 @@ int do_format_converter_tests()
// Deinterleaved/Deinterleaved f32 to s16.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init_deinterleaved(&config, converter_test_deinterleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
......@@ -1103,7 +1112,7 @@ int do_format_converter_tests()
ppDeinterleavedFrames[iChannel] = &deinterleavedFrames[iChannel];
}
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1126,20 +1135,21 @@ int do_format_converter_tests()
}
config.onRead = converter_test_interleaved_callback;
config.onReadDeinterleaved = NULL;
config.formatOut = mal_format_f32;
// Interleaved/Interleaved f32 to f32.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init(&config, converter_test_interleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
}
float interleavedFrames[MAL_MAX_CHANNELS * 1024];
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1158,7 +1168,7 @@ int do_format_converter_tests()
// Interleaved/Deinterleaved f32 to f32.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init(&config, converter_test_interleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
......@@ -1170,7 +1180,7 @@ int do_format_converter_tests()
ppDeinterleavedFrames[iChannel] = &deinterleavedFrames[iChannel];
}
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1192,17 +1202,21 @@ int do_format_converter_tests()
}
}
config.onRead = NULL;
config.onReadDeinterleaved = converter_test_deinterleaved_callback;
// Deinterleaved/Interleaved f32 to f32.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init_deinterleaved(&config, converter_test_deinterleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
}
float interleavedFrames[MAL_MAX_CHANNELS * 1024];
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read(&converter, 1024, interleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......@@ -1221,7 +1235,7 @@ int do_format_converter_tests()
// Deinterleaved/Deinterleaved f32 to f32.
{
mal_sine_wave_init(amplitude, periodsPerSecond, sampleRate, &sineWave);
result = mal_format_converter_init_deinterleaved(&config, converter_test_deinterleaved_callback, &sineWave, &converter);
result = mal_format_converter_init(&config, &converter);
if (result != MAL_SUCCESS) {
printf("Failed to initialize converter.\n");
return -1;
......@@ -1233,7 +1247,7 @@ int do_format_converter_tests()
ppDeinterleavedFrames[iChannel] = &deinterleavedFrames[iChannel];
}
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.pUserData);
mal_uint64 framesRead = mal_format_converter_read_deinterleaved(&converter, 1024, ppDeinterleavedFrames, converter.config.pUserData);
if (framesRead != 1024) {
printf("Failed to read interleaved data from converter.\n");
return -1;
......
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