Update external audio libraries.

This commit is contained in:
David Reid 2018-07-05 22:57:45 +10:00
parent c598701873
commit 6c96fa6301
4 changed files with 4493 additions and 690 deletions

671
src/external/dr_flac.h vendored

File diff suppressed because it is too large Load Diff

71
src/external/dr_mp3.h vendored
View File

@ -1,5 +1,5 @@
// MP3 audio decoder. Public domain. See "unlicense" statement at the end of this file. // MP3 audio decoder. Public domain. See "unlicense" statement at the end of this file.
// dr_mp3 - v0.2.3 - 2018-04-29 // dr_mp3 - v0.2.5 - 2018-06-22
// //
// David Reid - mackron@gmail.com // David Reid - mackron@gmail.com
// //
@ -339,7 +339,7 @@ void drmp3_free(void* p);
#define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3) #define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
#define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4) #define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
#define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3) #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_FRAME_576(h) ((h[1] & 14) == 2)
#define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6) #define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
@ -412,10 +412,10 @@ static int drmp3_have_simd()
#ifdef MINIMP3_TEST #ifdef MINIMP3_TEST
static int g_counter; static int g_counter;
if (g_counter++ > 100) if (g_counter++ > 100)
goto test_nosimd; return 0;
#endif #endif
if (g_have_simd) if (g_have_simd)
return g_have_simd - 1; goto end;
drmp3_cpuid(CPUInfo, 0); drmp3_cpuid(CPUInfo, 0);
if (CPUInfo[0] > 0) if (CPUInfo[0] > 0)
{ {
@ -423,11 +423,9 @@ static int drmp3_have_simd()
g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */ g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */
return g_have_simd - 1; return g_have_simd - 1;
} }
#ifdef MINIMP3_TEST
test_nosimd: end:
#endif return g_have_simd - 1;
g_have_simd = 1;
return 0;
#endif #endif
} }
#elif defined(__ARM_NEON) || defined(__aarch64__) #elif defined(__ARM_NEON) || defined(__aarch64__)
@ -760,8 +758,7 @@ static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf,
static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
{ {
static const drmp3_uint8 g_scf_long[9][23] = { static const drmp3_uint8 g_scf_long[8][23] = {
{ 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
{ 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
{ 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 }, { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 },
{ 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
@ -771,8 +768,7 @@ static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drm
{ 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 }, { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 },
{ 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 } { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 }
}; };
static const drmp3_uint8 g_scf_short[9][40] = { static const drmp3_uint8 g_scf_short[8][40] = {
{ 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
{ 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
{ 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
{ 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
@ -782,8 +778,7 @@ static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drm
{ 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
{ 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
}; };
static const drmp3_uint8 g_scf_mixed[9][40] = { static const drmp3_uint8 g_scf_mixed[8][40] = {
{ 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
{ 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
{ 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
{ 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
@ -796,7 +791,7 @@ static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drm
unsigned tables, scfsi = 0; unsigned tables, scfsi = 0;
int main_data_begin, part_23_sum = 0; int main_data_begin, part_23_sum = 0;
int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
if (DRMP3_HDR_TEST_MPEG1(hdr)) if (DRMP3_HDR_TEST_MPEG1(hdr))
@ -1020,25 +1015,25 @@ static float drmp3_L3_pow_43(int x)
static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit) static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
{ {
static const float g_pow43_signed[32] = { 0,0,1,-1,2.519842f,-2.519842f,4.326749f,-4.326749f,6.349604f,-6.349604f,8.549880f,-8.549880f,10.902724f,-10.902724f,13.390518f,-13.390518f,16.000000f,-16.000000f,18.720754f,-18.720754f,21.544347f,-21.544347f,24.463781f,-24.463781f,27.473142f,-27.473142f,30.567351f,-30.567351f,33.741992f,-33.741992f,36.993181f,-36.993181f }; static const float g_pow43_signed[32] = { 0,0,1,-1,2.519842f,-2.519842f,4.326749f,-4.326749f,6.349604f,-6.349604f,8.549880f,-8.549880f,10.902724f,-10.902724f,13.390518f,-13.390518f,16.000000f,-16.000000f,18.720754f,-18.720754f,21.544347f,-21.544347f,24.463781f,-24.463781f,27.473142f,-27.473142f,30.567351f,-30.567351f,33.741992f,-33.741992f,36.993181f,-36.993181f };
static const drmp3_int16 tab0[32] = { 0, }; static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static const drmp3_int16 tab1[] = { 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256 }; 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
static const drmp3_int16 tab2[] = { -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288 }; -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288,
static const drmp3_int16 tab3[] = { -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288 }; -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288,
static const drmp3_int16 tab5[] = { -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258 }; -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258,
static const drmp3_int16 tab6[] = { -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259 }; -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259,
static const drmp3_int16 tab7[] = { -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258 }; -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258,
static const drmp3_int16 tab8[] = { -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258 }; -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258,
static const drmp3_int16 tab9[] = { -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259 }; -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259,
static const drmp3_int16 tab10[] = { -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258 }; -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258,
static const drmp3_int16 tab11[] = { -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290 }; -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290,
static const drmp3_int16 tab12[] = { -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259 }; -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259,
static const drmp3_int16 tab13[] = { -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258 }; -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258,
static const drmp3_int16 tab15[] = { -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259 }; -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259,
static const drmp3_int16 tab16[] = { -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258 }; -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258,
static const drmp3_int16 tab24[] = { -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 }; -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 };
static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205}; static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 }; static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
static const drmp3_int16 * const tabindex[2*16] = { tab0,tab1,tab2,tab3,tab0,tab5,tab6,tab7,tab8,tab9,tab10,tab11,tab12,tab13,tab0,tab15,tab16,tab16,tab16,tab16,tab16,tab16,tab16,tab16,tab24,tab24,tab24,tab24,tab24,tab24,tab24,tab24 }; static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
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 }; 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_PEEK_BITS(n) (bs_cache >> (32 - n))
@ -1058,7 +1053,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 tab_num = gr_info->table_select[ireg];
int sfb_cnt = gr_info->region_count[ireg++]; int sfb_cnt = gr_info->region_count[ireg++];
const short *codebook = tabindex[tab_num]; const short *codebook = tabs + tabindex[tab_num];
int linbits = g_linbits[tab_num]; int linbits = g_linbits[tab_num];
do do
{ {
@ -1227,7 +1222,7 @@ static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const d
int prev = itop - max_blocks; int prev = itop - max_blocks;
ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]); ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]);
} }
drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress&1); drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1);
} }
static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb) static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb)
@ -2776,6 +2771,12 @@ void drmp3_free(void* p)
// REVISION HISTORY // REVISION HISTORY
// =============== // ===============
// //
// v0.2.5 - 2018-06-22
// - Bring up to date with minimp3.
//
// v0.2.4 - 2018-05-12
// - Bring up to date with minimp3.
//
// v0.2.3 - 2018-04-29 // v0.2.3 - 2018-04-29
// - Fix TCC build. // - Fix TCC build.
// //

349
src/external/dr_wav.h vendored
View File

@ -1,5 +1,5 @@
// WAV audio loader and writer. Public domain. See "unlicense" statement at the end of this file. // WAV audio loader and writer. Public domain. See "unlicense" statement at the end of this file.
// dr_wav - v0.7f - 2018-02-05 // dr_wav - v0.8.1 - 2018-06-29
// //
// David Reid - mackron@gmail.com // David Reid - mackron@gmail.com
@ -50,7 +50,7 @@
// drwav_free(pSampleData); // drwav_free(pSampleData);
// //
// The examples above use versions of the API that convert the audio data to a consistent format (32-bit signed PCM, in // The examples above use versions of the API that convert the audio data to a consistent format (32-bit signed PCM, in
// this case), but you can still output the audio data in it's internal format (see notes below for supported formats): // this case), but you can still output the audio data in its internal format (see notes below for supported formats):
// //
// size_t samplesRead = drwav_read(&wav, wav.totalSampleCount, pDecodedInterleavedSamples); // size_t samplesRead = drwav_read(&wav, wav.totalSampleCount, pDecodedInterleavedSamples);
// //
@ -246,7 +246,7 @@ typedef struct
// Block align. This is equal to the number of channels * bytes per sample. // Block align. This is equal to the number of channels * bytes per sample.
drwav_uint16 blockAlign; drwav_uint16 blockAlign;
// Bit's per sample. // Bits per sample.
drwav_uint16 bitsPerSample; drwav_uint16 bitsPerSample;
// The size of the extended data. Only used internally for validation, but left here for informational purposes. // The size of the extended data. Only used internally for validation, but left here for informational purposes.
@ -292,7 +292,7 @@ typedef struct
// The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. // The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc.
drwav_uint16 channels; drwav_uint16 channels;
// The bits per sample. Will be set to somthing like 16, 24, etc. // The bits per sample. Will be set to something like 16, 24, etc.
drwav_uint16 bitsPerSample; drwav_uint16 bitsPerSample;
// The number of bytes per sample. // The number of bytes per sample.
@ -316,6 +316,14 @@ typedef struct
drwav_uint64 bytesRemaining; drwav_uint64 bytesRemaining;
// Only used in sequential write mode. Keeps track of the desired size of the "data" chunk at the point of initialization time. Always
// set to 0 for non-sequential writes and when the drwav object is opened in read mode. Used for validation.
drwav_uint64 dataChunkDataSizeTargetWrite;
// Keeps track of whether or not the wav writer was initialized in sequential mode.
drwav_bool32 isSequentialWrite;
// A hack to avoid a DRWAV_MALLOC() when opening a decoder with drwav_open_memory(). // A hack to avoid a DRWAV_MALLOC() when opening a decoder with drwav_open_memory().
drwav__memory_stream memoryStream; drwav__memory_stream memoryStream;
drwav__memory_stream_write memoryStreamWrite; drwav__memory_stream_write memoryStreamWrite;
@ -381,11 +389,15 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
// This is the lowest level function for initializing a WAV file. You can also use drwav_init_file() and drwav_init_memory() // This is the lowest level function for initializing a WAV file. You can also use drwav_init_file() and drwav_init_memory()
// to open the stream from a file or from a block of memory respectively. // to open the stream from a file or from a block of memory respectively.
// //
// If the total sample count is known, you can use drwav_init_write_sequential(). This avoids the need for dr_wav to perform
// a post-processing step for storing the total sample count and the size of the data chunk which requires a backwards seek.
//
// If you want dr_wav to manage the memory allocation for you, consider using drwav_open() instead. This will allocate // If you want dr_wav to manage the memory allocation for you, consider using drwav_open() instead. This will allocate
// a drwav object on the heap and return a pointer to it. // a drwav object on the heap and return a pointer to it.
// //
// See also: drwav_init_file_write(), drwav_init_memory_write(), drwav_uninit() // See also: drwav_init_file_write(), drwav_init_memory_write(), drwav_uninit()
drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData); drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData);
drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData);
// Uninitializes the given drwav object. // Uninitializes the given drwav object.
// //
@ -403,8 +415,8 @@ void drwav_uninit(drwav* pWav);
// //
// Close the loader with drwav_close(). // Close the loader with drwav_close().
// //
// This is the lowest level function for opening a WAV file. You can also use drwav_open_file() and drwav_open_memory() // You can also use drwav_open_file() and drwav_open_memory() to open the stream from a file or from a block of
// to open the stream from a file or from a block of memory respectively. // memory respectively.
// //
// This is different from drwav_init() in that it will allocate the drwav object for you via DRWAV_MALLOC() before // This is different from drwav_init() in that it will allocate the drwav object for you via DRWAV_MALLOC() before
// initializing it. // initializing it.
@ -422,14 +434,15 @@ drwav* drwav_open(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserDat
// //
// Close the loader with drwav_close(). // Close the loader with drwav_close().
// //
// This is the lowest level function for opening a WAV file. You can also use drwav_open_file_write() and drwav_open_memory_write() // You can also use drwav_open_file_write() and drwav_open_memory_write() to open the stream from a file or from a block
// to open the stream from a file or from a block of memory respectively. // of memory respectively.
// //
// This is different from drwav_init_write() in that it will allocate the drwav object for you via DRWAV_MALLOC() before // This is different from drwav_init_write() in that it will allocate the drwav object for you via DRWAV_MALLOC() before
// initializing it. // initializing it.
// //
// See also: drwav_open_file_write(), drwav_open_memory_write(), drwav_close() // See also: drwav_open_file_write(), drwav_open_memory_write(), drwav_close()
drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData); drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData);
drwav* drwav_open_write_sequential(const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData);
// Uninitializes and deletes the the given drwav object. // Uninitializes and deletes the the given drwav object.
// //
@ -478,7 +491,7 @@ drwav_uint64 drwav_write(drwav* pWav, drwav_uint64 samplesToWrite, const void* p
//// Convertion Utilities //// //// Conversion Utilities ////
#ifndef DR_WAV_NO_CONVERSION_API #ifndef DR_WAV_NO_CONVERSION_API
// Reads a chunk of audio data and converts it to signed 16-bit PCM samples. // Reads a chunk of audio data and converts it to signed 16-bit PCM samples.
@ -587,6 +600,7 @@ drwav_bool32 drwav_init_file(drwav* pWav, const char* filename);
// objects because the operating system may restrict the number of file handles an application can have open at // objects because the operating system may restrict the number of file handles an application can have open at
// any given time. // any given time.
drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat); drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat);
drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
// Helper for opening a wave file using stdio. // Helper for opening a wave file using stdio.
// //
@ -601,6 +615,7 @@ drwav* drwav_open_file(const char* filename);
// objects because the operating system may restrict the number of file handles an application can have open at // objects because the operating system may restrict the number of file handles an application can have open at
// any given time. // any given time.
drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFormat); drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFormat);
drwav* drwav_open_file_write_sequential(const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
#endif //DR_WAV_NO_STDIO #endif //DR_WAV_NO_STDIO
@ -619,6 +634,7 @@ drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize);
// The buffer will remain allocated even after drwav_uninit() is called. Indeed, the buffer should not be // The buffer will remain allocated even after drwav_uninit() is called. Indeed, the buffer should not be
// considered valid until after drwav_uninit() has been called anyway. // considered valid until after drwav_uninit() has been called anyway.
drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat); drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat);
drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
// Helper for opening a loader from a pre-allocated memory buffer. // Helper for opening a loader from a pre-allocated memory buffer.
// //
@ -635,6 +651,7 @@ drwav* drwav_open_memory(const void* data, size_t dataSize);
// The buffer will remain allocated even after drwav_close() is called. Indeed, the buffer should not be // The buffer will remain allocated even after drwav_close() is called. Indeed, the buffer should not be
// considered valid until after drwav_close() has been called anyway. // considered valid until after drwav_close() has been called anyway.
drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat); drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat);
drwav* drwav_open_memory_write_sequential(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount);
#ifndef DR_WAV_NO_CONVERSION_API #ifndef DR_WAV_NO_CONVERSION_API
@ -822,6 +839,8 @@ 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__msadpcm(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
drwav_uint64 drwav_read_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut); drwav_uint64 drwav_read_s16__ima(drwav* pWav, drwav_uint64 samplesToRead, drwav_int16* pBufferOut);
drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData);
drwav* drwav_open_write__internal(const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData);
typedef struct typedef struct
{ {
@ -867,7 +886,7 @@ static drwav_bool32 drwav__read_chunk_header(drwav_read_proc onRead, void* pUser
pHeaderOut->sizeInBytes = drwav__bytes_to_u64(sizeInBytes) - 24; // <-- Subtract 24 because w64 includes the size of the header. pHeaderOut->sizeInBytes = drwav__bytes_to_u64(sizeInBytes) - 24; // <-- Subtract 24 because w64 includes the size of the header.
pHeaderOut->paddingSize = (unsigned int)(pHeaderOut->sizeInBytes % 8); pHeaderOut->paddingSize = (unsigned int)(pHeaderOut->sizeInBytes % 8);
pRunningBytesReadOut += 24; *pRunningBytesReadOut += 24;
} }
return DRWAV_TRUE; return DRWAV_TRUE;
@ -902,8 +921,8 @@ static drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSe
} }
// Skip junk chunks. // Skip non-fmt chunks.
if ((container == drwav_container_riff && drwav__fourcc_equal(header.id.fourcc, "JUNK")) || (container == drwav_container_w64 && drwav__guid_equal(header.id.guid, drwavGUID_W64_JUNK))) { if ((container == drwav_container_riff && !drwav__fourcc_equal(header.id.fourcc, "fmt ")) || (container == drwav_container_w64 && !drwav__guid_equal(header.id.guid, drwavGUID_W64_FMT))) {
if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) { if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
@ -999,6 +1018,23 @@ static drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSe
#ifndef DR_WAV_NO_STDIO #ifndef DR_WAV_NO_STDIO
FILE* drwav_fopen(const char* filePath, const char* openMode)
{
FILE* pFile;
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (fopen_s(&pFile, filePath, openMode) != 0) {
return DRWAV_FALSE;
}
#else
pFile = fopen(filePath, openMode);
if (pFile == NULL) {
return DRWAV_FALSE;
}
#endif
return pFile;
}
static size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) static size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
{ {
return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData); return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
@ -1016,51 +1052,41 @@ static drwav_bool32 drwav__on_seek_stdio(void* pUserData, int offset, drwav_seek
drwav_bool32 drwav_init_file(drwav* pWav, const char* filename) drwav_bool32 drwav_init_file(drwav* pWav, const char* filename)
{ {
FILE* pFile; FILE* pFile = drwav_fopen(filename, "rb");
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (fopen_s(&pFile, filename, "rb") != 0) {
return DRWAV_FALSE;
}
#else
pFile = fopen(filename, "rb");
if (pFile == NULL) { if (pFile == NULL) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
#endif
return drwav_init(pWav, drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile); return drwav_init(pWav, drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile);
} }
drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat)
drwav_bool32 drwav_init_file_write__internal(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential)
{ {
FILE* pFile; FILE* pFile = drwav_fopen(filename, "wb");
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (fopen_s(&pFile, filename, "wb") != 0) {
return DRWAV_FALSE;
}
#else
pFile = fopen(filename, "wb");
if (pFile == NULL) { if (pFile == NULL) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
#endif
return drwav_init_write(pWav, pFormat, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile); return drwav_init_write__internal(pWav, pFormat, totalSampleCount, isSequential, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile);
}
drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat)
{
return drwav_init_file_write__internal(pWav, filename, pFormat, 0, DRWAV_FALSE);
}
drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
{
return drwav_init_file_write__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE);
} }
drwav* drwav_open_file(const char* filename) drwav* drwav_open_file(const char* filename)
{ {
FILE* pFile; FILE* pFile = drwav_fopen(filename, "rb");
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (fopen_s(&pFile, filename, "rb") != 0) {
return NULL;
}
#else
pFile = fopen(filename, "rb");
if (pFile == NULL) { if (pFile == NULL) {
return NULL; return DRWAV_FALSE;
} }
#endif
drwav* pWav = drwav_open(drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile); drwav* pWav = drwav_open(drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile);
if (pWav == NULL) { if (pWav == NULL) {
@ -1071,21 +1097,15 @@ drwav* drwav_open_file(const char* filename)
return pWav; return pWav;
} }
drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFormat)
{
FILE* pFile;
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (fopen_s(&pFile, filename, "wb") != 0) {
return NULL;
}
#else
pFile = fopen(filename, "wb");
if (pFile == NULL) {
return NULL;
}
#endif
drwav* pWav = drwav_open_write(pFormat, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile); drwav* drwav_open_file_write__internal(const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential)
{
FILE* pFile = drwav_fopen(filename, "wb");
if (pFile == NULL) {
return DRWAV_FALSE;
}
drwav* pWav = drwav_open_write__internal(pFormat, totalSampleCount, isSequential, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile);
if (pWav == NULL) { if (pWav == NULL) {
fclose(pFile); fclose(pFile);
return NULL; return NULL;
@ -1093,6 +1113,16 @@ drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFor
return pWav; return pWav;
} }
drwav* drwav_open_file_write(const char* filename, const drwav_data_format* pFormat)
{
return drwav_open_file_write__internal(filename, pFormat, 0, DRWAV_FALSE);
}
drwav* drwav_open_file_write_sequential(const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
{
return drwav_open_file_write__internal(filename, pFormat, totalSampleCount, DRWAV_TRUE);
}
#endif //DR_WAV_NO_STDIO #endif //DR_WAV_NO_STDIO
@ -1232,7 +1262,8 @@ drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize)
return DRWAV_TRUE; return DRWAV_TRUE;
} }
drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat)
drwav_bool32 drwav_init_memory_write__internal(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential)
{ {
if (ppData == NULL) { if (ppData == NULL) {
return DRWAV_FALSE; return DRWAV_FALSE;
@ -1249,7 +1280,7 @@ drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSi
memoryStreamWrite.dataCapacity = 0; memoryStreamWrite.dataCapacity = 0;
memoryStreamWrite.currentWritePos = 0; memoryStreamWrite.currentWritePos = 0;
if (!drwav_init_write(pWav, pFormat, drwav__on_write_memory, drwav__on_seek_memory_write, (void*)&memoryStreamWrite)) { if (!drwav_init_write__internal(pWav, pFormat, totalSampleCount, isSequential, drwav__on_write_memory, drwav__on_seek_memory_write, (void*)&memoryStreamWrite)) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
@ -1258,6 +1289,17 @@ drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSi
return DRWAV_TRUE; return DRWAV_TRUE;
} }
drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat)
{
return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, 0, DRWAV_FALSE);
}
drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
{
return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE);
}
drwav* drwav_open_memory(const void* data, size_t dataSize) drwav* drwav_open_memory(const void* data, size_t dataSize)
{ {
if (data == NULL || dataSize == 0) { if (data == NULL || dataSize == 0) {
@ -1280,7 +1322,8 @@ drwav* drwav_open_memory(const void* data, size_t dataSize)
return pWav; return pWav;
} }
drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat)
drwav* drwav_open_memory_write__internal(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential)
{ {
if (ppData == NULL) { if (ppData == NULL) {
return NULL; return NULL;
@ -1297,7 +1340,7 @@ drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_dat
memoryStreamWrite.dataCapacity = 0; memoryStreamWrite.dataCapacity = 0;
memoryStreamWrite.currentWritePos = 0; memoryStreamWrite.currentWritePos = 0;
drwav* pWav = drwav_open_write(pFormat, drwav__on_write_memory, drwav__on_seek_memory_write, (void*)&memoryStreamWrite); drwav* pWav = drwav_open_write__internal(pFormat, totalSampleCount, isSequential, drwav__on_write_memory, drwav__on_seek_memory_write, (void*)&memoryStreamWrite);
if (pWav == NULL) { if (pWav == NULL) {
return NULL; return NULL;
} }
@ -1307,6 +1350,16 @@ drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_dat
return pWav; return pWav;
} }
drwav* drwav_open_memory_write(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat)
{
return drwav_open_memory_write__internal(ppData, pDataSize, pFormat, 0, DRWAV_FALSE);
}
drwav* drwav_open_memory_write_sequential(void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount)
{
return drwav_open_memory_write__internal(ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE);
}
drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData) drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData)
{ {
@ -1392,7 +1445,7 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
} }
// The next 24 bytes should be the "fmt " chunk. // The next bytes should be the "fmt " chunk.
drwav_fmt fmt; drwav_fmt fmt;
if (!drwav__read_fmt(onRead, onSeek, pUserData, pWav->container, &pWav->dataChunkDataPos, &fmt)) { if (!drwav__read_fmt(onRead, onSeek, pUserData, pWav->container, &pWav->dataChunkDataPos, &fmt)) {
return DRWAV_FALSE; // Failed to read the "fmt " chunk. return DRWAV_FALSE; // Failed to read the "fmt " chunk.
@ -1456,7 +1509,7 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
if (onRead(pUserData, &sampleCountFromFactChunk, 8) != 8) { if (onRead(pUserData, &sampleCountFromFactChunk, 8) != 8) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
pWav->dataChunkDataPos += 4; pWav->dataChunkDataPos += 8;
dataSize -= 8; dataSize -= 8;
} }
} }
@ -1518,8 +1571,8 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
#ifdef DR_WAV_LIBSNDFILE_COMPAT #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), // 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 // 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 // from the number of blocks, however this results in the inclusion of 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 // 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 // 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) { if (pWav->translatedFormatTag == DR_WAVE_FORMAT_ADPCM) {
@ -1535,12 +1588,51 @@ drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onS
return DRWAV_TRUE; return DRWAV_TRUE;
} }
drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
drwav_uint32 drwav_riff_chunk_size_riff(drwav_uint64 dataChunkSize)
{ {
if (onWrite == NULL || onSeek == NULL) { if (dataChunkSize <= (0xFFFFFFFF - 36)) {
return 36 + (drwav_uint32)dataChunkSize;
} else {
return 0xFFFFFFFF;
}
}
drwav_uint32 drwav_data_chunk_size_riff(drwav_uint64 dataChunkSize)
{
if (dataChunkSize <= 0xFFFFFFFF) {
return (drwav_uint32)dataChunkSize;
} else {
return 0xFFFFFFFF;
}
}
drwav_uint64 drwav_riff_chunk_size_w64(drwav_uint64 dataChunkSize)
{
return 80 + 24 + dataChunkSize; // +24 because W64 includes the size of the GUID and size fields.
}
drwav_uint64 drwav_data_chunk_size_w64(drwav_uint64 dataChunkSize)
{
return 24 + dataChunkSize; // +24 because W64 includes the size of the GUID and size fields.
}
drwav_bool32 drwav_init_write__internal(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
{
if (pWav == NULL) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
if (onWrite == NULL) {
return DRWAV_FALSE;
}
if (!isSequential && onSeek == NULL) {
return DRWAV_FALSE; // <-- onSeek is required when in non-sequential mode.
}
// Not currently supporting compressed formats. Will need to add support for the "fact" chunk before we enable this. // Not currently supporting compressed formats. Will need to add support for the "fact" chunk before we enable this.
if (pFormat->format == DR_WAVE_FORMAT_EXTENSIBLE) { if (pFormat->format == DR_WAVE_FORMAT_EXTENSIBLE) {
return DRWAV_FALSE; return DRWAV_FALSE;
@ -1557,20 +1649,42 @@ drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drw
pWav->fmt.formatTag = (drwav_uint16)pFormat->format; pWav->fmt.formatTag = (drwav_uint16)pFormat->format;
pWav->fmt.channels = (drwav_uint16)pFormat->channels; pWav->fmt.channels = (drwav_uint16)pFormat->channels;
pWav->fmt.sampleRate = pFormat->sampleRate; pWav->fmt.sampleRate = pFormat->sampleRate;
pWav->fmt.avgBytesPerSec = (drwav_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) >> 3); pWav->fmt.avgBytesPerSec = (drwav_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) / 8);
pWav->fmt.blockAlign = (drwav_uint16)((pFormat->channels * pFormat->bitsPerSample) >> 3); pWav->fmt.blockAlign = (drwav_uint16)((pFormat->channels * pFormat->bitsPerSample) / 8);
pWav->fmt.bitsPerSample = (drwav_uint16)pFormat->bitsPerSample; pWav->fmt.bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
pWav->fmt.extendedSize = 0; pWav->fmt.extendedSize = 0;
pWav->isSequentialWrite = isSequential;
size_t runningPos = 0; size_t runningPos = 0;
// The initial values for the "RIFF" and "data" chunks depends on whether or not we are initializing in sequential mode or not. In
// sequential mode we set this to its final values straight away since they can be calculated from the total sample count. In non-
// sequential mode we initialize it all to zero and fill it out in drwav_uninit() using a backwards seek.
drwav_uint64 initialDataChunkSize = 0;
if (isSequential) {
initialDataChunkSize = (totalSampleCount * pWav->fmt.bitsPerSample) / 8;
// The RIFF container has a limit on the number of samples. drwav is not allowing this. There's no practical limits for Wave64
// so for the sake of simplicity I'm not doing any validation for that.
if (pFormat->container == drwav_container_riff) {
if (initialDataChunkSize > (0xFFFFFFFF - 36)) {
return DRWAV_FALSE; // Not enough room to store every sample.
}
}
}
pWav->dataChunkDataSizeTargetWrite = initialDataChunkSize;
// "RIFF" chunk. // "RIFF" chunk.
drwav_uint64 chunkSizeRIFF = 0;
if (pFormat->container == drwav_container_riff) { if (pFormat->container == drwav_container_riff) {
drwav_uint32 chunkSizeRIFF = 36 + (drwav_uint32)initialDataChunkSize; // +36 = "RIFF"+[RIFF Chunk Size]+"WAVE" + [sizeof "fmt " chunk]
runningPos += pWav->onWrite(pUserData, "RIFF", 4); runningPos += pWav->onWrite(pUserData, "RIFF", 4);
runningPos += pWav->onWrite(pUserData, &chunkSizeRIFF, 4); runningPos += pWav->onWrite(pUserData, &chunkSizeRIFF, 4);
runningPos += pWav->onWrite(pUserData, "WAVE", 4); runningPos += pWav->onWrite(pUserData, "WAVE", 4);
} else { } else {
drwav_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize; // +24 because W64 includes the size of the GUID and size fields.
runningPos += pWav->onWrite(pUserData, drwavGUID_W64_RIFF, 16); runningPos += pWav->onWrite(pUserData, drwavGUID_W64_RIFF, 16);
runningPos += pWav->onWrite(pUserData, &chunkSizeRIFF, 8); runningPos += pWav->onWrite(pUserData, &chunkSizeRIFF, 8);
runningPos += pWav->onWrite(pUserData, drwavGUID_W64_WAVE, 16); runningPos += pWav->onWrite(pUserData, drwavGUID_W64_WAVE, 16);
@ -1596,14 +1710,14 @@ drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drw
runningPos += pWav->onWrite(pUserData, &pWav->fmt.bitsPerSample, 2); runningPos += pWav->onWrite(pUserData, &pWav->fmt.bitsPerSample, 2);
pWav->dataChunkDataPos = runningPos; pWav->dataChunkDataPos = runningPos;
pWav->dataChunkDataSize = 0;
// "data" chunk. // "data" chunk.
drwav_uint64 chunkSizeDATA = 0;
if (pFormat->container == drwav_container_riff) { if (pFormat->container == drwav_container_riff) {
drwav_uint32 chunkSizeDATA = (drwav_uint32)initialDataChunkSize;
runningPos += pWav->onWrite(pUserData, "data", 4); runningPos += pWav->onWrite(pUserData, "data", 4);
runningPos += pWav->onWrite(pUserData, &chunkSizeDATA, 4); runningPos += pWav->onWrite(pUserData, &chunkSizeDATA, 4);
} else { } else {
drwav_uint64 chunkSizeDATA = 24 + initialDataChunkSize; // +24 because W64 includes the size of the GUID and size fields.
runningPos += pWav->onWrite(pUserData, drwavGUID_W64_DATA, 16); runningPos += pWav->onWrite(pUserData, drwavGUID_W64_DATA, 16);
runningPos += pWav->onWrite(pUserData, &chunkSizeDATA, 8); runningPos += pWav->onWrite(pUserData, &chunkSizeDATA, 8);
} }
@ -1633,16 +1747,32 @@ drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drw
return DRWAV_TRUE; return DRWAV_TRUE;
} }
drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
{
return drwav_init_write__internal(pWav, pFormat, 0, DRWAV_FALSE, onWrite, onSeek, pUserData); // DRWAV_FALSE = Not Sequential
}
drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData)
{
return drwav_init_write__internal(pWav, pFormat, totalSampleCount, DRWAV_TRUE, onWrite, NULL, pUserData); // DRWAV_TRUE = Sequential
}
void drwav_uninit(drwav* pWav) void drwav_uninit(drwav* pWav)
{ {
if (pWav == NULL) { if (pWav == NULL) {
return; return;
} }
// If the drwav object was opened in write mode we'll need to finialize a few things: // If the drwav object was opened in write mode we'll need to finalize a few things:
// - Make sure the "data" chunk is aligned to 16-bits // - Make sure the "data" chunk is aligned to 16-bits for RIFF containers, or 64 bits for W64 containers.
// - Set the size of the "data" chunk. // - Set the size of the "data" chunk.
if (pWav->onWrite != NULL) { if (pWav->onWrite != NULL) {
// Validation for sequential mode.
if (pWav->isSequentialWrite) {
drwav_assert(pWav->dataChunkDataSize == pWav->dataChunkDataSizeTargetWrite);
}
// Padding. Do not adjust pWav->dataChunkDataSize - this should not include the padding. // Padding. Do not adjust pWav->dataChunkDataSize - this should not include the padding.
drwav_uint32 paddingSize = 0; drwav_uint32 paddingSize = 0;
if (pWav->container == drwav_container_riff) { if (pWav->container == drwav_container_riff) {
@ -1657,42 +1787,31 @@ void drwav_uninit(drwav* pWav)
} }
// Chunk sizes. // Chunk sizes. When using sequential mode, these will have been filled in at initialization time. We only need
if (pWav->onSeek) { // to do this when using non-sequential mode.
if (pWav->onSeek && !pWav->isSequentialWrite) {
if (pWav->container == drwav_container_riff) { if (pWav->container == drwav_container_riff) {
// The "RIFF" chunk size. // The "RIFF" chunk size.
if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) { if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) {
drwav_uint32 riffChunkSize = 36; drwav_uint32 riffChunkSize = drwav_riff_chunk_size_riff(pWav->dataChunkDataSize);
if (pWav->dataChunkDataSize <= (0xFFFFFFFF - 36)) {
riffChunkSize = 36 + (drwav_uint32)pWav->dataChunkDataSize;
} else {
riffChunkSize = 0xFFFFFFFF;
}
pWav->onWrite(pWav->pUserData, &riffChunkSize, 4); pWav->onWrite(pWav->pUserData, &riffChunkSize, 4);
} }
// the "data" chunk size. // the "data" chunk size.
if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 4, drwav_seek_origin_start)) { if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 4, drwav_seek_origin_start)) {
drwav_uint32 dataChunkSize = 0; drwav_uint32 dataChunkSize = drwav_data_chunk_size_riff(pWav->dataChunkDataSize);
if (pWav->dataChunkDataSize <= 0xFFFFFFFF) {
dataChunkSize = (drwav_uint32)pWav->dataChunkDataSize;
} else {
dataChunkSize = 0xFFFFFFFF;
}
pWav->onWrite(pWav->pUserData, &dataChunkSize, 4); pWav->onWrite(pWav->pUserData, &dataChunkSize, 4);
} }
} else { } else {
// The "RIFF" chunk size. // The "RIFF" chunk size.
if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) { if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) {
drwav_uint64 riffChunkSize = 80 + 24 + pWav->dataChunkDataSize; drwav_uint64 riffChunkSize = drwav_riff_chunk_size_w64(pWav->dataChunkDataSize);
pWav->onWrite(pWav->pUserData, &riffChunkSize, 8); pWav->onWrite(pWav->pUserData, &riffChunkSize, 8);
} }
// The "data" chunk size. // The "data" chunk size.
if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 16, drwav_seek_origin_start)) { if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos + 16, drwav_seek_origin_start)) {
drwav_uint64 dataChunkSize = 24 + pWav->dataChunkDataSize; // +24 because W64 includes the size of the GUID and size fields. drwav_uint64 dataChunkSize = drwav_data_chunk_size_w64(pWav->dataChunkDataSize);
pWav->onWrite(pWav->pUserData, &dataChunkSize, 8); pWav->onWrite(pWav->pUserData, &dataChunkSize, 8);
} }
} }
@ -1724,14 +1843,15 @@ drwav* drwav_open(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserDat
return pWav; return pWav;
} }
drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
drwav* drwav_open_write__internal(const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
{ {
drwav* pWav = (drwav*)DRWAV_MALLOC(sizeof(*pWav)); drwav* pWav = (drwav*)DRWAV_MALLOC(sizeof(*pWav));
if (pWav == NULL) { if (pWav == NULL) {
return NULL; return NULL;
} }
if (!drwav_init_write(pWav, pFormat, onWrite, onSeek, pUserData)) { if (!drwav_init_write__internal(pWav, pFormat, totalSampleCount, isSequential, onWrite, onSeek, pUserData)) {
DRWAV_FREE(pWav); DRWAV_FREE(pWav);
return NULL; return NULL;
} }
@ -1739,6 +1859,16 @@ drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWri
return pWav; return pWav;
} }
drwav* drwav_open_write(const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData)
{
return drwav_open_write__internal(pFormat, 0, DRWAV_FALSE, onWrite, onSeek, pUserData);
}
drwav* drwav_open_write_sequential(const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData)
{
return drwav_open_write__internal(pFormat, totalSampleCount, DRWAV_TRUE, onWrite, NULL, pUserData);
}
void drwav_close(drwav* pWav) void drwav_close(drwav* pWav)
{ {
drwav_uninit(pWav); drwav_uninit(pWav);
@ -1784,6 +1914,10 @@ drwav_uint64 drwav_read(drwav* pWav, drwav_uint64 samplesToRead, void* pBufferOu
drwav_bool32 drwav_seek_to_first_sample(drwav* pWav) drwav_bool32 drwav_seek_to_first_sample(drwav* pWav)
{ {
if (pWav->onWrite != NULL) {
return DRWAV_FALSE; // No seeking in write mode.
}
if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) { if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
@ -1800,6 +1934,10 @@ drwav_bool32 drwav_seek_to_sample(drwav* pWav, drwav_uint64 sample)
{ {
// Seeking should be compatible with wave files > 2GB. // Seeking should be compatible with wave files > 2GB.
if (pWav->onWrite != NULL) {
return DRWAV_FALSE; // No seeking in write mode.
}
if (pWav == NULL || pWav->onSeek == NULL) { if (pWav == NULL || pWav->onSeek == NULL) {
return DRWAV_FALSE; return DRWAV_FALSE;
} }
@ -1911,8 +2049,25 @@ drwav_uint64 drwav_write(drwav* pWav, drwav_uint64 samplesToWrite, const void* p
return 0; return 0;
} }
size_t bytesWritten = drwav_write_raw(pWav, (size_t)bytesToWrite, pData); drwav_uint64 bytesWritten = 0;
return ((drwav_uint64)bytesWritten * 8) / pWav->bitsPerSample; const drwav_uint8* pRunningData = (const drwav_uint8*)pData;
while (bytesToWrite > 0) {
drwav_uint64 bytesToWriteThisIteration = bytesToWrite;
if (bytesToWriteThisIteration > SIZE_MAX) {
bytesToWriteThisIteration = SIZE_MAX;
}
size_t bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
if (bytesJustWritten == 0) {
break;
}
bytesToWrite -= bytesJustWritten;
bytesWritten += bytesJustWritten;
pRunningData += bytesJustWritten;
}
return (bytesWritten * 8) / pWav->bitsPerSample;
} }
@ -3439,6 +3594,16 @@ void drwav_free(void* pDataReturnedByOpenAndRead)
// REVISION HISTORY // REVISION HISTORY
// //
// v0.8.1 - 2018-06-29
// - Add support for sequential writing APIs.
// - Disable seeking in write mode.
// - Fix bugs with Wave64.
// - Fix typos.
//
// v0.8 - 2018-04-27
// - Bug fix.
// - Start using major.minor.revision versioning.
//
// v0.7f - 2018-02-05 // v0.7f - 2018-02-05
// - Restrict ADPCM formats to a maximum of 2 channels. // - Restrict ADPCM formats to a maximum of 2 channels.
// //

4090
src/external/mini_al.h vendored

File diff suppressed because it is too large Load Diff