Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
223c8e84
Commit
223c8e84
authored
Jul 15, 2018
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a quick and dirty test for resampling.
This will be cleaned up later. Maybe.
parent
5b2b688b
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
210 additions
and
2 deletions
+210
-2
tests/mal_resampling.c
tests/mal_resampling.c
+195
-0
tests/mal_test_0.vcxproj
tests/mal_test_0.vcxproj
+10
-2
tests/mal_test_0.vcxproj.filters
tests/mal_test_0.vcxproj.filters
+3
-0
tools/mini_sigvis/mini_sigvis.h
tools/mini_sigvis/mini_sigvis.h
+2
-0
No files found.
tests/mal_resampling.c
0 → 100644
View file @
223c8e84
// We're using sigvis for visualizations. This will include mini_al for us, so no need to include mini_al in this file.
#define MAL_NO_SSE2
#define MAL_NO_AVX2
#define MINI_SIGVIS_IMPLEMENTATION
#include "../tools/mini_sigvis/mini_sigvis.h" // <-- Includes mini_al.
// There is a usage pattern for resampling that mini_al does not properly support which is where the client continuously
// reads samples until mal_src_read() returns 0. The problem with this pattern is that is consumes the samples sitting
// in the window which are needed to compute the next samples in future calls to mal_src_read() (assuming the client
// has re-filled the resampler's input data).
/*
for (;;) {
fill_src_input_data(&src, someData);
float buffer[4096]
while ((framesRead = mal_src_read(&src, ...) != 0) {
do_something_with_resampled_data(buffer);
}
}
*/
// In the use case above, the very last samples that are read from mal_src_read() will not have future samples to draw
// from in order to calculate the correct interpolation factor which in turn results in crackling.
mal_uint32
sampleRateIn
=
0
;
mal_uint32
sampleRateOut
=
0
;
mal_sine_wave
sineWave
;
// <-- This is the source data.
mal_src
src
;
float
srcInput
[
1024
];
mal_uint32
srcNextSampleIndex
=
mal_countof
(
srcInput
);
void
reload_src_input
()
{
mal_sine_wave_read
(
&
sineWave
,
mal_countof
(
srcInput
),
srcInput
);
srcNextSampleIndex
=
0
;
}
mal_uint32
on_src
(
mal_src
*
pSRC
,
mal_uint32
frameCount
,
void
**
ppSamplesOut
,
void
*
pUserData
)
{
mal_assert
(
pSRC
!=
NULL
);
mal_assert
(
pSRC
->
config
.
channels
==
1
);
(
void
)
pUserData
;
// Only read as much as is available in the input buffer. Do not reload the buffer here.
mal_uint32
framesAvailable
=
mal_countof
(
srcInput
)
-
srcNextSampleIndex
;
mal_uint32
framesToRead
=
frameCount
;
if
(
framesToRead
>
framesAvailable
)
{
framesToRead
=
framesAvailable
;
}
mal_copy_memory
(
ppSamplesOut
[
0
],
srcInput
+
srcNextSampleIndex
,
sizeof
(
float
)
*
framesToRead
);
srcNextSampleIndex
+=
framesToRead
;
return
framesToRead
;
}
mal_uint32
on_send_to_device
(
mal_device
*
pDevice
,
mal_uint32
frameCount
,
void
*
pFrames
)
{
(
void
)
pDevice
;
mal_assert
(
pDevice
->
format
==
mal_format_f32
);
mal_assert
(
pDevice
->
channels
==
1
);
float
*
pFramesF32
=
(
float
*
)
pFrames
;
// To reproduce the case we are needing to test, we need to read from the SRC in a very specific way. We keep looping
// until we've read the requested frame count, however we have an inner loop that keeps running until mal_src_read()
// returns 0, in which case we need to reload the SRC's input data and keep going.
mal_uint32
totalFramesRead
=
0
;
while
(
totalFramesRead
<
frameCount
)
{
mal_uint32
framesRemaining
=
frameCount
-
totalFramesRead
;
mal_uint32
maxFramesToRead
=
128
;
mal_uint32
framesToRead
=
framesRemaining
;
if
(
framesToRead
>
maxFramesToRead
)
{
framesToRead
=
maxFramesToRead
;
}
mal_uint32
framesRead
=
(
mal_uint32
)
mal_src_read_deinterleaved
(
&
src
,
framesToRead
,
(
void
**
)
&
pFramesF32
,
NULL
);
if
(
framesRead
==
0
)
{
reload_src_input
();
}
totalFramesRead
+=
framesRead
;
pFramesF32
+=
framesRead
;
}
mal_assert
(
totalFramesRead
==
frameCount
);
return
frameCount
;
}
int
main
(
int
argc
,
char
**
argv
)
{
(
void
)
argc
;
(
void
)
argv
;
mal_device_config
config
=
mal_device_config_init_playback
(
mal_format_f32
,
1
,
0
,
on_send_to_device
);
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
;
}
// For this test, we need the sine wave to be a different format to the device.
sampleRateOut
=
device
.
sampleRate
;
sampleRateIn
=
(
sampleRateOut
==
44100
)
?
48000
:
44100
;
mal_sine_wave_init
(
0
.
2
,
400
,
sampleRateIn
,
&
sineWave
);
mal_src_config
srcConfig
=
mal_src_config_init
(
sampleRateIn
,
sampleRateOut
,
1
,
on_src
,
NULL
);
srcConfig
.
algorithm
=
mal_src_algorithm_sinc
;
result
=
mal_src_init
(
&
srcConfig
,
&
src
);
if
(
result
!=
MAL_SUCCESS
)
{
printf
(
"Failed to create SRC.
\n
"
);
return
-
1
;
}
#if 0
msigvis_context sigvis;
result = msigvis_init(&sigvis);
if (result != MAL_SUCCESS) {
printf("Failed to initialize mini_sigvis context.\n");
return -1;
}
msigvis_screen screen;
result = msigvis_screen_init(&sigvis, 1280, 720, &screen);
if (result != MAL_SUCCESS) {
printf("Failed to initialize mini_sigvis screen.\n");
return -2;
}
msigvis_screen_show(&screen);
msigvis_channel channelSineWave;
result = msigvis_channel_init(&sigvis, mal_format_f32, sampleRateOut, &channelSineWave);
if (result != MAL_SUCCESS) {
printf("Failed to initialize mini_sigvis channel.\n");
return -3;
}
float testSamples[40960];
float* pFramesF32 = testSamples;
// To reproduce the case we are needing to test, we need to read from the SRC in a very specific way. We keep looping
// until we've read the requested frame count, however we have an inner loop that keeps running until mal_src_read()
// returns 0, in which case we need to reload the SRC's input data and keep going.
mal_uint32 totalFramesRead = 0;
while (totalFramesRead < mal_countof(testSamples)) {
mal_uint32 maxFramesToRead = 128;
mal_uint32 framesToRead = mal_countof(testSamples);
if (framesToRead > maxFramesToRead) {
framesToRead = maxFramesToRead;
}
mal_uint32 framesRead = (mal_uint32)mal_src_read_deinterleaved(&src, framesToRead, (void**)&pFramesF32, NULL);
if (framesRead == 0) {
reload_src_input();
}
totalFramesRead += framesRead;
pFramesF32 += framesRead;
}
msigvis_channel_push_samples(&channelSineWave, mal_countof(testSamples), testSamples);
msigvis_screen_add_channel(&screen, &channelSineWave);
int exitCode = msigvis_run(&sigvis);
msigvis_screen_uninit(&screen);
msigvis_uninit(&sigvis);
#else
result
=
mal_device_start
(
&
device
);
if
(
result
!=
MAL_SUCCESS
)
{
return
-
2
;
}
printf
(
"Press Enter to quit...
\n
"
);
getchar
();
mal_device_uninit
(
&
device
);
#endif
return
0
;
}
\ No newline at end of file
tests/mal_test_0.vcxproj
View file @
223c8e84
...
...
@@ -278,14 +278,22 @@
<ExcludedFromBuild
Condition=
"'$(Configuration)|$(Platform)'=='Debug|x64'"
>
true
</ExcludedFromBuild>
<ExcludedFromBuild
Condition=
"'$(Configuration)|$(Platform)'=='Release|x64'"
>
true
</ExcludedFromBuild>
</ClCompile>
<ClCompile
Include=
"mal_
test_0
.c"
>
<ClCompile
Include=
"mal_
resampling
.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)'=='Debug|ARM'"
>
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>
</ClCompile>
<ClCompile
Include=
"mal_test_0.c"
>
<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>
<ExcludedFromBuild
Condition=
"'$(Configuration)|$(Platform)'=='Debug|ARM'"
>
true
</ExcludedFromBuild>
...
...
tests/mal_test_0.vcxproj.filters
View file @
223c8e84
...
...
@@ -27,6 +27,9 @@
<ClCompile
Include=
"mal_dithering.c"
>
<Filter>
Source Files
</Filter>
</ClCompile>
<ClCompile
Include=
"mal_resampling.c"
>
<Filter>
Source Files
</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude
Include=
"..\mini_al.h"
>
...
...
tools/mini_sigvis/mini_sigvis.h
View file @
223c8e84
...
...
@@ -373,6 +373,8 @@ mal_result msigvis_screen_redraw(msigvis_screen* pScreen)
///////////////////////////////////////////////////////////////////////////////
mal_result
msigvis_channel_init
(
msigvis_context
*
pContext
,
mal_format
format
,
mal_uint32
sampleRate
,
msigvis_channel
*
pChannel
)
{
(
void
)
pContext
;
if
(
pChannel
==
NULL
)
{
return
MAL_INVALID_ARGS
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment