Commit dbb90b80 authored by David Reid's avatar David Reid

Add a basic test.

parent 380971d6
......@@ -7,5 +7,6 @@ tests/x64/
tests/Debug/
tests/Release/
tests/bin/
!./tests/DO_NOT_DELETE
*.vcxproj.user
\ No newline at end of file
!/tests/DO_NOT_DELETE
/tests/SDL2.dll
*.vcxproj.user
Build and run these test from this folder. Example:
clear && ./mal_test_0_build && ./bin/mal_test_0
These tests load resources from hard coded paths which point to the "res" folder. These
paths are based on the assumption that the current directory is where the build files
are located.
\ No newline at end of file
// Uncomment this to include Vorbis decoding tests, albeit with some annoying warnings with MinGW.
//#define MAL_INCLUDE_VORBIS_TESTS
#include "../extras/dr_flac.h"
#include "../extras/dr_mp3.h"
#include "../extras/dr_wav.h"
#ifdef MAL_INCLUDE_VORBIS_TESTS
#define STB_VORBIS_HEADER_ONLY
#include "../extras/stb_vorbis.c"
#endif
#define MAL_IMPLEMENTATION
#include "../mini_al.h"
mal_backend g_Backends[] = {
mal_backend_wasapi,
mal_backend_dsound,
mal_backend_winmm,
mal_backend_oss,
mal_backend_pulseaudio,
mal_backend_alsa,
mal_backend_jack,
mal_backend_opensl,
mal_backend_openal,
mal_backend_sdl,
mal_backend_null
};
void on_log(mal_context* pContext, mal_device* pDevice, const char* message)
{
(void)pContext;
(void)pDevice;
printf("%s\n", message);
}
int do_backend_test(mal_backend backend)
{
mal_result result = MAL_SUCCESS;
mal_context context;
mal_device_info* pPlaybackDeviceInfos;
mal_uint32 playbackDeviceCount;
mal_device_info* pCaptureDeviceInfos;
mal_uint32 captureDeviceCount;
printf("--- %s ---\n", mal_get_backend_name(backend));
// Context.
printf(" Creating Context... ");
{
mal_context_config contextConfig = mal_context_config_init(on_log);
result = mal_context_init(&backend, 1, &contextConfig, &context);
if (result == MAL_SUCCESS) {
printf(" Done\n");
} else {
if (result == MAL_NO_BACKEND) {
printf(" Not supported\n");
printf("--- End %s ---\n", mal_get_backend_name(backend));
printf("\n");
return 0;
} else {
printf(" Failed\n");
goto done;
}
}
}
// Enumeration.
printf(" Enumerating Devices... ");
{
result = mal_context_get_devices(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, &pCaptureDeviceInfos, &captureDeviceCount);
if (result == MAL_SUCCESS) {
printf("Done\n");
} else {
printf("Failed\n");
goto done;
}
printf(" Playback Devices (%d)\n", playbackDeviceCount);
for (mal_uint32 iDevice = 0; iDevice < playbackDeviceCount; ++iDevice) {
printf(" %d: %s\n", iDevice, pPlaybackDeviceInfos[iDevice].name);
}
printf(" Capture Devices (%d)\n", captureDeviceCount);
for (mal_uint32 iDevice = 0; iDevice < captureDeviceCount; ++iDevice) {
printf(" %d: %s\n", iDevice, pCaptureDeviceInfos[iDevice].name);
}
}
// Device Information.
printf(" Getting Device Information...\n");
{
printf(" Playback Devices (%d)\n", playbackDeviceCount);
for (mal_uint32 iDevice = 0; iDevice < playbackDeviceCount; ++iDevice) {
printf(" %d: %s\n", iDevice, pPlaybackDeviceInfos[iDevice].name);
result = mal_context_get_device_info(&context, mal_device_type_playback, &pPlaybackDeviceInfos[iDevice].id, mal_share_mode_shared, &pPlaybackDeviceInfos[iDevice]);
if (result == MAL_SUCCESS) {
printf(" Name: %s\n", pPlaybackDeviceInfos[iDevice].name);
} else {
printf(" ERROR\n");
}
}
printf(" Capture Devices (%d)\n", captureDeviceCount);
for (mal_uint32 iDevice = 0; iDevice < captureDeviceCount; ++iDevice) {
printf(" %d: %s\n", iDevice, pCaptureDeviceInfos[iDevice].name);
result = mal_context_get_device_info(&context, mal_device_type_capture, &pCaptureDeviceInfos[iDevice].id, mal_share_mode_shared, &pCaptureDeviceInfos[iDevice]);
if (result == MAL_SUCCESS) {
printf(" Name: %s\n", pCaptureDeviceInfos[iDevice].name);
} else {
printf(" ERROR\n");
}
}
}
done:
printf("--- End %s ---\n", mal_get_backend_name(backend));
printf("\n");
mal_context_uninit(&context);
return (result == MAL_SUCCESS) ? 0 : -1;
}
int do_backend_tests()
{
mal_bool32 hasErrorOccurred = MAL_FALSE;
// Tests are performed on a per-backend basis.
for (size_t iBackend = 0; iBackend < mal_countof(g_Backends); ++iBackend) {
int result = do_backend_test(g_Backends[iBackend]);
if (result < 0) {
hasErrorOccurred = MAL_TRUE;
}
}
return (hasErrorOccurred) ? -1 : 0;
}
typedef struct
{
mal_decoder* pDecoder;
mal_event endOfPlaybackEvent;
} playback_test_callback_data;
mal_uint32 on_send__playback_test(mal_device* pDevice, mal_uint32 frameCount, void* pFrames)
{
playback_test_callback_data* pData = (playback_test_callback_data*)pDevice->pUserData;
mal_assert(pData != NULL);
mal_uint64 framesRead = mal_decoder_read(pData->pDecoder, frameCount, pFrames);
if (framesRead == 0) {
mal_event_signal(&pData->endOfPlaybackEvent);
}
return (mal_uint32)framesRead;
}
int do_playback_test(mal_backend backend)
{
mal_result result = MAL_SUCCESS;
mal_device device;
mal_decoder decoder;
mal_bool32 haveDevice = MAL_FALSE;
mal_bool32 haveDecoder = MAL_FALSE;
playback_test_callback_data callbackData;
callbackData.pDecoder = &decoder;
printf("--- %s ---\n", mal_get_backend_name(backend));
// Device.
printf(" Opening Device... ");
{
mal_context_config contextConfig = mal_context_config_init(on_log);
mal_device_config deviceConfig = mal_device_config_init_default_playback(on_send__playback_test);
result = mal_device_init_ex(&backend, 1, &contextConfig, mal_device_type_playback, NULL, &deviceConfig, &callbackData, &device);
if (result == MAL_SUCCESS) {
printf("Done\n");
} else {
if (result == MAL_NO_BACKEND) {
printf(" Not supported\n");
printf("--- End %s ---\n", mal_get_backend_name(backend));
printf("\n");
return 0;
} else {
printf(" Failed\n");
goto done;
}
}
haveDevice = MAL_TRUE;
}
printf(" Opening Decoder... ");
{
result = mal_event_init(device.pContext, &callbackData.endOfPlaybackEvent);
if (result != MAL_SUCCESS) {
printf("Failed to init event.\n");
goto done;
}
mal_decoder_config decoderConfig = mal_decoder_config_init(device.format, device.channels, device.sampleRate);
result = mal_decoder_init_file("res/sine_s16_mono_48000.wav", &decoderConfig, &decoder);
if (result == MAL_SUCCESS) {
printf("Done\n");
} else {
printf("Failed to init decoder.\n");
goto done;
}
haveDecoder = MAL_TRUE;
}
printf(" Press Enter to start playback... ");
getchar();
{
result = mal_device_start(&device);
if (result != MAL_SUCCESS) {
printf("Failed to start device.\n");
goto done;
}
mal_event_wait(&callbackData.endOfPlaybackEvent); // Wait for the sound to finish.
printf("Done\n");
}
done:
printf("--- End %s ---\n", mal_get_backend_name(backend));
printf("\n");
if (haveDevice) {
mal_device_uninit(&device);
}
if (haveDecoder) {
mal_decoder_uninit(&decoder);
}
return (result == MAL_SUCCESS) ? 0 : -1;
}
int do_playback_tests()
{
mal_bool32 hasErrorOccurred = MAL_FALSE;
for (size_t iBackend = 0; iBackend < mal_countof(g_Backends); ++iBackend) {
int result = do_playback_test(g_Backends[iBackend]);
if (result < 0) {
hasErrorOccurred = MAL_TRUE;
}
}
return (hasErrorOccurred) ? -1 : 0;
}
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
mal_bool32 hasErrorOccurred = MAL_FALSE;
int result = 0;
printf("=== TESTING BACKENDS ===\n");
result = do_backend_tests();
if (result < 0) {
hasErrorOccurred = MAL_TRUE;
}
printf("=== END TESTING BACKENDS ===\n");
printf("\n");
printf("=== TESTING DEFAULT PLAYBACK DEVICES ===\n");
result = do_playback_tests();
if (result < 0) {
hasErrorOccurred = MAL_TRUE;
}
printf("=== END TESTING DEFAULT PLAYBACK DEVICES ===\n");
return (hasErrorOccurred) ? -1 : 0;
}
#define DR_FLAC_IMPLEMENTATION
#include "../extras/dr_flac.h"
#define DR_MP3_IMPLEMENTATION
#include "../extras/dr_mp3.h"
#define DR_WAV_IMPLEMENTATION
#include "../extras/dr_wav.h"
#ifdef MAL_INCLUDE_VORBIS_TESTS
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4456)
#pragma warning(disable:4457)
#pragma warning(disable:4100)
#pragma warning(disable:4244)
#pragma warning(disable:4701)
#pragma warning(disable:4245)
#endif
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
#undef STB_VORBIS_HEADER_ONLY
#include "../extras/stb_vorbis.c"
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif
\ No newline at end of file
#include "mal_test_0.c"
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3430EEA2-AC6E-4DC7-B684-1F698D01FAE8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>mal_test_0</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>../../../mal/</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>C:\dev-other\SDL2-2.0.3\lib\x86;C:\dev-other\openal-soft-1.16.0-bin\libs\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>../../../mal/</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>../../../mal/</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>C:\dev-other\SDL2-2.0.3\lib\x86;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>../../../mal/</OutDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>
</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<EntryPointSymbol>
</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="mal_test_0.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="mal_test_0.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\mini_al.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="mal_test_0.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mal_test_0.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\mini_al.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
#!/bin/bash
cc mal_test_0.c -o ./bin/mal_test_0 -Wall -ldl -lpthread
c++ mal_test_0.cpp -o ./bin/mal_test_0_cpp -Wall -ldl -lpthread
\ No newline at end of file
gcc mal_test_0.c -o bin/mal_test_0.exe -Wall
g++ mal_test_0.cpp -o bin/mal_test_0_cpp.exe -Wall
\ No newline at end of file
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