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
f07b84ce
Commit
f07b84ce
authored
Apr 21, 2018
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update extras.
parent
f62ce71b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
367 additions
and
223 deletions
+367
-223
extras/dr_flac.h
extras/dr_flac.h
+40
-4
extras/dr_mp3.h
extras/dr_mp3.h
+42
-38
extras/dr_wav.h
extras/dr_wav.h
+285
-181
No files found.
extras/dr_flac.h
View file @
f07b84ce
// FLAC audio decoder. Public domain. See "unlicense" statement at the end of this file.
// dr_flac - v0.8
d - 2017-09-22
// dr_flac - v0.8
g - 2018-04-19
//
// David Reid - mackron@gmail.com
...
...
@@ -106,6 +106,7 @@
//
//
// QUICK NOTES
// - dr_flac does not currently support changing the sample rate nor channel count mid stream.
// - Audio data is output as signed 32-bit PCM, regardless of the bits per sample the FLAC stream is encoded as.
// - This has not been tested on big-endian architectures.
// - Rice codes in unencoded binary form (see https://xiph.org/flac/format.html#rice_partition) has not been tested. If anybody
...
...
@@ -759,6 +760,8 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM)
#define DRFLAC_ARM
#endif
// Compile-time CPU feature support.
...
...
@@ -806,7 +809,7 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
#include <endian.h>
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1500
#if defined(_MSC_VER) && _MSC_VER >= 1500
&& (defined(DRFLAC_X86) || defined(DRFLAC_X64))
#define DRFLAC_HAS_LZCNT_INTRINSIC
#elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
#define DRFLAC_HAS_LZCNT_INTRINSIC
...
...
@@ -1694,7 +1697,7 @@ static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs)
#if !defined(DR_FLAC_NO_SIMD) && defined(DRFLAC_HAS_LZCNT_INTRINSIC)
#define DRFLAC_IMPLEMENT_CLZ_LZCNT
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1400
#if defined(_MSC_VER) && _MSC_VER >= 1400
&& (defined(DRFLAC_X64) || defined(DRFLAC_X86))
#define DRFLAC_IMPLEMENT_CLZ_MSVC
#endif
...
...
@@ -2402,6 +2405,16 @@ static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_
return
DRFLAC_FALSE
;
}
// From the FLAC spec:
// The Rice partition order in a Rice-coded residual section must be less than or equal to 8.
if
(
partitionOrder
>
8
)
{
return
DRFLAC_FALSE
;
}
// Validation check.
if
((
blockSize
/
(
1
<<
partitionOrder
))
<=
order
)
{
return
DRFLAC_FALSE
;
}
drflac_uint32
samplesInPartition
=
(
blockSize
/
(
1
<<
partitionOrder
))
-
order
;
drflac_uint32
partitionsRemaining
=
(
1
<<
partitionOrder
);
...
...
@@ -2446,7 +2459,10 @@ static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_
}
partitionsRemaining
-=
1
;
samplesInPartition
=
blockSize
/
(
1
<<
partitionOrder
);
if
(
partitionOrder
!=
0
)
{
samplesInPartition
=
blockSize
/
(
1
<<
partitionOrder
);
}
}
return
DRFLAC_TRUE
;
...
...
@@ -2982,7 +2998,17 @@ static drflac_result drflac__decode_frame(drflac* pFlac)
// This function should be called while the stream is sitting on the first byte after the frame header.
drflac_zero_memory
(
pFlac
->
currentFrame
.
subframes
,
sizeof
(
pFlac
->
currentFrame
.
subframes
));
// The frame block size must never be larger than the maximum block size defined by the FLAC stream.
if
(
pFlac
->
currentFrame
.
header
.
blockSize
>
pFlac
->
maxBlockSize
)
{
return
DRFLAC_ERROR
;
}
// The number of channels in the frame must match the channel count from the STREAMINFO block.
int
channelCount
=
drflac__get_channel_count_from_channel_assignment
(
pFlac
->
currentFrame
.
header
.
channelAssignment
);
if
(
channelCount
!=
(
int
)
pFlac
->
channels
)
{
return
DRFLAC_ERROR
;
}
for
(
int
i
=
0
;
i
<
channelCount
;
++
i
)
{
if
(
!
drflac__decode_subframe
(
&
pFlac
->
bs
,
&
pFlac
->
currentFrame
,
i
,
pFlac
->
pDecodedSamples
+
(
pFlac
->
currentFrame
.
header
.
blockSize
*
i
)))
{
return
DRFLAC_ERROR
;
...
...
@@ -5498,6 +5524,16 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, dr
// REVISION HISTORY
//
// v0.8g - 2018-04-19
// - Fix build on non-x86/x64 architectures.
//
// v0.8f - 2018-02-02
// - Stop pretending to support changing rate/channels mid stream.
//
// v0.8e - 2018-02-01
// - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream.
// - Fix a crash the the Rice partition order is invalid.
//
// v0.8d - 2017-09-22
// - Add support for decoding streams with ID3 tags. ID3 tags are just skipped.
//
...
...
extras/dr_mp3.h
View file @
f07b84ce
// MP3 audio decoder. Public domain. See "unlicense" statement at the end of this file.
// dr_mp3 - v0.
1c - 2018-03-1
1
// dr_mp3 - v0.
2 - 2018-04-2
1
//
// David Reid - mackron@gmail.com
//
...
...
@@ -333,12 +333,12 @@ void drmp3_free(void* p);
#define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
#define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
#define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))
*
3)
#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))
*
3)
#define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
#define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
#define DRMP3_BITS_DEQUANTIZER_OUT -1
#define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT
*
4 - 210)
#define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT
*
4 - 210)
#define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3)
#define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a))
...
...
@@ -351,7 +351,7 @@ void drmp3_free(void* p);
#define DR_MP3_ONLY_SIMD
#endif
#if
defined(_MSC_VER
) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__))
#if
(defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__))
#if defined(_MSC_VER)
#include <intrin.h>
#endif
...
...
@@ -571,7 +571,7 @@ static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
static
int
drmp3_hdr_frame_bytes
(
const
drmp3_uint8
*
h
,
int
free_format_size
)
{
int
frame_bytes
=
drmp3_hdr_frame_samples
(
h
)
*
drmp3_hdr_bitrate_kbps
(
h
)
*
125
/
drmp3_hdr_sample_rate_hz
(
h
);
int
frame_bytes
=
drmp3_hdr_frame_samples
(
h
)
*
drmp3_hdr_bitrate_kbps
(
h
)
*
125
/
drmp3_hdr_sample_rate_hz
(
h
);
if
(
DRMP3_HDR_IS_LAYER_1
(
h
))
{
frame_bytes
&=
~
3
;
/* slot align */
...
...
@@ -647,7 +647,7 @@ static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_ui
if
(
mask
&
m
)
{
int
b
=
drmp3_bs_get_bits
(
bs
,
6
);
s
=
g_deq_L12
[
ba
*
3
-
6
+
b
%
3
]
*
(
1
<<
21
>>
b
/
3
);
s
=
g_deq_L12
[
ba
*
3
-
6
+
b
%
3
]
*
(
1
<<
21
>>
b
/
3
);
}
*
scf
++
=
s
;
}
...
...
@@ -665,7 +665,7 @@ static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp
0
,
17
,
18
,
3
,
19
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
0
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
};
const
drmp3_L12_subband_alloc
*
subband_alloc
=
drmp3_L12_subband_alloc_table
(
hdr
,
sci
);
const
drmp3_L12_subband_alloc
*
subband_alloc
=
drmp3_L12_subband_alloc_table
(
hdr
,
sci
);
int
i
,
k
=
0
,
ba_bits
=
0
;
const
drmp3_uint8
*
ba_code_tab
=
g_bitalloc_code_tab
;
...
...
@@ -689,12 +689,12 @@ static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp
sci
->
bitalloc
[
2
*
i
+
1
]
=
sci
->
stereo_bands
?
ba
:
0
;
}
for
(
i
=
0
;
i
<
2
*
sci
->
total_bands
;
i
++
)
for
(
i
=
0
;
i
<
2
*
sci
->
total_bands
;
i
++
)
{
sci
->
scfcod
[
i
]
=
(
drmp3_uint8
)(
sci
->
bitalloc
[
i
]
?
DRMP3_HDR_IS_LAYER_1
(
hdr
)
?
2
:
drmp3_bs_get_bits
(
bs
,
2
)
:
6
);
}
drmp3_L12_read_scalefactors
(
bs
,
sci
->
bitalloc
,
sci
->
scfcod
,
sci
->
total_bands
*
2
,
sci
->
scf
);
drmp3_L12_read_scalefactors
(
bs
,
sci
->
bitalloc
,
sci
->
scfcod
,
sci
->
total_bands
*
2
,
sci
->
scf
);
for
(
i
=
sci
->
stereo_bands
;
i
<
sci
->
total_bands
;
i
++
)
{
...
...
@@ -1008,7 +1008,7 @@ static float drmp3_L3_pow_43(int x)
sign
=
2
*
x
&
64
;
frac
=
(
float
)((
x
&
63
)
-
sign
)
/
((
x
&
~
63
)
+
sign
);
return
g_pow43
[(
x
+
sign
)
>>
6
]
*
(
1
.
f
+
frac
*
((
4
.
f
/
3
)
+
frac
*
(
2
.
f
/
9
)))
*
mult
;
return
g_pow43
[(
x
+
sign
)
>>
6
]
*
(
1
.
f
+
frac
*
((
4
.
f
/
3
)
+
frac
*
(
2
.
f
/
9
)))
*
mult
;
}
static
void
drmp3_L3_huffman
(
float
*
dst
,
drmp3_bs
*
bs
,
const
drmp3_L3_gr_info
*
gr_info
,
const
float
*
scf
,
int
layer3gr_limit
)
...
...
@@ -1036,7 +1036,7 @@ static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *g
static
const
drmp3_uint8
g_linbits
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
2
,
3
,
4
,
6
,
8
,
10
,
13
,
4
,
5
,
6
,
7
,
8
,
9
,
11
,
13
};
#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n))
#define DRMP3_FLUSH_BITS(n) {
bs_cache <<= (n); bs_sh += (n);
}
#define DRMP3_FLUSH_BITS(n) {
bs_cache <<= (n); bs_sh += (n);
}
#define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
#define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
...
...
@@ -1052,7 +1052,7 @@ static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *g
{
int
tab_num
=
gr_info
->
table_select
[
ireg
];
int
sfb_cnt
=
gr_info
->
region_count
[
ireg
++
];
const
short
*
codebook
=
tabindex
[
tab_num
];
const
short
*
codebook
=
tabindex
[
tab_num
];
int
linbits
=
g_linbits
[
tab_num
];
do
{
...
...
@@ -1074,24 +1074,21 @@ static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *g
for
(
j
=
0
;
j
<
2
;
j
++
,
dst
++
,
leaf
>>=
4
)
{
int
lsb
=
leaf
&
0x0F
;
if
(
lsb
)
if
(
lsb
==
15
&&
linbits
)
{
if
(
lsb
==
15
&&
linbits
)
{
lsb
+=
DRMP3_PEEK_BITS
(
linbits
);
DRMP3_FLUSH_BITS
(
linbits
);
DRMP3_CHECK_BITS
;
*
dst
=
one
*
drmp3_L3_pow_43
(
lsb
)
*
((
drmp3_int32
)
bs_cache
<
0
?
-
1
:
1
);
}
else
{
*
dst
=
g_pow43_signed
[
lsb
*
2
+
(
bs_cache
>>
31
)]
*
one
;
}
DRMP3_FLUSH_BITS
(
1
);
lsb
+=
DRMP3_PEEK_BITS
(
linbits
);
DRMP3_FLUSH_BITS
(
linbits
);
DRMP3_CHECK_BITS
;
*
dst
=
one
*
drmp3_L3_pow_43
(
lsb
)
*
((
int32_t
)
bs_cache
<
0
?
-
1
:
1
);
}
else
{
*
dst
=
g_pow43_signed
[
lsb
*
2
+
(
bs_cache
>>
31
)]
*
one
;
}
DRMP3_FLUSH_BITS
(
lsb
?
1
:
0
);
}
DRMP3_CHECK_BITS
;
}
while
(
--
pairs_to_decode
);
}
while
((
big_val_cnt
-=
np
)
>
0
&&
--
sfb_cnt
>=
0
);
}
while
((
big_val_cnt
-=
np
)
>
0
&&
--
sfb_cnt
>=
0
);
}
for
(
np
=
1
-
big_val_cnt
;;
dst
+=
4
)
...
...
@@ -1107,8 +1104,8 @@ static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *g
{
break
;
}
#define DRMP3_RELOAD_SCALEFACTOR if (!--np) {
np = *sfb++/2; if (!np) break; one = *scf++;
}
#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) {
dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1)
}
#define DRMP3_RELOAD_SCALEFACTOR if (!--np) {
np = *sfb++/2; if (!np) break; one = *scf++;
}
#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) {
dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1)
}
DRMP3_RELOAD_SCALEFACTOR
;
DRMP3_DEQ_COUNT1
(
0
);
DRMP3_DEQ_COUNT1
(
1
);
...
...
@@ -1241,7 +1238,7 @@ static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sf
*
dst
++
=
src
[
2
*
len
];
}
}
memcpy
(
grbuf
,
scratch
,
(
dst
-
scratch
)
*
sizeof
(
float
));
memcpy
(
grbuf
,
scratch
,
(
dst
-
scratch
)
*
sizeof
(
float
));
}
static
void
drmp3_L3_antialias
(
float
*
grbuf
,
int
nbands
)
...
...
@@ -1720,8 +1717,8 @@ static void drmp3d_synth(float *xl, short *dstl, int nch, float *lins)
-
4
,
7
,
-
91
,
117
,
177
,
-
106
,
-
1428
,
1698
,
402
,
545
,
-
9416
,
9916
,
-
7154
,
12980
,
-
61289
,
66494
,
-
5
,
6
,
-
97
,
111
,
163
,
-
127
,
-
1498
,
1634
,
185
,
288
,
-
9585
,
9838
,
-
8540
,
11455
,
-
62684
,
65290
};
float
*
zlin
=
lins
+
15
*
64
;
const
float
*
w
=
g_win
;
float
*
zlin
=
lins
+
15
*
64
;
const
float
*
w
=
g_win
;
zlin
[
4
*
15
]
=
xl
[
18
*
16
];
zlin
[
4
*
15
+
1
]
=
xr
[
18
*
16
];
...
...
@@ -1742,10 +1739,10 @@ static void drmp3d_synth(float *xl, short *dstl, int nch, float *lins)
if
(
drmp3_have_simd
())
for
(
i
=
14
;
i
>=
0
;
i
--
)
{
#define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]);
#define DRMP3_V0(k) {
DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0),
DRMP3_VMUL(vy, w1)); }
#define DRMP3_V1(k) {
DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0),
DRMP3_VMUL(vy, w1))); }
#define DRMP3_V2(k) {
DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1),
DRMP3_VMUL(vz, w0))); }
drmp3_f4
a
,
b
;
#define DRMP3_V0(k) {
DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0),
DRMP3_VMUL(vy, w1)); }
#define DRMP3_V1(k) {
DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0),
DRMP3_VMUL(vy, w1))); }
#define DRMP3_V2(k) {
DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1),
DRMP3_VMUL(vz, w0))); }
drmp3_f4
a
,
b
;
zlin
[
4
*
i
]
=
xl
[
18
*
(
31
-
i
)];
zlin
[
4
*
i
+
1
]
=
xr
[
18
*
(
31
-
i
)];
zlin
[
4
*
i
+
2
]
=
xl
[
1
+
18
*
(
31
-
i
)];
...
...
@@ -1794,10 +1791,10 @@ static void drmp3d_synth(float *xl, short *dstl, int nch, float *lins)
#else
for
(
i
=
14
;
i
>=
0
;
i
--
)
{
#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *
vz = &zlin[4*i - k*64]; float *
vy = &zlin[4*i - (15 - k)*64];
#define DRMP3_S0(k) {
int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j] * w1 + vy[j] * w0, a[j] = vz[j] * w0 - vy[j] * w1;
}
#define DRMP3_S1(k) {
int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j] * w1 + vy[j] * w0, a[j] += vz[j] * w0 - vy[j] * w1;
}
#define DRMP3_S2(k) {
int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j] * w1 + vy[j] * w0, a[j] += vy[j] * w1 - vz[j] * w0;
}
#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *
vz = &zlin[4*i - k*64]; float *
vy = &zlin[4*i - (15 - k)*64];
#define DRMP3_S0(k) {
int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1;
}
#define DRMP3_S1(k) {
int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1;
}
#define DRMP3_S2(k) {
int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0;
}
float
a
[
4
],
b
[
4
];
zlin
[
4
*
i
]
=
xl
[
18
*
(
31
-
i
)];
...
...
@@ -2747,6 +2744,13 @@ void drmp3_free(void* p)
// REVISION HISTORY
// ===============
//
// v0.2 - 2018-04-21
// - Bring up to date with minimp3.
// - Start using major.minor.revision versioning.
//
// v0.1d - 2018-03-30
// - Bring up to date with minimp3.
//
// v0.1c - 2018-03-11
// - Fix C++ build error.
//
...
...
extras/dr_wav.h
View file @
f07b84ce
// WAV audio loader and writer. Public domain. See "unlicense" statement at the end of this file.
// dr_wav - v0.7
a - 2017-11-17
// dr_wav - v0.7
f - 2018-02-05
//
// David Reid - mackron@gmail.com
...
...
@@ -103,8 +103,8 @@
// - Signed 16-bit PCM
// - Signed 24-bit PCM
// - Signed 32-bit PCM
// - IEEE 32-bit floating point
.
// - IEEE 64-bit floating point
.
// - IEEE 32-bit floating point
// - IEEE 64-bit floating point
// - A-law and u-law
// - Microsoft ADPCM
// - IMA ADPCM (DVI, format code 0x11)
...
...
@@ -643,13 +643,13 @@ drwav_int16* drwav_open_and_read_s16(drwav_read_proc onRead, drwav_seek_proc onS
float
*
drwav_open_and_read_f32
(
drwav_read_proc
onRead
,
drwav_seek_proc
onSeek
,
void
*
pUserData
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
drwav_int32
*
drwav_open_and_read_s32
(
drwav_read_proc
onRead
,
drwav_seek_proc
onSeek
,
void
*
pUserData
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
#ifndef DR_WAV_NO_STDIO
// Opens an decodes a wav file in a single operation.
// Opens an
d
decodes a wav file in a single operation.
drwav_int16
*
drwav_open_and_read_file_s16
(
const
char
*
filename
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
float
*
drwav_open_and_read_file_f32
(
const
char
*
filename
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
drwav_int32
*
drwav_open_and_read_file_s32
(
const
char
*
filename
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
#endif
// Opens an decodes a wav file from a block of memory in a single operation.
// Opens an
d
decodes a wav file from a block of memory in a single operation.
drwav_int16
*
drwav_open_and_read_memory_s16
(
const
void
*
data
,
size_t
dataSize
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
float
*
drwav_open_and_read_memory_f32
(
const
void
*
data
,
size_t
dataSize
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
drwav_int32
*
drwav_open_and_read_memory_s32
(
const
void
*
data
,
size_t
dataSize
,
unsigned
int
*
channels
,
unsigned
int
*
sampleRate
,
drwav_uint64
*
totalSampleCount
);
...
...
@@ -820,6 +820,9 @@ static DRWAV_INLINE drwav_bool32 drwav__is_compressed_format_tag(drwav_uint16 fo
}
drwav_uint64
drwav_read_s16__msadpcm
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int16
*
pBufferOut
);
drwav_uint64
drwav_read_s16__ima
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int16
*
pBufferOut
);
typedef
struct
{
union
...
...
@@ -1395,6 +1398,11 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
return
DRWAV_FALSE
;
// Failed to read the "fmt " chunk.
}
// Basic validation.
if
(
fmt
.
sampleRate
==
0
||
fmt
.
channels
==
0
||
fmt
.
bitsPerSample
==
0
||
fmt
.
blockAlign
==
0
)
{
return
DRWAV_FALSE
;
// Invalid channel count. Probably an invalid WAV file.
}
// Translate the internal format.
unsigned
short
translatedFormatTag
=
fmt
.
formatTag
;
...
...
@@ -1470,11 +1478,16 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
pWav
->
sampleRate
=
fmt
.
sampleRate
;
pWav
->
channels
=
fmt
.
channels
;
pWav
->
bitsPerSample
=
fmt
.
bitsPerSample
;
pWav
->
bytesPerSample
=
(
unsigned
int
)(
fmt
.
blockAlign
/
fmt
.
channels
)
;
pWav
->
bytesPerSample
=
fmt
.
blockAlign
/
fmt
.
channels
;
pWav
->
bytesRemaining
=
dataSize
;
pWav
->
translatedFormatTag
=
translatedFormatTag
;
pWav
->
dataChunkDataSize
=
dataSize
;
// The bytes per sample should never be 0 at this point. This would indicate an invalid WAV file.
if
(
pWav
->
bytesPerSample
==
0
)
{
return
DRWAV_FALSE
;
}
if
(
sampleCountFromFactChunk
!=
0
)
{
pWav
->
totalSampleCount
=
sampleCountFromFactChunk
*
fmt
.
channels
;
}
else
{
...
...
@@ -1489,18 +1502,26 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
pWav
->
totalSampleCount
=
((
blockCount
*
(
fmt
.
blockAlign
-
(
4
*
pWav
->
channels
)))
*
2
)
+
(
blockCount
*
pWav
->
channels
);
}
}
if
(
pWav
->
translatedFormatTag
==
DR_WAVE_FORMAT_ADPCM
)
{
// The way we calculate the bytes per sample does not make sense for compressed formats so we just set it to 0.
if
(
drwav__is_compressed_format_tag
(
pWav
->
translatedFormatTag
))
{
pWav
->
bytesPerSample
=
0
;
}
// Some formats only support a certain number of channels.
if
(
pWav
->
translatedFormatTag
==
DR_WAVE_FORMAT_ADPCM
||
pWav
->
translatedFormatTag
==
DR_WAVE_FORMAT_DVI_ADPCM
)
{
if
(
pWav
->
channels
>
2
)
{
return
DRWAV_FALSE
;
}
}
#ifdef DR_WAV_LIBSNDFILE_COMPAT
// I use libsndfile as a benchmark for testing, however in the version I'm using (from the Windows installer on the libsndfile website),
// it appears the total sample count libsndfile uses for MS-ADPCM is incorrect. It would seem they are computing the total sample count
// from the number of blocks, however this results in the inclusion of the extra silent samples at the end of the last block. The correct
// way to know the total sample count is to inspect the "fact" chunk which should always be present for compressed formats, and should
// always include the sample count. This little block of code below is only used to emulate the libsndfile logic so I can properly run my
// correctness tests against libsndfile and is disabled by default.
// correctness tests against libsndfile
,
and is disabled by default.
if
(
pWav
->
translatedFormatTag
==
DR_WAVE_FORMAT_ADPCM
)
{
drwav_uint64
blockCount
=
dataSize
/
fmt
.
blockAlign
;
pWav
->
totalSampleCount
=
(
blockCount
*
(
fmt
.
blockAlign
-
(
6
*
pWav
->
channels
)))
*
2
;
// x2 because two samples per byte.
...
...
@@ -1798,27 +1819,40 @@ drwav_bool32 drwav_seek_to_sample(drwav* pWav, drwav_uint64 sample)
// to seek back to the start.
if
(
drwav__is_compressed_format_tag
(
pWav
->
translatedFormatTag
))
{
// TODO: This can be optimized.
// If we're seeking forward it's simple - just keep reading samples until we hit the sample we're requesting. If we're seeking backwards,
// we first need to seek back to the start and then just do the same thing as a forward seek.
if
(
sample
<
pWav
->
compressed
.
iCurrentSample
)
{
if
(
!
drwav_seek_to_first_sample
(
pWav
))
{
return
DRWAV_FALSE
;
}
}
if
(
sample
>
pWav
->
compressed
.
iCurrentSample
)
{
// Seeking forward - just move from the current position.
drwav_uint64
offset
=
sample
-
pWav
->
compressed
.
iCurrentSample
;
drwav_int16
devnull
[
2048
];
while
(
offset
>
0
)
{
drwav_uint64
samplesToRead
=
sample
;
drwav_uint64
samplesToRead
=
offset
;
if
(
samplesToRead
>
2048
)
{
samplesToRead
=
2048
;
}
drwav_uint64
samplesRead
=
drwav_read_s16
(
pWav
,
samplesToRead
,
devnull
);
drwav_uint64
samplesRead
=
0
;
if
(
pWav
->
translatedFormatTag
==
DR_WAVE_FORMAT_ADPCM
)
{
samplesRead
=
drwav_read_s16__msadpcm
(
pWav
,
samplesToRead
,
devnull
);
}
else
if
(
pWav
->
translatedFormatTag
==
DR_WAVE_FORMAT_DVI_ADPCM
)
{
samplesRead
=
drwav_read_s16__ima
(
pWav
,
samplesToRead
,
devnull
);
}
else
{
assert
(
DRWAV_FALSE
);
// If this assertion is triggered it means I've implemented a new compressed format but forgot to add a branch for it here.
}
if
(
samplesRead
!=
samplesToRead
)
{
return
DRWAV_FALSE
;
}
offset
-=
samplesRead
;
}
}
else
{
// Seeking backwards. Just use the fallback.
goto
fallback
;
}
}
else
{
drwav_uint64
totalSizeInBytes
=
pWav
->
totalSampleCount
*
pWav
->
bytesPerSample
;
...
...
@@ -1850,30 +1884,6 @@ drwav_bool32 drwav_seek_to_sample(drwav* pWav, drwav_uint64 sample)
}
}
return
DRWAV_TRUE
;
fallback:
// This is a generic seek implementation that just continuously reads samples into a temporary buffer. This should work for all supported
// formats, but it is not efficient. This should be used as a fall back.
if
(
!
drwav_seek_to_first_sample
(
pWav
))
{
return
DRWAV_FALSE
;
}
drwav_int16
devnull
[
2048
];
while
(
sample
>
0
)
{
drwav_uint64
samplesToRead
=
sample
;
if
(
samplesToRead
>
2048
)
{
samplesToRead
=
2048
;
}
drwav_uint64
samplesRead
=
drwav_read_s16
(
pWav
,
samplesToRead
,
devnull
);
if
(
samplesRead
!=
samplesToRead
)
{
return
DRWAV_FALSE
;
}
sample
-=
samplesRead
;
}
return
DRWAV_TRUE
;
}
...
...
@@ -1906,132 +1916,6 @@ drwav_uint64 drwav_write(drwav* pWav, drwav_uint64 samplesToWrite, const void* p
}
#ifndef DR_WAV_NO_CONVERSION_API
static
unsigned
short
g_drwavAlawTable
[
256
]
=
{
0xEA80
,
0xEB80
,
0xE880
,
0xE980
,
0xEE80
,
0xEF80
,
0xEC80
,
0xED80
,
0xE280
,
0xE380
,
0xE080
,
0xE180
,
0xE680
,
0xE780
,
0xE480
,
0xE580
,
0xF540
,
0xF5C0
,
0xF440
,
0xF4C0
,
0xF740
,
0xF7C0
,
0xF640
,
0xF6C0
,
0xF140
,
0xF1C0
,
0xF040
,
0xF0C0
,
0xF340
,
0xF3C0
,
0xF240
,
0xF2C0
,
0xAA00
,
0xAE00
,
0xA200
,
0xA600
,
0xBA00
,
0xBE00
,
0xB200
,
0xB600
,
0x8A00
,
0x8E00
,
0x8200
,
0x8600
,
0x9A00
,
0x9E00
,
0x9200
,
0x9600
,
0xD500
,
0xD700
,
0xD100
,
0xD300
,
0xDD00
,
0xDF00
,
0xD900
,
0xDB00
,
0xC500
,
0xC700
,
0xC100
,
0xC300
,
0xCD00
,
0xCF00
,
0xC900
,
0xCB00
,
0xFEA8
,
0xFEB8
,
0xFE88
,
0xFE98
,
0xFEE8
,
0xFEF8
,
0xFEC8
,
0xFED8
,
0xFE28
,
0xFE38
,
0xFE08
,
0xFE18
,
0xFE68
,
0xFE78
,
0xFE48
,
0xFE58
,
0xFFA8
,
0xFFB8
,
0xFF88
,
0xFF98
,
0xFFE8
,
0xFFF8
,
0xFFC8
,
0xFFD8
,
0xFF28
,
0xFF38
,
0xFF08
,
0xFF18
,
0xFF68
,
0xFF78
,
0xFF48
,
0xFF58
,
0xFAA0
,
0xFAE0
,
0xFA20
,
0xFA60
,
0xFBA0
,
0xFBE0
,
0xFB20
,
0xFB60
,
0xF8A0
,
0xF8E0
,
0xF820
,
0xF860
,
0xF9A0
,
0xF9E0
,
0xF920
,
0xF960
,
0xFD50
,
0xFD70
,
0xFD10
,
0xFD30
,
0xFDD0
,
0xFDF0
,
0xFD90
,
0xFDB0
,
0xFC50
,
0xFC70
,
0xFC10
,
0xFC30
,
0xFCD0
,
0xFCF0
,
0xFC90
,
0xFCB0
,
0x1580
,
0x1480
,
0x1780
,
0x1680
,
0x1180
,
0x1080
,
0x1380
,
0x1280
,
0x1D80
,
0x1C80
,
0x1F80
,
0x1E80
,
0x1980
,
0x1880
,
0x1B80
,
0x1A80
,
0x0AC0
,
0x0A40
,
0x0BC0
,
0x0B40
,
0x08C0
,
0x0840
,
0x09C0
,
0x0940
,
0x0EC0
,
0x0E40
,
0x0FC0
,
0x0F40
,
0x0CC0
,
0x0C40
,
0x0DC0
,
0x0D40
,
0x5600
,
0x5200
,
0x5E00
,
0x5A00
,
0x4600
,
0x4200
,
0x4E00
,
0x4A00
,
0x7600
,
0x7200
,
0x7E00
,
0x7A00
,
0x6600
,
0x6200
,
0x6E00
,
0x6A00
,
0x2B00
,
0x2900
,
0x2F00
,
0x2D00
,
0x2300
,
0x2100
,
0x2700
,
0x2500
,
0x3B00
,
0x3900
,
0x3F00
,
0x3D00
,
0x3300
,
0x3100
,
0x3700
,
0x3500
,
0x0158
,
0x0148
,
0x0178
,
0x0168
,
0x0118
,
0x0108
,
0x0138
,
0x0128
,
0x01D8
,
0x01C8
,
0x01F8
,
0x01E8
,
0x0198
,
0x0188
,
0x01B8
,
0x01A8
,
0x0058
,
0x0048
,
0x0078
,
0x0068
,
0x0018
,
0x0008
,
0x0038
,
0x0028
,
0x00D8
,
0x00C8
,
0x00F8
,
0x00E8
,
0x0098
,
0x0088
,
0x00B8
,
0x00A8
,
0x0560
,
0x0520
,
0x05E0
,
0x05A0
,
0x0460
,
0x0420
,
0x04E0
,
0x04A0
,
0x0760
,
0x0720
,
0x07E0
,
0x07A0
,
0x0660
,
0x0620
,
0x06E0
,
0x06A0
,
0x02B0
,
0x0290
,
0x02F0
,
0x02D0
,
0x0230
,
0x0210
,
0x0270
,
0x0250
,
0x03B0
,
0x0390
,
0x03F0
,
0x03D0
,
0x0330
,
0x0310
,
0x0370
,
0x0350
};
static
unsigned
short
g_drwavMulawTable
[
256
]
=
{
0x8284
,
0x8684
,
0x8A84
,
0x8E84
,
0x9284
,
0x9684
,
0x9A84
,
0x9E84
,
0xA284
,
0xA684
,
0xAA84
,
0xAE84
,
0xB284
,
0xB684
,
0xBA84
,
0xBE84
,
0xC184
,
0xC384
,
0xC584
,
0xC784
,
0xC984
,
0xCB84
,
0xCD84
,
0xCF84
,
0xD184
,
0xD384
,
0xD584
,
0xD784
,
0xD984
,
0xDB84
,
0xDD84
,
0xDF84
,
0xE104
,
0xE204
,
0xE304
,
0xE404
,
0xE504
,
0xE604
,
0xE704
,
0xE804
,
0xE904
,
0xEA04
,
0xEB04
,
0xEC04
,
0xED04
,
0xEE04
,
0xEF04
,
0xF004
,
0xF0C4
,
0xF144
,
0xF1C4
,
0xF244
,
0xF2C4
,
0xF344
,
0xF3C4
,
0xF444
,
0xF4C4
,
0xF544
,
0xF5C4
,
0xF644
,
0xF6C4
,
0xF744
,
0xF7C4
,
0xF844
,
0xF8A4
,
0xF8E4
,
0xF924
,
0xF964
,
0xF9A4
,
0xF9E4
,
0xFA24
,
0xFA64
,
0xFAA4
,
0xFAE4
,
0xFB24
,
0xFB64
,
0xFBA4
,
0xFBE4
,
0xFC24
,
0xFC64
,
0xFC94
,
0xFCB4
,
0xFCD4
,
0xFCF4
,
0xFD14
,
0xFD34
,
0xFD54
,
0xFD74
,
0xFD94
,
0xFDB4
,
0xFDD4
,
0xFDF4
,
0xFE14
,
0xFE34
,
0xFE54
,
0xFE74
,
0xFE8C
,
0xFE9C
,
0xFEAC
,
0xFEBC
,
0xFECC
,
0xFEDC
,
0xFEEC
,
0xFEFC
,
0xFF0C
,
0xFF1C
,
0xFF2C
,
0xFF3C
,
0xFF4C
,
0xFF5C
,
0xFF6C
,
0xFF7C
,
0xFF88
,
0xFF90
,
0xFF98
,
0xFFA0
,
0xFFA8
,
0xFFB0
,
0xFFB8
,
0xFFC0
,
0xFFC8
,
0xFFD0
,
0xFFD8
,
0xFFE0
,
0xFFE8
,
0xFFF0
,
0xFFF8
,
0x0000
,
0x7D7C
,
0x797C
,
0x757C
,
0x717C
,
0x6D7C
,
0x697C
,
0x657C
,
0x617C
,
0x5D7C
,
0x597C
,
0x557C
,
0x517C
,
0x4D7C
,
0x497C
,
0x457C
,
0x417C
,
0x3E7C
,
0x3C7C
,
0x3A7C
,
0x387C
,
0x367C
,
0x347C
,
0x327C
,
0x307C
,
0x2E7C
,
0x2C7C
,
0x2A7C
,
0x287C
,
0x267C
,
0x247C
,
0x227C
,
0x207C
,
0x1EFC
,
0x1DFC
,
0x1CFC
,
0x1BFC
,
0x1AFC
,
0x19FC
,
0x18FC
,
0x17FC
,
0x16FC
,
0x15FC
,
0x14FC
,
0x13FC
,
0x12FC
,
0x11FC
,
0x10FC
,
0x0FFC
,
0x0F3C
,
0x0EBC
,
0x0E3C
,
0x0DBC
,
0x0D3C
,
0x0CBC
,
0x0C3C
,
0x0BBC
,
0x0B3C
,
0x0ABC
,
0x0A3C
,
0x09BC
,
0x093C
,
0x08BC
,
0x083C
,
0x07BC
,
0x075C
,
0x071C
,
0x06DC
,
0x069C
,
0x065C
,
0x061C
,
0x05DC
,
0x059C
,
0x055C
,
0x051C
,
0x04DC
,
0x049C
,
0x045C
,
0x041C
,
0x03DC
,
0x039C
,
0x036C
,
0x034C
,
0x032C
,
0x030C
,
0x02EC
,
0x02CC
,
0x02AC
,
0x028C
,
0x026C
,
0x024C
,
0x022C
,
0x020C
,
0x01EC
,
0x01CC
,
0x01AC
,
0x018C
,
0x0174
,
0x0164
,
0x0154
,
0x0144
,
0x0134
,
0x0124
,
0x0114
,
0x0104
,
0x00F4
,
0x00E4
,
0x00D4
,
0x00C4
,
0x00B4
,
0x00A4
,
0x0094
,
0x0084
,
0x0078
,
0x0070
,
0x0068
,
0x0060
,
0x0058
,
0x0050
,
0x0048
,
0x0040
,
0x0038
,
0x0030
,
0x0028
,
0x0020
,
0x0018
,
0x0010
,
0x0008
,
0x0000
};
static
DRWAV_INLINE
drwav_int16
drwav__alaw_to_s16
(
drwav_uint8
sampleIn
)
{
return
(
short
)
g_drwavAlawTable
[
sampleIn
];
}
static
DRWAV_INLINE
drwav_int16
drwav__mulaw_to_s16
(
drwav_uint8
sampleIn
)
{
return
(
short
)
g_drwavMulawTable
[
sampleIn
];
}
static
void
drwav__pcm_to_s16
(
drwav_int16
*
pOut
,
const
unsigned
char
*
pIn
,
size_t
totalSampleCount
,
unsigned
short
bytesPerSample
)
{
// Special case for 8-bit sample data because it's treated as unsigned.
if
(
bytesPerSample
==
1
)
{
drwav_u8_to_s16
(
pOut
,
pIn
,
totalSampleCount
);
return
;
}
// Slightly more optimal implementation for common formats.
if
(
bytesPerSample
==
2
)
{
for
(
unsigned
int
i
=
0
;
i
<
totalSampleCount
;
++
i
)
{
*
pOut
++
=
((
drwav_int16
*
)
pIn
)[
i
];
}
return
;
}
if
(
bytesPerSample
==
3
)
{
drwav_s24_to_s16
(
pOut
,
pIn
,
totalSampleCount
);
return
;
}
if
(
bytesPerSample
==
4
)
{
drwav_s32_to_s16
(
pOut
,
(
const
drwav_int32
*
)
pIn
,
totalSampleCount
);
return
;
}
// Generic, slow converter.
for
(
unsigned
int
i
=
0
;
i
<
totalSampleCount
;
++
i
)
{
unsigned
short
sample
=
0
;
unsigned
short
shift
=
(
8
-
bytesPerSample
)
*
8
;
for
(
unsigned
short
j
=
0
;
j
<
bytesPerSample
&&
j
<
2
;
++
j
)
{
sample
|=
(
unsigned
short
)(
pIn
[
j
])
<<
shift
;
shift
+=
8
;
}
pIn
+=
bytesPerSample
;
*
pOut
++
=
sample
;
}
}
static
void
drwav__ieee_to_s16
(
drwav_int16
*
pOut
,
const
unsigned
char
*
pIn
,
size_t
totalSampleCount
,
unsigned
short
bytesPerSample
)
{
if
(
bytesPerSample
==
4
)
{
drwav_f32_to_s16
(
pOut
,
(
float
*
)
pIn
,
totalSampleCount
);
return
;
}
else
{
drwav_f64_to_s16
(
pOut
,
(
double
*
)
pIn
,
totalSampleCount
);
return
;
}
}
drwav_uint64
drwav_read_s16__pcm
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int16
*
pBufferOut
)
{
// Fast path.
if
(
pWav
->
bytesPerSample
==
2
)
{
return
drwav_read
(
pWav
,
samplesToRead
,
pBufferOut
);
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
drwav_uint64
samplesRead
=
drwav_read
(
pWav
,
drwav_min
(
samplesToRead
,
sizeof
(
sampleData
)
/
pWav
->
bytesPerSample
),
sampleData
);
if
(
samplesRead
==
0
)
{
break
;
}
drwav__pcm_to_s16
(
pBufferOut
,
sampleData
,
(
size_t
)
samplesRead
,
pWav
->
bytesPerSample
);
pBufferOut
+=
samplesRead
;
samplesToRead
-=
samplesRead
;
totalSamplesRead
+=
samplesRead
;
}
return
totalSamplesRead
;
}
drwav_uint64
drwav_read_s16__msadpcm
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int16
*
pBufferOut
)
{
...
...
@@ -2334,6 +2218,147 @@ drwav_uint64 drwav_read_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_
return
totalSamplesRead
;
}
#ifndef DR_WAV_NO_CONVERSION_API
static
unsigned
short
g_drwavAlawTable
[
256
]
=
{
0xEA80
,
0xEB80
,
0xE880
,
0xE980
,
0xEE80
,
0xEF80
,
0xEC80
,
0xED80
,
0xE280
,
0xE380
,
0xE080
,
0xE180
,
0xE680
,
0xE780
,
0xE480
,
0xE580
,
0xF540
,
0xF5C0
,
0xF440
,
0xF4C0
,
0xF740
,
0xF7C0
,
0xF640
,
0xF6C0
,
0xF140
,
0xF1C0
,
0xF040
,
0xF0C0
,
0xF340
,
0xF3C0
,
0xF240
,
0xF2C0
,
0xAA00
,
0xAE00
,
0xA200
,
0xA600
,
0xBA00
,
0xBE00
,
0xB200
,
0xB600
,
0x8A00
,
0x8E00
,
0x8200
,
0x8600
,
0x9A00
,
0x9E00
,
0x9200
,
0x9600
,
0xD500
,
0xD700
,
0xD100
,
0xD300
,
0xDD00
,
0xDF00
,
0xD900
,
0xDB00
,
0xC500
,
0xC700
,
0xC100
,
0xC300
,
0xCD00
,
0xCF00
,
0xC900
,
0xCB00
,
0xFEA8
,
0xFEB8
,
0xFE88
,
0xFE98
,
0xFEE8
,
0xFEF8
,
0xFEC8
,
0xFED8
,
0xFE28
,
0xFE38
,
0xFE08
,
0xFE18
,
0xFE68
,
0xFE78
,
0xFE48
,
0xFE58
,
0xFFA8
,
0xFFB8
,
0xFF88
,
0xFF98
,
0xFFE8
,
0xFFF8
,
0xFFC8
,
0xFFD8
,
0xFF28
,
0xFF38
,
0xFF08
,
0xFF18
,
0xFF68
,
0xFF78
,
0xFF48
,
0xFF58
,
0xFAA0
,
0xFAE0
,
0xFA20
,
0xFA60
,
0xFBA0
,
0xFBE0
,
0xFB20
,
0xFB60
,
0xF8A0
,
0xF8E0
,
0xF820
,
0xF860
,
0xF9A0
,
0xF9E0
,
0xF920
,
0xF960
,
0xFD50
,
0xFD70
,
0xFD10
,
0xFD30
,
0xFDD0
,
0xFDF0
,
0xFD90
,
0xFDB0
,
0xFC50
,
0xFC70
,
0xFC10
,
0xFC30
,
0xFCD0
,
0xFCF0
,
0xFC90
,
0xFCB0
,
0x1580
,
0x1480
,
0x1780
,
0x1680
,
0x1180
,
0x1080
,
0x1380
,
0x1280
,
0x1D80
,
0x1C80
,
0x1F80
,
0x1E80
,
0x1980
,
0x1880
,
0x1B80
,
0x1A80
,
0x0AC0
,
0x0A40
,
0x0BC0
,
0x0B40
,
0x08C0
,
0x0840
,
0x09C0
,
0x0940
,
0x0EC0
,
0x0E40
,
0x0FC0
,
0x0F40
,
0x0CC0
,
0x0C40
,
0x0DC0
,
0x0D40
,
0x5600
,
0x5200
,
0x5E00
,
0x5A00
,
0x4600
,
0x4200
,
0x4E00
,
0x4A00
,
0x7600
,
0x7200
,
0x7E00
,
0x7A00
,
0x6600
,
0x6200
,
0x6E00
,
0x6A00
,
0x2B00
,
0x2900
,
0x2F00
,
0x2D00
,
0x2300
,
0x2100
,
0x2700
,
0x2500
,
0x3B00
,
0x3900
,
0x3F00
,
0x3D00
,
0x3300
,
0x3100
,
0x3700
,
0x3500
,
0x0158
,
0x0148
,
0x0178
,
0x0168
,
0x0118
,
0x0108
,
0x0138
,
0x0128
,
0x01D8
,
0x01C8
,
0x01F8
,
0x01E8
,
0x0198
,
0x0188
,
0x01B8
,
0x01A8
,
0x0058
,
0x0048
,
0x0078
,
0x0068
,
0x0018
,
0x0008
,
0x0038
,
0x0028
,
0x00D8
,
0x00C8
,
0x00F8
,
0x00E8
,
0x0098
,
0x0088
,
0x00B8
,
0x00A8
,
0x0560
,
0x0520
,
0x05E0
,
0x05A0
,
0x0460
,
0x0420
,
0x04E0
,
0x04A0
,
0x0760
,
0x0720
,
0x07E0
,
0x07A0
,
0x0660
,
0x0620
,
0x06E0
,
0x06A0
,
0x02B0
,
0x0290
,
0x02F0
,
0x02D0
,
0x0230
,
0x0210
,
0x0270
,
0x0250
,
0x03B0
,
0x0390
,
0x03F0
,
0x03D0
,
0x0330
,
0x0310
,
0x0370
,
0x0350
};
static
unsigned
short
g_drwavMulawTable
[
256
]
=
{
0x8284
,
0x8684
,
0x8A84
,
0x8E84
,
0x9284
,
0x9684
,
0x9A84
,
0x9E84
,
0xA284
,
0xA684
,
0xAA84
,
0xAE84
,
0xB284
,
0xB684
,
0xBA84
,
0xBE84
,
0xC184
,
0xC384
,
0xC584
,
0xC784
,
0xC984
,
0xCB84
,
0xCD84
,
0xCF84
,
0xD184
,
0xD384
,
0xD584
,
0xD784
,
0xD984
,
0xDB84
,
0xDD84
,
0xDF84
,
0xE104
,
0xE204
,
0xE304
,
0xE404
,
0xE504
,
0xE604
,
0xE704
,
0xE804
,
0xE904
,
0xEA04
,
0xEB04
,
0xEC04
,
0xED04
,
0xEE04
,
0xEF04
,
0xF004
,
0xF0C4
,
0xF144
,
0xF1C4
,
0xF244
,
0xF2C4
,
0xF344
,
0xF3C4
,
0xF444
,
0xF4C4
,
0xF544
,
0xF5C4
,
0xF644
,
0xF6C4
,
0xF744
,
0xF7C4
,
0xF844
,
0xF8A4
,
0xF8E4
,
0xF924
,
0xF964
,
0xF9A4
,
0xF9E4
,
0xFA24
,
0xFA64
,
0xFAA4
,
0xFAE4
,
0xFB24
,
0xFB64
,
0xFBA4
,
0xFBE4
,
0xFC24
,
0xFC64
,
0xFC94
,
0xFCB4
,
0xFCD4
,
0xFCF4
,
0xFD14
,
0xFD34
,
0xFD54
,
0xFD74
,
0xFD94
,
0xFDB4
,
0xFDD4
,
0xFDF4
,
0xFE14
,
0xFE34
,
0xFE54
,
0xFE74
,
0xFE8C
,
0xFE9C
,
0xFEAC
,
0xFEBC
,
0xFECC
,
0xFEDC
,
0xFEEC
,
0xFEFC
,
0xFF0C
,
0xFF1C
,
0xFF2C
,
0xFF3C
,
0xFF4C
,
0xFF5C
,
0xFF6C
,
0xFF7C
,
0xFF88
,
0xFF90
,
0xFF98
,
0xFFA0
,
0xFFA8
,
0xFFB0
,
0xFFB8
,
0xFFC0
,
0xFFC8
,
0xFFD0
,
0xFFD8
,
0xFFE0
,
0xFFE8
,
0xFFF0
,
0xFFF8
,
0x0000
,
0x7D7C
,
0x797C
,
0x757C
,
0x717C
,
0x6D7C
,
0x697C
,
0x657C
,
0x617C
,
0x5D7C
,
0x597C
,
0x557C
,
0x517C
,
0x4D7C
,
0x497C
,
0x457C
,
0x417C
,
0x3E7C
,
0x3C7C
,
0x3A7C
,
0x387C
,
0x367C
,
0x347C
,
0x327C
,
0x307C
,
0x2E7C
,
0x2C7C
,
0x2A7C
,
0x287C
,
0x267C
,
0x247C
,
0x227C
,
0x207C
,
0x1EFC
,
0x1DFC
,
0x1CFC
,
0x1BFC
,
0x1AFC
,
0x19FC
,
0x18FC
,
0x17FC
,
0x16FC
,
0x15FC
,
0x14FC
,
0x13FC
,
0x12FC
,
0x11FC
,
0x10FC
,
0x0FFC
,
0x0F3C
,
0x0EBC
,
0x0E3C
,
0x0DBC
,
0x0D3C
,
0x0CBC
,
0x0C3C
,
0x0BBC
,
0x0B3C
,
0x0ABC
,
0x0A3C
,
0x09BC
,
0x093C
,
0x08BC
,
0x083C
,
0x07BC
,
0x075C
,
0x071C
,
0x06DC
,
0x069C
,
0x065C
,
0x061C
,
0x05DC
,
0x059C
,
0x055C
,
0x051C
,
0x04DC
,
0x049C
,
0x045C
,
0x041C
,
0x03DC
,
0x039C
,
0x036C
,
0x034C
,
0x032C
,
0x030C
,
0x02EC
,
0x02CC
,
0x02AC
,
0x028C
,
0x026C
,
0x024C
,
0x022C
,
0x020C
,
0x01EC
,
0x01CC
,
0x01AC
,
0x018C
,
0x0174
,
0x0164
,
0x0154
,
0x0144
,
0x0134
,
0x0124
,
0x0114
,
0x0104
,
0x00F4
,
0x00E4
,
0x00D4
,
0x00C4
,
0x00B4
,
0x00A4
,
0x0094
,
0x0084
,
0x0078
,
0x0070
,
0x0068
,
0x0060
,
0x0058
,
0x0050
,
0x0048
,
0x0040
,
0x0038
,
0x0030
,
0x0028
,
0x0020
,
0x0018
,
0x0010
,
0x0008
,
0x0000
};
static
DRWAV_INLINE
drwav_int16
drwav__alaw_to_s16
(
drwav_uint8
sampleIn
)
{
return
(
short
)
g_drwavAlawTable
[
sampleIn
];
}
static
DRWAV_INLINE
drwav_int16
drwav__mulaw_to_s16
(
drwav_uint8
sampleIn
)
{
return
(
short
)
g_drwavMulawTable
[
sampleIn
];
}
static
void
drwav__pcm_to_s16
(
drwav_int16
*
pOut
,
const
unsigned
char
*
pIn
,
size_t
totalSampleCount
,
unsigned
short
bytesPerSample
)
{
// Special case for 8-bit sample data because it's treated as unsigned.
if
(
bytesPerSample
==
1
)
{
drwav_u8_to_s16
(
pOut
,
pIn
,
totalSampleCount
);
return
;
}
// Slightly more optimal implementation for common formats.
if
(
bytesPerSample
==
2
)
{
for
(
unsigned
int
i
=
0
;
i
<
totalSampleCount
;
++
i
)
{
*
pOut
++
=
((
drwav_int16
*
)
pIn
)[
i
];
}
return
;
}
if
(
bytesPerSample
==
3
)
{
drwav_s24_to_s16
(
pOut
,
pIn
,
totalSampleCount
);
return
;
}
if
(
bytesPerSample
==
4
)
{
drwav_s32_to_s16
(
pOut
,
(
const
drwav_int32
*
)
pIn
,
totalSampleCount
);
return
;
}
// Anything more than 64 bits per sample is not supported.
if
(
bytesPerSample
>
8
)
{
drwav_zero_memory
(
pOut
,
totalSampleCount
*
sizeof
(
*
pOut
));
return
;
}
// Generic, slow converter.
for
(
unsigned
int
i
=
0
;
i
<
totalSampleCount
;
++
i
)
{
drwav_uint64
sample
=
0
;
unsigned
int
shift
=
(
8
-
bytesPerSample
)
*
8
;
unsigned
int
j
;
for
(
j
=
0
;
j
<
bytesPerSample
&&
j
<
8
;
j
+=
1
)
{
sample
|=
(
drwav_uint64
)(
pIn
[
j
])
<<
shift
;
shift
+=
8
;
}
pIn
+=
j
;
*
pOut
++
=
(
drwav_int16
)((
drwav_int64
)
sample
>>
48
);
}
}
static
void
drwav__ieee_to_s16
(
drwav_int16
*
pOut
,
const
unsigned
char
*
pIn
,
size_t
totalSampleCount
,
unsigned
short
bytesPerSample
)
{
if
(
bytesPerSample
==
4
)
{
drwav_f32_to_s16
(
pOut
,
(
float
*
)
pIn
,
totalSampleCount
);
return
;
}
else
if
(
bytesPerSample
==
8
)
{
drwav_f64_to_s16
(
pOut
,
(
double
*
)
pIn
,
totalSampleCount
);
return
;
}
else
{
// Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float.
drwav_zero_memory
(
pOut
,
totalSampleCount
*
sizeof
(
*
pOut
));
return
;
}
}
drwav_uint64
drwav_read_s16__pcm
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int16
*
pBufferOut
)
{
// Fast path.
if
(
pWav
->
bytesPerSample
==
2
)
{
return
drwav_read
(
pWav
,
samplesToRead
,
pBufferOut
);
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
drwav_uint64
samplesRead
=
drwav_read
(
pWav
,
drwav_min
(
samplesToRead
,
sizeof
(
sampleData
)
/
pWav
->
bytesPerSample
),
sampleData
);
if
(
samplesRead
==
0
)
{
break
;
}
drwav__pcm_to_s16
(
pBufferOut
,
sampleData
,
(
size_t
)
samplesRead
,
pWav
->
bytesPerSample
);
pBufferOut
+=
samplesRead
;
samplesToRead
-=
samplesRead
;
totalSamplesRead
+=
samplesRead
;
}
return
totalSamplesRead
;
}
drwav_uint64
drwav_read_s16__ieee
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int16
*
pBufferOut
)
{
drwav_uint64
totalSamplesRead
=
0
;
...
...
@@ -2529,17 +2554,27 @@ static void drwav__pcm_to_f32(float* pOut, const unsigned char* pIn, size_t samp
return
;
}
// Anything more than 64 bits per sample is not supported.
if
(
bytesPerSample
>
8
)
{
drwav_zero_memory
(
pOut
,
sampleCount
*
sizeof
(
*
pOut
));
return
;
}
// Generic, slow converter.
for
(
unsigned
int
i
=
0
;
i
<
sampleCount
;
++
i
)
{
unsigned
int
sample
=
0
;
drwav_uint64
sample
=
0
;
unsigned
int
shift
=
(
8
-
bytesPerSample
)
*
8
;
for
(
unsigned
short
j
=
0
;
j
<
bytesPerSample
&&
j
<
4
;
++
j
)
{
sample
|=
(
unsigned
int
)(
pIn
[
j
])
<<
shift
;
unsigned
int
j
;
for
(
j
=
0
;
j
<
bytesPerSample
&&
j
<
8
;
j
+=
1
)
{
sample
|=
(
drwav_uint64
)(
pIn
[
j
])
<<
shift
;
shift
+=
8
;
}
pIn
+=
bytesPerSample
;
*
pOut
++
=
(
float
)((
int
)
sample
/
2147483648
.
0
);
pIn
+=
j
;
*
pOut
++
=
(
float
)((
drwav_int64
)
sample
/
9223372036854775807
.
0
);
}
}
...
...
@@ -2550,15 +2585,23 @@ static void drwav__ieee_to_f32(float* pOut, const unsigned char* pIn, size_t sam
*
pOut
++
=
((
float
*
)
pIn
)[
i
];
}
return
;
}
else
{
}
else
if
(
bytesPerSample
==
8
)
{
drwav_f64_to_f32
(
pOut
,
(
double
*
)
pIn
,
sampleCount
);
return
;
}
else
{
// Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float.
drwav_zero_memory
(
pOut
,
sampleCount
*
sizeof
(
*
pOut
));
return
;
}
}
drwav_uint64
drwav_read_f32__pcm
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
float
*
pBufferOut
)
{
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2628,6 +2671,10 @@ drwav_uint64 drwav_read_f32__ieee(drwav* pWav, drwav_uint64 samplesToRead, float
return
drwav_read
(
pWav
,
samplesToRead
,
pBufferOut
);
}
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2648,6 +2695,10 @@ drwav_uint64 drwav_read_f32__ieee(drwav* pWav, drwav_uint64 samplesToRead, float
drwav_uint64
drwav_read_f32__alaw
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
float
*
pBufferOut
)
{
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2668,6 +2719,10 @@ drwav_uint64 drwav_read_f32__alaw(drwav* pWav, drwav_uint64 samplesToRead, float
drwav_uint64
drwav_read_f32__mulaw
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
float
*
pBufferOut
)
{
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2842,17 +2897,27 @@ static void drwav__pcm_to_s32(drwav_int32* pOut, const unsigned char* pIn, size_
return
;
}
// Anything more than 64 bits per sample is not supported.
if
(
bytesPerSample
>
8
)
{
drwav_zero_memory
(
pOut
,
totalSampleCount
*
sizeof
(
*
pOut
));
return
;
}
// Generic, slow converter.
for
(
unsigned
int
i
=
0
;
i
<
totalSampleCount
;
++
i
)
{
unsigned
int
sample
=
0
;
drwav_uint64
sample
=
0
;
unsigned
int
shift
=
(
8
-
bytesPerSample
)
*
8
;
for
(
unsigned
short
j
=
0
;
j
<
bytesPerSample
&&
j
<
4
;
++
j
)
{
sample
|=
(
unsigned
int
)(
pIn
[
j
])
<<
shift
;
unsigned
int
j
;
for
(
j
=
0
;
j
<
bytesPerSample
&&
j
<
8
;
j
+=
1
)
{
sample
|=
(
drwav_uint64
)(
pIn
[
j
])
<<
shift
;
shift
+=
8
;
}
pIn
+=
bytesPerSample
;
*
pOut
++
=
sample
;
pIn
+=
j
;
*
pOut
++
=
(
drwav_int32
)((
drwav_int64
)
sample
>>
32
)
;
}
}
...
...
@@ -2861,9 +2926,13 @@ static void drwav__ieee_to_s32(drwav_int32* pOut, const unsigned char* pIn, size
if
(
bytesPerSample
==
4
)
{
drwav_f32_to_s32
(
pOut
,
(
float
*
)
pIn
,
totalSampleCount
);
return
;
}
else
{
}
else
if
(
bytesPerSample
==
8
)
{
drwav_f64_to_s32
(
pOut
,
(
double
*
)
pIn
,
totalSampleCount
);
return
;
}
else
{
// Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float.
drwav_zero_memory
(
pOut
,
totalSampleCount
*
sizeof
(
*
pOut
));
return
;
}
}
...
...
@@ -2875,6 +2944,10 @@ drwav_uint64 drwav_read_s32__pcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_
return
drwav_read
(
pWav
,
samplesToRead
,
pBufferOut
);
}
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2939,6 +3012,10 @@ drwav_uint64 drwav_read_s32__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_
drwav_uint64
drwav_read_s32__ieee
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int32
*
pBufferOut
)
{
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2959,6 +3036,10 @@ drwav_uint64 drwav_read_s32__ieee(drwav* pWav, drwav_uint64 samplesToRead, drwav
drwav_uint64
drwav_read_s32__alaw
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int32
*
pBufferOut
)
{
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -2979,6 +3060,10 @@ drwav_uint64 drwav_read_s32__alaw(drwav* pWav, drwav_uint64 samplesToRead, drwav
drwav_uint64
drwav_read_s32__mulaw
(
drwav
*
pWav
,
drwav_uint64
samplesToRead
,
drwav_int32
*
pBufferOut
)
{
if
(
pWav
->
bytesPerSample
==
0
)
{
return
0
;
}
drwav_uint64
totalSamplesRead
=
0
;
unsigned
char
sampleData
[
4096
];
while
(
samplesToRead
>
0
)
{
...
...
@@ -3354,6 +3439,25 @@ void drwav_free(void* pDataReturnedByOpenAndRead)
// REVISION HISTORY
//
// v0.7f - 2018-02-05
// - Restrict ADPCM formats to a maximum of 2 channels.
//
// v0.7e - 2018-02-02
// - Fix a crash.
//
// v0.7d - 2018-02-01
// - Fix a crash.
//
// v0.7c - 2018-02-01
// - Set drwav.bytesPerSample to 0 for all compressed formats.
// - Fix a crash when reading 16-bit floating point WAV files. In this case dr_wav will output silence for
// all format conversion reading APIs (*_s16, *_s32, *_f32 APIs).
// - Fix some divide-by-zero errors.
//
// v0.7b - 2018-01-22
// - Fix errors with seeking of compressed formats.
// - Fix compilation error when DR_WAV_NO_CONVERSION_API
//
// v0.7a - 2017-11-17
// - Fix some GCC warnings.
//
...
...
@@ -3393,7 +3497,7 @@ void drwav_free(void* pDataReturnedByOpenAndRead)
//
// v0.5 - 2016-09-29
// - API CHANGE. Swap the order of "channels" and "sampleRate" parameters in drwav_open_and_read*(). Rationale for this is to
// keep it consistent with dr_audio and dr
wav
_flac.
// keep it consistent with dr_audio and dr_flac.
//
// v0.4b - 2016-09-18
// - Fixed a typo in documentation.
...
...
@@ -3403,8 +3507,8 @@ void drwav_free(void* pDataReturnedByOpenAndRead)
// - Change date format to ISO 8601 (YYYY-MM-DD)
//
// v0.4 - 2016-07-13
// - API CHANGE. Make onSeek consistent with dr
wav
_flac.
// - API CHANGE. Rename drwav_seek() to drwav_seek_to_sample() for clarity and consistency with dr
wav
_flac.
// - API CHANGE. Make onSeek consistent with dr_flac.
// - API CHANGE. Rename drwav_seek() to drwav_seek_to_sample() for clarity and consistency with dr_flac.
// - Added support for Sony Wave64.
//
// v0.3a - 2016-05-28
...
...
@@ -3418,7 +3522,7 @@ void drwav_free(void* pDataReturnedByOpenAndRead)
// - Fixed Linux/GCC build.
//
// v0.2 - 2016-05-11
// - Added support for reading data as signed 32-bit PCM for consistency with dr
wav
_flac.
// - Added support for reading data as signed 32-bit PCM for consistency with dr_flac.
//
// v0.1a - 2016-05-07
// - Fixed a bug in drwav_open_file() where the file handle would not be closed if the loader failed to initialize.
...
...
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