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
a4ddf179
Commit
a4ddf179
authored
Mar 25, 2018
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Format converter bug fixes.
parent
bbe719c4
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
230 additions
and
21 deletions
+230
-21
mini_al.h
mini_al.h
+17
-12
tests/mal_test_0.c
tests/mal_test_0.c
+213
-9
No files found.
mini_al.h
View file @
a4ddf179
...
...
@@ -16724,9 +16724,9 @@ mal_uint64 mal_format_converter_read_frames(mal_format_converter* pConverter, ma
mal_uint64
totalFramesRead
=
0
;
mal_uint32
sampleSizeIn
=
mal_get_bytes_per_sample
(
pConverter
->
config
.
formatIn
);
//
mal_uint32 sampleSizeOut = mal_get_bytes_per_sample(pConverter->config.formatOut);
mal_uint32
frameSizeIn
=
sampleSizeIn
*
pConverter
->
config
.
channels
;
//
mal_uint32 frameSizeOut = sampleSizeOut * pConverter->config.channels;
mal_uint32
sampleSizeOut
=
mal_get_bytes_per_sample
(
pConverter
->
config
.
formatOut
);
//
mal_uint32 frameSizeIn = sampleSizeIn * pConverter->config.channels;
mal_uint32
frameSizeOut
=
sampleSizeOut
*
pConverter
->
config
.
channels
;
mal_uint8
*
pNextFramesOut
=
(
mal_uint8
*
)
pFramesOut
;
if
(
pConverter
->
onRead
!=
NULL
)
{
...
...
@@ -16746,7 +16746,7 @@ mal_uint64 mal_format_converter_read_frames(mal_format_converter* pConverter, ma
}
totalFramesRead
+=
framesJustRead
;
pNextFramesOut
+=
framesJustRead
*
frameSize
In
;
pNextFramesOut
+=
framesJustRead
*
frameSize
Out
;
}
}
else
{
// Conversion required.
...
...
@@ -16770,7 +16770,7 @@ mal_uint64 mal_format_converter_read_frames(mal_format_converter* pConverter, ma
pConverter
->
onConvertPCM
(
pNextFramesOut
,
temp
,
framesJustRead
*
pConverter
->
config
.
channels
,
pConverter
->
config
.
ditherMode
);
totalFramesRead
+=
framesJustRead
;
pNextFramesOut
+=
framesJustRead
*
frameSize
In
;
pNextFramesOut
+=
framesJustRead
*
frameSize
Out
;
}
}
}
else
{
...
...
@@ -16823,7 +16823,7 @@ mal_uint64 mal_format_converter_read_frames(mal_format_converter* pConverter, ma
pConverter
->
onInterleavePCM
(
pNextFramesOut
,
(
const
void
**
)
ppTempSampleOfOutFormat
,
framesJustRead
,
pConverter
->
config
.
channels
);
totalFramesRead
+=
framesJustRead
;
pNextFramesOut
+=
framesJustRead
*
frameSize
In
;
pNextFramesOut
+=
framesJustRead
*
frameSize
Out
;
}
}
...
...
@@ -16838,7 +16838,7 @@ mal_uint64 mal_format_converter_read_frames_separated(mal_format_converter* pCon
mal_uint64
totalFramesRead
=
0
;
mal_uint32
sampleSizeIn
=
mal_get_bytes_per_sample
(
pConverter
->
config
.
formatIn
);
//
mal_uint32 sampleSizeOut = mal_get_bytes_per_sample(pConverter->config.formatOut);
mal_uint32
sampleSizeOut
=
mal_get_bytes_per_sample
(
pConverter
->
config
.
formatOut
);
mal_uint8
*
ppNextSamplesOut
[
MAL_MAX_CHANNELS
];
mal_copy_memory
(
ppNextSamplesOut
,
ppSamplesOut
,
sizeof
(
void
*
)
*
pConverter
->
config
.
channels
);
...
...
@@ -16881,7 +16881,7 @@ mal_uint64 mal_format_converter_read_frames_separated(mal_format_converter* pCon
totalFramesRead
+=
framesJustRead
;
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
pConverter
->
config
.
channels
;
++
iChannel
)
{
ppNextSamplesOut
[
iChannel
]
+=
framesJustRead
*
sampleSize
In
;
ppNextSamplesOut
[
iChannel
]
+=
framesJustRead
*
sampleSize
Out
;
}
}
}
else
{
...
...
@@ -16902,7 +16902,7 @@ mal_uint64 mal_format_converter_read_frames_separated(mal_format_converter* pCon
totalFramesRead
+=
framesJustRead
;
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
pConverter
->
config
.
channels
;
++
iChannel
)
{
ppNextSamplesOut
[
iChannel
]
+=
framesJustRead
*
sampleSize
In
;
ppNextSamplesOut
[
iChannel
]
+=
framesJustRead
*
sampleSize
Out
;
}
}
}
else
{
...
...
@@ -16910,6 +16910,11 @@ mal_uint64 mal_format_converter_read_frames_separated(mal_format_converter* pCon
mal_uint8
temp
[
MAL_MAX_CHANNELS
][
MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES
*
128
];
mal_assert
(
sizeof
(
temp
[
0
])
<=
0xFFFFFFFF
);
void
*
ppTemp
[
MAL_MAX_CHANNELS
];
for
(
mal_uint32
i
=
0
;
i
<
pConverter
->
config
.
channels
;
++
i
)
{
ppTemp
[
i
]
=
&
temp
[
i
];
}
mal_uint32
maxFramesToReadAtATime
=
sizeof
(
temp
[
0
])
/
sampleSizeIn
;
while
(
totalFramesRead
<
frameCount
)
{
...
...
@@ -16919,14 +16924,14 @@ mal_uint64 mal_format_converter_read_frames_separated(mal_format_converter* pCon
framesToReadRightNow
=
maxFramesToReadAtATime
;
}
mal_uint32
framesJustRead
=
(
mal_uint32
)
pConverter
->
onReadSeparated
(
pConverter
,
(
mal_uint32
)
framesToReadRightNow
,
(
void
**
)
ppNextSamplesOut
,
pConverter
->
pUserData
);
mal_uint32
framesJustRead
=
(
mal_uint32
)
pConverter
->
onReadSeparated
(
pConverter
,
(
mal_uint32
)
framesToReadRightNow
,
ppTemp
,
pConverter
->
pUserData
);
if
(
framesJustRead
==
0
)
{
break
;
}
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
pConverter
->
config
.
channels
;
iChannel
+=
1
)
{
pConverter
->
onConvertPCM
(
ppNextSamplesOut
[
iChannel
],
t
emp
[
iChannel
],
framesJustRead
,
pConverter
->
config
.
ditherMode
);
ppNextSamplesOut
[
iChannel
]
+=
framesJustRead
*
sampleSize
In
;
pConverter
->
onConvertPCM
(
ppNextSamplesOut
[
iChannel
],
ppT
emp
[
iChannel
],
framesJustRead
,
pConverter
->
config
.
ditherMode
);
ppNextSamplesOut
[
iChannel
]
+=
framesJustRead
*
sampleSize
Out
;
}
totalFramesRead
+=
framesJustRead
;
...
...
tests/mal_test_0.c
View file @
a4ddf179
...
...
@@ -34,6 +34,22 @@ void on_log(mal_context* pContext, mal_device* pDevice, const char* message)
printf
(
"%s
\n
"
,
message
);
}
FILE
*
mal_fopen
(
const
char
*
filePath
,
const
char
*
openMode
)
{
FILE
*
pFile
;
#if _MSC_VER
if
(
fopen_s
(
&
pFile
,
filePath
,
openMode
)
!=
0
)
{
return
NULL
;
}
#else
pFile
=
fopen
(
filePath
,
openMode
);
if
(
pFile
==
NULL
)
{
return
NULL
;
}
#endif
return
pFile
;
}
void
*
open_and_read_file_data
(
const
char
*
filePath
,
size_t
*
pSizeOut
)
{
...
...
@@ -44,17 +60,10 @@ void* open_and_read_file_data(const char* filePath, size_t* pSizeOut)
return
NULL
;
}
FILE
*
pFile
;
#if _MSC_VER
if
(
fopen_s
(
&
pFile
,
filePath
,
"rb"
)
!=
0
)
{
return
NULL
;
}
#else
pFile
=
fopen
(
filePath
,
"rb"
);
FILE
*
pFile
=
mal_fopen
(
filePath
,
"rb"
);
if
(
pFile
==
NULL
)
{
return
NULL
;
}
#endif
fseek
(
pFile
,
0
,
SEEK_END
);
mal_uint64
fileSize
=
ftell
(
pFile
);
...
...
@@ -168,7 +177,7 @@ int mal_pcm_compare(const void* a, const void* b, mal_uint64 count, mal_format f
case
mal_format_s24
:
{
mal_int32
sampleA
=
((
mal_int32
)(((
mal_uint32
)(
a_u8
[
i
*
3
+
0
])
<<
8
)
|
((
mal_uint32
)(
a_u8
[
i
*
3
+
1
])
<<
16
)
|
((
mal_uint32
)(
a_u8
[
i
*
3
+
2
]))
<<
24
))
>>
8
;
mal_int32
sampleB
=
((
mal_int32
)(((
mal_uint32
)(
b_u8
[
i
*
3
+
0
])
<<
8
)
|
((
mal_uint32
)(
b_u8
[
i
*
3
+
1
])
<<
16
)
|
((
mal_uint32
)(
b_u8
[
i
*
3
+
2
]))
<<
24
))
>>
8
;
;
mal_int32
sampleB
=
((
mal_int32
)(((
mal_uint32
)(
b_u8
[
i
*
3
+
0
])
<<
8
)
|
((
mal_uint32
)(
b_u8
[
i
*
3
+
1
])
<<
16
)
|
((
mal_uint32
)(
b_u8
[
i
*
3
+
2
]))
<<
24
))
>>
8
;
if
(
sampleA
!=
sampleB
)
{
if
(
abs
(
sampleA
-
sampleB
)
>
allowedDifference
)
{
// Allow a difference of 1.
printf
(
"Sample %I64u not equal. %d != %d (diff: %d)
\n
"
,
i
,
sampleA
,
sampleB
,
sampleA
-
sampleB
);
...
...
@@ -936,6 +945,192 @@ int do_interleaving_tests()
}
mal_uint32
converter_test_interleaved_callback
(
mal_format_converter
*
pConverter
,
mal_uint32
frameCount
,
void
*
pFramesOut
,
void
*
pUserData
)
{
mal_sine_wave
*
pSineWave
=
(
mal_sine_wave
*
)
pUserData
;
mal_assert
(
pSineWave
!=
NULL
);
float
*
pFramesOutF32
=
(
float
*
)
pFramesOut
;
for
(
mal_uint32
iFrame
=
0
;
iFrame
<
frameCount
;
iFrame
+=
1
)
{
float
sample
;
mal_sine_wave_read
(
pSineWave
,
1
,
&
sample
);
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
pConverter
->
config
.
channels
;
iChannel
+=
1
)
{
pFramesOutF32
[
iFrame
*
pConverter
->
config
.
channels
+
iChannel
]
=
sample
;
}
}
return
frameCount
;
}
mal_uint32
converter_test_separated_callback
(
mal_format_converter
*
pConverter
,
mal_uint32
frameCount
,
void
**
ppSamplesOut
,
void
*
pUserData
)
{
mal_sine_wave
*
pSineWave
=
(
mal_sine_wave
*
)
pUserData
;
mal_assert
(
pSineWave
!=
NULL
);
mal_sine_wave_read
(
pSineWave
,
frameCount
,
ppSamplesOut
[
0
]);
// Copy everything from the first channel over the others.
for
(
mal_uint32
iChannel
=
1
;
iChannel
<
pConverter
->
config
.
channels
;
iChannel
+=
1
)
{
mal_copy_memory
(
ppSamplesOut
[
iChannel
],
ppSamplesOut
[
0
],
frameCount
*
sizeof
(
float
));
}
return
frameCount
;
}
int
do_format_converter_tests
()
{
double
amplitude
=
1
;
double
periodsPerSecond
=
400
;
mal_uint32
sampleRate
=
48000
;
mal_result
result
=
MAL_SUCCESS
;
mal_sine_wave
sineWave
;
mal_format_converter
converter
;
mal_format_converter_config
config
;
mal_zero_object
(
&
config
);
config
.
formatIn
=
mal_format_f32
;
config
.
formatOut
=
mal_format_s16
;
config
.
channels
=
2
;
config
.
streamFormatIn
=
mal_stream_format_pcm
;
config
.
streamFormatOut
=
mal_stream_format_pcm
;
config
.
ditherMode
=
mal_dither_mode_none
;
// 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
);
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_frames
(
&
converter
,
1024
,
interleavedFrames
);
if
(
framesRead
!=
1024
)
{
printf
(
"Failed to read interleaved data from converter.
\n
"
);
return
-
1
;
}
FILE
*
pFile
=
mal_fopen
(
"res/output/converter_f32_to_s16_interleaved_interleaved__stereo_48000.raw"
,
"wb"
);
if
(
pFile
==
NULL
)
{
printf
(
"Failed to open output file.
\n
"
);
return
-
1
;
}
fwrite
(
interleavedFrames
,
sizeof
(
mal_int16
),
framesRead
*
converter
.
config
.
channels
,
pFile
);
fclose
(
pFile
);
}
// 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
);
if
(
result
!=
MAL_SUCCESS
)
{
printf
(
"Failed to initialize converter.
\n
"
);
return
-
1
;
}
mal_int16
separatedFrames
[
MAL_MAX_CHANNELS
][
1024
];
void
*
ppSeparatedFrames
[
MAL_MAX_CHANNELS
];
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
converter
.
config
.
channels
;
iChannel
+=
1
)
{
ppSeparatedFrames
[
iChannel
]
=
&
separatedFrames
[
iChannel
];
}
mal_uint64
framesRead
=
mal_format_converter_read_frames_separated
(
&
converter
,
1024
,
ppSeparatedFrames
);
if
(
framesRead
!=
1024
)
{
printf
(
"Failed to read interleaved data from converter.
\n
"
);
return
-
1
;
}
// Write a separate file for each channel.
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
converter
.
config
.
channels
;
iChannel
+=
1
)
{
char
filePath
[
256
];
snprintf
(
filePath
,
sizeof
(
filePath
),
"res/output/converter_f32_to_s16_interleaved_deinterleaved__stereo_48000.raw.%d"
,
iChannel
);
FILE
*
pFile
=
mal_fopen
(
filePath
,
"wb"
);
if
(
pFile
==
NULL
)
{
printf
(
"Failed to open output file.
\n
"
);
return
-
1
;
}
fwrite
(
ppSeparatedFrames
[
iChannel
],
sizeof
(
mal_int16
),
framesRead
,
pFile
);
fclose
(
pFile
);
}
}
// Deinterleaved/Interleaved f32 to s16.
{
mal_sine_wave_init
(
amplitude
,
periodsPerSecond
,
sampleRate
,
&
sineWave
);
result
=
mal_format_converter_init_separated
(
&
config
,
converter_test_separated_callback
,
&
sineWave
,
&
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_frames
(
&
converter
,
1024
,
interleavedFrames
);
if
(
framesRead
!=
1024
)
{
printf
(
"Failed to read interleaved data from converter.
\n
"
);
return
-
1
;
}
FILE
*
pFile
=
mal_fopen
(
"res/output/converter_f32_to_s16_deinterleaved_interleaved__stereo_48000.raw"
,
"wb"
);
if
(
pFile
==
NULL
)
{
printf
(
"Failed to open output file.
\n
"
);
return
-
1
;
}
fwrite
(
interleavedFrames
,
sizeof
(
mal_int16
),
framesRead
*
converter
.
config
.
channels
,
pFile
);
fclose
(
pFile
);
}
// Deinterleaved/Deinterleaved f32 to s16.
{
mal_sine_wave_init
(
amplitude
,
periodsPerSecond
,
sampleRate
,
&
sineWave
);
result
=
mal_format_converter_init_separated
(
&
config
,
converter_test_separated_callback
,
&
sineWave
,
&
converter
);
if
(
result
!=
MAL_SUCCESS
)
{
printf
(
"Failed to initialize converter.
\n
"
);
return
-
1
;
}
mal_int16
separatedFrames
[
MAL_MAX_CHANNELS
][
1024
];
void
*
ppSeparatedFrames
[
MAL_MAX_CHANNELS
];
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
converter
.
config
.
channels
;
iChannel
+=
1
)
{
ppSeparatedFrames
[
iChannel
]
=
&
separatedFrames
[
iChannel
];
}
mal_uint64
framesRead
=
mal_format_converter_read_frames_separated
(
&
converter
,
1024
,
ppSeparatedFrames
);
if
(
framesRead
!=
1024
)
{
printf
(
"Failed to read interleaved data from converter.
\n
"
);
return
-
1
;
}
// Write a separate file for each channel.
for
(
mal_uint32
iChannel
=
0
;
iChannel
<
converter
.
config
.
channels
;
iChannel
+=
1
)
{
char
filePath
[
256
];
snprintf
(
filePath
,
sizeof
(
filePath
),
"res/output/converter_f32_to_s16_deinterleaved_deinterleaved__stereo_48000.raw.%d"
,
iChannel
);
FILE
*
pFile
=
mal_fopen
(
filePath
,
"wb"
);
if
(
pFile
==
NULL
)
{
printf
(
"Failed to open output file.
\n
"
);
return
-
1
;
}
fwrite
(
ppSeparatedFrames
[
iChannel
],
sizeof
(
mal_int16
),
framesRead
,
pFile
);
fclose
(
pFile
);
}
}
return
0
;
}
int
do_backend_test
(
mal_backend
backend
)
{
mal_result
result
=
MAL_SUCCESS
;
...
...
@@ -1182,6 +1377,15 @@ int main(int argc, char** argv)
}
printf
(
"=== END TESTING INTERLEAVING/DEINTERLEAVING ===
\n
"
);
printf
(
"
\n
"
);
printf
(
"=== TESTING FORMAT CONVERTER ===
\n
"
);
result
=
do_format_converter_tests
();
if
(
result
<
0
)
{
hasErrorOccurred
=
MAL_TRUE
;
}
printf
(
"=== END TESTING FORMAT CONVERTER ===
\n
"
);
printf
(
"
\n
"
);
printf
(
"=== TESTING BACKENDS ===
\n
"
);
...
...
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