Commit 994c86fc authored by David Reid's avatar David Reid

Add initial support for dithering.

parent d50c5d22
This diff is collapsed.
#define MAL_USE_REFERENCE_CONVERSION_APIS
#define MAL_IMPLEMENTATION
#include "../mini_al.h"
// Two converters are needed here. One for converting f32 samples from the sine wave generator to the input format,
// and another for converting the input format to the output format for device output.
mal_sine_wave sineWave;
mal_format_converter converterIn;
mal_format_converter converterOut;
mal_uint32 on_convert_samples_in(mal_format_converter* pConverter, mal_uint32 frameCount, void* pFrames, void* pUserData)
{
(void)pUserData;
mal_assert(pConverter->config.formatIn == mal_format_f32);
mal_sine_wave* pSineWave = (mal_sine_wave*)pConverter->config.pUserData;
mal_assert(pSineWave);
return (mal_uint32)mal_sine_wave_read(pSineWave, frameCount, pFrames);
}
mal_uint32 on_convert_samples_out(mal_format_converter* pConverter, mal_uint32 frameCount, void* pFrames, void* pUserData)
{
(void)pUserData;
mal_format_converter* pConverterIn = (mal_format_converter*)pConverter->config.pUserData;
mal_assert(pConverterIn != NULL);
return (mal_uint32)mal_format_converter_read(pConverterIn, frameCount, pFrames, NULL);
}
mal_uint32 on_send_to_device__original(mal_device* pDevice, mal_uint32 frameCount, void* pFrames)
{
(void)pDevice;
mal_assert(pDevice->format == mal_format_f32);
mal_assert(pDevice->channels == 1);
return (mal_uint32)mal_sine_wave_read(&sineWave, frameCount, pFrames);
}
mal_uint32 on_send_to_device__dithered(mal_device* pDevice, mal_uint32 frameCount, void* pFrames)
{
mal_assert(pDevice->channels == 1);
mal_format_converter* pConverter = (mal_format_converter*)pDevice->pUserData;
mal_assert(pConverter != NULL);
mal_assert(pDevice->format == pConverter->config.formatOut);
return (mal_uint32)mal_format_converter_read(pConverter, frameCount, pFrames, NULL);
}
int do_dithering_test()
{
mal_sine_wave_init(0.5, 400, 48000, &sineWave);
mal_device_config config = mal_device_config_init_playback(mal_format_f32, 1, 0, on_send_to_device__original);
mal_device device;
mal_result result;
// We first play the sound the way it's meant to be played.
result = mal_device_init(NULL, mal_device_type_playback, NULL, &config, NULL, &device);
if (result != MAL_SUCCESS) {
return -1;
}
result = mal_device_start(&device);
if (result != MAL_SUCCESS) {
return -2;
}
printf("Press Enter to play enable dithering.\n");
getchar();
mal_device_uninit(&device);
// Now we play the sound after it's run through a dithered format converter.
mal_sine_wave_init(0.5, 400, 48000, &sineWave);
mal_format srcFormat = mal_format_s24;
mal_format dstFormat = mal_format_s16;
mal_dither_mode ditherMode = mal_dither_mode_triangle;
mal_format_converter_config converterInConfig;
mal_zero_object(&converterInConfig);
converterInConfig.formatIn = mal_format_f32; // <-- From the sine wave generator.
converterInConfig.formatOut = srcFormat;
converterInConfig.channels = config.channels;
converterInConfig.ditherMode = mal_dither_mode_none;
converterInConfig.onRead = on_convert_samples_in;
converterInConfig.pUserData = &sineWave;
result = mal_format_converter_init(&converterInConfig, &converterIn);
if (result != MAL_SUCCESS) {
return -3;
}
mal_format_converter_config converterOutConfig;
mal_zero_object(&converterInConfig);
converterOutConfig.formatIn = srcFormat;
converterOutConfig.formatOut = dstFormat;
converterOutConfig.channels = config.channels;
converterOutConfig.ditherMode = ditherMode;
converterOutConfig.onRead = on_convert_samples_out;
converterOutConfig.pUserData = &converterIn;
result = mal_format_converter_init(&converterOutConfig, &converterOut);
if (result != MAL_SUCCESS) {
return -3;
}
config = mal_device_config_init_playback(converterOutConfig.formatOut, 1, 0, on_send_to_device__dithered);
result = mal_device_init(NULL, mal_device_type_playback, NULL, &config, &converterOut, &device);
if (result != MAL_SUCCESS) {
return -1;
}
result = mal_device_start(&device);
if (result != MAL_SUCCESS) {
return -2;
}
printf("Press Enter to stop.\n");
getchar();
return 0;
}
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
do_dithering_test();
return 0;
}
\ No newline at end of file
......@@ -260,6 +260,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="mal_dithering.c" />
<ClCompile Include="mal_profiling.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
......@@ -269,12 +270,12 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="mal_test_0.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="mal_test_0.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
......
......@@ -24,6 +24,9 @@
<ClCompile Include="mal_profiling.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mal_dithering.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\mini_al.h">
......
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