rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h
Go to the documentation of this file.
1 /*
2 WAV audio loader and writer. Choice of public domain or MIT-0. See license statements at the end of this file.
3 dr_wav - v0.13.0 - 2021-07-01
4 
5 David Reid - mackron@gmail.com
6 
7 GitHub: https://github.com/mackron/dr_libs
8 */
9 
10 /*
11 Introduction
12 ============
13 This is a single file library. To use it, do something like the following in one .c file.
14 
15  ```c
16  #define DR_WAV_IMPLEMENTATION
17  #include "dr_wav.h"
18  ```
19 
20 You can then #include this file in other parts of the program as you would with any other header file. Do something like the following to read audio data:
21 
22  ```c
23  drwav wav;
24  if (!drwav_init_file(&wav, "my_song.wav", NULL)) {
25  // Error opening WAV file.
26  }
27 
28  drwav_int32* pDecodedInterleavedPCMFrames = malloc(wav.totalPCMFrameCount * wav.channels * sizeof(drwav_int32));
29  size_t numberOfSamplesActuallyDecoded = drwav_read_pcm_frames_s32(&wav, wav.totalPCMFrameCount, pDecodedInterleavedPCMFrames);
30 
31  ...
32 
33  drwav_uninit(&wav);
34  ```
35 
36 If you just want to quickly open and read the audio data in a single operation you can do something like this:
37 
38  ```c
39  unsigned int channels;
40  unsigned int sampleRate;
41  drwav_uint64 totalPCMFrameCount;
42  float* pSampleData = drwav_open_file_and_read_pcm_frames_f32("my_song.wav", &channels, &sampleRate, &totalPCMFrameCount, NULL);
43  if (pSampleData == NULL) {
44  // Error opening and reading WAV file.
45  }
46 
47  ...
48 
49  drwav_free(pSampleData, NULL);
50  ```
51 
52 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
53 audio data in its internal format (see notes below for supported formats):
54 
55  ```c
56  size_t framesRead = drwav_read_pcm_frames(&wav, wav.totalPCMFrameCount, pDecodedInterleavedPCMFrames);
57  ```
58 
59 You can also read the raw bytes of audio data, which could be useful if dr_wav does not have native support for a particular data format:
60 
61  ```c
62  size_t bytesRead = drwav_read_raw(&wav, bytesToRead, pRawDataBuffer);
63  ```
64 
65 dr_wav can also be used to output WAV files. This does not currently support compressed formats. To use this, look at `drwav_init_write()`,
66 `drwav_init_file_write()`, etc. Use `drwav_write_pcm_frames()` to write samples, or `drwav_write_raw()` to write raw data in the "data" chunk.
67 
68  ```c
69  drwav_data_format format;
70  format.container = drwav_container_riff; // <-- drwav_container_riff = normal WAV files, drwav_container_w64 = Sony Wave64.
71  format.format = DR_WAVE_FORMAT_PCM; // <-- Any of the DR_WAVE_FORMAT_* codes.
72  format.channels = 2;
73  format.sampleRate = 44100;
74  format.bitsPerSample = 16;
75  drwav_init_file_write(&wav, "data/recording.wav", &format, NULL);
76 
77  ...
78 
79  drwav_uint64 framesWritten = drwav_write_pcm_frames(pWav, frameCount, pSamples);
80  ```
81 
82 dr_wav has seamless support the Sony Wave64 format. The decoder will automatically detect it and it should Just Work without any manual intervention.
83 
84 
85 Build Options
86 =============
87 #define these options before including this file.
88 
89 #define DR_WAV_NO_CONVERSION_API
90  Disables conversion APIs such as `drwav_read_pcm_frames_f32()` and `drwav_s16_to_f32()`.
91 
92 #define DR_WAV_NO_STDIO
93  Disables APIs that initialize a decoder from a file such as `drwav_init_file()`, `drwav_init_file_write()`, etc.
94 
95 
96 
97 Notes
98 =====
99 - Samples are always interleaved.
100 - The default read function does not do any data conversion. Use `drwav_read_pcm_frames_f32()`, `drwav_read_pcm_frames_s32()` and `drwav_read_pcm_frames_s16()`
101  to read and convert audio data to 32-bit floating point, signed 32-bit integer and signed 16-bit integer samples respectively. Tested and supported internal
102  formats include the following:
103  - Unsigned 8-bit PCM
104  - Signed 12-bit PCM
105  - Signed 16-bit PCM
106  - Signed 24-bit PCM
107  - Signed 32-bit PCM
108  - IEEE 32-bit floating point
109  - IEEE 64-bit floating point
110  - A-law and u-law
111  - Microsoft ADPCM
112  - IMA ADPCM (DVI, format code 0x11)
113 - dr_wav will try to read the WAV file as best it can, even if it's not strictly conformant to the WAV format.
114 */
115 
116 #ifndef dr_wav_h
117 #define dr_wav_h
118 
119 #ifdef __cplusplus
120 extern "C" {
121 #endif
122 
123 #define DRWAV_STRINGIFY(x) #x
124 #define DRWAV_XSTRINGIFY(x) DRWAV_STRINGIFY(x)
125 
126 #define DRWAV_VERSION_MAJOR 0
127 #define DRWAV_VERSION_MINOR 13
128 #define DRWAV_VERSION_REVISION 0
129 #define DRWAV_VERSION_STRING DRWAV_XSTRINGIFY(DRWAV_VERSION_MAJOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_MINOR) "." DRWAV_XSTRINGIFY(DRWAV_VERSION_REVISION)
130 
131 #include <stddef.h> /* For size_t. */
132 
133 /* Sized types. */
134 typedef signed char drwav_int8;
135 typedef unsigned char drwav_uint8;
136 typedef signed short drwav_int16;
137 typedef unsigned short drwav_uint16;
138 typedef signed int drwav_int32;
139 typedef unsigned int drwav_uint32;
140 #if defined(_MSC_VER) && !defined(__clang__)
141  typedef signed __int64 drwav_int64;
142  typedef unsigned __int64 drwav_uint64;
143 #else
144  #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
145  #pragma GCC diagnostic push
146  #pragma GCC diagnostic ignored "-Wlong-long"
147  #if defined(__clang__)
148  #pragma GCC diagnostic ignored "-Wc++11-long-long"
149  #endif
150  #endif
151  typedef signed long long drwav_int64;
152  typedef unsigned long long drwav_uint64;
153  #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
154  #pragma GCC diagnostic pop
155  #endif
156 #endif
157 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
158  typedef drwav_uint64 drwav_uintptr;
159 #else
161 #endif
164 #define DRWAV_TRUE 1
165 #define DRWAV_FALSE 0
166 
167 #if !defined(DRWAV_API)
168  #if defined(DRWAV_DLL)
169  #if defined(_WIN32)
170  #define DRWAV_DLL_IMPORT __declspec(dllimport)
171  #define DRWAV_DLL_EXPORT __declspec(dllexport)
172  #define DRWAV_DLL_PRIVATE static
173  #else
174  #if defined(__GNUC__) && __GNUC__ >= 4
175  #define DRWAV_DLL_IMPORT __attribute__((visibility("default")))
176  #define DRWAV_DLL_EXPORT __attribute__((visibility("default")))
177  #define DRWAV_DLL_PRIVATE __attribute__((visibility("hidden")))
178  #else
179  #define DRWAV_DLL_IMPORT
180  #define DRWAV_DLL_EXPORT
181  #define DRWAV_DLL_PRIVATE static
182  #endif
183  #endif
184 
185  #if defined(DR_WAV_IMPLEMENTATION) || defined(DRWAV_IMPLEMENTATION)
186  #define DRWAV_API DRWAV_DLL_EXPORT
187  #else
188  #define DRWAV_API DRWAV_DLL_IMPORT
189  #endif
190  #define DRWAV_PRIVATE DRWAV_DLL_PRIVATE
191  #else
192  #define DRWAV_API extern
193  #define DRWAV_PRIVATE static
194  #endif
195 #endif
196 
198 #define DRWAV_SUCCESS 0
199 #define DRWAV_ERROR -1 /* A generic error. */
200 #define DRWAV_INVALID_ARGS -2
201 #define DRWAV_INVALID_OPERATION -3
202 #define DRWAV_OUT_OF_MEMORY -4
203 #define DRWAV_OUT_OF_RANGE -5
204 #define DRWAV_ACCESS_DENIED -6
205 #define DRWAV_DOES_NOT_EXIST -7
206 #define DRWAV_ALREADY_EXISTS -8
207 #define DRWAV_TOO_MANY_OPEN_FILES -9
208 #define DRWAV_INVALID_FILE -10
209 #define DRWAV_TOO_BIG -11
210 #define DRWAV_PATH_TOO_LONG -12
211 #define DRWAV_NAME_TOO_LONG -13
212 #define DRWAV_NOT_DIRECTORY -14
213 #define DRWAV_IS_DIRECTORY -15
214 #define DRWAV_DIRECTORY_NOT_EMPTY -16
215 #define DRWAV_END_OF_FILE -17
216 #define DRWAV_NO_SPACE -18
217 #define DRWAV_BUSY -19
218 #define DRWAV_IO_ERROR -20
219 #define DRWAV_INTERRUPT -21
220 #define DRWAV_UNAVAILABLE -22
221 #define DRWAV_ALREADY_IN_USE -23
222 #define DRWAV_BAD_ADDRESS -24
223 #define DRWAV_BAD_SEEK -25
224 #define DRWAV_BAD_PIPE -26
225 #define DRWAV_DEADLOCK -27
226 #define DRWAV_TOO_MANY_LINKS -28
227 #define DRWAV_NOT_IMPLEMENTED -29
228 #define DRWAV_NO_MESSAGE -30
229 #define DRWAV_BAD_MESSAGE -31
230 #define DRWAV_NO_DATA_AVAILABLE -32
231 #define DRWAV_INVALID_DATA -33
232 #define DRWAV_TIMEOUT -34
233 #define DRWAV_NO_NETWORK -35
234 #define DRWAV_NOT_UNIQUE -36
235 #define DRWAV_NOT_SOCKET -37
236 #define DRWAV_NO_ADDRESS -38
237 #define DRWAV_BAD_PROTOCOL -39
238 #define DRWAV_PROTOCOL_UNAVAILABLE -40
239 #define DRWAV_PROTOCOL_NOT_SUPPORTED -41
240 #define DRWAV_PROTOCOL_FAMILY_NOT_SUPPORTED -42
241 #define DRWAV_ADDRESS_FAMILY_NOT_SUPPORTED -43
242 #define DRWAV_SOCKET_NOT_SUPPORTED -44
243 #define DRWAV_CONNECTION_RESET -45
244 #define DRWAV_ALREADY_CONNECTED -46
245 #define DRWAV_NOT_CONNECTED -47
246 #define DRWAV_CONNECTION_REFUSED -48
247 #define DRWAV_NO_HOST -49
248 #define DRWAV_IN_PROGRESS -50
249 #define DRWAV_CANCELLED -51
250 #define DRWAV_MEMORY_ALREADY_MAPPED -52
251 #define DRWAV_AT_END -53
252 
253 /* Common data formats. */
254 #define DR_WAVE_FORMAT_PCM 0x1
255 #define DR_WAVE_FORMAT_ADPCM 0x2
256 #define DR_WAVE_FORMAT_IEEE_FLOAT 0x3
257 #define DR_WAVE_FORMAT_ALAW 0x6
258 #define DR_WAVE_FORMAT_MULAW 0x7
259 #define DR_WAVE_FORMAT_DVI_ADPCM 0x11
260 #define DR_WAVE_FORMAT_EXTENSIBLE 0xFFFE
261 
262 /* Flags to pass into drwav_init_ex(), etc. */
263 #define DRWAV_SEQUENTIAL 0x00000001
264 
265 DRWAV_API void drwav_version(drwav_uint32* pMajor, drwav_uint32* pMinor, drwav_uint32* pRevision);
266 DRWAV_API const char* drwav_version_string(void);
267 
268 typedef enum
269 {
273 
274 typedef enum
275 {
280 
281 typedef struct
282 {
283  union
284  {
285  drwav_uint8 fourcc[4];
286  drwav_uint8 guid[16];
287  } id;
288 
289  /* The size in bytes of the chunk. */
290  drwav_uint64 sizeInBytes;
291 
292  /*
293  RIFF = 2 byte alignment.
294  W64 = 8 byte alignment.
295  */
296  unsigned int paddingSize;
298 
299 typedef struct
300 {
301  /*
302  The format tag exactly as specified in the wave file's "fmt" chunk. This can be used by applications
303  that require support for data formats not natively supported by dr_wav.
304  */
305  drwav_uint16 formatTag;
306 
307  /* The number of channels making up the audio data. When this is set to 1 it is mono, 2 is stereo, etc. */
308  drwav_uint16 channels;
309 
310  /* The sample rate. Usually set to something like 44100. */
311  drwav_uint32 sampleRate;
312 
313  /* Average bytes per second. You probably don't need this, but it's left here for informational purposes. */
314  drwav_uint32 avgBytesPerSec;
315 
316  /* Block align. This is equal to the number of channels * bytes per sample. */
317  drwav_uint16 blockAlign;
318 
319  /* Bits per sample. */
320  drwav_uint16 bitsPerSample;
321 
322  /* The size of the extended data. Only used internally for validation, but left here for informational purposes. */
323  drwav_uint16 extendedSize;
324 
325  /*
326  The number of valid bits per sample. When <formatTag> is equal to WAVE_FORMAT_EXTENSIBLE, <bitsPerSample>
327  is always rounded up to the nearest multiple of 8. This variable contains information about exactly how
328  many bits are valid per sample. Mainly used for informational purposes.
329  */
330  drwav_uint16 validBitsPerSample;
331 
332  /* The channel mask. Not used at the moment. */
333  drwav_uint32 channelMask;
334 
335  /* The sub-format, exactly as specified by the wave file. */
336  drwav_uint8 subFormat[16];
337 } drwav_fmt;
338 
340 
341 
342 /*
343 Callback for when data is read. Return value is the number of bytes actually read.
344 
345 pUserData [in] The user data that was passed to drwav_init() and family.
346 pBufferOut [out] The output buffer.
347 bytesToRead [in] The number of bytes to read.
348 
349 Returns the number of bytes actually read.
350 
351 A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
352 either the entire bytesToRead is filled or you have reached the end of the stream.
353 */
354 typedef size_t (* drwav_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
355 
356 /*
357 Callback for when data is written. Returns value is the number of bytes actually written.
358 
359 pUserData [in] The user data that was passed to drwav_init_write() and family.
360 pData [out] A pointer to the data to write.
361 bytesToWrite [in] The number of bytes to write.
362 
363 Returns the number of bytes actually written.
364 
365 If the return value differs from bytesToWrite, it indicates an error.
366 */
367 typedef size_t (* drwav_write_proc)(void* pUserData, const void* pData, size_t bytesToWrite);
368 
369 /*
370 Callback for when data needs to be seeked.
371 
372 pUserData [in] The user data that was passed to drwav_init() and family.
373 offset [in] The number of bytes to move, relative to the origin. Will never be negative.
374 origin [in] The origin of the seek - the current position or the start of the stream.
375 
376 Returns whether or not the seek was successful.
377 
378 Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which will be either drwav_seek_origin_start or
379 drwav_seek_origin_current.
380 */
381 typedef drwav_bool32 (* drwav_seek_proc)(void* pUserData, int offset, drwav_seek_origin origin);
382 
383 /*
384 Callback for when drwav_init_ex() finds a chunk.
385 
386 pChunkUserData [in] The user data that was passed to the pChunkUserData parameter of drwav_init_ex() and family.
387 onRead [in] A pointer to the function to call when reading.
388 onSeek [in] A pointer to the function to call when seeking.
389 pReadSeekUserData [in] The user data that was passed to the pReadSeekUserData parameter of drwav_init_ex() and family.
390 pChunkHeader [in] A pointer to an object containing basic header information about the chunk. Use this to identify the chunk.
391 container [in] Whether or not the WAV file is a RIFF or Wave64 container. If you're unsure of the difference, assume RIFF.
392 pFMT [in] A pointer to the object containing the contents of the "fmt" chunk.
393 
394 Returns the number of bytes read + seeked.
395 
396 To read data from the chunk, call onRead(), passing in pReadSeekUserData as the first parameter. Do the same for seeking with onSeek(). The return value must
397 be the total number of bytes you have read _plus_ seeked.
398 
399 Use the `container` argument to discriminate the fields in `pChunkHeader->id`. If the container is `drwav_container_riff` or `drwav_container_rf64` you should
400 use `id.fourcc`, otherwise you should use `id.guid`.
401 
402 The `pFMT` parameter can be used to determine the data format of the wave file. Use `drwav_fmt_get_format()` to get the sample format, which will be one of the
403 `DR_WAVE_FORMAT_*` identifiers.
404 
405 The read pointer will be sitting on the first byte after the chunk's header. You must not attempt to read beyond the boundary of the chunk.
406 */
407 typedef drwav_uint64 (* drwav_chunk_proc)(void* pChunkUserData, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_chunk_header* pChunkHeader, drwav_container container, const drwav_fmt* pFMT);
408 
409 typedef struct
410 {
411  void* pUserData;
412  void* (* onMalloc)(size_t sz, void* pUserData);
413  void* (* onRealloc)(void* p, size_t sz, void* pUserData);
414  void (* onFree)(void* p, void* pUserData);
416 
417 /* Structure for internal use. Only used for loaders opened with drwav_init_memory(). */
418 typedef struct
419 {
420  const drwav_uint8* data;
421  size_t dataSize;
422  size_t currentReadPos;
424 
425 /* Structure for internal use. Only used for writers opened with drwav_init_memory_write(). */
426 typedef struct
427 {
428  void** ppData;
429  size_t* pDataSize;
430  size_t dataSize;
431  size_t dataCapacity;
432  size_t currentWritePos;
434 
435 typedef struct
436 {
437  drwav_container container; /* RIFF, W64. */
438  drwav_uint32 format; /* DR_WAVE_FORMAT_* */
439  drwav_uint32 channels;
440  drwav_uint32 sampleRate;
441  drwav_uint32 bitsPerSample;
443 
444 typedef enum
445 {
447 
448  /*
449  Unknown simply means a chunk that drwav does not handle specifically. You can still ask to
450  receive these chunks as metadata objects. It is then up to you to interpret the chunk's data.
451  You can also write unknown metadata to a wav file. Be careful writing unknown chunks if you
452  have also edited the audio data. The unknown chunks could represent offsets/sizes that no
453  longer correctly correspond to the audio data.
454  */
456 
457  /* Only 1 of each of these metadata items are allowed in a wav file. */
463 
464  /*
465  Wav files often have a LIST chunk. This is a chunk that contains a set of subchunks. For this
466  higher-level metadata API, we don't make a distinction between a regular chunk and a LIST
467  subchunk. Instead, they are all just 'metadata' items.
468 
469  There can be multiple of these metadata items in a wav file.
470  */
474 
484 
485  /* Other type constants for convenience. */
495 
499 
500  drwav_metadata_type_all = -2, /*0xFFFFFFFF & ~drwav_metadata_type_unknown,*/
503 
504 /*
505 Sampler Metadata
506 
507 The sampler chunk contains information about how a sound should be played in the context of a whole
508 audio production, and when used in a sampler. See https://en.wikipedia.org/wiki/Sample-based_synthesis.
509 */
510 typedef enum
511 {
516 
517 typedef struct
518 {
519  /* The ID of the associated cue point, see drwav_cue and drwav_cue_point. As with all cue point IDs, this can correspond to a label chunk to give this loop a name, see drwav_list_label_or_note. */
520  drwav_uint32 cuePointId;
521 
522  /* See drwav_smpl_loop_type. */
523  drwav_uint32 type;
524 
525  /* The byte offset of the first sample to be played in the loop. */
526  drwav_uint32 firstSampleByteOffset;
527 
528  /* The byte offset into the audio data of the last sample to be played in the loop. */
529  drwav_uint32 lastSampleByteOffset;
530 
531  /* A value to represent that playback should occur at a point between samples. This value ranges from 0 to UINT32_MAX. Where a value of 0 means no fraction, and a value of (UINT32_MAX / 2) would mean half a sample. */
532  drwav_uint32 sampleFraction;
533 
534  /* Number of times to play the loop. 0 means loop infinitely. */
535  drwav_uint32 playCount;
537 
538 typedef struct
539 {
540  /* IDs for a particular MIDI manufacturer. 0 if not used. */
541  drwav_uint32 manufacturerId;
542  drwav_uint32 productId;
543 
544  /* The period of 1 sample in nanoseconds. */
545  drwav_uint32 samplePeriodNanoseconds;
546 
547  /* The MIDI root note of this file. 0 to 127. */
548  drwav_uint32 midiUnityNote;
549 
550  /* The fraction of a semitone up from the given MIDI note. This is a value from 0 to UINT32_MAX, where 0 means no change and (UINT32_MAX / 2) is half a semitone (AKA 50 cents). */
551  drwav_uint32 midiPitchFraction;
552 
553  /* Data relating to SMPTE standards which are used for syncing audio and video. 0 if not used. */
554  drwav_uint32 smpteFormat;
555  drwav_uint32 smpteOffset;
556 
557  /* drwav_smpl_loop loops. */
558  drwav_uint32 sampleLoopCount;
559 
560  /* Optional sampler-specific data. */
561  drwav_uint32 samplerSpecificDataSizeInBytes;
562 
563  drwav_smpl_loop* pLoops;
564  drwav_uint8* pSamplerSpecificData;
565 } drwav_smpl;
566 
567 /*
568 Instrument Metadata
569 
570 The inst metadata contains data about how a sound should be played as part of an instrument. This
571 commonly read by samplers. See https://en.wikipedia.org/wiki/Sample-based_synthesis.
572 */
573 typedef struct
574 {
575  drwav_int8 midiUnityNote; /* The root note of the audio as a MIDI note number. 0 to 127. */
576  drwav_int8 fineTuneCents; /* -50 to +50 */
577  drwav_int8 gainDecibels; /* -64 to +64 */
578  drwav_int8 lowNote; /* 0 to 127 */
579  drwav_int8 highNote; /* 0 to 127 */
580  drwav_int8 lowVelocity; /* 1 to 127 */
581  drwav_int8 highVelocity; /* 1 to 127 */
582 } drwav_inst;
583 
584 /*
585 Cue Metadata
586 
587 Cue points are markers at specific points in the audio. They often come with an associated piece of
588 drwav_list_label_or_note metadata which contains the text for the marker.
589 */
590 typedef struct
591 {
592  /* Unique identification value. */
593  drwav_uint32 id;
594 
595  /* Set to 0. This is only relevant if there is a 'playlist' chunk - which is not supported by dr_wav. */
596  drwav_uint32 playOrderPosition;
597 
598  /* Should always be "data". This represents the fourcc value of the chunk that this cue point corresponds to. dr_wav only supports a single data chunk so this should always be "data". */
599  drwav_uint8 dataChunkId[4];
600 
601  /* Set to 0. This is only relevant if there is a wave list chunk. dr_wav, like lots of readers/writers, do not support this. */
602  drwav_uint32 chunkStart;
603 
604  /* Set to 0 for uncompressed formats. Else the last byte in compressed wave data where decompression can begin to find the value of the corresponding sample value. */
605  drwav_uint32 blockStart;
606 
607  /* For uncompressed formats this is the byte offset of the cue point into the audio data. For compressed formats this is relative to the block specified with blockStart. */
608  drwav_uint32 sampleByteOffset;
610 
611 typedef struct
612 {
613  drwav_uint32 cuePointCount;
614  drwav_cue_point *pCuePoints;
615 } drwav_cue;
616 
617 /*
618 Acid Metadata
619 
620 This chunk contains some information about the time signature and the tempo of the audio.
621 */
622 typedef enum
623 {
624  drwav_acid_flag_one_shot = 1, /* If this is not set, then it is a loop instead of a one-shot. */
628  drwav_acid_flag_acidizer = 16 /* Not sure what this means. */
630 
631 typedef struct
632 {
633  /* A bit-field, see drwav_acid_flag. */
634  drwav_uint32 flags;
635 
636  /* Valid if flags contains drwav_acid_flag_root_note_set. It represents the MIDI root note the file - a value from 0 to 127. */
637  drwav_uint16 midiUnityNote;
638 
639  /* Reserved values that should probably be ignored. reserved1 seems to often be 128 and reserved2 is 0. */
640  drwav_uint16 reserved1;
641  float reserved2;
642 
643  /* Number of beats. */
644  drwav_uint32 numBeats;
645 
646  /* The time signature of the audio. */
647  drwav_uint16 meterDenominator;
648  drwav_uint16 meterNumerator;
649 
650  /* Beats per minute of the track. Setting a value of 0 suggests that there is no tempo. */
651  float tempo;
652 } drwav_acid;
653 
654 /*
655 Cue Label or Note metadata
656 
657 These are 2 different types of metadata, but they have the exact same format. Labels tend to be the
658 more common and represent a short name for a cue point. Notes might be used to represent a longer
659 comment.
660 */
661 typedef struct
662 {
663  /* The ID of a cue point that this label or note corresponds to. */
664  drwav_uint32 cuePointId;
665 
666  /* Size of the string not including any null terminator. */
667  drwav_uint32 stringLength;
668 
669  /* The string. The *init_with_metadata functions null terminate this for convenience. */
670  char* pString;
672 
673 /*
674 BEXT metadata, also known as Broadcast Wave Format (BWF)
675 
676 This metadata adds some extra description to an audio file. You must check the version field to
677 determine if the UMID or the loudness fields are valid.
678 */
679 typedef struct
680 {
681  /*
682  These top 3 fields, and the umid field are actually defined in the standard as a statically
683  sized buffers. In order to reduce the size of this struct (and therefore the union in the
684  metadata struct), we instead store these as pointers.
685  */
686  char* pDescription; /* Can be NULL or a null-terminated string, must be <= 256 characters. */
687  char* pOriginatorName; /* Can be NULL or a null-terminated string, must be <= 32 characters. */
688  char* pOriginatorReference; /* Can be NULL or a null-terminated string, must be <= 32 characters. */
689  char pOriginationDate[10]; /* ASCII "yyyy:mm:dd". */
690  char pOriginationTime[8]; /* ASCII "hh:mm:ss". */
691  drwav_uint64 timeReference; /* First sample count since midnight. */
692  drwav_uint16 version; /* Version of the BWF, check this to see if the fields below are valid. */
693 
694  /*
695  Unrestricted ASCII characters containing a collection of strings terminated by CR/LF. Each
696  string shall contain a description of a coding process applied to the audio data.
697  */
698  char* pCodingHistory;
699  drwav_uint32 codingHistorySize;
700 
701  /* Fields below this point are only valid if the version is 1 or above. */
702  drwav_uint8* pUMID; /* Exactly 64 bytes of SMPTE UMID */
703 
704  /* Fields below this point are only valid if the version is 2 or above. */
705  drwav_uint16 loudnessValue; /* Integrated Loudness Value of the file in LUFS (multiplied by 100). */
706  drwav_uint16 loudnessRange; /* Loudness Range of the file in LU (multiplied by 100). */
707  drwav_uint16 maxTruePeakLevel; /* Maximum True Peak Level of the file expressed as dBTP (multiplied by 100). */
708  drwav_uint16 maxMomentaryLoudness; /* Highest value of the Momentary Loudness Level of the file in LUFS (multiplied by 100). */
709  drwav_uint16 maxShortTermLoudness; /* Highest value of the Short-Term Loudness Level of the file in LUFS (multiplied by 100). */
710 } drwav_bext;
711 
712 /*
713 Info Text Metadata
714 
715 There a many different types of information text that can be saved in this format. This is where
716 things like the album name, the artists, the year it was produced, etc are saved. See
717 drwav_metadata_type for the full list of types that dr_wav supports.
718 */
719 typedef struct
720 {
721  /* Size of the string not including any null terminator. */
722  drwav_uint32 stringLength;
723 
724  /* The string. The *init_with_metadata functions null terminate this for convenience. */
725  char* pString;
727 
728 /*
729 Labelled Cue Region Metadata
730 
731 The labelled cue region metadata is used to associate some region of audio with text. The region
732 starts at a cue point, and extends for the given number of samples.
733 */
734 typedef struct
735 {
736  /* The ID of a cue point that this object corresponds to. */
737  drwav_uint32 cuePointId;
738 
739  /* The number of samples from the cue point forwards that should be considered this region */
740  drwav_uint32 sampleLength;
741 
742  /* Four characters used to say what the purpose of this region is. */
743  drwav_uint8 purposeId[4];
744 
745  /* Unsure of the exact meanings of these. It appears to be acceptable to set them all to 0. */
746  drwav_uint16 country;
747  drwav_uint16 language;
748  drwav_uint16 dialect;
749  drwav_uint16 codePage;
750 
751  /* Size of the string not including any null terminator. */
752  drwav_uint32 stringLength;
753 
754  /* The string. The *init_with_metadata functions null terminate this for convenience. */
755  char* pString;
757 
758 /*
759 Unknown Metadata
760 
761 This chunk just represents a type of chunk that dr_wav does not understand.
762 
763 Unknown metadata has a location attached to it. This is because wav files can have a LIST chunk
764 that contains subchunks. These LIST chunks can be one of two types. An adtl list, or an INFO
765 list. This enum is used to specify the location of a chunk that dr_wav currently doesn't support.
766 */
767 typedef enum
768 {
774 
775 typedef struct
776 {
777  drwav_uint8 id[4];
778  drwav_metadata_location chunkLocation;
779  drwav_uint32 dataSizeInBytes;
780  drwav_uint8* pData;
782 
783 /*
784 Metadata is saved as a union of all the supported types.
785 */
786 typedef struct
787 {
788  /* Determines which item in the union is valid. */
789  drwav_metadata_type type;
790 
791  union
792  {
793  drwav_cue cue;
794  drwav_smpl smpl;
795  drwav_acid acid;
796  drwav_inst inst;
797  drwav_bext bext;
798  drwav_list_label_or_note labelOrNote; /* List label or list note. */
799  drwav_list_labelled_cue_region labelledCueRegion;
800  drwav_list_info_text infoText; /* Any of the list info types. */
801  drwav_unknown_metadata unknown;
802  } data;
804 
805 typedef struct
806 {
807  /* A pointer to the function to call when more data is needed. */
808  drwav_read_proc onRead;
809 
810  /* A pointer to the function to call when data needs to be written. Only used when the drwav object is opened in write mode. */
811  drwav_write_proc onWrite;
812 
813  /* A pointer to the function to call when the wav file needs to be seeked. */
814  drwav_seek_proc onSeek;
815 
816  /* The user data to pass to callbacks. */
817  void* pUserData;
818 
819  /* Allocation callbacks. */
820  drwav_allocation_callbacks allocationCallbacks;
821 
822 
823  /* Whether or not the WAV file is formatted as a standard RIFF file or W64. */
824  drwav_container container;
825 
826 
827  /* Structure containing format information exactly as specified by the wav file. */
828  drwav_fmt fmt;
829 
830  /* The sample rate. Will be set to something like 44100. */
831  drwav_uint32 sampleRate;
832 
833  /* The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. */
834  drwav_uint16 channels;
835 
836  /* The bits per sample. Will be set to something like 16, 24, etc. */
837  drwav_uint16 bitsPerSample;
838 
839  /* Equal to fmt.formatTag, or the value specified by fmt.subFormat if fmt.formatTag is equal to 65534 (WAVE_FORMAT_EXTENSIBLE). */
840  drwav_uint16 translatedFormatTag;
841 
842  /* The total number of PCM frames making up the audio data. */
843  drwav_uint64 totalPCMFrameCount;
844 
845 
846  /* The size in bytes of the data chunk. */
847  drwav_uint64 dataChunkDataSize;
848 
849  /* The position in the stream of the first data byte of the data chunk. This is used for seeking. */
850  drwav_uint64 dataChunkDataPos;
851 
852  /* The number of bytes remaining in the data chunk. */
853  drwav_uint64 bytesRemaining;
854 
855  /* The current read position in PCM frames. */
856  drwav_uint64 readCursorInPCMFrames;
857 
858 
859  /*
860  Only used in sequential write mode. Keeps track of the desired size of the "data" chunk at the point of initialization time. Always
861  set to 0 for non-sequential writes and when the drwav object is opened in read mode. Used for validation.
862  */
863  drwav_uint64 dataChunkDataSizeTargetWrite;
864 
865  /* Keeps track of whether or not the wav writer was initialized in sequential mode. */
866  drwav_bool32 isSequentialWrite;
867 
868 
869  /* A bit-field of drwav_metadata_type values, only bits set in this variable are parsed and saved */
870  drwav_metadata_type allowedMetadataTypes;
871 
872  /* A array of metadata. This is valid after the *init_with_metadata call returns. It will be valid until drwav_uninit() is called. You can take ownership of this data with drwav_take_ownership_of_metadata(). */
873  drwav_metadata* pMetadata;
874  drwav_uint32 metadataCount;
875 
876 
877  /* A hack to avoid a DRWAV_MALLOC() when opening a decoder with drwav_init_memory(). */
878  drwav__memory_stream memoryStream;
879  drwav__memory_stream_write memoryStreamWrite;
880 
881 
882  /* Microsoft ADPCM specific data. */
883  struct
884  {
885  drwav_uint32 bytesRemainingInBlock;
886  drwav_uint16 predictor[2];
887  drwav_int32 delta[2];
888  drwav_int32 cachedFrames[4]; /* Samples are stored in this cache during decoding. */
889  drwav_uint32 cachedFrameCount;
890  drwav_int32 prevFrames[2][2]; /* The previous 2 samples for each channel (2 channels at most). */
891  } msadpcm;
892 
893  /* IMA ADPCM specific data. */
894  struct
895  {
896  drwav_uint32 bytesRemainingInBlock;
897  drwav_int32 predictor[2];
898  drwav_int32 stepIndex[2];
899  drwav_int32 cachedFrames[16]; /* Samples are stored in this cache during decoding. */
900  drwav_uint32 cachedFrameCount;
901  } ima;
902 } drwav;
903 
904 
905 /*
906 Initializes a pre-allocated drwav object for reading.
907 
908 pWav [out] A pointer to the drwav object being initialized.
909 onRead [in] The function to call when data needs to be read from the client.
910 onSeek [in] The function to call when the read position of the client data needs to move.
911 onChunk [in, optional] The function to call when a chunk is enumerated at initialized time.
912 pUserData, pReadSeekUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
913 pChunkUserData [in, optional] A pointer to application defined data that will be passed to onChunk.
914 flags [in, optional] A set of flags for controlling how things are loaded.
915 
916 Returns true if successful; false otherwise.
917 
918 Close the loader with drwav_uninit().
919 
920 This is the lowest level function for initializing a WAV file. You can also use drwav_init_file() and drwav_init_memory()
921 to open the stream from a file or from a block of memory respectively.
922 
923 Possible values for flags:
924  DRWAV_SEQUENTIAL: Never perform a backwards seek while loading. This disables the chunk callback and will cause this function
925  to return as soon as the data chunk is found. Any chunks after the data chunk will be ignored.
926 
927 drwav_init() is equivalent to "drwav_init_ex(pWav, onRead, onSeek, NULL, pUserData, NULL, 0);".
928 
929 The onChunk callback is not called for the WAVE or FMT chunks. The contents of the FMT chunk can be read from pWav->fmt
930 after the function returns.
931 
932 See also: drwav_init_file(), drwav_init_memory(), drwav_uninit()
933 */
934 DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
935 DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
936 DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
937 
938 /*
939 Initializes a pre-allocated drwav object for writing.
940 
941 onWrite [in] The function to call when data needs to be written.
942 onSeek [in] The function to call when the write position needs to move.
943 pUserData [in, optional] A pointer to application defined data that will be passed to onWrite and onSeek.
944 metadata, numMetadata [in, optional] An array of metadata objects that should be written to the file. The array is not edited. You are responsible for this metadata memory and it must maintain valid until drwav_uninit() is called.
945 
946 Returns true if successful; false otherwise.
947 
948 Close the writer with drwav_uninit().
949 
950 This is the lowest level function for initializing a WAV file. You can also use drwav_init_file_write() and drwav_init_memory_write()
951 to open the stream from a file or from a block of memory respectively.
952 
953 If the total sample count is known, you can use drwav_init_write_sequential(). This avoids the need for dr_wav to perform
954 a post-processing step for storing the total sample count and the size of the data chunk which requires a backwards seek.
955 
956 See also: drwav_init_file_write(), drwav_init_memory_write(), drwav_uninit()
957 */
958 DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
959 DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
960 DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks);
961 DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks, drwav_metadata* pMetadata, drwav_uint32 metadataCount);
962 
963 /*
964 Utility function to determine the target size of the entire data to be written (including all headers and chunks).
965 
966 Returns the target size in bytes.
967 
968 The metadata argument can be NULL meaning no metadata exists.
969 
970 Useful if the application needs to know the size to allocate.
971 
972 Only writing to the RIFF chunk and one data chunk is currently supported.
973 
974 See also: drwav_init_write(), drwav_init_file_write(), drwav_init_memory_write()
975 */
976 DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalFrameCount, drwav_metadata* pMetadata, drwav_uint32 metadataCount);
977 
978 /*
979 Take ownership of the metadata objects that were allocated via one of the init_with_metadata() function calls. The init_with_metdata functions perform a single heap allocation for this metadata.
980 
981 Useful if you want the data to persist beyond the lifetime of the drwav object.
982 
983 You must free the data returned from this function using drwav_free().
984 */
986 
987 /*
988 Uninitializes the given drwav object.
989 
990 Use this only for objects initialized with drwav_init*() functions (drwav_init(), drwav_init_ex(), drwav_init_write(), drwav_init_write_sequential()).
991 */
993 
994 
995 /*
996 Reads raw audio data.
997 
998 This is the lowest level function for reading audio data. It simply reads the given number of
999 bytes of the raw internal sample data.
1000 
1001 Consider using drwav_read_pcm_frames_s16(), drwav_read_pcm_frames_s32() or drwav_read_pcm_frames_f32() for
1002 reading sample data in a consistent format.
1003 
1004 pBufferOut can be NULL in which case a seek will be performed.
1005 
1006 Returns the number of bytes actually read.
1007 */
1008 DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut);
1009 
1010 /*
1011 Reads up to the specified number of PCM frames from the WAV file.
1012 
1013 The output data will be in the file's internal format, converted to native-endian byte order. Use
1014 drwav_read_pcm_frames_s16/f32/s32() to read data in a specific format.
1015 
1016 If the return value is less than <framesToRead> it means the end of the file has been reached or
1017 you have requested more PCM frames than can possibly fit in the output buffer.
1018 
1019 This function will only work when sample data is of a fixed size and uncompressed. If you are
1020 using a compressed format consider using drwav_read_raw() or drwav_read_pcm_frames_s16/s32/f32().
1021 
1022 pBufferOut can be NULL in which case a seek will be performed.
1023 */
1024 DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
1025 DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
1026 DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut);
1027 
1028 /*
1029 Seeks to the given PCM frame.
1030 
1031 Returns true if successful; false otherwise.
1032 */
1034 
1035 /*
1036 Retrieves the current read position in pcm frames.
1037 */
1039 
1040 /*
1041 Retrieves the length of the file.
1042 */
1044 
1045 
1046 /*
1047 Writes raw audio data.
1048 
1049 Returns the number of bytes actually written. If this differs from bytesToWrite, it indicates an error.
1050 */
1051 DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData);
1052 
1053 /*
1054 Writes PCM frames.
1055 
1056 Returns the number of PCM frames written.
1057 
1058 Input samples need to be in native-endian byte order. On big-endian architectures the input data will be converted to
1059 little-endian. Use drwav_write_raw() to write raw audio data without performing any conversion.
1060 */
1061 DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
1062 DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
1063 DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData);
1064 
1065 /* Conversion Utilities */
1066 #ifndef DR_WAV_NO_CONVERSION_API
1067 
1068 /*
1069 Reads a chunk of audio data and converts it to signed 16-bit PCM samples.
1070 
1071 pBufferOut can be NULL in which case a seek will be performed.
1072 
1073 Returns the number of PCM frames actually read.
1074 
1075 If the return value is less than <framesToRead> it means the end of the file has been reached.
1076 */
1080 
1081 /* Low-level function for converting unsigned 8-bit PCM samples to signed 16-bit PCM samples. */
1082 DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
1083 
1084 /* Low-level function for converting signed 24-bit PCM samples to signed 16-bit PCM samples. */
1085 DRWAV_API void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
1086 
1087 /* Low-level function for converting signed 32-bit PCM samples to signed 16-bit PCM samples. */
1088 DRWAV_API void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount);
1089 
1090 /* Low-level function for converting IEEE 32-bit floating point samples to signed 16-bit PCM samples. */
1091 DRWAV_API void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount);
1092 
1093 /* Low-level function for converting IEEE 64-bit floating point samples to signed 16-bit PCM samples. */
1094 DRWAV_API void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount);
1095 
1096 /* Low-level function for converting A-law samples to signed 16-bit PCM samples. */
1097 DRWAV_API void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
1098 
1099 /* Low-level function for converting u-law samples to signed 16-bit PCM samples. */
1100 DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount);
1101 
1102 
1103 /*
1104 Reads a chunk of audio data and converts it to IEEE 32-bit floating point samples.
1105 
1106 pBufferOut can be NULL in which case a seek will be performed.
1107 
1108 Returns the number of PCM frames actually read.
1109 
1110 If the return value is less than <framesToRead> it means the end of the file has been reached.
1111 */
1112 DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
1113 DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
1114 DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut);
1115 
1116 /* Low-level function for converting unsigned 8-bit PCM samples to IEEE 32-bit floating point samples. */
1117 DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
1118 
1119 /* Low-level function for converting signed 16-bit PCM samples to IEEE 32-bit floating point samples. */
1120 DRWAV_API void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount);
1121 
1122 /* Low-level function for converting signed 24-bit PCM samples to IEEE 32-bit floating point samples. */
1123 DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
1124 
1125 /* Low-level function for converting signed 32-bit PCM samples to IEEE 32-bit floating point samples. */
1126 DRWAV_API void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount);
1127 
1128 /* Low-level function for converting IEEE 64-bit floating point samples to IEEE 32-bit floating point samples. */
1129 DRWAV_API void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount);
1130 
1131 /* Low-level function for converting A-law samples to IEEE 32-bit floating point samples. */
1132 DRWAV_API void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
1133 
1134 /* Low-level function for converting u-law samples to IEEE 32-bit floating point samples. */
1135 DRWAV_API void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount);
1136 
1137 
1138 /*
1139 Reads a chunk of audio data and converts it to signed 32-bit PCM samples.
1140 
1141 pBufferOut can be NULL in which case a seek will be performed.
1142 
1143 Returns the number of PCM frames actually read.
1144 
1145 If the return value is less than <framesToRead> it means the end of the file has been reached.
1146 */
1150 
1151 /* Low-level function for converting unsigned 8-bit PCM samples to signed 32-bit PCM samples. */
1152 DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
1153 
1154 /* Low-level function for converting signed 16-bit PCM samples to signed 32-bit PCM samples. */
1155 DRWAV_API void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount);
1156 
1157 /* Low-level function for converting signed 24-bit PCM samples to signed 32-bit PCM samples. */
1158 DRWAV_API void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
1159 
1160 /* Low-level function for converting IEEE 32-bit floating point samples to signed 32-bit PCM samples. */
1161 DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount);
1162 
1163 /* Low-level function for converting IEEE 64-bit floating point samples to signed 32-bit PCM samples. */
1164 DRWAV_API void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount);
1165 
1166 /* Low-level function for converting A-law samples to signed 32-bit PCM samples. */
1167 DRWAV_API void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
1168 
1169 /* Low-level function for converting u-law samples to signed 32-bit PCM samples. */
1170 DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount);
1171 
1172 #endif /* DR_WAV_NO_CONVERSION_API */
1173 
1174 
1175 /* High-Level Convenience Helpers */
1176 
1177 #ifndef DR_WAV_NO_STDIO
1178 /*
1179 Helper for initializing a wave file for reading using stdio.
1180 
1181 This holds the internal FILE object until drwav_uninit() is called. Keep this in mind if you're caching drwav
1182 objects because the operating system may restrict the number of file handles an application can have open at
1183 any given time.
1184 */
1185 DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
1186 DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
1187 DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
1188 DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
1189 DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav* pWav, const char* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
1190 DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav* pWav, const wchar_t* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
1191 
1192 
1193 /*
1194 Helper for initializing a wave file for writing using stdio.
1195 
1196 This holds the internal FILE object until drwav_uninit() is called. Keep this in mind if you're caching drwav
1197 objects because the operating system may restrict the number of file handles an application can have open at
1198 any given time.
1199 */
1200 DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
1201 DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
1202 DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
1203 DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
1204 DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
1205 DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
1206 #endif /* DR_WAV_NO_STDIO */
1207 
1208 /*
1209 Helper for initializing a loader from a pre-allocated memory buffer.
1210 
1211 This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
1212 the lifetime of the drwav object.
1213 
1214 The buffer should contain the contents of the entire wave file, not just the sample data.
1215 */
1216 DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks);
1217 DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
1218 DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav* pWav, const void* data, size_t dataSize, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks);
1219 
1220 /*
1221 Helper for initializing a writer which outputs data to a memory buffer.
1222 
1223 dr_wav will manage the memory allocations, however it is up to the caller to free the data with drwav_free().
1224 
1225 The buffer will remain allocated even after drwav_uninit() is called. The buffer should not be considered valid
1226 until after drwav_uninit() has been called.
1227 */
1228 DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks);
1229 DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks);
1230 DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks);
1231 
1232 
1233 #ifndef DR_WAV_NO_CONVERSION_API
1234 /*
1235 Opens and reads an entire wav file in a single operation.
1236 
1237 The return value is a heap-allocated buffer containing the audio data. Use drwav_free() to free the buffer.
1238 */
1239 DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1240 DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1241 DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1242 #ifndef DR_WAV_NO_STDIO
1243 /*
1244 Opens and decodes an entire wav file in a single operation.
1245 
1246 The return value is a heap-allocated buffer containing the audio data. Use drwav_free() to free the buffer.
1247 */
1248 DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1249 DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1250 DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1251 DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1252 DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1253 DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1254 #endif
1255 /*
1256 Opens and decodes an entire wav file from a block of memory in a single operation.
1257 
1258 The return value is a heap-allocated buffer containing the audio data. Use drwav_free() to free the buffer.
1259 */
1260 DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1261 DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1262 DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks);
1263 #endif
1264 
1265 /* Frees data that was allocated internally by dr_wav. */
1266 DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks);
1267 
1268 /* Converts bytes from a wav stream to a sized type of native endian. */
1275 DRWAV_API float drwav_bytes_to_f32(const drwav_uint8* data);
1276 
1277 /* Compares a GUID for the purpose of checking the type of a Wave64 chunk. */
1279 
1280 /* Compares a four-character-code for the purpose of checking the type of a RIFF chunk. */
1281 DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b);
1282 
1283 #ifdef __cplusplus
1284 }
1285 #endif
1286 #endif /* dr_wav_h */
1287 
1288 
1289 /************************************************************************************************************************************************************
1290  ************************************************************************************************************************************************************
1291 
1292  IMPLEMENTATION
1293 
1294  ************************************************************************************************************************************************************
1295  ************************************************************************************************************************************************************/
1296 #if defined(DR_WAV_IMPLEMENTATION) || defined(DRWAV_IMPLEMENTATION)
1297 #ifndef dr_wav_c
1298 #define dr_wav_c
1299 
1300 #include <stdlib.h>
1301 #include <string.h> /* For memcpy(), memset() */
1302 #include <limits.h> /* For INT_MAX */
1303 
1304 #ifndef DR_WAV_NO_STDIO
1305 #include <stdio.h>
1306 #include <wchar.h>
1307 #endif
1308 
1309 /* Standard library stuff. */
1310 #ifndef DRWAV_ASSERT
1311 #include <assert.h>
1312 #define DRWAV_ASSERT(expression) assert(expression)
1313 #endif
1314 #ifndef DRWAV_MALLOC
1315 #define DRWAV_MALLOC(sz) malloc((sz))
1316 #endif
1317 #ifndef DRWAV_REALLOC
1318 #define DRWAV_REALLOC(p, sz) realloc((p), (sz))
1319 #endif
1320 #ifndef DRWAV_FREE
1321 #define DRWAV_FREE(p) free((p))
1322 #endif
1323 #ifndef DRWAV_COPY_MEMORY
1324 #define DRWAV_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
1325 #endif
1326 #ifndef DRWAV_ZERO_MEMORY
1327 #define DRWAV_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
1328 #endif
1329 #ifndef DRWAV_ZERO_OBJECT
1330 #define DRWAV_ZERO_OBJECT(p) DRWAV_ZERO_MEMORY((p), sizeof(*p))
1331 #endif
1332 
1333 #define drwav_countof(x) (sizeof(x) / sizeof(x[0]))
1334 #define drwav_align(x, a) ((((x) + (a) - 1) / (a)) * (a))
1335 #define drwav_min(a, b) (((a) < (b)) ? (a) : (b))
1336 #define drwav_max(a, b) (((a) > (b)) ? (a) : (b))
1337 #define drwav_clamp(x, lo, hi) (drwav_max((lo), drwav_min((hi), (x))))
1338 
1339 #define DRWAV_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
1340 
1341 /* CPU architecture. */
1342 #if defined(__x86_64__) || defined(_M_X64)
1343  #define DRWAV_X64
1344 #elif defined(__i386) || defined(_M_IX86)
1345  #define DRWAV_X86
1346 #elif defined(__arm__) || defined(_M_ARM)
1347  #define DRWAV_ARM
1348 #endif
1349 
1350 #ifdef _MSC_VER
1351  #define DRWAV_INLINE __forceinline
1352 #elif defined(__GNUC__)
1353  /*
1354  I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
1355  the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
1356  case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
1357  command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
1358  I am using "__inline__" only when we're compiling in strict ANSI mode.
1359  */
1360  #if defined(__STRICT_ANSI__)
1361  #define DRWAV_INLINE __inline__ __attribute__((always_inline))
1362  #else
1363  #define DRWAV_INLINE inline __attribute__((always_inline))
1364  #endif
1365 #elif defined(__WATCOMC__)
1366  #define DRWAV_INLINE __inline
1367 #else
1368  #define DRWAV_INLINE
1369 #endif
1370 
1371 #if defined(SIZE_MAX)
1372  #define DRWAV_SIZE_MAX SIZE_MAX
1373 #else
1374  #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
1375  #define DRWAV_SIZE_MAX ((drwav_uint64)0xFFFFFFFFFFFFFFFF)
1376  #else
1377  #define DRWAV_SIZE_MAX 0xFFFFFFFF
1378  #endif
1379 #endif
1380 
1381 #if defined(_MSC_VER) && _MSC_VER >= 1400
1382  #define DRWAV_HAS_BYTESWAP16_INTRINSIC
1383  #define DRWAV_HAS_BYTESWAP32_INTRINSIC
1384  #define DRWAV_HAS_BYTESWAP64_INTRINSIC
1385 #elif defined(__clang__)
1386  #if defined(__has_builtin)
1387  #if __has_builtin(__builtin_bswap16)
1388  #define DRWAV_HAS_BYTESWAP16_INTRINSIC
1389  #endif
1390  #if __has_builtin(__builtin_bswap32)
1391  #define DRWAV_HAS_BYTESWAP32_INTRINSIC
1392  #endif
1393  #if __has_builtin(__builtin_bswap64)
1394  #define DRWAV_HAS_BYTESWAP64_INTRINSIC
1395  #endif
1396  #endif
1397 #elif defined(__GNUC__)
1398  #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
1399  #define DRWAV_HAS_BYTESWAP32_INTRINSIC
1400  #define DRWAV_HAS_BYTESWAP64_INTRINSIC
1401  #endif
1402  #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
1403  #define DRWAV_HAS_BYTESWAP16_INTRINSIC
1404  #endif
1405 #endif
1406 
1407 DRWAV_API void drwav_version(drwav_uint32* pMajor, drwav_uint32* pMinor, drwav_uint32* pRevision)
1408 {
1409  if (pMajor) {
1410  *pMajor = DRWAV_VERSION_MAJOR;
1411  }
1412 
1413  if (pMinor) {
1414  *pMinor = DRWAV_VERSION_MINOR;
1415  }
1416 
1417  if (pRevision) {
1418  *pRevision = DRWAV_VERSION_REVISION;
1419  }
1420 }
1421 
1422 DRWAV_API const char* drwav_version_string(void)
1423 {
1424  return DRWAV_VERSION_STRING;
1425 }
1426 
1427 /*
1428 These limits are used for basic validation when initializing the decoder. If you exceed these limits, first of all: what on Earth are
1429 you doing?! (Let me know, I'd be curious!) Second, you can adjust these by #define-ing them before the dr_wav implementation.
1430 */
1431 #ifndef DRWAV_MAX_SAMPLE_RATE
1432 #define DRWAV_MAX_SAMPLE_RATE 384000
1433 #endif
1434 #ifndef DRWAV_MAX_CHANNELS
1435 #define DRWAV_MAX_CHANNELS 256
1436 #endif
1437 #ifndef DRWAV_MAX_BITS_PER_SAMPLE
1438 #define DRWAV_MAX_BITS_PER_SAMPLE 64
1439 #endif
1440 
1441 static const drwav_uint8 drwavGUID_W64_RIFF[16] = {0x72,0x69,0x66,0x66, 0x2E,0x91, 0xCF,0x11, 0xA5,0xD6, 0x28,0xDB,0x04,0xC1,0x00,0x00}; /* 66666972-912E-11CF-A5D6-28DB04C10000 */
1442 static const drwav_uint8 drwavGUID_W64_WAVE[16] = {0x77,0x61,0x76,0x65, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; /* 65766177-ACF3-11D3-8CD1-00C04F8EDB8A */
1443 /*static const drwav_uint8 drwavGUID_W64_JUNK[16] = {0x6A,0x75,0x6E,0x6B, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};*/ /* 6B6E756A-ACF3-11D3-8CD1-00C04F8EDB8A */
1444 static const drwav_uint8 drwavGUID_W64_FMT [16] = {0x66,0x6D,0x74,0x20, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; /* 20746D66-ACF3-11D3-8CD1-00C04F8EDB8A */
1445 static const drwav_uint8 drwavGUID_W64_FACT[16] = {0x66,0x61,0x63,0x74, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; /* 74636166-ACF3-11D3-8CD1-00C04F8EDB8A */
1446 static const drwav_uint8 drwavGUID_W64_DATA[16] = {0x64,0x61,0x74,0x61, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A}; /* 61746164-ACF3-11D3-8CD1-00C04F8EDB8A */
1447 /*static const drwav_uint8 drwavGUID_W64_SMPL[16] = {0x73,0x6D,0x70,0x6C, 0xF3,0xAC, 0xD3,0x11, 0x8C,0xD1, 0x00,0xC0,0x4F,0x8E,0xDB,0x8A};*/ /* 6C706D73-ACF3-11D3-8CD1-00C04F8EDB8A */
1448 
1449 
1450 static DRWAV_INLINE int drwav__is_little_endian(void)
1451 {
1452 #if defined(DRWAV_X86) || defined(DRWAV_X64)
1453  return DRWAV_TRUE;
1454 #elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN
1455  return DRWAV_TRUE;
1456 #else
1457  int n = 1;
1458  return (*(char*)&n) == 1;
1459 #endif
1460 }
1461 
1462 
1463 static DRWAV_INLINE void drwav_bytes_to_guid(const drwav_uint8* data, drwav_uint8* guid)
1464 {
1465  int i;
1466  for (i = 0; i < 16; ++i) {
1467  guid[i] = data[i];
1468  }
1469 }
1470 
1471 
1473 {
1474 #ifdef DRWAV_HAS_BYTESWAP16_INTRINSIC
1475  #if defined(_MSC_VER)
1476  return _byteswap_ushort(n);
1477  #elif defined(__GNUC__) || defined(__clang__)
1478  return __builtin_bswap16(n);
1479  #else
1480  #error "This compiler does not support the byte swap intrinsic."
1481  #endif
1482 #else
1483  return ((n & 0xFF00) >> 8) |
1484  ((n & 0x00FF) << 8);
1485 #endif
1486 }
1487 
1489 {
1490 #ifdef DRWAV_HAS_BYTESWAP32_INTRINSIC
1491  #if defined(_MSC_VER)
1492  return _byteswap_ulong(n);
1493  #elif defined(__GNUC__) || defined(__clang__)
1494  #if defined(DRWAV_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRWAV_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
1495  /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
1496  drwav_uint32 r;
1497  __asm__ __volatile__ (
1498  #if defined(DRWAV_64BIT)
1499  "rev %w[out], %w[in]" : [out]"=r"(r) : [in]"r"(n) /* <-- This is untested. If someone in the community could test this, that would be appreciated! */
1500  #else
1501  "rev %[out], %[in]" : [out]"=r"(r) : [in]"r"(n)
1502  #endif
1503  );
1504  return r;
1505  #else
1506  return __builtin_bswap32(n);
1507  #endif
1508  #else
1509  #error "This compiler does not support the byte swap intrinsic."
1510  #endif
1511 #else
1512  return ((n & 0xFF000000) >> 24) |
1513  ((n & 0x00FF0000) >> 8) |
1514  ((n & 0x0000FF00) << 8) |
1515  ((n & 0x000000FF) << 24);
1516 #endif
1517 }
1518 
1520 {
1521 #ifdef DRWAV_HAS_BYTESWAP64_INTRINSIC
1522  #if defined(_MSC_VER)
1523  return _byteswap_uint64(n);
1524  #elif defined(__GNUC__) || defined(__clang__)
1525  return __builtin_bswap64(n);
1526  #else
1527  #error "This compiler does not support the byte swap intrinsic."
1528  #endif
1529 #else
1530  /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */
1531  return ((n & ((drwav_uint64)0xFF000000 << 32)) >> 56) |
1532  ((n & ((drwav_uint64)0x00FF0000 << 32)) >> 40) |
1533  ((n & ((drwav_uint64)0x0000FF00 << 32)) >> 24) |
1534  ((n & ((drwav_uint64)0x000000FF << 32)) >> 8) |
1535  ((n & ((drwav_uint64)0xFF000000 )) << 8) |
1536  ((n & ((drwav_uint64)0x00FF0000 )) << 24) |
1537  ((n & ((drwav_uint64)0x0000FF00 )) << 40) |
1538  ((n & ((drwav_uint64)0x000000FF )) << 56);
1539 #endif
1540 }
1541 
1542 
1544 {
1546 }
1547 
1548 static DRWAV_INLINE void drwav__bswap_samples_s16(drwav_int16* pSamples, drwav_uint64 sampleCount)
1549 {
1550  drwav_uint64 iSample;
1551  for (iSample = 0; iSample < sampleCount; iSample += 1) {
1552  pSamples[iSample] = drwav__bswap_s16(pSamples[iSample]);
1553  }
1554 }
1555 
1556 
1558 {
1559  drwav_uint8 t;
1560  t = p[0];
1561  p[0] = p[2];
1562  p[2] = t;
1563 }
1564 
1565 static DRWAV_INLINE void drwav__bswap_samples_s24(drwav_uint8* pSamples, drwav_uint64 sampleCount)
1566 {
1567  drwav_uint64 iSample;
1568  for (iSample = 0; iSample < sampleCount; iSample += 1) {
1569  drwav_uint8* pSample = pSamples + (iSample*3);
1570  drwav__bswap_s24(pSample);
1571  }
1572 }
1573 
1574 
1576 {
1578 }
1579 
1580 static DRWAV_INLINE void drwav__bswap_samples_s32(drwav_int32* pSamples, drwav_uint64 sampleCount)
1581 {
1582  drwav_uint64 iSample;
1583  for (iSample = 0; iSample < sampleCount; iSample += 1) {
1584  pSamples[iSample] = drwav__bswap_s32(pSamples[iSample]);
1585  }
1586 }
1587 
1588 
1589 static DRWAV_INLINE float drwav__bswap_f32(float n)
1590 {
1591  union {
1592  drwav_uint32 i;
1593  float f;
1594  } x;
1595  x.f = n;
1596  x.i = drwav__bswap32(x.i);
1597 
1598  return x.f;
1599 }
1600 
1601 static DRWAV_INLINE void drwav__bswap_samples_f32(float* pSamples, drwav_uint64 sampleCount)
1602 {
1603  drwav_uint64 iSample;
1604  for (iSample = 0; iSample < sampleCount; iSample += 1) {
1605  pSamples[iSample] = drwav__bswap_f32(pSamples[iSample]);
1606  }
1607 }
1608 
1609 
1610 static DRWAV_INLINE double drwav__bswap_f64(double n)
1611 {
1612  union {
1613  drwav_uint64 i;
1614  double f;
1615  } x;
1616  x.f = n;
1617  x.i = drwav__bswap64(x.i);
1618 
1619  return x.f;
1620 }
1621 
1622 static DRWAV_INLINE void drwav__bswap_samples_f64(double* pSamples, drwav_uint64 sampleCount)
1623 {
1624  drwav_uint64 iSample;
1625  for (iSample = 0; iSample < sampleCount; iSample += 1) {
1626  pSamples[iSample] = drwav__bswap_f64(pSamples[iSample]);
1627  }
1628 }
1629 
1630 
1631 static DRWAV_INLINE void drwav__bswap_samples_pcm(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
1632 {
1633  /* Assumes integer PCM. Floating point PCM is done in drwav__bswap_samples_ieee(). */
1634  switch (bytesPerSample)
1635  {
1636  case 2: /* s16, s12 (loosely packed) */
1637  {
1638  drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount);
1639  } break;
1640  case 3: /* s24 */
1641  {
1642  drwav__bswap_samples_s24((drwav_uint8*)pSamples, sampleCount);
1643  } break;
1644  case 4: /* s32 */
1645  {
1646  drwav__bswap_samples_s32((drwav_int32*)pSamples, sampleCount);
1647  } break;
1648  default:
1649  {
1650  /* Unsupported format. */
1652  } break;
1653  }
1654 }
1655 
1656 static DRWAV_INLINE void drwav__bswap_samples_ieee(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
1657 {
1658  switch (bytesPerSample)
1659  {
1660  #if 0 /* Contributions welcome for f16 support. */
1661  case 2: /* f16 */
1662  {
1663  drwav__bswap_samples_f16((drwav_float16*)pSamples, sampleCount);
1664  } break;
1665  #endif
1666  case 4: /* f32 */
1667  {
1668  drwav__bswap_samples_f32((float*)pSamples, sampleCount);
1669  } break;
1670  case 8: /* f64 */
1671  {
1672  drwav__bswap_samples_f64((double*)pSamples, sampleCount);
1673  } break;
1674  default:
1675  {
1676  /* Unsupported format. */
1678  } break;
1679  }
1680 }
1681 
1682 static DRWAV_INLINE void drwav__bswap_samples(void* pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample, drwav_uint16 format)
1683 {
1684  switch (format)
1685  {
1686  case DR_WAVE_FORMAT_PCM:
1687  {
1688  drwav__bswap_samples_pcm(pSamples, sampleCount, bytesPerSample);
1689  } break;
1690 
1692  {
1693  drwav__bswap_samples_ieee(pSamples, sampleCount, bytesPerSample);
1694  } break;
1695 
1696  case DR_WAVE_FORMAT_ALAW:
1697  case DR_WAVE_FORMAT_MULAW:
1698  {
1699  drwav__bswap_samples_s16((drwav_int16*)pSamples, sampleCount);
1700  } break;
1701 
1702  case DR_WAVE_FORMAT_ADPCM:
1704  default:
1705  {
1706  /* Unsupported format. */
1708  } break;
1709  }
1710 }
1711 
1712 
1713 DRWAV_PRIVATE void* drwav__malloc_default(size_t sz, void* pUserData)
1714 {
1715  (void)pUserData;
1716  return DRWAV_MALLOC(sz);
1717 }
1718 
1719 DRWAV_PRIVATE void* drwav__realloc_default(void* p, size_t sz, void* pUserData)
1720 {
1721  (void)pUserData;
1722  return DRWAV_REALLOC(p, sz);
1723 }
1724 
1725 DRWAV_PRIVATE void drwav__free_default(void* p, void* pUserData)
1726 {
1727  (void)pUserData;
1728  DRWAV_FREE(p);
1729 }
1730 
1731 
1732 DRWAV_PRIVATE void* drwav__malloc_from_callbacks(size_t sz, const drwav_allocation_callbacks* pAllocationCallbacks)
1733 {
1734  if (pAllocationCallbacks == NULL) {
1735  return NULL;
1736  }
1737 
1738  if (pAllocationCallbacks->onMalloc != NULL) {
1739  return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
1740  }
1741 
1742  /* Try using realloc(). */
1743  if (pAllocationCallbacks->onRealloc != NULL) {
1744  return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
1745  }
1746 
1747  return NULL;
1748 }
1749 
1750 DRWAV_PRIVATE void* drwav__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drwav_allocation_callbacks* pAllocationCallbacks)
1751 {
1752  if (pAllocationCallbacks == NULL) {
1753  return NULL;
1754  }
1755 
1756  if (pAllocationCallbacks->onRealloc != NULL) {
1757  return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
1758  }
1759 
1760  /* Try emulating realloc() in terms of malloc()/free(). */
1761  if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
1762  void* p2;
1763 
1764  p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
1765  if (p2 == NULL) {
1766  return NULL;
1767  }
1768 
1769  if (p != NULL) {
1770  DRWAV_COPY_MEMORY(p2, p, szOld);
1771  pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
1772  }
1773 
1774  return p2;
1775  }
1776 
1777  return NULL;
1778 }
1779 
1780 DRWAV_PRIVATE void drwav__free_from_callbacks(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
1781 {
1782  if (p == NULL || pAllocationCallbacks == NULL) {
1783  return;
1784  }
1785 
1786  if (pAllocationCallbacks->onFree != NULL) {
1787  pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
1788  }
1789 }
1790 
1791 
1793 {
1794  if (pAllocationCallbacks != NULL) {
1795  /* Copy. */
1796  return *pAllocationCallbacks;
1797  } else {
1798  /* Defaults. */
1799  drwav_allocation_callbacks allocationCallbacks;
1800  allocationCallbacks.pUserData = NULL;
1801  allocationCallbacks.onMalloc = drwav__malloc_default;
1802  allocationCallbacks.onRealloc = drwav__realloc_default;
1803  allocationCallbacks.onFree = drwav__free_default;
1804  return allocationCallbacks;
1805  }
1806 }
1807 
1808 
1810 {
1811  return
1812  formatTag == DR_WAVE_FORMAT_ADPCM ||
1813  formatTag == DR_WAVE_FORMAT_DVI_ADPCM;
1814 }
1815 
1817 {
1818  return (unsigned int)(chunkSize % 2);
1819 }
1820 
1822 {
1823  return (unsigned int)(chunkSize % 8);
1824 }
1825 
1829 
1830 DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_chunk_header* pHeaderOut)
1831 {
1832  if (container == drwav_container_riff || container == drwav_container_rf64) {
1833  drwav_uint8 sizeInBytes[4];
1834 
1835  if (onRead(pUserData, pHeaderOut->id.fourcc, 4) != 4) {
1836  return DRWAV_AT_END;
1837  }
1838 
1839  if (onRead(pUserData, sizeInBytes, 4) != 4) {
1840  return DRWAV_INVALID_FILE;
1841  }
1842 
1843  pHeaderOut->sizeInBytes = drwav_bytes_to_u32(sizeInBytes);
1844  pHeaderOut->paddingSize = drwav__chunk_padding_size_riff(pHeaderOut->sizeInBytes);
1845  *pRunningBytesReadOut += 8;
1846  } else {
1847  drwav_uint8 sizeInBytes[8];
1848 
1849  if (onRead(pUserData, pHeaderOut->id.guid, 16) != 16) {
1850  return DRWAV_AT_END;
1851  }
1852 
1853  if (onRead(pUserData, sizeInBytes, 8) != 8) {
1854  return DRWAV_INVALID_FILE;
1855  }
1856 
1857  pHeaderOut->sizeInBytes = drwav_bytes_to_u64(sizeInBytes) - 24; /* <-- Subtract 24 because w64 includes the size of the header. */
1858  pHeaderOut->paddingSize = drwav__chunk_padding_size_w64(pHeaderOut->sizeInBytes);
1859  *pRunningBytesReadOut += 24;
1860  }
1861 
1862  return DRWAV_SUCCESS;
1863 }
1864 
1866 {
1867  drwav_uint64 bytesRemainingToSeek = offset;
1868  while (bytesRemainingToSeek > 0) {
1869  if (bytesRemainingToSeek > 0x7FFFFFFF) {
1870  if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) {
1871  return DRWAV_FALSE;
1872  }
1873  bytesRemainingToSeek -= 0x7FFFFFFF;
1874  } else {
1875  if (!onSeek(pUserData, (int)bytesRemainingToSeek, drwav_seek_origin_current)) {
1876  return DRWAV_FALSE;
1877  }
1878  bytesRemainingToSeek = 0;
1879  }
1880  }
1881 
1882  return DRWAV_TRUE;
1883 }
1884 
1886 {
1887  if (offset <= 0x7FFFFFFF) {
1888  return onSeek(pUserData, (int)offset, drwav_seek_origin_start);
1889  }
1890 
1891  /* Larger than 32-bit seek. */
1892  if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_start)) {
1893  return DRWAV_FALSE;
1894  }
1895  offset -= 0x7FFFFFFF;
1896 
1897  for (;;) {
1898  if (offset <= 0x7FFFFFFF) {
1899  return onSeek(pUserData, (int)offset, drwav_seek_origin_current);
1900  }
1901 
1902  if (!onSeek(pUserData, 0x7FFFFFFF, drwav_seek_origin_current)) {
1903  return DRWAV_FALSE;
1904  }
1905  offset -= 0x7FFFFFFF;
1906  }
1907 
1908  /* Should never get here. */
1909  /*return DRWAV_TRUE; */
1910 }
1911 
1912 
1913 DRWAV_PRIVATE drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_container container, drwav_uint64* pRunningBytesReadOut, drwav_fmt* fmtOut)
1914 {
1916  drwav_uint8 fmt[16];
1917 
1918  if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) {
1919  return DRWAV_FALSE;
1920  }
1921 
1922 
1923  /* Skip non-fmt chunks. */
1924  while (((container == drwav_container_riff || container == drwav_container_rf64) && !drwav_fourcc_equal(header.id.fourcc, "fmt ")) || (container == drwav_container_w64 && !drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT))) {
1925  if (!drwav__seek_forward(onSeek, header.sizeInBytes + header.paddingSize, pUserData)) {
1926  return DRWAV_FALSE;
1927  }
1928  *pRunningBytesReadOut += header.sizeInBytes + header.paddingSize;
1929 
1930  /* Try the next header. */
1931  if (drwav__read_chunk_header(onRead, pUserData, container, pRunningBytesReadOut, &header) != DRWAV_SUCCESS) {
1932  return DRWAV_FALSE;
1933  }
1934  }
1935 
1936 
1937  /* Validation. */
1938  if (container == drwav_container_riff || container == drwav_container_rf64) {
1939  if (!drwav_fourcc_equal(header.id.fourcc, "fmt ")) {
1940  return DRWAV_FALSE;
1941  }
1942  } else {
1943  if (!drwav_guid_equal(header.id.guid, drwavGUID_W64_FMT)) {
1944  return DRWAV_FALSE;
1945  }
1946  }
1947 
1948 
1949  if (onRead(pUserData, fmt, sizeof(fmt)) != sizeof(fmt)) {
1950  return DRWAV_FALSE;
1951  }
1952  *pRunningBytesReadOut += sizeof(fmt);
1953 
1954  fmtOut->formatTag = drwav_bytes_to_u16(fmt + 0);
1955  fmtOut->channels = drwav_bytes_to_u16(fmt + 2);
1956  fmtOut->sampleRate = drwav_bytes_to_u32(fmt + 4);
1957  fmtOut->avgBytesPerSec = drwav_bytes_to_u32(fmt + 8);
1958  fmtOut->blockAlign = drwav_bytes_to_u16(fmt + 12);
1959  fmtOut->bitsPerSample = drwav_bytes_to_u16(fmt + 14);
1960 
1961  fmtOut->extendedSize = 0;
1962  fmtOut->validBitsPerSample = 0;
1963  fmtOut->channelMask = 0;
1964  memset(fmtOut->subFormat, 0, sizeof(fmtOut->subFormat));
1965 
1966  if (header.sizeInBytes > 16) {
1967  drwav_uint8 fmt_cbSize[2];
1968  int bytesReadSoFar = 0;
1969 
1970  if (onRead(pUserData, fmt_cbSize, sizeof(fmt_cbSize)) != sizeof(fmt_cbSize)) {
1971  return DRWAV_FALSE; /* Expecting more data. */
1972  }
1973  *pRunningBytesReadOut += sizeof(fmt_cbSize);
1974 
1975  bytesReadSoFar = 18;
1976 
1977  fmtOut->extendedSize = drwav_bytes_to_u16(fmt_cbSize);
1978  if (fmtOut->extendedSize > 0) {
1979  /* Simple validation. */
1980  if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
1981  if (fmtOut->extendedSize != 22) {
1982  return DRWAV_FALSE;
1983  }
1984  }
1985 
1986  if (fmtOut->formatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
1987  drwav_uint8 fmtext[22];
1988  if (onRead(pUserData, fmtext, fmtOut->extendedSize) != fmtOut->extendedSize) {
1989  return DRWAV_FALSE; /* Expecting more data. */
1990  }
1991 
1992  fmtOut->validBitsPerSample = drwav_bytes_to_u16(fmtext + 0);
1993  fmtOut->channelMask = drwav_bytes_to_u32(fmtext + 2);
1994  drwav_bytes_to_guid(fmtext + 6, fmtOut->subFormat);
1995  } else {
1996  if (!onSeek(pUserData, fmtOut->extendedSize, drwav_seek_origin_current)) {
1997  return DRWAV_FALSE;
1998  }
1999  }
2000  *pRunningBytesReadOut += fmtOut->extendedSize;
2001 
2002  bytesReadSoFar += fmtOut->extendedSize;
2003  }
2004 
2005  /* Seek past any leftover bytes. For w64 the leftover will be defined based on the chunk size. */
2006  if (!onSeek(pUserData, (int)(header.sizeInBytes - bytesReadSoFar), drwav_seek_origin_current)) {
2007  return DRWAV_FALSE;
2008  }
2009  *pRunningBytesReadOut += (header.sizeInBytes - bytesReadSoFar);
2010  }
2011 
2012  if (header.paddingSize > 0) {
2013  if (!onSeek(pUserData, header.paddingSize, drwav_seek_origin_current)) {
2014  return DRWAV_FALSE;
2015  }
2016  *pRunningBytesReadOut += header.paddingSize;
2017  }
2018 
2019  return DRWAV_TRUE;
2020 }
2021 
2022 
2023 DRWAV_PRIVATE size_t drwav__on_read(drwav_read_proc onRead, void* pUserData, void* pBufferOut, size_t bytesToRead, drwav_uint64* pCursor)
2024 {
2025  size_t bytesRead;
2026 
2027  DRWAV_ASSERT(onRead != NULL);
2028  DRWAV_ASSERT(pCursor != NULL);
2029 
2030  bytesRead = onRead(pUserData, pBufferOut, bytesToRead);
2031  *pCursor += bytesRead;
2032  return bytesRead;
2033 }
2034 
2035 #if 0
2036 DRWAV_PRIVATE drwav_bool32 drwav__on_seek(drwav_seek_proc onSeek, void* pUserData, int offset, drwav_seek_origin origin, drwav_uint64* pCursor)
2037 {
2038  DRWAV_ASSERT(onSeek != NULL);
2039  DRWAV_ASSERT(pCursor != NULL);
2040 
2041  if (!onSeek(pUserData, offset, origin)) {
2042  return DRWAV_FALSE;
2043  }
2044 
2045  if (origin == drwav_seek_origin_start) {
2046  *pCursor = offset;
2047  } else {
2048  *pCursor += offset;
2049  }
2050 
2051  return DRWAV_TRUE;
2052 }
2053 #endif
2054 
2055 
2056 #define DRWAV_SMPL_BYTES 36
2057 #define DRWAV_SMPL_LOOP_BYTES 24
2058 #define DRWAV_INST_BYTES 7
2059 #define DRWAV_ACID_BYTES 24
2060 #define DRWAV_CUE_BYTES 4
2061 #define DRWAV_BEXT_BYTES 602
2062 #define DRWAV_BEXT_DESCRIPTION_BYTES 256
2063 #define DRWAV_BEXT_ORIGINATOR_NAME_BYTES 32
2064 #define DRWAV_BEXT_ORIGINATOR_REF_BYTES 32
2065 #define DRWAV_BEXT_RESERVED_BYTES 180
2066 #define DRWAV_BEXT_UMID_BYTES 64
2067 #define DRWAV_CUE_POINT_BYTES 24
2068 #define DRWAV_LIST_LABEL_OR_NOTE_BYTES 4
2069 #define DRWAV_LIST_LABELLED_TEXT_BYTES 20
2070 
2071 #define DRWAV_METADATA_ALIGNMENT 8
2072 
2073 typedef enum
2074 {
2078 
2079 typedef struct
2080 {
2081  drwav_read_proc onRead;
2082  drwav_seek_proc onSeek;
2083  void *pReadSeekUserData;
2085  drwav_metadata *pMetadata;
2086  drwav_uint32 metadataCount;
2087  drwav_uint8 *pData;
2088  drwav_uint8 *pDataCursor;
2089  drwav_uint64 metadataCursor;
2090  drwav_uint64 extraCapacity;
2092 
2094 {
2095  drwav_uint64 cap = sizeof(drwav_metadata) * (drwav_uint64)pParser->metadataCount + pParser->extraCapacity;
2096  if (cap > DRWAV_SIZE_MAX) {
2097  return 0; /* Too big. */
2098  }
2099 
2100  return (size_t)cap; /* Safe cast thanks to the check above. */
2101 }
2102 
2103 DRWAV_PRIVATE drwav_uint8* drwav__metadata_get_memory(drwav__metadata_parser* pParser, size_t size, size_t align)
2104 {
2105  drwav_uint8* pResult;
2106 
2107  if (align) {
2108  drwav_uintptr modulo = (drwav_uintptr)pParser->pDataCursor % align;
2109  if (modulo != 0) {
2110  pParser->pDataCursor += align - modulo;
2111  }
2112  }
2113 
2114  pResult = pParser->pDataCursor;
2115 
2116  /*
2117  Getting to the point where this function is called means there should always be memory
2118  available. Out of memory checks should have been done at an earlier stage.
2119  */
2120  DRWAV_ASSERT((pResult + size) <= (pParser->pData + drwav__metadata_memory_capacity(pParser)));
2121 
2122  pParser->pDataCursor += size;
2123  return pResult;
2124 }
2125 
2127 {
2128  size_t extra = bytes + (align ? (align - 1) : 0);
2129  pParser->extraCapacity += extra;
2130 }
2131 
2133 {
2134  if (pParser->extraCapacity != 0 || pParser->metadataCount != 0) {
2135  free(pParser->pData);
2136 
2137  pParser->pData = (drwav_uint8*)pAllocationCallbacks->onMalloc(drwav__metadata_memory_capacity(pParser), pAllocationCallbacks->pUserData);
2138  pParser->pDataCursor = pParser->pData;
2139 
2140  if (pParser->pData == NULL) {
2141  return DRWAV_OUT_OF_MEMORY;
2142  }
2143 
2144  /*
2145  We don't need to worry about specifying an alignment here because malloc always returns something
2146  of suitable alignment. This also means than pParser->pMetadata is all that we need to store in order
2147  for us to free when we are done.
2148  */
2149  pParser->pMetadata = (drwav_metadata*)drwav__metadata_get_memory(pParser, sizeof(drwav_metadata) * pParser->metadataCount, 1);
2150  pParser->metadataCursor = 0;
2151  }
2152 
2153  return DRWAV_SUCCESS;
2154 }
2155 
2156 DRWAV_PRIVATE size_t drwav__metadata_parser_read(drwav__metadata_parser* pParser, void* pBufferOut, size_t bytesToRead, drwav_uint64* pCursor)
2157 {
2158  if (pCursor != NULL) {
2159  return drwav__on_read(pParser->onRead, pParser->pReadSeekUserData, pBufferOut, bytesToRead, pCursor);
2160  } else {
2161  return pParser->onRead(pParser->pReadSeekUserData, pBufferOut, bytesToRead);
2162  }
2163 }
2164 
2166 {
2167  drwav_uint8 smplHeaderData[DRWAV_SMPL_BYTES];
2168  drwav_uint64 totalBytesRead = 0;
2169  size_t bytesJustRead = drwav__metadata_parser_read(pParser, smplHeaderData, sizeof(smplHeaderData), &totalBytesRead);
2170 
2172 
2173  if (bytesJustRead == sizeof(smplHeaderData)) {
2174  drwav_uint32 iSampleLoop;
2175 
2176  pMetadata->type = drwav_metadata_type_smpl;
2177  pMetadata->data.smpl.manufacturerId = drwav_bytes_to_u32(smplHeaderData + 0);
2178  pMetadata->data.smpl.productId = drwav_bytes_to_u32(smplHeaderData + 4);
2179  pMetadata->data.smpl.samplePeriodNanoseconds = drwav_bytes_to_u32(smplHeaderData + 8);
2180  pMetadata->data.smpl.midiUnityNote = drwav_bytes_to_u32(smplHeaderData + 12);
2181  pMetadata->data.smpl.midiPitchFraction = drwav_bytes_to_u32(smplHeaderData + 16);
2182  pMetadata->data.smpl.smpteFormat = drwav_bytes_to_u32(smplHeaderData + 20);
2183  pMetadata->data.smpl.smpteOffset = drwav_bytes_to_u32(smplHeaderData + 24);
2184  pMetadata->data.smpl.sampleLoopCount = drwav_bytes_to_u32(smplHeaderData + 28);
2185  pMetadata->data.smpl.samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(smplHeaderData + 32);
2187 
2188  for (iSampleLoop = 0; iSampleLoop < pMetadata->data.smpl.sampleLoopCount; ++iSampleLoop) {
2189  drwav_uint8 smplLoopData[DRWAV_SMPL_LOOP_BYTES];
2190  bytesJustRead = drwav__metadata_parser_read(pParser, smplLoopData, sizeof(smplLoopData), &totalBytesRead);
2191 
2192  if (bytesJustRead == sizeof(smplLoopData)) {
2193  pMetadata->data.smpl.pLoops[iSampleLoop].cuePointId = drwav_bytes_to_u32(smplLoopData + 0);
2194  pMetadata->data.smpl.pLoops[iSampleLoop].type = drwav_bytes_to_u32(smplLoopData + 4);
2195  pMetadata->data.smpl.pLoops[iSampleLoop].firstSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 8);
2196  pMetadata->data.smpl.pLoops[iSampleLoop].lastSampleByteOffset = drwav_bytes_to_u32(smplLoopData + 12);
2197  pMetadata->data.smpl.pLoops[iSampleLoop].sampleFraction = drwav_bytes_to_u32(smplLoopData + 16);
2198  pMetadata->data.smpl.pLoops[iSampleLoop].playCount = drwav_bytes_to_u32(smplLoopData + 20);
2199  } else {
2200  break;
2201  }
2202  }
2203 
2204  if (pMetadata->data.smpl.samplerSpecificDataSizeInBytes > 0) {
2207 
2208  bytesJustRead = drwav__metadata_parser_read(pParser, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes, &totalBytesRead);
2209  }
2210  }
2211 
2212  return totalBytesRead;
2213 }
2214 
2216 {
2217  drwav_uint8 cueHeaderSectionData[DRWAV_CUE_BYTES];
2218  drwav_uint64 totalBytesRead = 0;
2219  size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueHeaderSectionData, sizeof(cueHeaderSectionData), &totalBytesRead);
2220 
2222 
2223  if (bytesJustRead == sizeof(cueHeaderSectionData)) {
2224  pMetadata->type = drwav_metadata_type_cue;
2225  pMetadata->data.cue.cuePointCount = drwav_bytes_to_u32(cueHeaderSectionData);
2227  DRWAV_ASSERT(pMetadata->data.cue.pCuePoints != NULL);
2228 
2229  if (pMetadata->data.cue.cuePointCount > 0) {
2230  drwav_uint32 iCuePoint;
2231 
2232  for (iCuePoint = 0; iCuePoint < pMetadata->data.cue.cuePointCount; ++iCuePoint) {
2233  drwav_uint8 cuePointData[DRWAV_CUE_POINT_BYTES];
2234  bytesJustRead = drwav__metadata_parser_read(pParser, cuePointData, sizeof(cuePointData), &totalBytesRead);
2235 
2236  if (bytesJustRead == sizeof(cuePointData)) {
2237  pMetadata->data.cue.pCuePoints[iCuePoint].id = drwav_bytes_to_u32(cuePointData + 0);
2238  pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition = drwav_bytes_to_u32(cuePointData + 4);
2239  pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[0] = cuePointData[8];
2240  pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[1] = cuePointData[9];
2241  pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[2] = cuePointData[10];
2242  pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId[3] = cuePointData[11];
2243  pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart = drwav_bytes_to_u32(cuePointData + 12);
2244  pMetadata->data.cue.pCuePoints[iCuePoint].blockStart = drwav_bytes_to_u32(cuePointData + 16);
2245  pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset = drwav_bytes_to_u32(cuePointData + 20);
2246  } else {
2247  break;
2248  }
2249  }
2250  }
2251  }
2252 
2253  return totalBytesRead;
2254 }
2255 
2257 {
2258  drwav_uint8 instData[DRWAV_INST_BYTES];
2259  drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, instData, sizeof(instData), NULL);
2260 
2262 
2263  if (bytesRead == sizeof(instData)) {
2264  pMetadata->type = drwav_metadata_type_inst;
2265  pMetadata->data.inst.midiUnityNote = (drwav_int8)instData[0];
2266  pMetadata->data.inst.fineTuneCents = (drwav_int8)instData[1];
2267  pMetadata->data.inst.gainDecibels = (drwav_int8)instData[2];
2268  pMetadata->data.inst.lowNote = (drwav_int8)instData[3];
2269  pMetadata->data.inst.highNote = (drwav_int8)instData[4];
2270  pMetadata->data.inst.lowVelocity = (drwav_int8)instData[5];
2271  pMetadata->data.inst.highVelocity = (drwav_int8)instData[6];
2272  }
2273 
2274  return bytesRead;
2275 }
2276 
2278 {
2279  drwav_uint8 acidData[DRWAV_ACID_BYTES];
2280  drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, acidData, sizeof(acidData), NULL);
2281 
2283 
2284  if (bytesRead == sizeof(acidData)) {
2285  pMetadata->type = drwav_metadata_type_acid;
2286  pMetadata->data.acid.flags = drwav_bytes_to_u32(acidData + 0);
2287  pMetadata->data.acid.midiUnityNote = drwav_bytes_to_u16(acidData + 4);
2288  pMetadata->data.acid.reserved1 = drwav_bytes_to_u16(acidData + 6);
2289  pMetadata->data.acid.reserved2 = drwav_bytes_to_f32(acidData + 8);
2290  pMetadata->data.acid.numBeats = drwav_bytes_to_u32(acidData + 12);
2291  pMetadata->data.acid.meterDenominator = drwav_bytes_to_u16(acidData + 16);
2292  pMetadata->data.acid.meterNumerator = drwav_bytes_to_u16(acidData + 18);
2293  pMetadata->data.acid.tempo = drwav_bytes_to_f32(acidData + 20);
2294  }
2295 
2296  return bytesRead;
2297 }
2298 
2299 DRWAV_PRIVATE size_t drwav__strlen_clamped(char* str, size_t maxToRead)
2300 {
2301  size_t result = 0;
2302 
2303  while (*str++ && result < maxToRead) {
2304  result += 1;
2305  }
2306 
2307  return result;
2308 }
2309 
2310 DRWAV_PRIVATE char* drwav__metadata_copy_string(drwav__metadata_parser* pParser, char* str, size_t maxToRead)
2311 {
2312  size_t len = drwav__strlen_clamped(str, maxToRead);
2313 
2314  if (len) {
2315  char* result = (char*)drwav__metadata_get_memory(pParser, len + 1, 1);
2316  DRWAV_ASSERT(result != NULL);
2317 
2318  memcpy(result, str, len);
2319  result[len] = '\0';
2320 
2321  return result;
2322  } else {
2323  return NULL;
2324  }
2325 }
2326 
2328 {
2329  drwav_uint8 bextData[DRWAV_BEXT_BYTES];
2330  drwav_uint64 bytesRead = drwav__metadata_parser_read(pParser, bextData, sizeof(bextData), NULL);
2331 
2333 
2334  if (bytesRead == sizeof(bextData)) {
2335  drwav_uint8* pReadPointer;
2336  drwav_uint32 timeReferenceLow;
2337  drwav_uint32 timeReferenceHigh;
2338  size_t extraBytes;
2339 
2340  pMetadata->type = drwav_metadata_type_bext;
2341 
2342  pReadPointer = bextData;
2343  pMetadata->data.bext.pDescription = drwav__metadata_copy_string(pParser, (char*)(pReadPointer), DRWAV_BEXT_DESCRIPTION_BYTES);
2344  pReadPointer += DRWAV_BEXT_DESCRIPTION_BYTES;
2345 
2346  pMetadata->data.bext.pOriginatorName = drwav__metadata_copy_string(pParser, (char*)(pReadPointer), DRWAV_BEXT_ORIGINATOR_NAME_BYTES);
2347  pReadPointer += DRWAV_BEXT_ORIGINATOR_NAME_BYTES;
2348 
2349  pMetadata->data.bext.pOriginatorReference = drwav__metadata_copy_string(pParser, (char*)(pReadPointer), DRWAV_BEXT_ORIGINATOR_REF_BYTES);
2350  pReadPointer += DRWAV_BEXT_ORIGINATOR_REF_BYTES;
2351 
2352  memcpy(pReadPointer, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate));
2353  pReadPointer += sizeof(pMetadata->data.bext.pOriginationDate);
2354 
2355  memcpy(pReadPointer, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime));
2356  pReadPointer += sizeof(pMetadata->data.bext.pOriginationTime);
2357 
2358  timeReferenceLow = drwav_bytes_to_u32(pReadPointer);
2359  pReadPointer += sizeof(drwav_uint32);
2360  timeReferenceHigh = drwav_bytes_to_u32(pReadPointer);
2361  pReadPointer += sizeof(drwav_uint32);
2362  pMetadata->data.bext.timeReference = ((drwav_uint64)timeReferenceHigh << 32) + timeReferenceLow;
2363 
2364  pMetadata->data.bext.version = drwav_bytes_to_u16(pReadPointer);
2365  pReadPointer += sizeof(drwav_uint16);
2366 
2368  memcpy(pMetadata->data.bext.pUMID, pReadPointer, DRWAV_BEXT_UMID_BYTES);
2369  pReadPointer += DRWAV_BEXT_UMID_BYTES;
2370 
2371  pMetadata->data.bext.loudnessValue = drwav_bytes_to_u16(pReadPointer);
2372  pReadPointer += sizeof(drwav_uint16);
2373 
2374  pMetadata->data.bext.loudnessRange = drwav_bytes_to_u16(pReadPointer);
2375  pReadPointer += sizeof(drwav_uint16);
2376 
2377  pMetadata->data.bext.maxTruePeakLevel = drwav_bytes_to_u16(pReadPointer);
2378  pReadPointer += sizeof(drwav_uint16);
2379 
2380  pMetadata->data.bext.maxMomentaryLoudness = drwav_bytes_to_u16(pReadPointer);
2381  pReadPointer += sizeof(drwav_uint16);
2382 
2383  pMetadata->data.bext.maxShortTermLoudness = drwav_bytes_to_u16(pReadPointer);
2384  pReadPointer += sizeof(drwav_uint16);
2385 
2386  DRWAV_ASSERT((pReadPointer + DRWAV_BEXT_RESERVED_BYTES) == (bextData + DRWAV_BEXT_BYTES));
2387 
2388  extraBytes = (size_t)(chunkSize - DRWAV_BEXT_BYTES);
2389  if (extraBytes > 0) {
2390  pMetadata->data.bext.pCodingHistory = (char*)drwav__metadata_get_memory(pParser, extraBytes + 1, 1);
2391  DRWAV_ASSERT(pMetadata->data.bext.pCodingHistory != NULL);
2392 
2393  bytesRead += drwav__metadata_parser_read(pParser, pMetadata->data.bext.pCodingHistory, extraBytes, NULL);
2394  pMetadata->data.bext.codingHistorySize = (drwav_uint32)strlen(pMetadata->data.bext.pCodingHistory);
2395  } else {
2396  pMetadata->data.bext.pCodingHistory = NULL;
2397  pMetadata->data.bext.codingHistorySize = 0;
2398  }
2399  }
2400 
2401  return bytesRead;
2402 }
2403 
2405 {
2407  drwav_uint64 totalBytesRead = 0;
2408  size_t bytesJustRead = drwav__metadata_parser_read(pParser, cueIDBuffer, sizeof(cueIDBuffer), &totalBytesRead);
2409 
2411 
2412  if (bytesJustRead == sizeof(cueIDBuffer)) {
2413  drwav_uint32 sizeIncludingNullTerminator;
2414 
2415  pMetadata->type = type;
2416  pMetadata->data.labelOrNote.cuePointId = drwav_bytes_to_u32(cueIDBuffer);
2417 
2418  sizeIncludingNullTerminator = (drwav_uint32)chunkSize - DRWAV_LIST_LABEL_OR_NOTE_BYTES;
2419  if (sizeIncludingNullTerminator > 0) {
2420  pMetadata->data.labelOrNote.stringLength = sizeIncludingNullTerminator - 1;
2421  pMetadata->data.labelOrNote.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
2422  DRWAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
2423 
2424  bytesJustRead = drwav__metadata_parser_read(pParser, pMetadata->data.labelOrNote.pString, sizeIncludingNullTerminator, &totalBytesRead);
2425  } else {
2426  pMetadata->data.labelOrNote.stringLength = 0;
2427  pMetadata->data.labelOrNote.pString = NULL;
2428  }
2429  }
2430 
2431  return totalBytesRead;
2432 }
2433 
2435 {
2437  drwav_uint64 totalBytesRead = 0;
2438  size_t bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &totalBytesRead);
2439 
2441 
2442  if (bytesJustRead == sizeof(buffer)) {
2443  drwav_uint32 sizeIncludingNullTerminator;
2444 
2446  pMetadata->data.labelledCueRegion.cuePointId = drwav_bytes_to_u32(buffer + 0);
2447  pMetadata->data.labelledCueRegion.sampleLength = drwav_bytes_to_u32(buffer + 4);
2448  pMetadata->data.labelledCueRegion.purposeId[0] = buffer[8];
2449  pMetadata->data.labelledCueRegion.purposeId[1] = buffer[9];
2450  pMetadata->data.labelledCueRegion.purposeId[2] = buffer[10];
2451  pMetadata->data.labelledCueRegion.purposeId[3] = buffer[11];
2452  pMetadata->data.labelledCueRegion.country = drwav_bytes_to_u16(buffer + 12);
2453  pMetadata->data.labelledCueRegion.language = drwav_bytes_to_u16(buffer + 14);
2454  pMetadata->data.labelledCueRegion.dialect = drwav_bytes_to_u16(buffer + 16);
2455  pMetadata->data.labelledCueRegion.codePage = drwav_bytes_to_u16(buffer + 18);
2456 
2457  sizeIncludingNullTerminator = (drwav_uint32)chunkSize - DRWAV_LIST_LABELLED_TEXT_BYTES;
2458  if (sizeIncludingNullTerminator > 0) {
2459  pMetadata->data.labelledCueRegion.stringLength = sizeIncludingNullTerminator - 1;
2460  pMetadata->data.labelledCueRegion.pString = (char*)drwav__metadata_get_memory(pParser, sizeIncludingNullTerminator, 1);
2462 
2463  bytesJustRead = drwav__metadata_parser_read(pParser, pMetadata->data.labelledCueRegion.pString, sizeIncludingNullTerminator, &totalBytesRead);
2464  } else {
2465  pMetadata->data.labelledCueRegion.stringLength = 0;
2466  pMetadata->data.labelledCueRegion.pString = NULL;
2467  }
2468  }
2469 
2470  return totalBytesRead;
2471 }
2472 
2474 {
2475  drwav_uint64 bytesRead = 0;
2476  drwav_uint32 stringSizeWithNullTerminator = (drwav_uint32)chunkSize;
2477 
2478  if (pParser->stage == drwav__metadata_parser_stage_count) {
2479  pParser->metadataCount += 1;
2480  drwav__metadata_request_extra_memory_for_stage_2(pParser, stringSizeWithNullTerminator, 1);
2481  } else {
2482  drwav_metadata* pMetadata = &pParser->pMetadata[pParser->metadataCursor];
2483  pMetadata->type = type;
2484  if (stringSizeWithNullTerminator > 0) {
2485  pMetadata->data.infoText.stringLength = stringSizeWithNullTerminator - 1;
2486  pMetadata->data.infoText.pString = (char*)drwav__metadata_get_memory(pParser, stringSizeWithNullTerminator, 1);
2487  DRWAV_ASSERT(pMetadata->data.infoText.pString != NULL);
2488 
2489  bytesRead = drwav__metadata_parser_read(pParser, pMetadata->data.infoText.pString, (size_t)stringSizeWithNullTerminator, NULL);
2490  if (bytesRead == chunkSize) {
2491  pParser->metadataCursor += 1;
2492  } else {
2493  /* Failed to parse. */
2494  }
2495  } else {
2496  pMetadata->data.infoText.stringLength = 0;
2497  pMetadata->data.infoText.pString = NULL;
2498  pParser->metadataCursor += 1;
2499  }
2500  }
2501 
2502  return bytesRead;
2503 }
2504 
2506 {
2507  drwav_uint64 bytesRead = 0;
2508 
2509  if (location == drwav_metadata_location_invalid) {
2510  return 0;
2511  }
2512 
2513  if (drwav_fourcc_equal(pChunkId, "data") || drwav_fourcc_equal(pChunkId, "fmt") || drwav_fourcc_equal(pChunkId, "fact")) {
2514  return 0;
2515  }
2516 
2517  if (pParser->stage == drwav__metadata_parser_stage_count) {
2518  pParser->metadataCount += 1;
2519  drwav__metadata_request_extra_memory_for_stage_2(pParser, (size_t)chunkSize, 1);
2520  } else {
2521  drwav_metadata* pMetadata = &pParser->pMetadata[pParser->metadataCursor];
2522  pMetadata->type = drwav_metadata_type_unknown;
2523  pMetadata->data.unknown.chunkLocation = location;
2524  pMetadata->data.unknown.id[0] = pChunkId[0];
2525  pMetadata->data.unknown.id[1] = pChunkId[1];
2526  pMetadata->data.unknown.id[2] = pChunkId[2];
2527  pMetadata->data.unknown.id[3] = pChunkId[3];
2528  pMetadata->data.unknown.dataSizeInBytes = (drwav_uint32)chunkSize;
2529  pMetadata->data.unknown.pData = (drwav_uint8 *)drwav__metadata_get_memory(pParser, (size_t)chunkSize, 1);
2530  DRWAV_ASSERT(pMetadata->data.unknown.pData != NULL);
2531 
2532  bytesRead = drwav__metadata_parser_read(pParser, pMetadata->data.unknown.pData, pMetadata->data.unknown.dataSizeInBytes, NULL);
2533  if (bytesRead == pMetadata->data.unknown.dataSizeInBytes) {
2534  pParser->metadataCursor += 1;
2535  } else {
2536  /* Failed to read. */
2537  }
2538  }
2539 
2540  return bytesRead;
2541 }
2542 
2543 DRWAV_PRIVATE drwav_bool32 drwav__chunk_matches(drwav_uint64 allowedMetadataTypes, const drwav_uint8* pChunkID, drwav_metadata_type type, const char* pID)
2544 {
2545  return (allowedMetadataTypes & type) && drwav_fourcc_equal(pChunkID, pID);
2546 }
2547 
2549 {
2550  const drwav_uint8 *pChunkID = pChunkHeader->id.fourcc;
2551  drwav_uint64 bytesRead = 0;
2552 
2553  if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_smpl, "smpl")) {
2554  if (pChunkHeader->sizeInBytes >= DRWAV_SMPL_BYTES) {
2555  if (pParser->stage == drwav__metadata_parser_stage_count) {
2556  drwav_uint8 buffer[4];
2557  size_t bytesJustRead;
2558 
2559  if (!pParser->onSeek(pParser->pReadSeekUserData, 28, drwav_seek_origin_current)) {
2560  return bytesRead;
2561  }
2562  bytesRead += 28;
2563 
2564  bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
2565  if (bytesJustRead == sizeof(buffer)) {
2566  drwav_uint32 loopCount = drwav_bytes_to_u32(buffer);
2567 
2568  bytesJustRead = drwav__metadata_parser_read(pParser, buffer, sizeof(buffer), &bytesRead);
2569  if (bytesJustRead == sizeof(buffer)) {
2570  drwav_uint32 samplerSpecificDataSizeInBytes = drwav_bytes_to_u32(buffer);
2571 
2572  pParser->metadataCount += 1;
2574  drwav__metadata_request_extra_memory_for_stage_2(pParser, samplerSpecificDataSizeInBytes, 1);
2575  }
2576  }
2577  } else {
2578  bytesRead = drwav__read_smpl_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor]);
2579  if (bytesRead == pChunkHeader->sizeInBytes) {
2580  pParser->metadataCursor += 1;
2581  } else {
2582  /* Failed to parse. */
2583  }
2584  }
2585  } else {
2586  /* Incorrectly formed chunk. */
2587  }
2588  } else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_inst, "inst")) {
2589  if (pChunkHeader->sizeInBytes == DRWAV_INST_BYTES) {
2590  if (pParser->stage == drwav__metadata_parser_stage_count) {
2591  pParser->metadataCount += 1;
2592  } else {
2593  bytesRead = drwav__read_inst_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor]);
2594  if (bytesRead == pChunkHeader->sizeInBytes) {
2595  pParser->metadataCursor += 1;
2596  } else {
2597  /* Failed to parse. */
2598  }
2599  }
2600  } else {
2601  /* Incorrectly formed chunk. */
2602  }
2603  } else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_acid, "acid")) {
2604  if (pChunkHeader->sizeInBytes == DRWAV_ACID_BYTES) {
2605  if (pParser->stage == drwav__metadata_parser_stage_count) {
2606  pParser->metadataCount += 1;
2607  } else {
2608  bytesRead = drwav__read_acid_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor]);
2609  if (bytesRead == pChunkHeader->sizeInBytes) {
2610  pParser->metadataCursor += 1;
2611  } else {
2612  /* Failed to parse. */
2613  }
2614  }
2615  } else {
2616  /* Incorrectly formed chunk. */
2617  }
2618  } else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_cue, "cue ")) {
2619  if (pChunkHeader->sizeInBytes >= DRWAV_CUE_BYTES) {
2620  if (pParser->stage == drwav__metadata_parser_stage_count) {
2621  size_t cueCount;
2622 
2623  pParser->metadataCount += 1;
2624  cueCount = (size_t)(pChunkHeader->sizeInBytes - DRWAV_CUE_BYTES) / DRWAV_CUE_POINT_BYTES;
2626  } else {
2627  bytesRead = drwav__read_cue_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor]);
2628  if (bytesRead == pChunkHeader->sizeInBytes) {
2629  pParser->metadataCursor += 1;
2630  } else {
2631  /* Failed to parse. */
2632  }
2633  }
2634  } else {
2635  /* Incorrectly formed chunk. */
2636  }
2637  } else if (drwav__chunk_matches(allowedMetadataTypes, pChunkID, drwav_metadata_type_bext, "bext")) {
2638  if (pChunkHeader->sizeInBytes >= DRWAV_BEXT_BYTES) {
2639  if (pParser->stage == drwav__metadata_parser_stage_count) {
2640  /* The description field is the largest one in a bext chunk, so that is the max size of this temporary buffer. */
2641  char buffer[DRWAV_BEXT_DESCRIPTION_BYTES + 1];
2642  size_t allocSizeNeeded = DRWAV_BEXT_UMID_BYTES; /* We know we will need SMPTE umid size. */
2643  size_t bytesJustRead;
2644 
2645  buffer[DRWAV_BEXT_DESCRIPTION_BYTES] = '\0';
2646  bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_DESCRIPTION_BYTES, &bytesRead);
2647  if (bytesJustRead != DRWAV_BEXT_DESCRIPTION_BYTES) {
2648  return bytesRead;
2649  }
2650  allocSizeNeeded += strlen(buffer) + 1;
2651 
2652  buffer[DRWAV_BEXT_ORIGINATOR_NAME_BYTES] = '\0';
2653  bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_ORIGINATOR_NAME_BYTES, &bytesRead);
2654  if (bytesJustRead != DRWAV_BEXT_ORIGINATOR_NAME_BYTES) {
2655  return bytesRead;
2656  }
2657  allocSizeNeeded += strlen(buffer) + 1;
2658 
2659  buffer[DRWAV_BEXT_ORIGINATOR_REF_BYTES] = '\0';
2660  bytesJustRead = drwav__metadata_parser_read(pParser, buffer, DRWAV_BEXT_ORIGINATOR_REF_BYTES, &bytesRead);
2661  if (bytesJustRead != DRWAV_BEXT_ORIGINATOR_REF_BYTES) {
2662  return bytesRead;
2663  }
2664  allocSizeNeeded += strlen(buffer) + 1;
2665  allocSizeNeeded += (size_t)pChunkHeader->sizeInBytes - DRWAV_BEXT_BYTES; /* Coding history. */
2666 
2667  drwav__metadata_request_extra_memory_for_stage_2(pParser, allocSizeNeeded, 1);
2668 
2669  pParser->metadataCount += 1;
2670  } else {
2671  bytesRead = drwav__read_bext_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], pChunkHeader->sizeInBytes);
2672  if (bytesRead == pChunkHeader->sizeInBytes) {
2673  pParser->metadataCursor += 1;
2674  } else {
2675  /* Failed to parse. */
2676  }
2677  }
2678  } else {
2679  /* Incorrectly formed chunk. */
2680  }
2681  } else if (drwav_fourcc_equal(pChunkID, "LIST") || drwav_fourcc_equal(pChunkID, "list")) {
2683  while (bytesRead < pChunkHeader->sizeInBytes) {
2684  drwav_uint8 subchunkId[4];
2685  drwav_uint8 subchunkSizeBuffer[4];
2686  drwav_uint64 subchunkDataSize;
2687  drwav_uint64 subchunkBytesRead = 0;
2688  drwav_uint64 bytesJustRead = drwav__metadata_parser_read(pParser, subchunkId, sizeof(subchunkId), &bytesRead);
2689  if (bytesJustRead != sizeof(subchunkId)) {
2690  break;
2691  }
2692 
2693  /*
2694  The first thing in a list chunk should be "adtl" or "INFO".
2695 
2696  - adtl means this list is a Associated Data List Chunk and will contain labels, notes
2697  or labelled cue regions.
2698  - INFO means this list is an Info List Chunk containing info text chunks such as IPRD
2699  which would specifies the album of this wav file.
2700 
2701  No data follows the adtl or INFO id so we just make note of what type this list is and
2702  continue.
2703  */
2704  if (drwav_fourcc_equal(subchunkId, "adtl")) {
2706  continue;
2707  } else if (drwav_fourcc_equal(subchunkId, "INFO")) {
2709  continue;
2710  }
2711 
2712  bytesJustRead = drwav__metadata_parser_read(pParser, subchunkSizeBuffer, sizeof(subchunkSizeBuffer), &bytesRead);
2713  if (bytesJustRead != sizeof(subchunkSizeBuffer)) {
2714  break;
2715  }
2716  subchunkDataSize = drwav_bytes_to_u32(subchunkSizeBuffer);
2717 
2718  if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_label, "labl") || drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_note, "note")) {
2719  if (subchunkDataSize >= DRWAV_LIST_LABEL_OR_NOTE_BYTES) {
2720  drwav_uint64 stringSizeWithNullTerm = subchunkDataSize - DRWAV_LIST_LABEL_OR_NOTE_BYTES;
2721  if (pParser->stage == drwav__metadata_parser_stage_count) {
2722  pParser->metadataCount += 1;
2723  drwav__metadata_request_extra_memory_for_stage_2(pParser, (size_t)stringSizeWithNullTerm, 1);
2724  } else {
2725  subchunkBytesRead = drwav__read_list_label_or_note_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], subchunkDataSize, drwav_fourcc_equal(subchunkId, "labl") ? drwav_metadata_type_list_label : drwav_metadata_type_list_note);
2726  if (subchunkBytesRead == subchunkDataSize) {
2727  pParser->metadataCursor += 1;
2728  } else {
2729  /* Failed to parse. */
2730  }
2731  }
2732  } else {
2733  /* Incorrectly formed chunk. */
2734  }
2735  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_labelled_cue_region, "ltxt")) {
2736  if (subchunkDataSize >= DRWAV_LIST_LABELLED_TEXT_BYTES) {
2737  drwav_uint64 stringSizeWithNullTerminator = subchunkDataSize - DRWAV_LIST_LABELLED_TEXT_BYTES;
2738  if (pParser->stage == drwav__metadata_parser_stage_count) {
2739  pParser->metadataCount += 1;
2740  drwav__metadata_request_extra_memory_for_stage_2(pParser, (size_t)stringSizeWithNullTerminator, 1);
2741  } else {
2742  subchunkBytesRead = drwav__read_list_labelled_cue_region_to_metadata_obj(pParser, &pParser->pMetadata[pParser->metadataCursor], subchunkDataSize);
2743  if (subchunkBytesRead == subchunkDataSize) {
2744  pParser->metadataCursor += 1;
2745  } else {
2746  /* Failed to parse. */
2747  }
2748  }
2749  } else {
2750  /* Incorrectly formed chunk. */
2751  }
2752  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_software, "ISFT")) {
2753  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_software);
2754  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_copyright, "ICOP")) {
2755  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_copyright);
2756  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_title, "INAM")) {
2757  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_title);
2758  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_artist, "IART")) {
2759  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_artist);
2760  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_comment, "ICMT")) {
2761  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_comment);
2762  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_date, "ICRD")) {
2763  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_date);
2764  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_genre, "IGNR")) {
2765  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_genre);
2766  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_album, "IPRD")) {
2767  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_album);
2768  } else if (drwav__chunk_matches(allowedMetadataTypes, subchunkId, drwav_metadata_type_list_info_tracknumber, "ITRK")) {
2769  subchunkBytesRead = drwav__metadata_process_info_text_chunk(pParser, subchunkDataSize, drwav_metadata_type_list_info_tracknumber);
2770  } else if (allowedMetadataTypes & drwav_metadata_type_unknown) {
2771  subchunkBytesRead = drwav__metadata_process_unknown_chunk(pParser, subchunkId, subchunkDataSize, listType);
2772  }
2773 
2774  bytesRead += subchunkBytesRead;
2775  DRWAV_ASSERT(subchunkBytesRead <= subchunkDataSize);
2776 
2777  if (subchunkBytesRead < subchunkDataSize) {
2778  drwav_uint64 bytesToSeek = subchunkDataSize - subchunkBytesRead;
2779 
2780  if (!pParser->onSeek(pParser->pReadSeekUserData, (int)bytesToSeek, drwav_seek_origin_current)) {
2781  break;
2782  }
2783  bytesRead += bytesToSeek;
2784  }
2785 
2786  if ((subchunkDataSize % 2) == 1) {
2787  if (!pParser->onSeek(pParser->pReadSeekUserData, 1, drwav_seek_origin_current)) {
2788  break;
2789  }
2790  bytesRead += 1;
2791  }
2792  }
2793  } else if (allowedMetadataTypes & drwav_metadata_type_unknown) {
2794  bytesRead = drwav__metadata_process_unknown_chunk(pParser, pChunkID, pChunkHeader->sizeInBytes, drwav_metadata_location_top_level);
2795  }
2796 
2797  return bytesRead;
2798 }
2799 
2800 
2802 {
2803  /*
2804  The bytes per frame is a bit ambiguous. It can be either be based on the bits per sample, or the block align. The way I'm doing it here
2805  is that if the bits per sample is a multiple of 8, use floor(bitsPerSample*channels/8), otherwise fall back to the block align.
2806  */
2807  if ((pWav->bitsPerSample & 0x7) == 0) {
2808  /* Bits per sample is a multiple of 8. */
2809  return (pWav->bitsPerSample * pWav->fmt.channels) >> 3;
2810  } else {
2811  return pWav->fmt.blockAlign;
2812  }
2813 }
2814 
2816 {
2817  if (pFMT == NULL) {
2818  return 0;
2819  }
2820 
2821  if (pFMT->formatTag != DR_WAVE_FORMAT_EXTENSIBLE) {
2822  return pFMT->formatTag;
2823  } else {
2824  return drwav_bytes_to_u16(pFMT->subFormat); /* Only the first two bytes are required. */
2825  }
2826 }
2827 
2828 DRWAV_PRIVATE drwav_bool32 drwav_preinit(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pReadSeekUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
2829 {
2830  if (pWav == NULL || onRead == NULL || onSeek == NULL) {
2831  return DRWAV_FALSE;
2832  }
2833 
2834  DRWAV_ZERO_MEMORY(pWav, sizeof(*pWav));
2835  pWav->onRead = onRead;
2836  pWav->onSeek = onSeek;
2837  pWav->pUserData = pReadSeekUserData;
2839 
2841  return DRWAV_FALSE; /* Invalid allocation callbacks. */
2842  }
2843 
2844  return DRWAV_TRUE;
2845 }
2846 
2847 DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav* pWav, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags)
2848 {
2849  /* This function assumes drwav_preinit() has been called beforehand. */
2850 
2851  drwav_uint64 cursor; /* <-- Keeps track of the byte position so we can seek to specific locations. */
2852  drwav_bool32 sequential;
2853  drwav_uint8 riff[4];
2854  drwav_fmt fmt;
2855  unsigned short translatedFormatTag;
2856  drwav_bool32 foundDataChunk;
2857  drwav_uint64 dataChunkSize = 0; /* <-- Important! Don't explicitly set this to 0 anywhere else. Calculation of the size of the data chunk is performed in different paths depending on the container. */
2858  drwav_uint64 sampleCountFromFactChunk = 0; /* Same as dataChunkSize - make sure this is the only place this is initialized to 0. */
2859  drwav_uint64 chunkSize;
2860  drwav__metadata_parser metadataParser;
2861 
2862  cursor = 0;
2863  sequential = (flags & DRWAV_SEQUENTIAL) != 0;
2864 
2865  /* The first 4 bytes should be the RIFF identifier. */
2866  if (drwav__on_read(pWav->onRead, pWav->pUserData, riff, sizeof(riff), &cursor) != sizeof(riff)) {
2867  return DRWAV_FALSE;
2868  }
2869 
2870  /*
2871  The first 4 bytes can be used to identify the container. For RIFF files it will start with "RIFF" and for
2872  w64 it will start with "riff".
2873  */
2874  if (drwav_fourcc_equal(riff, "RIFF")) {
2876  } else if (drwav_fourcc_equal(riff, "riff")) {
2877  int i;
2878  drwav_uint8 riff2[12];
2879 
2881 
2882  /* Check the rest of the GUID for validity. */
2883  if (drwav__on_read(pWav->onRead, pWav->pUserData, riff2, sizeof(riff2), &cursor) != sizeof(riff2)) {
2884  return DRWAV_FALSE;
2885  }
2886 
2887  for (i = 0; i < 12; ++i) {
2888  if (riff2[i] != drwavGUID_W64_RIFF[i+4]) {
2889  return DRWAV_FALSE;
2890  }
2891  }
2892  } else if (drwav_fourcc_equal(riff, "RF64")) {
2894  } else {
2895  return DRWAV_FALSE; /* Unknown or unsupported container. */
2896  }
2897 
2898 
2899  if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) {
2900  drwav_uint8 chunkSizeBytes[4];
2901  drwav_uint8 wave[4];
2902 
2903  /* RIFF/WAVE */
2904  if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
2905  return DRWAV_FALSE;
2906  }
2907 
2908  if (pWav->container == drwav_container_riff) {
2909  if (drwav_bytes_to_u32(chunkSizeBytes) < 36) {
2910  return DRWAV_FALSE; /* Chunk size should always be at least 36 bytes. */
2911  }
2912  } else {
2913  if (drwav_bytes_to_u32(chunkSizeBytes) != 0xFFFFFFFF) {
2914  return DRWAV_FALSE; /* Chunk size should always be set to -1/0xFFFFFFFF for RF64. The actual size is retrieved later. */
2915  }
2916  }
2917 
2918  if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
2919  return DRWAV_FALSE;
2920  }
2921 
2922  if (!drwav_fourcc_equal(wave, "WAVE")) {
2923  return DRWAV_FALSE; /* Expecting "WAVE". */
2924  }
2925  } else {
2926  drwav_uint8 chunkSizeBytes[8];
2927  drwav_uint8 wave[16];
2928 
2929  /* W64 */
2930  if (drwav__on_read(pWav->onRead, pWav->pUserData, chunkSizeBytes, sizeof(chunkSizeBytes), &cursor) != sizeof(chunkSizeBytes)) {
2931  return DRWAV_FALSE;
2932  }
2933 
2934  if (drwav_bytes_to_u64(chunkSizeBytes) < 80) {
2935  return DRWAV_FALSE;
2936  }
2937 
2938  if (drwav__on_read(pWav->onRead, pWav->pUserData, wave, sizeof(wave), &cursor) != sizeof(wave)) {
2939  return DRWAV_FALSE;
2940  }
2941 
2942  if (!drwav_guid_equal(wave, drwavGUID_W64_WAVE)) {
2943  return DRWAV_FALSE;
2944  }
2945  }
2946 
2947 
2948  /* For RF64, the "ds64" chunk must come next, before the "fmt " chunk. */
2949  if (pWav->container == drwav_container_rf64) {
2950  drwav_uint8 sizeBytes[8];
2951  drwav_uint64 bytesRemainingInChunk;
2953  drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
2954  if (result != DRWAV_SUCCESS) {
2955  return DRWAV_FALSE;
2956  }
2957 
2958  if (!drwav_fourcc_equal(header.id.fourcc, "ds64")) {
2959  return DRWAV_FALSE; /* Expecting "ds64". */
2960  }
2961 
2962  bytesRemainingInChunk = header.sizeInBytes + header.paddingSize;
2963 
2964  /* We don't care about the size of the RIFF chunk - skip it. */
2965  if (!drwav__seek_forward(pWav->onSeek, 8, pWav->pUserData)) {
2966  return DRWAV_FALSE;
2967  }
2968  bytesRemainingInChunk -= 8;
2969  cursor += 8;
2970 
2971 
2972  /* Next 8 bytes is the size of the "data" chunk. */
2973  if (drwav__on_read(pWav->onRead, pWav->pUserData, sizeBytes, sizeof(sizeBytes), &cursor) != sizeof(sizeBytes)) {
2974  return DRWAV_FALSE;
2975  }
2976  bytesRemainingInChunk -= 8;
2977  dataChunkSize = drwav_bytes_to_u64(sizeBytes);
2978 
2979 
2980  /* Next 8 bytes is the same count which we would usually derived from the FACT chunk if it was available. */
2981  if (drwav__on_read(pWav->onRead, pWav->pUserData, sizeBytes, sizeof(sizeBytes), &cursor) != sizeof(sizeBytes)) {
2982  return DRWAV_FALSE;
2983  }
2984  bytesRemainingInChunk -= 8;
2985  sampleCountFromFactChunk = drwav_bytes_to_u64(sizeBytes);
2986 
2987 
2988  /* Skip over everything else. */
2989  if (!drwav__seek_forward(pWav->onSeek, bytesRemainingInChunk, pWav->pUserData)) {
2990  return DRWAV_FALSE;
2991  }
2992  cursor += bytesRemainingInChunk;
2993  }
2994 
2995 
2996  /* The next bytes should be the "fmt " chunk. */
2997  if (!drwav__read_fmt(pWav->onRead, pWav->onSeek, pWav->pUserData, pWav->container, &cursor, &fmt)) {
2998  return DRWAV_FALSE; /* Failed to read the "fmt " chunk. */
2999  }
3000 
3001  /* Basic validation. */
3002  if ((fmt.sampleRate == 0 || fmt.sampleRate > DRWAV_MAX_SAMPLE_RATE) ||
3003  (fmt.channels == 0 || fmt.channels > DRWAV_MAX_CHANNELS) ||
3005  fmt.blockAlign == 0) {
3006  return DRWAV_FALSE; /* Probably an invalid WAV file. */
3007  }
3008 
3009 
3010  /* Translate the internal format. */
3011  translatedFormatTag = fmt.formatTag;
3012  if (translatedFormatTag == DR_WAVE_FORMAT_EXTENSIBLE) {
3013  translatedFormatTag = drwav_bytes_to_u16(fmt.subFormat + 0);
3014  }
3015 
3016  memset(&metadataParser, 0, sizeof(metadataParser));
3017 
3018  /* Not tested on W64. */
3019  if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) {
3020  drwav_uint64 cursorForMetadata = cursor;
3021 
3022  metadataParser.onRead = pWav->onRead;
3023  metadataParser.onSeek = pWav->onSeek;
3024  metadataParser.pReadSeekUserData = pWav->pUserData;
3025  metadataParser.stage = drwav__metadata_parser_stage_count;
3026 
3027  for (;;) {
3028  drwav_result result;
3029  drwav_uint64 bytesRead;
3030  drwav_uint64 remainingBytes;
3032 
3033  result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursorForMetadata, &header);
3034  if (result != DRWAV_SUCCESS) {
3035  break;
3036  }
3037 
3038  bytesRead = drwav__metadata_process_chunk(&metadataParser, &header, pWav->allowedMetadataTypes);
3039  DRWAV_ASSERT(bytesRead <= header.sizeInBytes);
3040 
3041  remainingBytes = header.sizeInBytes - bytesRead + header.paddingSize;
3042  if (!drwav__seek_forward(pWav->onSeek, remainingBytes, pWav->pUserData)) {
3043  break;
3044  }
3045  cursorForMetadata += remainingBytes;
3046  }
3047 
3048  if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
3049  return DRWAV_FALSE;
3050  }
3051 
3052  drwav__metadata_alloc(&metadataParser, &pWav->allocationCallbacks);
3053  metadataParser.stage = drwav__metadata_parser_stage_read;
3054  }
3055 
3056  /*
3057  We need to enumerate over each chunk for two reasons:
3058  1) The "data" chunk may not be the next one
3059  2) We may want to report each chunk back to the client
3060 
3061  In order to correctly report each chunk back to the client we will need to keep looping until the end of the file.
3062  */
3063  foundDataChunk = DRWAV_FALSE;
3064 
3065  /* The next chunk we care about is the "data" chunk. This is not necessarily the next chunk so we'll need to loop. */
3066  for (;;) {
3068  drwav_result result = drwav__read_chunk_header(pWav->onRead, pWav->pUserData, pWav->container, &cursor, &header);
3069  if (result != DRWAV_SUCCESS) {
3070  if (!foundDataChunk) {
3071  return DRWAV_FALSE;
3072  } else {
3073  break; /* Probably at the end of the file. Get out of the loop. */
3074  }
3075  }
3076 
3077  /* Tell the client about this chunk. */
3078  if (!sequential && onChunk != NULL) {
3079  drwav_uint64 callbackBytesRead = onChunk(pChunkUserData, pWav->onRead, pWav->onSeek, pWav->pUserData, &header, pWav->container, &fmt);
3080 
3081  /*
3082  dr_wav may need to read the contents of the chunk, so we now need to seek back to the position before
3083  we called the callback.
3084  */
3085  if (callbackBytesRead > 0) {
3086  if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
3087  return DRWAV_FALSE;
3088  }
3089  }
3090  }
3091 
3092  if (!sequential && pWav->allowedMetadataTypes != drwav_metadata_type_none && (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64)) {
3093  drwav_uint64 bytesRead = drwav__metadata_process_chunk(&metadataParser, &header, pWav->allowedMetadataTypes);
3094 
3095  if (bytesRead > 0) {
3096  if (!drwav__seek_from_start(pWav->onSeek, cursor, pWav->pUserData)) {
3097  return DRWAV_FALSE;
3098  }
3099  }
3100  }
3101 
3102 
3103  if (!foundDataChunk) {
3104  pWav->dataChunkDataPos = cursor;
3105  }
3106 
3107  chunkSize = header.sizeInBytes;
3108  if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) {
3109  if (drwav_fourcc_equal(header.id.fourcc, "data")) {
3110  foundDataChunk = DRWAV_TRUE;
3111  if (pWav->container != drwav_container_rf64) { /* The data chunk size for RF64 will always be set to 0xFFFFFFFF here. It was set to it's true value earlier. */
3112  dataChunkSize = chunkSize;
3113  }
3114  }
3115  } else {
3116  if (drwav_guid_equal(header.id.guid, drwavGUID_W64_DATA)) {
3117  foundDataChunk = DRWAV_TRUE;
3118  dataChunkSize = chunkSize;
3119  }
3120  }
3121 
3122  /*
3123  If at this point we have found the data chunk and we're running in sequential mode, we need to break out of this loop. The reason for
3124  this is that we would otherwise require a backwards seek which sequential mode forbids.
3125  */
3126  if (foundDataChunk && sequential) {
3127  break;
3128  }
3129 
3130  /* Optional. Get the total sample count from the FACT chunk. This is useful for compressed formats. */
3131  if (pWav->container == drwav_container_riff) {
3132  if (drwav_fourcc_equal(header.id.fourcc, "fact")) {
3133  drwav_uint32 sampleCount;
3134  if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCount, 4, &cursor) != 4) {
3135  return DRWAV_FALSE;
3136  }
3137  chunkSize -= 4;
3138 
3139  if (!foundDataChunk) {
3140  pWav->dataChunkDataPos = cursor;
3141  }
3142 
3143  /*
3144  The sample count in the "fact" chunk is either unreliable, or I'm not understanding it properly. For now I am only enabling this
3145  for Microsoft ADPCM formats.
3146  */
3148  sampleCountFromFactChunk = sampleCount;
3149  } else {
3150  sampleCountFromFactChunk = 0;
3151  }
3152  }
3153  } else if (pWav->container == drwav_container_w64) {
3154  if (drwav_guid_equal(header.id.guid, drwavGUID_W64_FACT)) {
3155  if (drwav__on_read(pWav->onRead, pWav->pUserData, &sampleCountFromFactChunk, 8, &cursor) != 8) {
3156  return DRWAV_FALSE;
3157  }
3158  chunkSize -= 8;
3159 
3160  if (!foundDataChunk) {
3161  pWav->dataChunkDataPos = cursor;
3162  }
3163  }
3164  } else if (pWav->container == drwav_container_rf64) {
3165  /* We retrieved the sample count from the ds64 chunk earlier so no need to do that here. */
3166  }
3167 
3168  /* Make sure we seek past the padding. */
3169  chunkSize += header.paddingSize;
3170  if (!drwav__seek_forward(pWav->onSeek, chunkSize, pWav->pUserData)) {
3171  break;
3172  }
3173  cursor += chunkSize;
3174 
3175  if (!foundDataChunk) {
3176  pWav->dataChunkDataPos = cursor;
3177  }
3178  }
3179 
3180  pWav->pMetadata = metadataParser.pMetadata;
3181  pWav->metadataCount = metadataParser.metadataCount;
3182 
3183  /* If we haven't found a data chunk, return an error. */
3184  if (!foundDataChunk) {
3185  return DRWAV_FALSE;
3186  }
3187 
3188  /* We may have moved passed the data chunk. If so we need to move back. If running in sequential mode we can assume we are already sitting on the data chunk. */
3189  if (!sequential) {
3190  if (!drwav__seek_from_start(pWav->onSeek, pWav->dataChunkDataPos, pWav->pUserData)) {
3191  return DRWAV_FALSE;
3192  }
3193  cursor = pWav->dataChunkDataPos;
3194  }
3195 
3196 
3197  /* At this point we should be sitting on the first byte of the raw audio data. */
3198 
3199  pWav->fmt = fmt;
3200  pWav->sampleRate = fmt.sampleRate;
3201  pWav->channels = fmt.channels;
3202  pWav->bitsPerSample = fmt.bitsPerSample;
3203  pWav->bytesRemaining = dataChunkSize;
3204  pWav->translatedFormatTag = translatedFormatTag;
3205  pWav->dataChunkDataSize = dataChunkSize;
3206 
3207  if (sampleCountFromFactChunk != 0) {
3208  pWav->totalPCMFrameCount = sampleCountFromFactChunk;
3209  } else {
3210  pWav->totalPCMFrameCount = dataChunkSize / drwav_get_bytes_per_pcm_frame(pWav);
3211 
3213  drwav_uint64 totalBlockHeaderSizeInBytes;
3214  drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
3215 
3216  /* Make sure any trailing partial block is accounted for. */
3217  if ((blockCount * fmt.blockAlign) < dataChunkSize) {
3218  blockCount += 1;
3219  }
3220 
3221  /* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
3222  totalBlockHeaderSizeInBytes = blockCount * (6*fmt.channels);
3223  pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
3224  }
3226  drwav_uint64 totalBlockHeaderSizeInBytes;
3227  drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
3228 
3229  /* Make sure any trailing partial block is accounted for. */
3230  if ((blockCount * fmt.blockAlign) < dataChunkSize) {
3231  blockCount += 1;
3232  }
3233 
3234  /* We decode two samples per byte. There will be blockCount headers in the data chunk. This is enough to know how to calculate the total PCM frame count. */
3235  totalBlockHeaderSizeInBytes = blockCount * (4*fmt.channels);
3236  pWav->totalPCMFrameCount = ((dataChunkSize - totalBlockHeaderSizeInBytes) * 2) / fmt.channels;
3237 
3238  /* The header includes a decoded sample for each channel which acts as the initial predictor sample. */
3239  pWav->totalPCMFrameCount += blockCount;
3240  }
3241  }
3242 
3243  /* Some formats only support a certain number of channels. */
3245  if (pWav->channels > 2) {
3246  return DRWAV_FALSE;
3247  }
3248  }
3249 
3250 #ifdef DR_WAV_LIBSNDFILE_COMPAT
3251  /*
3252  I use libsndfile as a benchmark for testing, however in the version I'm using (from the Windows installer on the libsndfile website),
3253  it appears the total sample count libsndfile uses for MS-ADPCM is incorrect. It would seem they are computing the total sample count
3254  from the number of blocks, however this results in the inclusion of extra silent samples at the end of the last block. The correct
3255  way to know the total sample count is to inspect the "fact" chunk, which should always be present for compressed formats, and should
3256  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
3257  correctness tests against libsndfile, and is disabled by default.
3258  */
3260  drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
3261  pWav->totalPCMFrameCount = (((blockCount * (fmt.blockAlign - (6*pWav->channels))) * 2)) / fmt.channels; /* x2 because two samples per byte. */
3262  }
3264  drwav_uint64 blockCount = dataChunkSize / fmt.blockAlign;
3265  pWav->totalPCMFrameCount = (((blockCount * (fmt.blockAlign - (4*pWav->channels))) * 2) + (blockCount * pWav->channels)) / fmt.channels;
3266  }
3267 #endif
3268 
3269  return DRWAV_TRUE;
3270 }
3271 
3272 DRWAV_API drwav_bool32 drwav_init(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
3273 {
3274  return drwav_init_ex(pWav, onRead, onSeek, NULL, pUserData, NULL, 0, pAllocationCallbacks);
3275 }
3276 
3277 DRWAV_API drwav_bool32 drwav_init_ex(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void* pReadSeekUserData, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
3278 {
3279  if (!drwav_preinit(pWav, onRead, onSeek, pReadSeekUserData, pAllocationCallbacks)) {
3280  return DRWAV_FALSE;
3281  }
3282 
3283  return drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
3284 }
3285 
3286 DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav* pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
3287 {
3288  if (!drwav_preinit(pWav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
3289  return DRWAV_FALSE;
3290  }
3291 
3292  pWav->allowedMetadataTypes = drwav_metadata_type_all_including_unknown; /* <-- Needs to be set to tell drwav_init_ex() that we need to process metadata. */
3293  return drwav_init__internal(pWav, NULL, NULL, flags);
3294 }
3295 
3297 {
3298  drwav_metadata *result = pWav->pMetadata;
3299 
3300  pWav->pMetadata = NULL;
3301  pWav->metadataCount = 0;
3302 
3303  return result;
3304 }
3305 
3306 
3307 DRWAV_PRIVATE size_t drwav__write(drwav* pWav, const void* pData, size_t dataSize)
3308 {
3309  DRWAV_ASSERT(pWav != NULL);
3310  DRWAV_ASSERT(pWav->onWrite != NULL);
3311 
3312  /* Generic write. Assumes no byte reordering required. */
3313  return pWav->onWrite(pWav->pUserData, pData, dataSize);
3314 }
3315 
3317 {
3318  DRWAV_ASSERT(pWav != NULL);
3319  DRWAV_ASSERT(pWav->onWrite != NULL);
3320 
3321  return pWav->onWrite(pWav->pUserData, &byte, 1);
3322 }
3323 
3325 {
3326  DRWAV_ASSERT(pWav != NULL);
3327  DRWAV_ASSERT(pWav->onWrite != NULL);
3328 
3329  if (!drwav__is_little_endian()) {
3330  value = drwav__bswap16(value);
3331  }
3332 
3333  return drwav__write(pWav, &value, 2);
3334 }
3335 
3337 {
3338  DRWAV_ASSERT(pWav != NULL);
3339  DRWAV_ASSERT(pWav->onWrite != NULL);
3340 
3341  if (!drwav__is_little_endian()) {
3342  value = drwav__bswap32(value);
3343  }
3344 
3345  return drwav__write(pWav, &value, 4);
3346 }
3347 
3349 {
3350  DRWAV_ASSERT(pWav != NULL);
3351  DRWAV_ASSERT(pWav->onWrite != NULL);
3352 
3353  if (!drwav__is_little_endian()) {
3354  value = drwav__bswap64(value);
3355  }
3356 
3357  return drwav__write(pWav, &value, 8);
3358 }
3359 
3360 DRWAV_PRIVATE size_t drwav__write_f32ne_to_le(drwav* pWav, float value)
3361 {
3362  union {
3363  drwav_uint32 u32;
3364  float f32;
3365  } u;
3366 
3367  DRWAV_ASSERT(pWav != NULL);
3368  DRWAV_ASSERT(pWav->onWrite != NULL);
3369 
3370  u.f32 = value;
3371 
3372  if (!drwav__is_little_endian()) {
3373  u.u32 = drwav__bswap32(u.u32);
3374  }
3375 
3376  return drwav__write(pWav, &u.u32, 4);
3377 }
3378 
3379 DRWAV_PRIVATE size_t drwav__write_or_count(drwav* pWav, const void* pData, size_t dataSize)
3380 {
3381  if (pWav == NULL) {
3382  return dataSize;
3383  }
3384 
3385  return drwav__write(pWav, pData, dataSize);
3386 }
3387 
3389 {
3390  if (pWav == NULL) {
3391  return 1;
3392  }
3393 
3394  return drwav__write_byte(pWav, byte);
3395 }
3396 
3398 {
3399  if (pWav == NULL) {
3400  return 2;
3401  }
3402 
3403  return drwav__write_u16ne_to_le(pWav, value);
3404 }
3405 
3407 {
3408  if (pWav == NULL) {
3409  return 4;
3410  }
3411 
3412  return drwav__write_u32ne_to_le(pWav, value);
3413 }
3414 
3415 #if 0 /* Unused for now. */
3416 DRWAV_PRIVATE size_t drwav__write_or_count_u64ne_to_le(drwav* pWav, drwav_uint64 value)
3417 {
3418  if (pWav == NULL) {
3419  return 8;
3420  }
3421 
3422  return drwav__write_u64ne_to_le(pWav, value);
3423 }
3424 #endif
3425 
3426 DRWAV_PRIVATE size_t drwav__write_or_count_f32ne_to_le(drwav* pWav, float value)
3427 {
3428  if (pWav == NULL) {
3429  return 4;
3430  }
3431 
3432  return drwav__write_f32ne_to_le(pWav, value);
3433 }
3434 
3435 DRWAV_PRIVATE size_t drwav__write_or_count_string_to_fixed_size_buf(drwav* pWav, char* str, size_t bufFixedSize)
3436 {
3437  size_t len;
3438 
3439  if (pWav == NULL) {
3440  return bufFixedSize;
3441  }
3442 
3443  len = drwav__strlen_clamped(str, bufFixedSize);
3444  drwav__write_or_count(pWav, str, len);
3445 
3446  if (len < bufFixedSize) {
3447  size_t i;
3448  for (i = 0; i < bufFixedSize - len; ++i) {
3449  drwav__write_byte(pWav, 0);
3450  }
3451  }
3452 
3453  return bufFixedSize;
3454 }
3455 
3456 
3457 /* pWav can be NULL meaning just count the bytes that would be written. */
3458 DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav* pWav, drwav_metadata* pMetadatas, drwav_uint32 metadataCount)
3459 {
3460  size_t bytesWritten = 0;
3461  drwav_bool32 hasListAdtl = DRWAV_FALSE;
3462  drwav_bool32 hasListInfo = DRWAV_FALSE;
3463  drwav_uint32 iMetadata;
3464 
3465  if (pMetadatas == NULL || metadataCount == 0) {
3466  return 0;
3467  }
3468 
3469  for (iMetadata = 0; iMetadata < metadataCount; ++iMetadata) {
3470  drwav_metadata* pMetadata = &pMetadatas[iMetadata];
3471  drwav_uint32 chunkSize = 0;
3472 
3474  hasListInfo = DRWAV_TRUE;
3475  }
3476 
3478  hasListAdtl = DRWAV_TRUE;
3479  }
3480 
3481  switch (pMetadata->type) {
3483  {
3484  drwav_uint32 iLoop;
3485 
3487 
3488  bytesWritten += drwav__write_or_count(pWav, "smpl", 4);
3489  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3490 
3491  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.manufacturerId);
3492  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.productId);
3493  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.samplePeriodNanoseconds);
3494  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.midiUnityNote);
3495  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.midiPitchFraction);
3496  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.smpteFormat);
3497  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.smpteOffset);
3498  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.sampleLoopCount);
3500 
3501  for (iLoop = 0; iLoop < pMetadata->data.smpl.sampleLoopCount; ++iLoop) {
3502  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].cuePointId);
3503  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].type);
3504  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].firstSampleByteOffset);
3505  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].lastSampleByteOffset);
3506  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].sampleFraction);
3507  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.smpl.pLoops[iLoop].playCount);
3508  }
3509 
3510  if (pMetadata->data.smpl.samplerSpecificDataSizeInBytes > 0) {
3511  bytesWritten += drwav__write(pWav, pMetadata->data.smpl.pSamplerSpecificData, pMetadata->data.smpl.samplerSpecificDataSizeInBytes);
3512  }
3513  } break;
3514 
3516  {
3517  chunkSize = DRWAV_INST_BYTES;
3518 
3519  bytesWritten += drwav__write_or_count(pWav, "inst", 4);
3520  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3521  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.midiUnityNote, 1);
3522  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.fineTuneCents, 1);
3523  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.gainDecibels, 1);
3524  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.lowNote, 1);
3525  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.highNote, 1);
3526  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.lowVelocity, 1);
3527  bytesWritten += drwav__write_or_count(pWav, &pMetadata->data.inst.highVelocity, 1);
3528  } break;
3529 
3531  {
3532  drwav_uint32 iCuePoint;
3533 
3534  chunkSize = DRWAV_CUE_BYTES + DRWAV_CUE_POINT_BYTES * pMetadata->data.cue.cuePointCount;
3535 
3536  bytesWritten += drwav__write_or_count(pWav, "cue ", 4);
3537  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3538  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.cuePointCount);
3539  for (iCuePoint = 0; iCuePoint < pMetadata->data.cue.cuePointCount; ++iCuePoint) {
3540  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].id);
3541  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].playOrderPosition);
3542  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].dataChunkId, 4);
3543  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].chunkStart);
3544  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].blockStart);
3545  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.cue.pCuePoints[iCuePoint].sampleByteOffset);
3546  }
3547  } break;
3548 
3550  {
3551  chunkSize = DRWAV_ACID_BYTES;
3552 
3553  bytesWritten += drwav__write_or_count(pWav, "acid", 4);
3554  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3555  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.acid.flags);
3556  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.midiUnityNote);
3557  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.reserved1);
3558  bytesWritten += drwav__write_or_count_f32ne_to_le(pWav, pMetadata->data.acid.reserved2);
3559  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.acid.numBeats);
3560  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.meterDenominator);
3561  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.acid.meterNumerator);
3562  bytesWritten += drwav__write_or_count_f32ne_to_le(pWav, pMetadata->data.acid.tempo);
3563  } break;
3564 
3566  {
3567  char reservedBuf[DRWAV_BEXT_RESERVED_BYTES];
3568  drwav_uint32 timeReferenceLow;
3569  drwav_uint32 timeReferenceHigh;
3570 
3571  chunkSize = DRWAV_BEXT_BYTES + pMetadata->data.bext.codingHistorySize;
3572 
3573  bytesWritten += drwav__write_or_count(pWav, "bext", 4);
3574  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3575 
3579  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pOriginationDate, sizeof(pMetadata->data.bext.pOriginationDate));
3580  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pOriginationTime, sizeof(pMetadata->data.bext.pOriginationTime));
3581 
3582  timeReferenceLow = (drwav_uint32)(pMetadata->data.bext.timeReference & 0xFFFFFFFF);
3583  timeReferenceHigh = (drwav_uint32)(pMetadata->data.bext.timeReference >> 32);
3584  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, timeReferenceLow);
3585  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, timeReferenceHigh);
3586 
3587  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.version);
3588  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pUMID, DRWAV_BEXT_UMID_BYTES);
3589  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.loudnessValue);
3590  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.loudnessRange);
3591  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxTruePeakLevel);
3592  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxMomentaryLoudness);
3593  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.bext.maxShortTermLoudness);
3594 
3595  memset(reservedBuf, 0, sizeof(reservedBuf));
3596  bytesWritten += drwav__write_or_count(pWav, reservedBuf, sizeof(reservedBuf));
3597 
3598  if (pMetadata->data.bext.codingHistorySize > 0) {
3599  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.bext.pCodingHistory, pMetadata->data.bext.codingHistorySize);
3600  }
3601  } break;
3602 
3604  {
3606  chunkSize = pMetadata->data.unknown.dataSizeInBytes;
3607 
3608  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
3609  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3610  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.pData, pMetadata->data.unknown.dataSizeInBytes);
3611  }
3612  } break;
3613 
3614  default: break;
3615  }
3616  if ((chunkSize % 2) != 0) {
3617  bytesWritten += drwav__write_or_count_byte(pWav, 0);
3618  }
3619  }
3620 
3621  if (hasListInfo) {
3622  drwav_uint32 chunkSize = 4; /* Start with 4 bytes for "INFO". */
3623  for (iMetadata = 0; iMetadata < metadataCount; ++iMetadata) {
3624  drwav_metadata* pMetadata = &pMetadatas[iMetadata];
3625 
3626  if ((pMetadata->type & drwav_metadata_type_list_all_info_strings)) {
3627  chunkSize += 8; /* For id and string size. */
3628  chunkSize += pMetadata->data.infoText.stringLength + 1; /* Include null terminator. */
3630  chunkSize += 8; /* For id string size. */
3631  chunkSize += pMetadata->data.unknown.dataSizeInBytes;
3632  }
3633 
3634  if ((chunkSize % 2) != 0) {
3635  chunkSize += 1;
3636  }
3637  }
3638 
3639  bytesWritten += drwav__write_or_count(pWav, "LIST", 4);
3640  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3641  bytesWritten += drwav__write_or_count(pWav, "INFO", 4);
3642 
3643  for (iMetadata = 0; iMetadata < metadataCount; ++iMetadata) {
3644  drwav_metadata* pMetadata = &pMetadatas[iMetadata];
3645  drwav_uint32 subchunkSize = 0;
3646 
3648  const char* pID = NULL;
3649 
3650  switch (pMetadata->type) {
3651  case drwav_metadata_type_list_info_software: pID = "ISFT"; break;
3652  case drwav_metadata_type_list_info_copyright: pID = "ICOP"; break;
3653  case drwav_metadata_type_list_info_title: pID = "INAM"; break;
3654  case drwav_metadata_type_list_info_artist: pID = "IART"; break;
3655  case drwav_metadata_type_list_info_comment: pID = "ICMT"; break;
3656  case drwav_metadata_type_list_info_date: pID = "ICRD"; break;
3657  case drwav_metadata_type_list_info_genre: pID = "IGNR"; break;
3658  case drwav_metadata_type_list_info_album: pID = "IPRD"; break;
3659  case drwav_metadata_type_list_info_tracknumber: pID = "ITRK"; break;
3660  default: break;
3661  }
3662 
3663  DRWAV_ASSERT(pID != NULL);
3664 
3665  if (pMetadata->data.infoText.stringLength) {
3666  subchunkSize = pMetadata->data.infoText.stringLength + 1;
3667  bytesWritten += drwav__write_or_count(pWav, pID, 4);
3668  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
3669  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.infoText.pString, pMetadata->data.infoText.stringLength);
3670  bytesWritten += drwav__write_or_count_byte(pWav, '\0');
3671  }
3673  if (pMetadata->data.unknown.dataSizeInBytes) {
3674  subchunkSize = pMetadata->data.unknown.dataSizeInBytes;
3675 
3676  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
3677  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.unknown.dataSizeInBytes);
3678  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.pData, subchunkSize);
3679  }
3680  }
3681 
3682  if ((subchunkSize % 2) != 0) {
3683  bytesWritten += drwav__write_or_count_byte(pWav, 0);
3684  }
3685  }
3686  }
3687 
3688  if (hasListAdtl) {
3689  drwav_uint32 chunkSize = 4; /* start with 4 bytes for "adtl" */
3690 
3691  for (iMetadata = 0; iMetadata < metadataCount; ++iMetadata) {
3692  drwav_metadata* pMetadata = &pMetadatas[iMetadata];
3693 
3694  switch (pMetadata->type)
3695  {
3698  {
3699  chunkSize += 8; /* for id and chunk size */
3700  chunkSize += DRWAV_LIST_LABEL_OR_NOTE_BYTES;
3701 
3702  if (pMetadata->data.labelOrNote.stringLength > 0) {
3703  chunkSize += pMetadata->data.labelOrNote.stringLength + 1;
3704  }
3705  } break;
3706 
3708  {
3709  chunkSize += 8; /* for id and chunk size */
3710  chunkSize += DRWAV_LIST_LABELLED_TEXT_BYTES;
3711 
3712  if (pMetadata->data.labelledCueRegion.stringLength > 0) {
3713  chunkSize += pMetadata->data.labelledCueRegion.stringLength + 1;
3714  }
3715  } break;
3716 
3718  {
3720  chunkSize += 8; /* for id and chunk size */
3721  chunkSize += pMetadata->data.unknown.dataSizeInBytes;
3722  }
3723  } break;
3724 
3725  default: break;
3726  }
3727 
3728  if ((chunkSize % 2) != 0) {
3729  chunkSize += 1;
3730  }
3731  }
3732 
3733  bytesWritten += drwav__write_or_count(pWav, "LIST", 4);
3734  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, chunkSize);
3735  bytesWritten += drwav__write_or_count(pWav, "adtl", 4);
3736 
3737  for (iMetadata = 0; iMetadata < metadataCount; ++iMetadata) {
3738  drwav_metadata* pMetadata = &pMetadatas[iMetadata];
3739  drwav_uint32 subchunkSize = 0;
3740 
3741  switch (pMetadata->type)
3742  {
3745  {
3746  if (pMetadata->data.labelOrNote.stringLength > 0) {
3747  const char *pID = NULL;
3748 
3749  if (pMetadata->type == drwav_metadata_type_list_label) {
3750  pID = "labl";
3751  }
3752  else if (pMetadata->type == drwav_metadata_type_list_note) {
3753  pID = "note";
3754  }
3755 
3756  DRWAV_ASSERT(pID != NULL);
3757  DRWAV_ASSERT(pMetadata->data.labelOrNote.pString != NULL);
3758 
3759  subchunkSize = DRWAV_LIST_LABEL_OR_NOTE_BYTES;
3760 
3761  bytesWritten += drwav__write_or_count(pWav, pID, 4);
3762  subchunkSize += pMetadata->data.labelOrNote.stringLength + 1;
3763  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
3764 
3765  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelOrNote.cuePointId);
3766  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.labelOrNote.pString, pMetadata->data.labelOrNote.stringLength);
3767  bytesWritten += drwav__write_or_count_byte(pWav, '\0');
3768  }
3769  } break;
3770 
3772  {
3773  subchunkSize = DRWAV_LIST_LABELLED_TEXT_BYTES;
3774 
3775  bytesWritten += drwav__write_or_count(pWav, "ltxt", 4);
3776  if (pMetadata->data.labelledCueRegion.stringLength > 0) {
3777  subchunkSize += pMetadata->data.labelledCueRegion.stringLength + 1;
3778  }
3779  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
3780  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelledCueRegion.cuePointId);
3781  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, pMetadata->data.labelledCueRegion.sampleLength);
3782  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.labelledCueRegion.purposeId, 4);
3783  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.country);
3784  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.language);
3785  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.dialect);
3786  bytesWritten += drwav__write_or_count_u16ne_to_le(pWav, pMetadata->data.labelledCueRegion.codePage);
3787 
3788  if (pMetadata->data.labelledCueRegion.stringLength > 0) {
3790 
3791  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.labelledCueRegion.pString, pMetadata->data.labelledCueRegion.stringLength);
3792  bytesWritten += drwav__write_or_count_byte(pWav, '\0');
3793  }
3794  } break;
3795 
3797  {
3799  subchunkSize = pMetadata->data.unknown.dataSizeInBytes;
3800 
3801  DRWAV_ASSERT(pMetadata->data.unknown.pData != NULL);
3802  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.id, 4);
3803  bytesWritten += drwav__write_or_count_u32ne_to_le(pWav, subchunkSize);
3804  bytesWritten += drwav__write_or_count(pWav, pMetadata->data.unknown.pData, subchunkSize);
3805  }
3806  } break;
3807 
3808  default: break;
3809  }
3810 
3811  if ((subchunkSize % 2) != 0) {
3812  bytesWritten += drwav__write_or_count_byte(pWav, 0);
3813  }
3814  }
3815  }
3816 
3817  DRWAV_ASSERT((bytesWritten % 2) == 0);
3818 
3819  return bytesWritten;
3820 }
3821 
3823 {
3824  drwav_uint64 chunkSize = 4 + 24 + (drwav_uint64)drwav__write_or_count_metadata(NULL, pMetadata, metadataCount) + 8 + dataChunkSize + drwav__chunk_padding_size_riff(dataChunkSize); /* 4 = "WAVE". 24 = "fmt " chunk. 8 = "data" + u32 data size. */
3825  if (chunkSize > 0xFFFFFFFFUL) {
3826  chunkSize = 0xFFFFFFFFUL;
3827  }
3828 
3829  return (drwav_uint32)chunkSize; /* Safe cast due to the clamp above. */
3830 }
3831 
3833 {
3834  if (dataChunkSize <= 0xFFFFFFFFUL) {
3835  return (drwav_uint32)dataChunkSize;
3836  } else {
3837  return 0xFFFFFFFFUL;
3838  }
3839 }
3840 
3842 {
3843  drwav_uint64 dataSubchunkPaddingSize = drwav__chunk_padding_size_w64(dataChunkSize);
3844 
3845  return 80 + 24 + dataChunkSize + dataSubchunkPaddingSize; /* +24 because W64 includes the size of the GUID and size fields. */
3846 }
3847 
3849 {
3850  return 24 + dataChunkSize; /* +24 because W64 includes the size of the GUID and size fields. */
3851 }
3852 
3854 {
3855  drwav_uint64 chunkSize = 4 + 36 + 24 + (drwav_uint64)drwav__write_or_count_metadata(NULL, metadata, numMetadata) + 8 + dataChunkSize + drwav__chunk_padding_size_riff(dataChunkSize); /* 4 = "WAVE". 36 = "ds64" chunk. 24 = "fmt " chunk. 8 = "data" + u32 data size. */
3856  if (chunkSize > 0xFFFFFFFFUL) {
3857  chunkSize = 0xFFFFFFFFUL;
3858  }
3859 
3860  return chunkSize;
3861 }
3862 
3864 {
3865  return dataChunkSize;
3866 }
3867 
3868 
3869 
3870 DRWAV_PRIVATE drwav_bool32 drwav_preinit_write(drwav* pWav, const drwav_data_format* pFormat, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
3871 {
3872  if (pWav == NULL || onWrite == NULL) {
3873  return DRWAV_FALSE;
3874  }
3875 
3876  if (!isSequential && onSeek == NULL) {
3877  return DRWAV_FALSE; /* <-- onSeek is required when in non-sequential mode. */
3878  }
3879 
3880  /* Not currently supporting compressed formats. Will need to add support for the "fact" chunk before we enable this. */
3881  if (pFormat->format == DR_WAVE_FORMAT_EXTENSIBLE) {
3882  return DRWAV_FALSE;
3883  }
3884  if (pFormat->format == DR_WAVE_FORMAT_ADPCM || pFormat->format == DR_WAVE_FORMAT_DVI_ADPCM) {
3885  return DRWAV_FALSE;
3886  }
3887 
3888  DRWAV_ZERO_MEMORY(pWav, sizeof(*pWav));
3889  pWav->onWrite = onWrite;
3890  pWav->onSeek = onSeek;
3891  pWav->pUserData = pUserData;
3893 
3895  return DRWAV_FALSE; /* Invalid allocation callbacks. */
3896  }
3897 
3898  pWav->fmt.formatTag = (drwav_uint16)pFormat->format;
3899  pWav->fmt.channels = (drwav_uint16)pFormat->channels;
3900  pWav->fmt.sampleRate = pFormat->sampleRate;
3901  pWav->fmt.avgBytesPerSec = (drwav_uint32)((pFormat->bitsPerSample * pFormat->sampleRate * pFormat->channels) / 8);
3902  pWav->fmt.blockAlign = (drwav_uint16)((pFormat->channels * pFormat->bitsPerSample) / 8);
3903  pWav->fmt.bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
3904  pWav->fmt.extendedSize = 0;
3905  pWav->isSequentialWrite = isSequential;
3906 
3907  return DRWAV_TRUE;
3908 }
3909 
3910 
3912 {
3913  /* The function assumes drwav_preinit_write() was called beforehand. */
3914 
3915  size_t runningPos = 0;
3916  drwav_uint64 initialDataChunkSize = 0;
3917  drwav_uint64 chunkSizeFMT;
3918 
3919  /*
3920  The initial values for the "RIFF" and "data" chunks depends on whether or not we are initializing in sequential mode or not. In
3921  sequential mode we set this to its final values straight away since they can be calculated from the total sample count. In non-
3922  sequential mode we initialize it all to zero and fill it out in drwav_uninit() using a backwards seek.
3923  */
3924  if (pWav->isSequentialWrite) {
3925  initialDataChunkSize = (totalSampleCount * pWav->fmt.bitsPerSample) / 8;
3926 
3927  /*
3928  The RIFF container has a limit on the number of samples. drwav is not allowing this. There's no practical limits for Wave64
3929  so for the sake of simplicity I'm not doing any validation for that.
3930  */
3931  if (pFormat->container == drwav_container_riff) {
3932  if (initialDataChunkSize > (0xFFFFFFFFUL - 36)) {
3933  return DRWAV_FALSE; /* Not enough room to store every sample. */
3934  }
3935  }
3936  }
3937 
3938  pWav->dataChunkDataSizeTargetWrite = initialDataChunkSize;
3939 
3940 
3941  /* "RIFF" chunk. */
3942  if (pFormat->container == drwav_container_riff) {
3943  drwav_uint32 chunkSizeRIFF = 28 + (drwav_uint32)initialDataChunkSize; /* +28 = "WAVE" + [sizeof "fmt " chunk] */
3944  runningPos += drwav__write(pWav, "RIFF", 4);
3945  runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeRIFF);
3946  runningPos += drwav__write(pWav, "WAVE", 4);
3947  } else if (pFormat->container == drwav_container_w64) {
3948  drwav_uint64 chunkSizeRIFF = 80 + 24 + initialDataChunkSize; /* +24 because W64 includes the size of the GUID and size fields. */
3949  runningPos += drwav__write(pWav, drwavGUID_W64_RIFF, 16);
3950  runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeRIFF);
3951  runningPos += drwav__write(pWav, drwavGUID_W64_WAVE, 16);
3952  } else if (pFormat->container == drwav_container_rf64) {
3953  runningPos += drwav__write(pWav, "RF64", 4);
3954  runningPos += drwav__write_u32ne_to_le(pWav, 0xFFFFFFFF); /* Always 0xFFFFFFFF for RF64. Set to a proper value in the "ds64" chunk. */
3955  runningPos += drwav__write(pWav, "WAVE", 4);
3956  }
3957 
3958 
3959  /* "ds64" chunk (RF64 only). */
3960  if (pFormat->container == drwav_container_rf64) {
3961  drwav_uint32 initialds64ChunkSize = 28; /* 28 = [Size of RIFF (8 bytes)] + [Size of DATA (8 bytes)] + [Sample Count (8 bytes)] + [Table Length (4 bytes)]. Table length always set to 0. */
3962  drwav_uint64 initialRiffChunkSize = 8 + initialds64ChunkSize + initialDataChunkSize; /* +8 for the ds64 header. */
3963 
3964  runningPos += drwav__write(pWav, "ds64", 4);
3965  runningPos += drwav__write_u32ne_to_le(pWav, initialds64ChunkSize); /* Size of ds64. */
3966  runningPos += drwav__write_u64ne_to_le(pWav, initialRiffChunkSize); /* Size of RIFF. Set to true value at the end. */
3967  runningPos += drwav__write_u64ne_to_le(pWav, initialDataChunkSize); /* Size of DATA. Set to true value at the end. */
3968  runningPos += drwav__write_u64ne_to_le(pWav, totalSampleCount); /* Sample count. */
3969  runningPos += drwav__write_u32ne_to_le(pWav, 0); /* Table length. Always set to zero in our case since we're not doing any other chunks than "DATA". */
3970  }
3971 
3972 
3973  /* "fmt " chunk. */
3974  if (pFormat->container == drwav_container_riff || pFormat->container == drwav_container_rf64) {
3975  chunkSizeFMT = 16;
3976  runningPos += drwav__write(pWav, "fmt ", 4);
3977  runningPos += drwav__write_u32ne_to_le(pWav, (drwav_uint32)chunkSizeFMT);
3978  } else if (pFormat->container == drwav_container_w64) {
3979  chunkSizeFMT = 40;
3980  runningPos += drwav__write(pWav, drwavGUID_W64_FMT, 16);
3981  runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeFMT);
3982  }
3983 
3984  runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.formatTag);
3985  runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.channels);
3986  runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.sampleRate);
3987  runningPos += drwav__write_u32ne_to_le(pWav, pWav->fmt.avgBytesPerSec);
3988  runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.blockAlign);
3989  runningPos += drwav__write_u16ne_to_le(pWav, pWav->fmt.bitsPerSample);
3990 
3991  /* TODO: is a 'fact' chunk required for DR_WAVE_FORMAT_IEEE_FLOAT? */
3992 
3993  if (!pWav->isSequentialWrite && pWav->pMetadata != NULL && pWav->metadataCount > 0 && (pFormat->container == drwav_container_riff || pFormat->container == drwav_container_rf64)) {
3994  runningPos += drwav__write_or_count_metadata(pWav, pWav->pMetadata, pWav->metadataCount);
3995  }
3996 
3997  pWav->dataChunkDataPos = runningPos;
3998 
3999  /* "data" chunk. */
4000  if (pFormat->container == drwav_container_riff) {
4001  drwav_uint32 chunkSizeDATA = (drwav_uint32)initialDataChunkSize;
4002  runningPos += drwav__write(pWav, "data", 4);
4003  runningPos += drwav__write_u32ne_to_le(pWav, chunkSizeDATA);
4004  } else if (pFormat->container == drwav_container_w64) {
4005  drwav_uint64 chunkSizeDATA = 24 + initialDataChunkSize; /* +24 because W64 includes the size of the GUID and size fields. */
4006  runningPos += drwav__write(pWav, drwavGUID_W64_DATA, 16);
4007  runningPos += drwav__write_u64ne_to_le(pWav, chunkSizeDATA);
4008  } else if (pFormat->container == drwav_container_rf64) {
4009  runningPos += drwav__write(pWav, "data", 4);
4010  runningPos += drwav__write_u32ne_to_le(pWav, 0xFFFFFFFF); /* Always set to 0xFFFFFFFF for RF64. The true size of the data chunk is specified in the ds64 chunk. */
4011  }
4012 
4013  /* Set some properties for the client's convenience. */
4014  pWav->container = pFormat->container;
4015  pWav->channels = (drwav_uint16)pFormat->channels;
4016  pWav->sampleRate = pFormat->sampleRate;
4017  pWav->bitsPerSample = (drwav_uint16)pFormat->bitsPerSample;
4018  pWav->translatedFormatTag = (drwav_uint16)pFormat->format;
4019  pWav->dataChunkDataPos = runningPos;
4020 
4021  return DRWAV_TRUE;
4022 }
4023 
4024 
4025 DRWAV_API drwav_bool32 drwav_init_write(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
4026 {
4027  if (!drwav_preinit_write(pWav, pFormat, DRWAV_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
4028  return DRWAV_FALSE;
4029  }
4030 
4031  return drwav_init_write__internal(pWav, pFormat, 0); /* DRWAV_FALSE = Not Sequential */
4032 }
4033 
4034 DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
4035 {
4036  if (!drwav_preinit_write(pWav, pFormat, DRWAV_TRUE, onWrite, NULL, pUserData, pAllocationCallbacks)) {
4037  return DRWAV_FALSE;
4038  }
4039 
4040  return drwav_init_write__internal(pWav, pFormat, totalSampleCount); /* DRWAV_TRUE = Sequential */
4041 }
4042 
4043 DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav* pWav, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks)
4044 {
4045  if (pFormat == NULL) {
4046  return DRWAV_FALSE;
4047  }
4048 
4049  return drwav_init_write_sequential(pWav, pFormat, totalPCMFrameCount*pFormat->channels, onWrite, pUserData, pAllocationCallbacks);
4050 }
4051 
4052 DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav* pWav, const drwav_data_format* pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void* pUserData, const drwav_allocation_callbacks* pAllocationCallbacks, drwav_metadata* pMetadata, drwav_uint32 metadataCount)
4053 {
4054  if (!drwav_preinit_write(pWav, pFormat, DRWAV_FALSE, onWrite, onSeek, pUserData, pAllocationCallbacks)) {
4055  return DRWAV_FALSE;
4056  }
4057 
4058  pWav->pMetadata = pMetadata;
4059  pWav->metadataCount = metadataCount;
4060 
4061  return drwav_init_write__internal(pWav, pFormat, 0);
4062 }
4063 
4064 
4065 DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format* pFormat, drwav_uint64 totalFrameCount, drwav_metadata* pMetadata, drwav_uint32 metadataCount)
4066 {
4067  /* Casting totalFrameCount to drwav_int64 for VC6 compatibility. No issues in practice because nobody is going to exhaust the whole 63 bits. */
4068  drwav_uint64 targetDataSizeBytes = (drwav_uint64)((drwav_int64)totalFrameCount * pFormat->channels * pFormat->bitsPerSample/8.0);
4069  drwav_uint64 riffChunkSizeBytes;
4070  drwav_uint64 fileSizeBytes = 0;
4071 
4072  if (pFormat->container == drwav_container_riff) {
4073  riffChunkSizeBytes = drwav__riff_chunk_size_riff(targetDataSizeBytes, pMetadata, metadataCount);
4074  fileSizeBytes = (8 + riffChunkSizeBytes); /* +8 because WAV doesn't include the size of the ChunkID and ChunkSize fields. */
4075  } else if (pFormat->container == drwav_container_w64) {
4076  riffChunkSizeBytes = drwav__riff_chunk_size_w64(targetDataSizeBytes);
4077  fileSizeBytes = riffChunkSizeBytes;
4078  } else if (pFormat->container == drwav_container_rf64) {
4079  riffChunkSizeBytes = drwav__riff_chunk_size_rf64(targetDataSizeBytes, pMetadata, metadataCount);
4080  fileSizeBytes = (8 + riffChunkSizeBytes); /* +8 because WAV doesn't include the size of the ChunkID and ChunkSize fields. */
4081  }
4082 
4083  return fileSizeBytes;
4084 }
4085 
4086 
4087 #ifndef DR_WAV_NO_STDIO
4088 
4089 /* drwav_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */
4090 #include <errno.h>
4092 {
4093  switch (e)
4094  {
4095  case 0: return DRWAV_SUCCESS;
4096  #ifdef EPERM
4097  case EPERM: return DRWAV_INVALID_OPERATION;
4098  #endif
4099  #ifdef ENOENT
4100  case ENOENT: return DRWAV_DOES_NOT_EXIST;
4101  #endif
4102  #ifdef ESRCH
4103  case ESRCH: return DRWAV_DOES_NOT_EXIST;
4104  #endif
4105  #ifdef EINTR
4106  case EINTR: return DRWAV_INTERRUPT;
4107  #endif
4108  #ifdef EIO
4109  case EIO: return DRWAV_IO_ERROR;
4110  #endif
4111  #ifdef ENXIO
4112  case ENXIO: return DRWAV_DOES_NOT_EXIST;
4113  #endif
4114  #ifdef E2BIG
4115  case E2BIG: return DRWAV_INVALID_ARGS;
4116  #endif
4117  #ifdef ENOEXEC
4118  case ENOEXEC: return DRWAV_INVALID_FILE;
4119  #endif
4120  #ifdef EBADF
4121  case EBADF: return DRWAV_INVALID_FILE;
4122  #endif
4123  #ifdef ECHILD
4124  case ECHILD: return DRWAV_ERROR;
4125  #endif
4126  #ifdef EAGAIN
4127  case EAGAIN: return DRWAV_UNAVAILABLE;
4128  #endif
4129  #ifdef ENOMEM
4130  case ENOMEM: return DRWAV_OUT_OF_MEMORY;
4131  #endif
4132  #ifdef EACCES
4133  case EACCES: return DRWAV_ACCESS_DENIED;
4134  #endif
4135  #ifdef EFAULT
4136  case EFAULT: return DRWAV_BAD_ADDRESS;
4137  #endif
4138  #ifdef ENOTBLK
4139  case ENOTBLK: return DRWAV_ERROR;
4140  #endif
4141  #ifdef EBUSY
4142  case EBUSY: return DRWAV_BUSY;
4143  #endif
4144  #ifdef EEXIST
4145  case EEXIST: return DRWAV_ALREADY_EXISTS;
4146  #endif
4147  #ifdef EXDEV
4148  case EXDEV: return DRWAV_ERROR;
4149  #endif
4150  #ifdef ENODEV
4151  case ENODEV: return DRWAV_DOES_NOT_EXIST;
4152  #endif
4153  #ifdef ENOTDIR
4154  case ENOTDIR: return DRWAV_NOT_DIRECTORY;
4155  #endif
4156  #ifdef EISDIR
4157  case EISDIR: return DRWAV_IS_DIRECTORY;
4158  #endif
4159  #ifdef EINVAL
4160  case EINVAL: return DRWAV_INVALID_ARGS;
4161  #endif
4162  #ifdef ENFILE
4163  case ENFILE: return DRWAV_TOO_MANY_OPEN_FILES;
4164  #endif
4165  #ifdef EMFILE
4166  case EMFILE: return DRWAV_TOO_MANY_OPEN_FILES;
4167  #endif
4168  #ifdef ENOTTY
4169  case ENOTTY: return DRWAV_INVALID_OPERATION;
4170  #endif
4171  #ifdef ETXTBSY
4172  case ETXTBSY: return DRWAV_BUSY;
4173  #endif
4174  #ifdef EFBIG
4175  case EFBIG: return DRWAV_TOO_BIG;
4176  #endif
4177  #ifdef ENOSPC
4178  case ENOSPC: return DRWAV_NO_SPACE;
4179  #endif
4180  #ifdef ESPIPE
4181  case ESPIPE: return DRWAV_BAD_SEEK;
4182  #endif
4183  #ifdef EROFS
4184  case EROFS: return DRWAV_ACCESS_DENIED;
4185  #endif
4186  #ifdef EMLINK
4187  case EMLINK: return DRWAV_TOO_MANY_LINKS;
4188  #endif
4189  #ifdef EPIPE
4190  case EPIPE: return DRWAV_BAD_PIPE;
4191  #endif
4192  #ifdef EDOM
4193  case EDOM: return DRWAV_OUT_OF_RANGE;
4194  #endif
4195  #ifdef ERANGE
4196  case ERANGE: return DRWAV_OUT_OF_RANGE;
4197  #endif
4198  #ifdef EDEADLK
4199  case EDEADLK: return DRWAV_DEADLOCK;
4200  #endif
4201  #ifdef ENAMETOOLONG
4202  case ENAMETOOLONG: return DRWAV_PATH_TOO_LONG;
4203  #endif
4204  #ifdef ENOLCK
4205  case ENOLCK: return DRWAV_ERROR;
4206  #endif
4207  #ifdef ENOSYS
4208  case ENOSYS: return DRWAV_NOT_IMPLEMENTED;
4209  #endif
4210  #ifdef ENOTEMPTY
4211  case ENOTEMPTY: return DRWAV_DIRECTORY_NOT_EMPTY;
4212  #endif
4213  #ifdef ELOOP
4214  case ELOOP: return DRWAV_TOO_MANY_LINKS;
4215  #endif
4216  #ifdef ENOMSG
4217  case ENOMSG: return DRWAV_NO_MESSAGE;
4218  #endif
4219  #ifdef EIDRM
4220  case EIDRM: return DRWAV_ERROR;
4221  #endif
4222  #ifdef ECHRNG
4223  case ECHRNG: return DRWAV_ERROR;
4224  #endif
4225  #ifdef EL2NSYNC
4226  case EL2NSYNC: return DRWAV_ERROR;
4227  #endif
4228  #ifdef EL3HLT
4229  case EL3HLT: return DRWAV_ERROR;
4230  #endif
4231  #ifdef EL3RST
4232  case EL3RST: return DRWAV_ERROR;
4233  #endif
4234  #ifdef ELNRNG
4235  case ELNRNG: return DRWAV_OUT_OF_RANGE;
4236  #endif
4237  #ifdef EUNATCH
4238  case EUNATCH: return DRWAV_ERROR;
4239  #endif
4240  #ifdef ENOCSI
4241  case ENOCSI: return DRWAV_ERROR;
4242  #endif
4243  #ifdef EL2HLT
4244  case EL2HLT: return DRWAV_ERROR;
4245  #endif
4246  #ifdef EBADE
4247  case EBADE: return DRWAV_ERROR;
4248  #endif
4249  #ifdef EBADR
4250  case EBADR: return DRWAV_ERROR;
4251  #endif
4252  #ifdef EXFULL
4253  case EXFULL: return DRWAV_ERROR;
4254  #endif
4255  #ifdef ENOANO
4256  case ENOANO: return DRWAV_ERROR;
4257  #endif
4258  #ifdef EBADRQC
4259  case EBADRQC: return DRWAV_ERROR;
4260  #endif
4261  #ifdef EBADSLT
4262  case EBADSLT: return DRWAV_ERROR;
4263  #endif
4264  #ifdef EBFONT
4265  case EBFONT: return DRWAV_INVALID_FILE;
4266  #endif
4267  #ifdef ENOSTR
4268  case ENOSTR: return DRWAV_ERROR;
4269  #endif
4270  #ifdef ENODATA
4271  case ENODATA: return DRWAV_NO_DATA_AVAILABLE;
4272  #endif
4273  #ifdef ETIME
4274  case ETIME: return DRWAV_TIMEOUT;
4275  #endif
4276  #ifdef ENOSR
4277  case ENOSR: return DRWAV_NO_DATA_AVAILABLE;
4278  #endif
4279  #ifdef ENONET
4280  case ENONET: return DRWAV_NO_NETWORK;
4281  #endif
4282  #ifdef ENOPKG
4283  case ENOPKG: return DRWAV_ERROR;
4284  #endif
4285  #ifdef EREMOTE
4286  case EREMOTE: return DRWAV_ERROR;
4287  #endif
4288  #ifdef ENOLINK
4289  case ENOLINK: return DRWAV_ERROR;
4290  #endif
4291  #ifdef EADV
4292  case EADV: return DRWAV_ERROR;
4293  #endif
4294  #ifdef ESRMNT
4295  case ESRMNT: return DRWAV_ERROR;
4296  #endif
4297  #ifdef ECOMM
4298  case ECOMM: return DRWAV_ERROR;
4299  #endif
4300  #ifdef EPROTO
4301  case EPROTO: return DRWAV_ERROR;
4302  #endif
4303  #ifdef EMULTIHOP
4304  case EMULTIHOP: return DRWAV_ERROR;
4305  #endif
4306  #ifdef EDOTDOT
4307  case EDOTDOT: return DRWAV_ERROR;
4308  #endif
4309  #ifdef EBADMSG
4310  case EBADMSG: return DRWAV_BAD_MESSAGE;
4311  #endif
4312  #ifdef EOVERFLOW
4313  case EOVERFLOW: return DRWAV_TOO_BIG;
4314  #endif
4315  #ifdef ENOTUNIQ
4316  case ENOTUNIQ: return DRWAV_NOT_UNIQUE;
4317  #endif
4318  #ifdef EBADFD
4319  case EBADFD: return DRWAV_ERROR;
4320  #endif
4321  #ifdef EREMCHG
4322  case EREMCHG: return DRWAV_ERROR;
4323  #endif
4324  #ifdef ELIBACC
4325  case ELIBACC: return DRWAV_ACCESS_DENIED;
4326  #endif
4327  #ifdef ELIBBAD
4328  case ELIBBAD: return DRWAV_INVALID_FILE;
4329  #endif
4330  #ifdef ELIBSCN
4331  case ELIBSCN: return DRWAV_INVALID_FILE;
4332  #endif
4333  #ifdef ELIBMAX
4334  case ELIBMAX: return DRWAV_ERROR;
4335  #endif
4336  #ifdef ELIBEXEC
4337  case ELIBEXEC: return DRWAV_ERROR;
4338  #endif
4339  #ifdef EILSEQ
4340  case EILSEQ: return DRWAV_INVALID_DATA;
4341  #endif
4342  #ifdef ERESTART
4343  case ERESTART: return DRWAV_ERROR;
4344  #endif
4345  #ifdef ESTRPIPE
4346  case ESTRPIPE: return DRWAV_ERROR;
4347  #endif
4348  #ifdef EUSERS
4349  case EUSERS: return DRWAV_ERROR;
4350  #endif
4351  #ifdef ENOTSOCK
4352  case ENOTSOCK: return DRWAV_NOT_SOCKET;
4353  #endif
4354  #ifdef EDESTADDRREQ
4355  case EDESTADDRREQ: return DRWAV_NO_ADDRESS;
4356  #endif
4357  #ifdef EMSGSIZE
4358  case EMSGSIZE: return DRWAV_TOO_BIG;
4359  #endif
4360  #ifdef EPROTOTYPE
4361  case EPROTOTYPE: return DRWAV_BAD_PROTOCOL;
4362  #endif
4363  #ifdef ENOPROTOOPT
4364  case ENOPROTOOPT: return DRWAV_PROTOCOL_UNAVAILABLE;
4365  #endif
4366  #ifdef EPROTONOSUPPORT
4367  case EPROTONOSUPPORT: return DRWAV_PROTOCOL_NOT_SUPPORTED;
4368  #endif
4369  #ifdef ESOCKTNOSUPPORT
4370  case ESOCKTNOSUPPORT: return DRWAV_SOCKET_NOT_SUPPORTED;
4371  #endif
4372  #ifdef EOPNOTSUPP
4373  case EOPNOTSUPP: return DRWAV_INVALID_OPERATION;
4374  #endif
4375  #ifdef EPFNOSUPPORT
4376  case EPFNOSUPPORT: return DRWAV_PROTOCOL_FAMILY_NOT_SUPPORTED;
4377  #endif
4378  #ifdef EAFNOSUPPORT
4379  case EAFNOSUPPORT: return DRWAV_ADDRESS_FAMILY_NOT_SUPPORTED;
4380  #endif
4381  #ifdef EADDRINUSE
4382  case EADDRINUSE: return DRWAV_ALREADY_IN_USE;
4383  #endif
4384  #ifdef EADDRNOTAVAIL
4385  case EADDRNOTAVAIL: return DRWAV_ERROR;
4386  #endif
4387  #ifdef ENETDOWN
4388  case ENETDOWN: return DRWAV_NO_NETWORK;
4389  #endif
4390  #ifdef ENETUNREACH
4391  case ENETUNREACH: return DRWAV_NO_NETWORK;
4392  #endif
4393  #ifdef ENETRESET
4394  case ENETRESET: return DRWAV_NO_NETWORK;
4395  #endif
4396  #ifdef ECONNABORTED
4397  case ECONNABORTED: return DRWAV_NO_NETWORK;
4398  #endif
4399  #ifdef ECONNRESET
4400  case ECONNRESET: return DRWAV_CONNECTION_RESET;
4401  #endif
4402  #ifdef ENOBUFS
4403  case ENOBUFS: return DRWAV_NO_SPACE;
4404  #endif
4405  #ifdef EISCONN
4406  case EISCONN: return DRWAV_ALREADY_CONNECTED;
4407  #endif
4408  #ifdef ENOTCONN
4409  case ENOTCONN: return DRWAV_NOT_CONNECTED;
4410  #endif
4411  #ifdef ESHUTDOWN
4412  case ESHUTDOWN: return DRWAV_ERROR;
4413  #endif
4414  #ifdef ETOOMANYREFS
4415  case ETOOMANYREFS: return DRWAV_ERROR;
4416  #endif
4417  #ifdef ETIMEDOUT
4418  case ETIMEDOUT: return DRWAV_TIMEOUT;
4419  #endif
4420  #ifdef ECONNREFUSED
4421  case ECONNREFUSED: return DRWAV_CONNECTION_REFUSED;
4422  #endif
4423  #ifdef EHOSTDOWN
4424  case EHOSTDOWN: return DRWAV_NO_HOST;
4425  #endif
4426  #ifdef EHOSTUNREACH
4427  case EHOSTUNREACH: return DRWAV_NO_HOST;
4428  #endif
4429  #ifdef EALREADY
4430  case EALREADY: return DRWAV_IN_PROGRESS;
4431  #endif
4432  #ifdef EINPROGRESS
4433  case EINPROGRESS: return DRWAV_IN_PROGRESS;
4434  #endif
4435  #ifdef ESTALE
4436  case ESTALE: return DRWAV_INVALID_FILE;
4437  #endif
4438  #ifdef EUCLEAN
4439  case EUCLEAN: return DRWAV_ERROR;
4440  #endif
4441  #ifdef ENOTNAM
4442  case ENOTNAM: return DRWAV_ERROR;
4443  #endif
4444  #ifdef ENAVAIL
4445  case ENAVAIL: return DRWAV_ERROR;
4446  #endif
4447  #ifdef EISNAM
4448  case EISNAM: return DRWAV_ERROR;
4449  #endif
4450  #ifdef EREMOTEIO
4451  case EREMOTEIO: return DRWAV_IO_ERROR;
4452  #endif
4453  #ifdef EDQUOT
4454  case EDQUOT: return DRWAV_NO_SPACE;
4455  #endif
4456  #ifdef ENOMEDIUM
4457  case ENOMEDIUM: return DRWAV_DOES_NOT_EXIST;
4458  #endif
4459  #ifdef EMEDIUMTYPE
4460  case EMEDIUMTYPE: return DRWAV_ERROR;
4461  #endif
4462  #ifdef ECANCELED
4463  case ECANCELED: return DRWAV_CANCELLED;
4464  #endif
4465  #ifdef ENOKEY
4466  case ENOKEY: return DRWAV_ERROR;
4467  #endif
4468  #ifdef EKEYEXPIRED
4469  case EKEYEXPIRED: return DRWAV_ERROR;
4470  #endif
4471  #ifdef EKEYREVOKED
4472  case EKEYREVOKED: return DRWAV_ERROR;
4473  #endif
4474  #ifdef EKEYREJECTED
4475  case EKEYREJECTED: return DRWAV_ERROR;
4476  #endif
4477  #ifdef EOWNERDEAD
4478  case EOWNERDEAD: return DRWAV_ERROR;
4479  #endif
4480  #ifdef ENOTRECOVERABLE
4481  case ENOTRECOVERABLE: return DRWAV_ERROR;
4482  #endif
4483  #ifdef ERFKILL
4484  case ERFKILL: return DRWAV_ERROR;
4485  #endif
4486  #ifdef EHWPOISON
4487  case EHWPOISON: return DRWAV_ERROR;
4488  #endif
4489  default: return DRWAV_ERROR;
4490  }
4491 }
4492 
4493 DRWAV_PRIVATE drwav_result drwav_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
4494 {
4495 #if defined(_MSC_VER) && _MSC_VER >= 1400
4496  errno_t err;
4497 #endif
4498 
4499  if (ppFile != NULL) {
4500  *ppFile = NULL; /* Safety. */
4501  }
4502 
4503  if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
4504  return DRWAV_INVALID_ARGS;
4505  }
4506 
4507 #if defined(_MSC_VER) && _MSC_VER >= 1400
4508  err = fopen_s(ppFile, pFilePath, pOpenMode);
4509  if (err != 0) {
4510  return drwav_result_from_errno(err);
4511  }
4512 #else
4513 #if defined(_WIN32) || defined(__APPLE__)
4514  *ppFile = fopen(pFilePath, pOpenMode);
4515 #else
4516  #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
4517  *ppFile = fopen64(pFilePath, pOpenMode);
4518  #else
4519  *ppFile = fopen(pFilePath, pOpenMode);
4520  #endif
4521 #endif
4522  if (*ppFile == NULL) {
4524  if (result == DRWAV_SUCCESS) {
4525  result = DRWAV_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
4526  }
4527 
4528  return result;
4529  }
4530 #endif
4531 
4532  return DRWAV_SUCCESS;
4533 }
4534 
4535 /*
4536 _wfopen() isn't always available in all compilation environments.
4537 
4538  * Windows only.
4539  * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
4540  * MinGW-64 (both 32- and 64-bit) seems to support it.
4541  * MinGW wraps it in !defined(__STRICT_ANSI__).
4542  * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
4543 
4544 This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
4545 fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
4546 */
4547 #if defined(_WIN32)
4548  #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
4549  #define DRWAV_HAS_WFOPEN
4550  #endif
4551 #endif
4552 
4553 DRWAV_PRIVATE drwav_result drwav_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drwav_allocation_callbacks* pAllocationCallbacks)
4554 {
4555  if (ppFile != NULL) {
4556  *ppFile = NULL; /* Safety. */
4557  }
4558 
4559  if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
4560  return DRWAV_INVALID_ARGS;
4561  }
4562 
4563 #if defined(DRWAV_HAS_WFOPEN)
4564  {
4565  /* Use _wfopen() on Windows. */
4566  #if defined(_MSC_VER) && _MSC_VER >= 1400
4567  errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
4568  if (err != 0) {
4569  return drwav_result_from_errno(err);
4570  }
4571  #else
4572  *ppFile = _wfopen(pFilePath, pOpenMode);
4573  if (*ppFile == NULL) {
4575  }
4576  #endif
4577  (void)pAllocationCallbacks;
4578  }
4579 #else
4580  /*
4581  Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can
4582  think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
4583  maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility.
4584  */
4585  {
4586  mbstate_t mbs;
4587  size_t lenMB;
4588  const wchar_t* pFilePathTemp = pFilePath;
4589  char* pFilePathMB = NULL;
4590  char pOpenModeMB[32] = {0};
4591 
4592  /* Get the length first. */
4593  DRWAV_ZERO_OBJECT(&mbs);
4594  lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
4595  if (lenMB == (size_t)-1) {
4597  }
4598 
4599  pFilePathMB = (char*)drwav__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
4600  if (pFilePathMB == NULL) {
4601  return DRWAV_OUT_OF_MEMORY;
4602  }
4603 
4604  pFilePathTemp = pFilePath;
4605  DRWAV_ZERO_OBJECT(&mbs);
4606  wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
4607 
4608  /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
4609  {
4610  size_t i = 0;
4611  for (;;) {
4612  if (pOpenMode[i] == 0) {
4613  pOpenModeMB[i] = '\0';
4614  break;
4615  }
4616 
4617  pOpenModeMB[i] = (char)pOpenMode[i];
4618  i += 1;
4619  }
4620  }
4621 
4622  *ppFile = fopen(pFilePathMB, pOpenModeMB);
4623 
4624  drwav__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
4625  }
4626 
4627  if (*ppFile == NULL) {
4628  return DRWAV_ERROR;
4629  }
4630 #endif
4631 
4632  return DRWAV_SUCCESS;
4633 }
4634 
4635 
4636 DRWAV_PRIVATE size_t drwav__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
4637 {
4638  return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
4639 }
4640 
4641 DRWAV_PRIVATE size_t drwav__on_write_stdio(void* pUserData, const void* pData, size_t bytesToWrite)
4642 {
4643  return fwrite(pData, 1, bytesToWrite, (FILE*)pUserData);
4644 }
4645 
4646 DRWAV_PRIVATE drwav_bool32 drwav__on_seek_stdio(void* pUserData, int offset, drwav_seek_origin origin)
4647 {
4648  return fseek((FILE*)pUserData, offset, (origin == drwav_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
4649 }
4650 
4651 DRWAV_API drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks)
4652 {
4653  return drwav_init_file_ex(pWav, filename, NULL, NULL, 0, pAllocationCallbacks);
4654 }
4655 
4656 
4657 DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav* pWav, FILE* pFile, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, drwav_metadata_type allowedMetadataTypes, const drwav_allocation_callbacks* pAllocationCallbacks)
4658 {
4659  drwav_bool32 result;
4660 
4661  result = drwav_preinit(pWav, drwav__on_read_stdio, drwav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
4662  if (result != DRWAV_TRUE) {
4663  fclose(pFile);
4664  return result;
4665  }
4666 
4667  pWav->allowedMetadataTypes = allowedMetadataTypes;
4668 
4669  result = drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
4670  if (result != DRWAV_TRUE) {
4671  fclose(pFile);
4672  return result;
4673  }
4674 
4675  return DRWAV_TRUE;
4676 }
4677 
4678 DRWAV_API drwav_bool32 drwav_init_file_ex(drwav* pWav, const char* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
4679 {
4680  FILE* pFile;
4681  if (drwav_fopen(&pFile, filename, "rb") != DRWAV_SUCCESS) {
4682  return DRWAV_FALSE;
4683  }
4684 
4685  /* This takes ownership of the FILE* object. */
4686  return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, drwav_metadata_type_none, pAllocationCallbacks);
4687 }
4688 
4689 DRWAV_API drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks)
4690 {
4691  return drwav_init_file_ex_w(pWav, filename, NULL, NULL, 0, pAllocationCallbacks);
4692 }
4693 
4694 DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav* pWav, const wchar_t* filename, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
4695 {
4696  FILE* pFile;
4697  if (drwav_wfopen(&pFile, filename, L"rb", pAllocationCallbacks) != DRWAV_SUCCESS) {
4698  return DRWAV_FALSE;
4699  }
4700 
4701  /* This takes ownership of the FILE* object. */
4702  return drwav_init_file__internal_FILE(pWav, pFile, onChunk, pChunkUserData, flags, drwav_metadata_type_none, pAllocationCallbacks);
4703 }
4704 
4705 DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav* pWav, const char* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
4706 {
4707  FILE* pFile;
4708  if (drwav_fopen(&pFile, filename, "rb") != DRWAV_SUCCESS) {
4709  return DRWAV_FALSE;
4710  }
4711 
4712  /* This takes ownership of the FILE* object. */
4713  return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags, drwav_metadata_type_all_including_unknown, pAllocationCallbacks);
4714 }
4715 
4716 DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav* pWav, const wchar_t* filename, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
4717 {
4718  FILE* pFile;
4719  if (drwav_wfopen(&pFile, filename, L"rb", pAllocationCallbacks) != DRWAV_SUCCESS) {
4720  return DRWAV_FALSE;
4721  }
4722 
4723  /* This takes ownership of the FILE* object. */
4724  return drwav_init_file__internal_FILE(pWav, pFile, NULL, NULL, flags, drwav_metadata_type_all_including_unknown, pAllocationCallbacks);
4725 }
4726 
4727 
4728 DRWAV_PRIVATE drwav_bool32 drwav_init_file_write__internal_FILE(drwav* pWav, FILE* pFile, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
4729 {
4730  drwav_bool32 result;
4731 
4732  result = drwav_preinit_write(pWav, pFormat, isSequential, drwav__on_write_stdio, drwav__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
4733  if (result != DRWAV_TRUE) {
4734  fclose(pFile);
4735  return result;
4736  }
4737 
4738  result = drwav_init_write__internal(pWav, pFormat, totalSampleCount);
4739  if (result != DRWAV_TRUE) {
4740  fclose(pFile);
4741  return result;
4742  }
4743 
4744  return DRWAV_TRUE;
4745 }
4746 
4747 DRWAV_PRIVATE drwav_bool32 drwav_init_file_write__internal(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
4748 {
4749  FILE* pFile;
4750  if (drwav_fopen(&pFile, filename, "wb") != DRWAV_SUCCESS) {
4751  return DRWAV_FALSE;
4752  }
4753 
4754  /* This takes ownership of the FILE* object. */
4755  return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
4756 }
4757 
4758 DRWAV_PRIVATE drwav_bool32 drwav_init_file_write_w__internal(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks* pAllocationCallbacks)
4759 {
4760  FILE* pFile;
4761  if (drwav_wfopen(&pFile, filename, L"wb", pAllocationCallbacks) != DRWAV_SUCCESS) {
4762  return DRWAV_FALSE;
4763  }
4764 
4765  /* This takes ownership of the FILE* object. */
4766  return drwav_init_file_write__internal_FILE(pWav, pFile, pFormat, totalSampleCount, isSequential, pAllocationCallbacks);
4767 }
4768 
4769 DRWAV_API drwav_bool32 drwav_init_file_write(drwav* pWav, const char* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
4770 {
4771  return drwav_init_file_write__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
4772 }
4773 
4774 DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
4775 {
4776  return drwav_init_file_write__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
4777 }
4778 
4779 DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav* pWav, const char* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
4780 {
4781  if (pFormat == NULL) {
4782  return DRWAV_FALSE;
4783  }
4784 
4785  return drwav_init_file_write_sequential(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
4786 }
4787 
4788 DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
4789 {
4790  return drwav_init_file_write_w__internal(pWav, filename, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
4791 }
4792 
4793 DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
4794 {
4795  return drwav_init_file_write_w__internal(pWav, filename, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
4796 }
4797 
4798 DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav* pWav, const wchar_t* filename, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
4799 {
4800  if (pFormat == NULL) {
4801  return DRWAV_FALSE;
4802  }
4803 
4804  return drwav_init_file_write_sequential_w(pWav, filename, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
4805 }
4806 #endif /* DR_WAV_NO_STDIO */
4807 
4808 
4809 DRWAV_PRIVATE size_t drwav__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
4810 {
4811  drwav* pWav = (drwav*)pUserData;
4812  size_t bytesRemaining;
4813 
4814  DRWAV_ASSERT(pWav != NULL);
4816 
4817  bytesRemaining = pWav->memoryStream.dataSize - pWav->memoryStream.currentReadPos;
4818  if (bytesToRead > bytesRemaining) {
4819  bytesToRead = bytesRemaining;
4820  }
4821 
4822  if (bytesToRead > 0) {
4823  DRWAV_COPY_MEMORY(pBufferOut, pWav->memoryStream.data + pWav->memoryStream.currentReadPos, bytesToRead);
4824  pWav->memoryStream.currentReadPos += bytesToRead;
4825  }
4826 
4827  return bytesToRead;
4828 }
4829 
4830 DRWAV_PRIVATE drwav_bool32 drwav__on_seek_memory(void* pUserData, int offset, drwav_seek_origin origin)
4831 {
4832  drwav* pWav = (drwav*)pUserData;
4833  DRWAV_ASSERT(pWav != NULL);
4834 
4835  if (origin == drwav_seek_origin_current) {
4836  if (offset > 0) {
4837  if (pWav->memoryStream.currentReadPos + offset > pWav->memoryStream.dataSize) {
4838  return DRWAV_FALSE; /* Trying to seek too far forward. */
4839  }
4840  } else {
4841  if (pWav->memoryStream.currentReadPos < (size_t)-offset) {
4842  return DRWAV_FALSE; /* Trying to seek too far backwards. */
4843  }
4844  }
4845 
4846  /* This will never underflow thanks to the clamps above. */
4847  pWav->memoryStream.currentReadPos += offset;
4848  } else {
4849  if ((drwav_uint32)offset <= pWav->memoryStream.dataSize) {
4850  pWav->memoryStream.currentReadPos = offset;
4851  } else {
4852  return DRWAV_FALSE; /* Trying to seek too far forward. */
4853  }
4854  }
4855 
4856  return DRWAV_TRUE;
4857 }
4858 
4859 DRWAV_PRIVATE size_t drwav__on_write_memory(void* pUserData, const void* pDataIn, size_t bytesToWrite)
4860 {
4861  drwav* pWav = (drwav*)pUserData;
4862  size_t bytesRemaining;
4863 
4864  DRWAV_ASSERT(pWav != NULL);
4866 
4867  bytesRemaining = pWav->memoryStreamWrite.dataCapacity - pWav->memoryStreamWrite.currentWritePos;
4868  if (bytesRemaining < bytesToWrite) {
4869  /* Need to reallocate. */
4870  void* pNewData;
4871  size_t newDataCapacity = (pWav->memoryStreamWrite.dataCapacity == 0) ? 256 : pWav->memoryStreamWrite.dataCapacity * 2;
4872 
4873  /* If doubling wasn't enough, just make it the minimum required size to write the data. */
4874  if ((newDataCapacity - pWav->memoryStreamWrite.currentWritePos) < bytesToWrite) {
4875  newDataCapacity = pWav->memoryStreamWrite.currentWritePos + bytesToWrite;
4876  }
4877 
4879  if (pNewData == NULL) {
4880  return 0;
4881  }
4882 
4883  *pWav->memoryStreamWrite.ppData = pNewData;
4884  pWav->memoryStreamWrite.dataCapacity = newDataCapacity;
4885  }
4886 
4887  DRWAV_COPY_MEMORY(((drwav_uint8*)(*pWav->memoryStreamWrite.ppData)) + pWav->memoryStreamWrite.currentWritePos, pDataIn, bytesToWrite);
4888 
4889  pWav->memoryStreamWrite.currentWritePos += bytesToWrite;
4892  }
4893 
4895 
4896  return bytesToWrite;
4897 }
4898 
4899 DRWAV_PRIVATE drwav_bool32 drwav__on_seek_memory_write(void* pUserData, int offset, drwav_seek_origin origin)
4900 {
4901  drwav* pWav = (drwav*)pUserData;
4902  DRWAV_ASSERT(pWav != NULL);
4903 
4904  if (origin == drwav_seek_origin_current) {
4905  if (offset > 0) {
4906  if (pWav->memoryStreamWrite.currentWritePos + offset > pWav->memoryStreamWrite.dataSize) {
4907  offset = (int)(pWav->memoryStreamWrite.dataSize - pWav->memoryStreamWrite.currentWritePos); /* Trying to seek too far forward. */
4908  }
4909  } else {
4910  if (pWav->memoryStreamWrite.currentWritePos < (size_t)-offset) {
4911  offset = -(int)pWav->memoryStreamWrite.currentWritePos; /* Trying to seek too far backwards. */
4912  }
4913  }
4914 
4915  /* This will never underflow thanks to the clamps above. */
4916  pWav->memoryStreamWrite.currentWritePos += offset;
4917  } else {
4918  if ((drwav_uint32)offset <= pWav->memoryStreamWrite.dataSize) {
4919  pWav->memoryStreamWrite.currentWritePos = offset;
4920  } else {
4921  pWav->memoryStreamWrite.currentWritePos = pWav->memoryStreamWrite.dataSize; /* Trying to seek too far forward. */
4922  }
4923  }
4924 
4925  return DRWAV_TRUE;
4926 }
4927 
4928 DRWAV_API drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks)
4929 {
4930  return drwav_init_memory_ex(pWav, data, dataSize, NULL, NULL, 0, pAllocationCallbacks);
4931 }
4932 
4933 DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav* pWav, const void* data, size_t dataSize, drwav_chunk_proc onChunk, void* pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
4934 {
4935  if (data == NULL || dataSize == 0) {
4936  return DRWAV_FALSE;
4937  }
4938 
4939  if (!drwav_preinit(pWav, drwav__on_read_memory, drwav__on_seek_memory, pWav, pAllocationCallbacks)) {
4940  return DRWAV_FALSE;
4941  }
4942 
4943  pWav->memoryStream.data = (const drwav_uint8*)data;
4944  pWav->memoryStream.dataSize = dataSize;
4945  pWav->memoryStream.currentReadPos = 0;
4946 
4947  return drwav_init__internal(pWav, onChunk, pChunkUserData, flags);
4948 }
4949 
4950 DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav* pWav, const void* data, size_t dataSize, drwav_uint32 flags, const drwav_allocation_callbacks* pAllocationCallbacks)
4951 {
4952  if (data == NULL || dataSize == 0) {
4953  return DRWAV_FALSE;
4954  }
4955 
4956  if (!drwav_preinit(pWav, drwav__on_read_memory, drwav__on_seek_memory, pWav, pAllocationCallbacks)) {
4957  return DRWAV_FALSE;
4958  }
4959 
4960  pWav->memoryStream.data = (const drwav_uint8*)data;
4961  pWav->memoryStream.dataSize = dataSize;
4962  pWav->memoryStream.currentReadPos = 0;
4963 
4965 
4966  return drwav_init__internal(pWav, NULL, NULL, flags);
4967 }
4968 
4969 
4970 DRWAV_PRIVATE 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, const drwav_allocation_callbacks* pAllocationCallbacks)
4971 {
4972  if (ppData == NULL || pDataSize == NULL) {
4973  return DRWAV_FALSE;
4974  }
4975 
4976  *ppData = NULL; /* Important because we're using realloc()! */
4977  *pDataSize = 0;
4978 
4979  if (!drwav_preinit_write(pWav, pFormat, isSequential, drwav__on_write_memory, drwav__on_seek_memory_write, pWav, pAllocationCallbacks)) {
4980  return DRWAV_FALSE;
4981  }
4982 
4983  pWav->memoryStreamWrite.ppData = ppData;
4984  pWav->memoryStreamWrite.pDataSize = pDataSize;
4985  pWav->memoryStreamWrite.dataSize = 0;
4986  pWav->memoryStreamWrite.dataCapacity = 0;
4988 
4989  return drwav_init_write__internal(pWav, pFormat, totalSampleCount);
4990 }
4991 
4992 DRWAV_API drwav_bool32 drwav_init_memory_write(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, const drwav_allocation_callbacks* pAllocationCallbacks)
4993 {
4994  return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, 0, DRWAV_FALSE, pAllocationCallbacks);
4995 }
4996 
4997 DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks* pAllocationCallbacks)
4998 {
4999  return drwav_init_memory_write__internal(pWav, ppData, pDataSize, pFormat, totalSampleCount, DRWAV_TRUE, pAllocationCallbacks);
5000 }
5001 
5002 DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav* pWav, void** ppData, size_t* pDataSize, const drwav_data_format* pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks* pAllocationCallbacks)
5003 {
5004  if (pFormat == NULL) {
5005  return DRWAV_FALSE;
5006  }
5007 
5008  return drwav_init_memory_write_sequential(pWav, ppData, pDataSize, pFormat, totalPCMFrameCount*pFormat->channels, pAllocationCallbacks);
5009 }
5010 
5011 
5012 
5014 {
5015  drwav_result result = DRWAV_SUCCESS;
5016 
5017  if (pWav == NULL) {
5018  return DRWAV_INVALID_ARGS;
5019  }
5020 
5021  /*
5022  If the drwav object was opened in write mode we'll need to finalize a few things:
5023  - Make sure the "data" chunk is aligned to 16-bits for RIFF containers, or 64 bits for W64 containers.
5024  - Set the size of the "data" chunk.
5025  */
5026  if (pWav->onWrite != NULL) {
5027  drwav_uint32 paddingSize = 0;
5028 
5029  /* Padding. Do not adjust pWav->dataChunkDataSize - this should not include the padding. */
5030  if (pWav->container == drwav_container_riff || pWav->container == drwav_container_rf64) {
5032  } else {
5033  paddingSize = drwav__chunk_padding_size_w64(pWav->dataChunkDataSize);
5034  }
5035 
5036  if (paddingSize > 0) {
5037  drwav_uint64 paddingData = 0;
5038  drwav__write(pWav, &paddingData, paddingSize); /* Byte order does not matter for this. */
5039  }
5040 
5041  /*
5042  Chunk sizes. When using sequential mode, these will have been filled in at initialization time. We only need
5043  to do this when using non-sequential mode.
5044  */
5045  if (pWav->onSeek && !pWav->isSequentialWrite) {
5046  if (pWav->container == drwav_container_riff) {
5047  /* The "RIFF" chunk size. */
5048  if (pWav->onSeek(pWav->pUserData, 4, drwav_seek_origin_start)) {
5050  drwav__write_u32ne_to_le(pWav, riffChunkSize);
5051  }
5052 
5053  /* The "data" chunk size. */
5054  if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 4, drwav_seek_origin_start)) {
5056  drwav__write_u32ne_to_le(pWav, dataChunkSize);
5057  }
5058  } else if (pWav->container == drwav_container_w64) {
5059  /* The "RIFF" chunk size. */
5060  if (pWav->onSeek(pWav->pUserData, 16, drwav_seek_origin_start)) {
5062  drwav__write_u64ne_to_le(pWav, riffChunkSize);
5063  }
5064 
5065  /* The "data" chunk size. */
5066  if (pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos - 8, drwav_seek_origin_start)) {
5068  drwav__write_u64ne_to_le(pWav, dataChunkSize);
5069  }
5070  } else if (pWav->container == drwav_container_rf64) {
5071  /* We only need to update the ds64 chunk. The "RIFF" and "data" chunks always have their sizes set to 0xFFFFFFFF for RF64. */
5072  int ds64BodyPos = 12 + 8;
5073 
5074  /* The "RIFF" chunk size. */
5075  if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 0, drwav_seek_origin_start)) {
5077  drwav__write_u64ne_to_le(pWav, riffChunkSize);
5078  }
5079 
5080  /* The "data" chunk size. */
5081  if (pWav->onSeek(pWav->pUserData, ds64BodyPos + 8, drwav_seek_origin_start)) {
5083  drwav__write_u64ne_to_le(pWav, dataChunkSize);
5084  }
5085  }
5086  }
5087 
5088  /* Validation for sequential mode. */
5089  if (pWav->isSequentialWrite) {
5090  if (pWav->dataChunkDataSize != pWav->dataChunkDataSizeTargetWrite) {
5091  result = DRWAV_INVALID_FILE;
5092  }
5093  }
5094  } else {
5095  if (pWav->pMetadata != NULL) {
5097  }
5098  }
5099 
5100 #ifndef DR_WAV_NO_STDIO
5101  /*
5102  If we opened the file with drwav_open_file() we will want to close the file handle. We can know whether or not drwav_open_file()
5103  was used by looking at the onRead and onSeek callbacks.
5104  */
5105  if (pWav->onRead == drwav__on_read_stdio || pWav->onWrite == drwav__on_write_stdio) {
5106  fclose((FILE*)pWav->pUserData);
5107  }
5108 #endif
5109 
5110  return result;
5111 }
5112 
5113 
5114 
5115 DRWAV_API size_t drwav_read_raw(drwav* pWav, size_t bytesToRead, void* pBufferOut)
5116 {
5117  size_t bytesRead;
5118 
5119  if (pWav == NULL || bytesToRead == 0) {
5120  return 0; /* Invalid args. */
5121  }
5122 
5123  if (bytesToRead > pWav->bytesRemaining) {
5124  bytesToRead = (size_t)pWav->bytesRemaining;
5125  }
5126 
5127  if (bytesToRead == 0) {
5128  return 0; /* At end. */
5129  }
5130 
5131  if (pBufferOut != NULL) {
5132  bytesRead = pWav->onRead(pWav->pUserData, pBufferOut, bytesToRead);
5133  } else {
5134  /* We need to seek. If we fail, we need to read-and-discard to make sure we get a good byte count. */
5135  bytesRead = 0;
5136  while (bytesRead < bytesToRead) {
5137  size_t bytesToSeek = (bytesToRead - bytesRead);
5138  if (bytesToSeek > 0x7FFFFFFF) {
5139  bytesToSeek = 0x7FFFFFFF;
5140  }
5141 
5142  if (pWav->onSeek(pWav->pUserData, (int)bytesToSeek, drwav_seek_origin_current) == DRWAV_FALSE) {
5143  break;
5144  }
5145 
5146  bytesRead += bytesToSeek;
5147  }
5148 
5149  /* When we get here we may need to read-and-discard some data. */
5150  while (bytesRead < bytesToRead) {
5151  drwav_uint8 buffer[4096];
5152  size_t bytesSeeked;
5153  size_t bytesToSeek = (bytesToRead - bytesRead);
5154  if (bytesToSeek > sizeof(buffer)) {
5155  bytesToSeek = sizeof(buffer);
5156  }
5157 
5158  bytesSeeked = pWav->onRead(pWav->pUserData, buffer, bytesToSeek);
5159  bytesRead += bytesSeeked;
5160 
5161  if (bytesSeeked < bytesToSeek) {
5162  break; /* Reached the end. */
5163  }
5164  }
5165  }
5166 
5167  pWav->readCursorInPCMFrames += bytesRead / drwav_get_bytes_per_pcm_frame(pWav);
5168 
5169  pWav->bytesRemaining -= bytesRead;
5170  return bytesRead;
5171 }
5172 
5173 
5174 
5175 DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
5176 {
5177  drwav_uint32 bytesPerFrame;
5178  drwav_uint64 bytesToRead; /* Intentionally uint64 instead of size_t so we can do a check that we're not reading too much on 32-bit builds. */
5179 
5180  if (pWav == NULL || framesToRead == 0) {
5181  return 0;
5182  }
5183 
5184  /* Cannot use this function for compressed formats. */
5186  return 0;
5187  }
5188 
5189  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
5190  if (bytesPerFrame == 0) {
5191  return 0;
5192  }
5193 
5194  /* Don't try to read more samples than can potentially fit in the output buffer. */
5195  bytesToRead = framesToRead * bytesPerFrame;
5196  if (bytesToRead > DRWAV_SIZE_MAX) {
5197  bytesToRead = (DRWAV_SIZE_MAX / bytesPerFrame) * bytesPerFrame; /* Round the number of bytes to read to a clean frame boundary. */
5198  }
5199 
5200  /*
5201  Doing an explicit check here just to make it clear that we don't want to be attempt to read anything if there's no bytes to read. There
5202  *could* be a time where it evaluates to 0 due to overflowing.
5203  */
5204  if (bytesToRead == 0) {
5205  return 0;
5206  }
5207 
5208  return drwav_read_raw(pWav, (size_t)bytesToRead, pBufferOut) / bytesPerFrame;
5209 }
5210 
5211 DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
5212 {
5213  drwav_uint64 framesRead = drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
5214 
5215  if (pBufferOut != NULL) {
5216  drwav__bswap_samples(pBufferOut, framesRead*pWav->channels, drwav_get_bytes_per_pcm_frame(pWav)/pWav->channels, pWav->translatedFormatTag);
5217  }
5218 
5219  return framesRead;
5220 }
5221 
5222 DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav* pWav, drwav_uint64 framesToRead, void* pBufferOut)
5223 {
5224  if (drwav__is_little_endian()) {
5225  return drwav_read_pcm_frames_le(pWav, framesToRead, pBufferOut);
5226  } else {
5227  return drwav_read_pcm_frames_be(pWav, framesToRead, pBufferOut);
5228  }
5229 }
5230 
5231 
5232 
5234 {
5235  if (pWav->onWrite != NULL) {
5236  return DRWAV_FALSE; /* No seeking in write mode. */
5237  }
5238 
5239  if (!pWav->onSeek(pWav->pUserData, (int)pWav->dataChunkDataPos, drwav_seek_origin_start)) {
5240  return DRWAV_FALSE;
5241  }
5242 
5244  /* Cached data needs to be cleared for compressed formats. */
5246  DRWAV_ZERO_OBJECT(&pWav->msadpcm);
5247  } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
5248  DRWAV_ZERO_OBJECT(&pWav->ima);
5249  } else {
5250  DRWAV_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. */
5251  }
5252  }
5253 
5254  pWav->readCursorInPCMFrames = 0;
5255  pWav->bytesRemaining = pWav->dataChunkDataSize;
5256 
5257  return DRWAV_TRUE;
5258 }
5259 
5261 {
5262  /* Seeking should be compatible with wave files > 2GB. */
5263 
5264  if (pWav == NULL || pWav->onSeek == NULL) {
5265  return DRWAV_FALSE;
5266  }
5267 
5268  /* No seeking in write mode. */
5269  if (pWav->onWrite != NULL) {
5270  return DRWAV_FALSE;
5271  }
5272 
5273  /* If there are no samples, just return DRWAV_TRUE without doing anything. */
5274  if (pWav->totalPCMFrameCount == 0) {
5275  return DRWAV_TRUE;
5276  }
5277 
5278  /* Make sure the sample is clamped. */
5279  if (targetFrameIndex >= pWav->totalPCMFrameCount) {
5280  targetFrameIndex = pWav->totalPCMFrameCount - 1;
5281  }
5282 
5283  /*
5284  For compressed formats we just use a slow generic seek. If we are seeking forward we just seek forward. If we are going backwards we need
5285  to seek back to the start.
5286  */
5288  /* TODO: This can be optimized. */
5289 
5290  /*
5291  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,
5292  we first need to seek back to the start and then just do the same thing as a forward seek.
5293  */
5294  if (targetFrameIndex < pWav->readCursorInPCMFrames) {
5295  if (!drwav_seek_to_first_pcm_frame(pWav)) {
5296  return DRWAV_FALSE;
5297  }
5298  }
5299 
5300  if (targetFrameIndex > pWav->readCursorInPCMFrames) {
5301  drwav_uint64 offsetInFrames = targetFrameIndex - pWav->readCursorInPCMFrames;
5302 
5303  drwav_int16 devnull[2048];
5304  while (offsetInFrames > 0) {
5305  drwav_uint64 framesRead = 0;
5306  drwav_uint64 framesToRead = offsetInFrames;
5307  if (framesToRead > drwav_countof(devnull)/pWav->channels) {
5308  framesToRead = drwav_countof(devnull)/pWav->channels;
5309  }
5310 
5312  framesRead = drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, devnull);
5313  } else if (pWav->translatedFormatTag == DR_WAVE_FORMAT_DVI_ADPCM) {
5314  framesRead = drwav_read_pcm_frames_s16__ima(pWav, framesToRead, devnull);
5315  } else {
5316  DRWAV_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. */
5317  }
5318 
5319  if (framesRead != framesToRead) {
5320  return DRWAV_FALSE;
5321  }
5322 
5323  offsetInFrames -= framesRead;
5324  }
5325  }
5326  } else {
5327  drwav_uint64 totalSizeInBytes;
5328  drwav_uint64 currentBytePos;
5329  drwav_uint64 targetBytePos;
5330  drwav_uint64 offset;
5331 
5332  totalSizeInBytes = pWav->totalPCMFrameCount * drwav_get_bytes_per_pcm_frame(pWav);
5333  DRWAV_ASSERT(totalSizeInBytes >= pWav->bytesRemaining);
5334 
5335  currentBytePos = totalSizeInBytes - pWav->bytesRemaining;
5336  targetBytePos = targetFrameIndex * drwav_get_bytes_per_pcm_frame(pWav);
5337 
5338  if (currentBytePos < targetBytePos) {
5339  /* Offset forwards. */
5340  offset = (targetBytePos - currentBytePos);
5341  } else {
5342  /* Offset backwards. */
5343  if (!drwav_seek_to_first_pcm_frame(pWav)) {
5344  return DRWAV_FALSE;
5345  }
5346  offset = targetBytePos;
5347  }
5348 
5349  while (offset > 0) {
5350  int offset32 = ((offset > INT_MAX) ? INT_MAX : (int)offset);
5351  if (!pWav->onSeek(pWav->pUserData, offset32, drwav_seek_origin_current)) {
5352  return DRWAV_FALSE;
5353  }
5354 
5355  pWav->readCursorInPCMFrames += offset32 / drwav_get_bytes_per_pcm_frame(pWav);
5356  pWav->bytesRemaining -= offset32;
5357  offset -= offset32;
5358  }
5359  }
5360 
5361  return DRWAV_TRUE;
5362 }
5363 
5365 {
5366  if (pCursor == NULL) {
5367  return DRWAV_INVALID_ARGS;
5368  }
5369 
5370  *pCursor = 0; /* Safety. */
5371 
5372  if (pWav == NULL) {
5373  return DRWAV_INVALID_ARGS;
5374  }
5375 
5376  *pCursor = pWav->readCursorInPCMFrames;
5377 
5378  return DRWAV_SUCCESS;
5379 }
5380 
5382 {
5383  if (pLength == NULL) {
5384  return DRWAV_INVALID_ARGS;
5385  }
5386 
5387  *pLength = 0; /* Safety. */
5388 
5389  if (pWav == NULL) {
5390  return DRWAV_INVALID_ARGS;
5391  }
5392 
5393  *pLength = pWav->totalPCMFrameCount;
5394 
5395  return DRWAV_SUCCESS;
5396 }
5397 
5398 
5399 DRWAV_API size_t drwav_write_raw(drwav* pWav, size_t bytesToWrite, const void* pData)
5400 {
5401  size_t bytesWritten;
5402 
5403  if (pWav == NULL || bytesToWrite == 0 || pData == NULL) {
5404  return 0;
5405  }
5406 
5407  bytesWritten = pWav->onWrite(pWav->pUserData, pData, bytesToWrite);
5408  pWav->dataChunkDataSize += bytesWritten;
5409 
5410  return bytesWritten;
5411 }
5412 
5413 DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
5414 {
5415  drwav_uint64 bytesToWrite;
5416  drwav_uint64 bytesWritten;
5417  const drwav_uint8* pRunningData;
5418 
5419  if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
5420  return 0;
5421  }
5422 
5423  bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
5424  if (bytesToWrite > DRWAV_SIZE_MAX) {
5425  return 0;
5426  }
5427 
5428  bytesWritten = 0;
5429  pRunningData = (const drwav_uint8*)pData;
5430 
5431  while (bytesToWrite > 0) {
5432  size_t bytesJustWritten;
5433  drwav_uint64 bytesToWriteThisIteration;
5434 
5435  bytesToWriteThisIteration = bytesToWrite;
5436  DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX); /* <-- This is checked above. */
5437 
5438  bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, pRunningData);
5439  if (bytesJustWritten == 0) {
5440  break;
5441  }
5442 
5443  bytesToWrite -= bytesJustWritten;
5444  bytesWritten += bytesJustWritten;
5445  pRunningData += bytesJustWritten;
5446  }
5447 
5448  return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
5449 }
5450 
5451 DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
5452 {
5453  drwav_uint64 bytesToWrite;
5454  drwav_uint64 bytesWritten;
5455  drwav_uint32 bytesPerSample;
5456  const drwav_uint8* pRunningData;
5457 
5458  if (pWav == NULL || framesToWrite == 0 || pData == NULL) {
5459  return 0;
5460  }
5461 
5462  bytesToWrite = ((framesToWrite * pWav->channels * pWav->bitsPerSample) / 8);
5463  if (bytesToWrite > DRWAV_SIZE_MAX) {
5464  return 0;
5465  }
5466 
5467  bytesWritten = 0;
5468  pRunningData = (const drwav_uint8*)pData;
5469 
5470  bytesPerSample = drwav_get_bytes_per_pcm_frame(pWav) / pWav->channels;
5471 
5472  while (bytesToWrite > 0) {
5473  drwav_uint8 temp[4096];
5474  drwav_uint32 sampleCount;
5475  size_t bytesJustWritten;
5476  drwav_uint64 bytesToWriteThisIteration;
5477 
5478  bytesToWriteThisIteration = bytesToWrite;
5479  DRWAV_ASSERT(bytesToWriteThisIteration <= DRWAV_SIZE_MAX); /* <-- This is checked above. */
5480 
5481  /*
5482  WAV files are always little-endian. We need to byte swap on big-endian architectures. Since our input buffer is read-only we need
5483  to use an intermediary buffer for the conversion.
5484  */
5485  sampleCount = sizeof(temp)/bytesPerSample;
5486 
5487  if (bytesToWriteThisIteration > ((drwav_uint64)sampleCount)*bytesPerSample) {
5488  bytesToWriteThisIteration = ((drwav_uint64)sampleCount)*bytesPerSample;
5489  }
5490 
5491  DRWAV_COPY_MEMORY(temp, pRunningData, (size_t)bytesToWriteThisIteration);
5492  drwav__bswap_samples(temp, sampleCount, bytesPerSample, pWav->translatedFormatTag);
5493 
5494  bytesJustWritten = drwav_write_raw(pWav, (size_t)bytesToWriteThisIteration, temp);
5495  if (bytesJustWritten == 0) {
5496  break;
5497  }
5498 
5499  bytesToWrite -= bytesJustWritten;
5500  bytesWritten += bytesJustWritten;
5501  pRunningData += bytesJustWritten;
5502  }
5503 
5504  return (bytesWritten * 8) / pWav->bitsPerSample / pWav->channels;
5505 }
5506 
5507 DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav* pWav, drwav_uint64 framesToWrite, const void* pData)
5508 {
5509  if (drwav__is_little_endian()) {
5510  return drwav_write_pcm_frames_le(pWav, framesToWrite, pData);
5511  } else {
5512  return drwav_write_pcm_frames_be(pWav, framesToWrite, pData);
5513  }
5514 }
5515 
5516 
5518 {
5519  drwav_uint64 totalFramesRead = 0;
5520 
5521  DRWAV_ASSERT(pWav != NULL);
5522  DRWAV_ASSERT(framesToRead > 0);
5523 
5524  /* TODO: Lots of room for optimization here. */
5525 
5526  while (pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
5527  DRWAV_ASSERT(framesToRead > 0); /* This loop iteration will never get hit with framesToRead == 0 because it's asserted at the top, and we check for 0 inside the loop just below. */
5528 
5529  /* If there are no cached frames we need to load a new block. */
5530  if (pWav->msadpcm.cachedFrameCount == 0 && pWav->msadpcm.bytesRemainingInBlock == 0) {
5531  if (pWav->channels == 1) {
5532  /* Mono. */
5533  drwav_uint8 header[7];
5534  if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
5535  return totalFramesRead;
5536  }
5537  pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
5538 
5539  pWav->msadpcm.predictor[0] = header[0];
5540  pWav->msadpcm.delta[0] = drwav_bytes_to_s16(header + 1);
5541  pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav_bytes_to_s16(header + 3);
5542  pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav_bytes_to_s16(header + 5);
5543  pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][0];
5544  pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[0][1];
5545  pWav->msadpcm.cachedFrameCount = 2;
5546  } else {
5547  /* Stereo. */
5548  drwav_uint8 header[14];
5549  if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
5550  return totalFramesRead;
5551  }
5552  pWav->msadpcm.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
5553 
5554  pWav->msadpcm.predictor[0] = header[0];
5555  pWav->msadpcm.predictor[1] = header[1];
5556  pWav->msadpcm.delta[0] = drwav_bytes_to_s16(header + 2);
5557  pWav->msadpcm.delta[1] = drwav_bytes_to_s16(header + 4);
5558  pWav->msadpcm.prevFrames[0][1] = (drwav_int32)drwav_bytes_to_s16(header + 6);
5559  pWav->msadpcm.prevFrames[1][1] = (drwav_int32)drwav_bytes_to_s16(header + 8);
5560  pWav->msadpcm.prevFrames[0][0] = (drwav_int32)drwav_bytes_to_s16(header + 10);
5561  pWav->msadpcm.prevFrames[1][0] = (drwav_int32)drwav_bytes_to_s16(header + 12);
5562 
5563  pWav->msadpcm.cachedFrames[0] = pWav->msadpcm.prevFrames[0][0];
5564  pWav->msadpcm.cachedFrames[1] = pWav->msadpcm.prevFrames[1][0];
5565  pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1];
5566  pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1];
5567  pWav->msadpcm.cachedFrameCount = 2;
5568  }
5569  }
5570 
5571  /* Output anything that's cached. */
5572  while (framesToRead > 0 && pWav->msadpcm.cachedFrameCount > 0 && pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
5573  if (pBufferOut != NULL) {
5574  drwav_uint32 iSample = 0;
5575  for (iSample = 0; iSample < pWav->channels; iSample += 1) {
5576  pBufferOut[iSample] = (drwav_int16)pWav->msadpcm.cachedFrames[(drwav_countof(pWav->msadpcm.cachedFrames) - (pWav->msadpcm.cachedFrameCount*pWav->channels)) + iSample];
5577  }
5578 
5579  pBufferOut += pWav->channels;
5580  }
5581 
5582  framesToRead -= 1;
5583  totalFramesRead += 1;
5584  pWav->readCursorInPCMFrames += 1;
5585  pWav->msadpcm.cachedFrameCount -= 1;
5586  }
5587 
5588  if (framesToRead == 0) {
5589  break;
5590  }
5591 
5592 
5593  /*
5594  If there's nothing left in the cache, just go ahead and load more. If there's nothing left to load in the current block we just continue to the next
5595  loop iteration which will trigger the loading of a new block.
5596  */
5597  if (pWav->msadpcm.cachedFrameCount == 0) {
5598  if (pWav->msadpcm.bytesRemainingInBlock == 0) {
5599  continue;
5600  } else {
5601  static drwav_int32 adaptationTable[] = {
5602  230, 230, 230, 230, 307, 409, 512, 614,
5603  768, 614, 512, 409, 307, 230, 230, 230
5604  };
5605  static drwav_int32 coeff1Table[] = { 256, 512, 0, 192, 240, 460, 392 };
5606  static drwav_int32 coeff2Table[] = { 0, -256, 0, 64, 0, -208, -232 };
5607 
5608  drwav_uint8 nibbles;
5609  drwav_int32 nibble0;
5610  drwav_int32 nibble1;
5611 
5612  if (pWav->onRead(pWav->pUserData, &nibbles, 1) != 1) {
5613  return totalFramesRead;
5614  }
5615  pWav->msadpcm.bytesRemainingInBlock -= 1;
5616 
5617  /* TODO: Optimize away these if statements. */
5618  nibble0 = ((nibbles & 0xF0) >> 4); if ((nibbles & 0x80)) { nibble0 |= 0xFFFFFFF0UL; }
5619  nibble1 = ((nibbles & 0x0F) >> 0); if ((nibbles & 0x08)) { nibble1 |= 0xFFFFFFF0UL; }
5620 
5621  if (pWav->channels == 1) {
5622  /* Mono. */
5623  drwav_int32 newSample0;
5624  drwav_int32 newSample1;
5625 
5626  newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
5627  newSample0 += nibble0 * pWav->msadpcm.delta[0];
5628  newSample0 = drwav_clamp(newSample0, -32768, 32767);
5629 
5630  pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
5631  if (pWav->msadpcm.delta[0] < 16) {
5632  pWav->msadpcm.delta[0] = 16;
5633  }
5634 
5635  pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
5636  pWav->msadpcm.prevFrames[0][1] = newSample0;
5637 
5638 
5639  newSample1 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
5640  newSample1 += nibble1 * pWav->msadpcm.delta[0];
5641  newSample1 = drwav_clamp(newSample1, -32768, 32767);
5642 
5643  pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[0]) >> 8;
5644  if (pWav->msadpcm.delta[0] < 16) {
5645  pWav->msadpcm.delta[0] = 16;
5646  }
5647 
5648  pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
5649  pWav->msadpcm.prevFrames[0][1] = newSample1;
5650 
5651 
5652  pWav->msadpcm.cachedFrames[2] = newSample0;
5653  pWav->msadpcm.cachedFrames[3] = newSample1;
5654  pWav->msadpcm.cachedFrameCount = 2;
5655  } else {
5656  /* Stereo. */
5657  drwav_int32 newSample0;
5658  drwav_int32 newSample1;
5659 
5660  /* Left. */
5661  newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8;
5662  newSample0 += nibble0 * pWav->msadpcm.delta[0];
5663  newSample0 = drwav_clamp(newSample0, -32768, 32767);
5664 
5665  pWav->msadpcm.delta[0] = (adaptationTable[((nibbles & 0xF0) >> 4)] * pWav->msadpcm.delta[0]) >> 8;
5666  if (pWav->msadpcm.delta[0] < 16) {
5667  pWav->msadpcm.delta[0] = 16;
5668  }
5669 
5670  pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1];
5671  pWav->msadpcm.prevFrames[0][1] = newSample0;
5672 
5673 
5674  /* Right. */
5675  newSample1 = ((pWav->msadpcm.prevFrames[1][1] * coeff1Table[pWav->msadpcm.predictor[1]]) + (pWav->msadpcm.prevFrames[1][0] * coeff2Table[pWav->msadpcm.predictor[1]])) >> 8;
5676  newSample1 += nibble1 * pWav->msadpcm.delta[1];
5677  newSample1 = drwav_clamp(newSample1, -32768, 32767);
5678 
5679  pWav->msadpcm.delta[1] = (adaptationTable[((nibbles & 0x0F) >> 0)] * pWav->msadpcm.delta[1]) >> 8;
5680  if (pWav->msadpcm.delta[1] < 16) {
5681  pWav->msadpcm.delta[1] = 16;
5682  }
5683 
5684  pWav->msadpcm.prevFrames[1][0] = pWav->msadpcm.prevFrames[1][1];
5685  pWav->msadpcm.prevFrames[1][1] = newSample1;
5686 
5687  pWav->msadpcm.cachedFrames[2] = newSample0;
5688  pWav->msadpcm.cachedFrames[3] = newSample1;
5689  pWav->msadpcm.cachedFrameCount = 1;
5690  }
5691  }
5692  }
5693  }
5694 
5695  return totalFramesRead;
5696 }
5697 
5698 
5700 {
5701  drwav_uint64 totalFramesRead = 0;
5702  drwav_uint32 iChannel;
5703 
5704  static drwav_int32 indexTable[16] = {
5705  -1, -1, -1, -1, 2, 4, 6, 8,
5706  -1, -1, -1, -1, 2, 4, 6, 8
5707  };
5708 
5709  static drwav_int32 stepTable[89] = {
5710  7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
5711  19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
5712  50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
5713  130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
5714  337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
5715  876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
5716  2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5717  5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
5718  15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
5719  };
5720 
5721  DRWAV_ASSERT(pWav != NULL);
5722  DRWAV_ASSERT(framesToRead > 0);
5723 
5724  /* TODO: Lots of room for optimization here. */
5725 
5726  while (pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
5727  DRWAV_ASSERT(framesToRead > 0); /* This loop iteration will never get hit with framesToRead == 0 because it's asserted at the top, and we check for 0 inside the loop just below. */
5728 
5729  /* If there are no cached samples we need to load a new block. */
5730  if (pWav->ima.cachedFrameCount == 0 && pWav->ima.bytesRemainingInBlock == 0) {
5731  if (pWav->channels == 1) {
5732  /* Mono. */
5733  drwav_uint8 header[4];
5734  if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
5735  return totalFramesRead;
5736  }
5737  pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
5738 
5739  if (header[2] >= drwav_countof(stepTable)) {
5741  pWav->ima.bytesRemainingInBlock = 0;
5742  return totalFramesRead; /* Invalid data. */
5743  }
5744 
5745  pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
5746  pWav->ima.stepIndex[0] = header[2];
5747  pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[0];
5748  pWav->ima.cachedFrameCount = 1;
5749  } else {
5750  /* Stereo. */
5751  drwav_uint8 header[8];
5752  if (pWav->onRead(pWav->pUserData, header, sizeof(header)) != sizeof(header)) {
5753  return totalFramesRead;
5754  }
5755  pWav->ima.bytesRemainingInBlock = pWav->fmt.blockAlign - sizeof(header);
5756 
5757  if (header[2] >= drwav_countof(stepTable) || header[6] >= drwav_countof(stepTable)) {
5759  pWav->ima.bytesRemainingInBlock = 0;
5760  return totalFramesRead; /* Invalid data. */
5761  }
5762 
5763  pWav->ima.predictor[0] = drwav_bytes_to_s16(header + 0);
5764  pWav->ima.stepIndex[0] = header[2];
5765  pWav->ima.predictor[1] = drwav_bytes_to_s16(header + 4);
5766  pWav->ima.stepIndex[1] = header[6];
5767 
5768  pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 2] = pWav->ima.predictor[0];
5769  pWav->ima.cachedFrames[drwav_countof(pWav->ima.cachedFrames) - 1] = pWav->ima.predictor[1];
5770  pWav->ima.cachedFrameCount = 1;
5771  }
5772  }
5773 
5774  /* Output anything that's cached. */
5775  while (framesToRead > 0 && pWav->ima.cachedFrameCount > 0 && pWav->readCursorInPCMFrames < pWav->totalPCMFrameCount) {
5776  if (pBufferOut != NULL) {
5777  drwav_uint32 iSample;
5778  for (iSample = 0; iSample < pWav->channels; iSample += 1) {
5779  pBufferOut[iSample] = (drwav_int16)pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + iSample];
5780  }
5781  pBufferOut += pWav->channels;
5782  }
5783 
5784  framesToRead -= 1;
5785  totalFramesRead += 1;
5786  pWav->readCursorInPCMFrames += 1;
5787  pWav->ima.cachedFrameCount -= 1;
5788  }
5789 
5790  if (framesToRead == 0) {
5791  break;
5792  }
5793 
5794  /*
5795  If there's nothing left in the cache, just go ahead and load more. If there's nothing left to load in the current block we just continue to the next
5796  loop iteration which will trigger the loading of a new block.
5797  */
5798  if (pWav->ima.cachedFrameCount == 0) {
5799  if (pWav->ima.bytesRemainingInBlock == 0) {
5800  continue;
5801  } else {
5802  /*
5803  From what I can tell with stereo streams, it looks like every 4 bytes (8 samples) is for one channel. So it goes 4 bytes for the
5804  left channel, 4 bytes for the right channel.
5805  */
5806  pWav->ima.cachedFrameCount = 8;
5807  for (iChannel = 0; iChannel < pWav->channels; ++iChannel) {
5808  drwav_uint32 iByte;
5809  drwav_uint8 nibbles[4];
5810  if (pWav->onRead(pWav->pUserData, &nibbles, 4) != 4) {
5811  pWav->ima.cachedFrameCount = 0;
5812  return totalFramesRead;
5813  }
5814  pWav->ima.bytesRemainingInBlock -= 4;
5815 
5816  for (iByte = 0; iByte < 4; ++iByte) {
5817  drwav_uint8 nibble0 = ((nibbles[iByte] & 0x0F) >> 0);
5818  drwav_uint8 nibble1 = ((nibbles[iByte] & 0xF0) >> 4);
5819 
5820  drwav_int32 step = stepTable[pWav->ima.stepIndex[iChannel]];
5821  drwav_int32 predictor = pWav->ima.predictor[iChannel];
5822 
5823  drwav_int32 diff = step >> 3;
5824  if (nibble0 & 1) diff += step >> 2;
5825  if (nibble0 & 2) diff += step >> 1;
5826  if (nibble0 & 4) diff += step;
5827  if (nibble0 & 8) diff = -diff;
5828 
5829  predictor = drwav_clamp(predictor + diff, -32768, 32767);
5830  pWav->ima.predictor[iChannel] = predictor;
5831  pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble0], 0, (drwav_int32)drwav_countof(stepTable)-1);
5832  pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+0)*pWav->channels + iChannel] = predictor;
5833 
5834 
5835  step = stepTable[pWav->ima.stepIndex[iChannel]];
5836  predictor = pWav->ima.predictor[iChannel];
5837 
5838  diff = step >> 3;
5839  if (nibble1 & 1) diff += step >> 2;
5840  if (nibble1 & 2) diff += step >> 1;
5841  if (nibble1 & 4) diff += step;
5842  if (nibble1 & 8) diff = -diff;
5843 
5844  predictor = drwav_clamp(predictor + diff, -32768, 32767);
5845  pWav->ima.predictor[iChannel] = predictor;
5846  pWav->ima.stepIndex[iChannel] = drwav_clamp(pWav->ima.stepIndex[iChannel] + indexTable[nibble1], 0, (drwav_int32)drwav_countof(stepTable)-1);
5847  pWav->ima.cachedFrames[(drwav_countof(pWav->ima.cachedFrames) - (pWav->ima.cachedFrameCount*pWav->channels)) + (iByte*2+1)*pWav->channels + iChannel] = predictor;
5848  }
5849  }
5850  }
5851  }
5852  }
5853 
5854  return totalFramesRead;
5855 }
5856 
5857 
5858 #ifndef DR_WAV_NO_CONVERSION_API
5859 static unsigned short g_drwavAlawTable[256] = {
5860  0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80, 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
5861  0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0, 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
5862  0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600, 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
5863  0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00, 0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,
5864  0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8, 0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,
5865  0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8, 0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,
5866  0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60, 0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,
5867  0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0, 0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,
5868  0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280, 0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,
5869  0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940, 0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,
5870  0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00, 0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,
5871  0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500, 0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,
5872  0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128, 0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,
5873  0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028, 0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,
5874  0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0, 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,
5875  0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250, 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350
5876 };
5877 
5878 static unsigned short g_drwavMulawTable[256] = {
5879  0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84, 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,
5880  0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84, 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,
5881  0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804, 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,
5882  0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444, 0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844,
5883  0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64, 0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64,
5884  0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74, 0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74,
5885  0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC, 0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C,
5886  0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0, 0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000,
5887  0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C, 0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C,
5888  0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C, 0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C,
5889  0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC, 0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC,
5890  0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC, 0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC,
5891  0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C, 0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C,
5892  0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C, 0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C,
5893  0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104, 0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084,
5894  0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040, 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000
5895 };
5896 
5898 {
5899  return (short)g_drwavAlawTable[sampleIn];
5900 }
5901 
5903 {
5904  return (short)g_drwavMulawTable[sampleIn];
5905 }
5906 
5907 
5908 
5909 DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
5910 {
5911  unsigned int i;
5912 
5913  /* Special case for 8-bit sample data because it's treated as unsigned. */
5914  if (bytesPerSample == 1) {
5915  drwav_u8_to_s16(pOut, pIn, totalSampleCount);
5916  return;
5917  }
5918 
5919 
5920  /* Slightly more optimal implementation for common formats. */
5921  if (bytesPerSample == 2) {
5922  for (i = 0; i < totalSampleCount; ++i) {
5923  *pOut++ = ((const drwav_int16*)pIn)[i];
5924  }
5925  return;
5926  }
5927  if (bytesPerSample == 3) {
5928  drwav_s24_to_s16(pOut, pIn, totalSampleCount);
5929  return;
5930  }
5931  if (bytesPerSample == 4) {
5932  drwav_s32_to_s16(pOut, (const drwav_int32*)pIn, totalSampleCount);
5933  return;
5934  }
5935 
5936 
5937  /* Anything more than 64 bits per sample is not supported. */
5938  if (bytesPerSample > 8) {
5939  DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
5940  return;
5941  }
5942 
5943 
5944  /* Generic, slow converter. */
5945  for (i = 0; i < totalSampleCount; ++i) {
5946  drwav_uint64 sample = 0;
5947  unsigned int shift = (8 - bytesPerSample) * 8;
5948 
5949  unsigned int j;
5950  for (j = 0; j < bytesPerSample; j += 1) {
5951  DRWAV_ASSERT(j < 8);
5952  sample |= (drwav_uint64)(pIn[j]) << shift;
5953  shift += 8;
5954  }
5955 
5956  pIn += j;
5957  *pOut++ = (drwav_int16)((drwav_int64)sample >> 48);
5958  }
5959 }
5960 
5961 DRWAV_PRIVATE void drwav__ieee_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
5962 {
5963  if (bytesPerSample == 4) {
5964  drwav_f32_to_s16(pOut, (const float*)pIn, totalSampleCount);
5965  return;
5966  } else if (bytesPerSample == 8) {
5967  drwav_f64_to_s16(pOut, (const double*)pIn, totalSampleCount);
5968  return;
5969  } else {
5970  /* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
5971  DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
5972  return;
5973  }
5974 }
5975 
5977 {
5978  drwav_uint64 totalFramesRead;
5979  drwav_uint8 sampleData[4096];
5980  drwav_uint32 bytesPerFrame;
5981 
5982  /* Fast path. */
5983  if ((pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 16) || pBufferOut == NULL) {
5984  return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
5985  }
5986 
5987  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
5988  if (bytesPerFrame == 0) {
5989  return 0;
5990  }
5991 
5992  totalFramesRead = 0;
5993 
5994  while (framesToRead > 0) {
5995  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
5996  if (framesRead == 0) {
5997  break;
5998  }
5999 
6000  drwav__pcm_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
6001 
6002  pBufferOut += framesRead*pWav->channels;
6003  framesToRead -= framesRead;
6004  totalFramesRead += framesRead;
6005  }
6006 
6007  return totalFramesRead;
6008 }
6009 
6011 {
6012  drwav_uint64 totalFramesRead;
6013  drwav_uint8 sampleData[4096];
6014  drwav_uint32 bytesPerFrame;
6015 
6016  if (pBufferOut == NULL) {
6017  return drwav_read_pcm_frames(pWav, framesToRead, NULL);
6018  }
6019 
6020  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6021  if (bytesPerFrame == 0) {
6022  return 0;
6023  }
6024 
6025  totalFramesRead = 0;
6026 
6027  while (framesToRead > 0) {
6028  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6029  if (framesRead == 0) {
6030  break;
6031  }
6032 
6033  drwav__ieee_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
6034 
6035  pBufferOut += framesRead*pWav->channels;
6036  framesToRead -= framesRead;
6037  totalFramesRead += framesRead;
6038  }
6039 
6040  return totalFramesRead;
6041 }
6042 
6044 {
6045  drwav_uint64 totalFramesRead;
6046  drwav_uint8 sampleData[4096];
6047  drwav_uint32 bytesPerFrame;
6048 
6049  if (pBufferOut == NULL) {
6050  return drwav_read_pcm_frames(pWav, framesToRead, NULL);
6051  }
6052 
6053  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6054  if (bytesPerFrame == 0) {
6055  return 0;
6056  }
6057 
6058  totalFramesRead = 0;
6059 
6060  while (framesToRead > 0) {
6061  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6062  if (framesRead == 0) {
6063  break;
6064  }
6065 
6066  drwav_alaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
6067 
6068  pBufferOut += framesRead*pWav->channels;
6069  framesToRead -= framesRead;
6070  totalFramesRead += framesRead;
6071  }
6072 
6073  return totalFramesRead;
6074 }
6075 
6077 {
6078  drwav_uint64 totalFramesRead;
6079  drwav_uint8 sampleData[4096];
6080  drwav_uint32 bytesPerFrame;
6081 
6082  if (pBufferOut == NULL) {
6083  return drwav_read_pcm_frames(pWav, framesToRead, NULL);
6084  }
6085 
6086  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6087  if (bytesPerFrame == 0) {
6088  return 0;
6089  }
6090 
6091  totalFramesRead = 0;
6092 
6093  while (framesToRead > 0) {
6094  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6095  if (framesRead == 0) {
6096  break;
6097  }
6098 
6099  drwav_mulaw_to_s16(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
6100 
6101  pBufferOut += framesRead*pWav->channels;
6102  framesToRead -= framesRead;
6103  totalFramesRead += framesRead;
6104  }
6105 
6106  return totalFramesRead;
6107 }
6108 
6110 {
6111  if (pWav == NULL || framesToRead == 0) {
6112  return 0;
6113  }
6114 
6115  if (pBufferOut == NULL) {
6116  return drwav_read_pcm_frames(pWav, framesToRead, NULL);
6117  }
6118 
6119  /* Don't try to read more samples than can potentially fit in the output buffer. */
6120  if (framesToRead * pWav->channels * sizeof(drwav_int16) > DRWAV_SIZE_MAX) {
6121  framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int16) / pWav->channels;
6122  }
6123 
6124  if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
6125  return drwav_read_pcm_frames_s16__pcm(pWav, framesToRead, pBufferOut);
6126  }
6127 
6129  return drwav_read_pcm_frames_s16__ieee(pWav, framesToRead, pBufferOut);
6130  }
6131 
6133  return drwav_read_pcm_frames_s16__alaw(pWav, framesToRead, pBufferOut);
6134  }
6135 
6137  return drwav_read_pcm_frames_s16__mulaw(pWav, framesToRead, pBufferOut);
6138  }
6139 
6141  return drwav_read_pcm_frames_s16__msadpcm(pWav, framesToRead, pBufferOut);
6142  }
6143 
6145  return drwav_read_pcm_frames_s16__ima(pWav, framesToRead, pBufferOut);
6146  }
6147 
6148  return 0;
6149 }
6150 
6152 {
6153  drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
6154  if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
6155  drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
6156  }
6157 
6158  return framesRead;
6159 }
6160 
6162 {
6163  drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, framesToRead, pBufferOut);
6164  if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
6165  drwav__bswap_samples_s16(pBufferOut, framesRead*pWav->channels);
6166  }
6167 
6168  return framesRead;
6169 }
6170 
6171 
6172 DRWAV_API void drwav_u8_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
6173 {
6174  int r;
6175  size_t i;
6176  for (i = 0; i < sampleCount; ++i) {
6177  int x = pIn[i];
6178  r = x << 8;
6179  r = r - 32768;
6180  pOut[i] = (short)r;
6181  }
6182 }
6183 
6184 DRWAV_API void drwav_s24_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
6185 {
6186  int r;
6187  size_t i;
6188  for (i = 0; i < sampleCount; ++i) {
6189  int x = ((int)(((unsigned int)(((const drwav_uint8*)pIn)[i*3+0]) << 8) | ((unsigned int)(((const drwav_uint8*)pIn)[i*3+1]) << 16) | ((unsigned int)(((const drwav_uint8*)pIn)[i*3+2])) << 24)) >> 8;
6190  r = x >> 8;
6191  pOut[i] = (short)r;
6192  }
6193 }
6194 
6195 DRWAV_API void drwav_s32_to_s16(drwav_int16* pOut, const drwav_int32* pIn, size_t sampleCount)
6196 {
6197  int r;
6198  size_t i;
6199  for (i = 0; i < sampleCount; ++i) {
6200  int x = pIn[i];
6201  r = x >> 16;
6202  pOut[i] = (short)r;
6203  }
6204 }
6205 
6206 DRWAV_API void drwav_f32_to_s16(drwav_int16* pOut, const float* pIn, size_t sampleCount)
6207 {
6208  int r;
6209  size_t i;
6210  for (i = 0; i < sampleCount; ++i) {
6211  float x = pIn[i];
6212  float c;
6213  c = ((x < -1) ? -1 : ((x > 1) ? 1 : x));
6214  c = c + 1;
6215  r = (int)(c * 32767.5f);
6216  r = r - 32768;
6217  pOut[i] = (short)r;
6218  }
6219 }
6220 
6221 DRWAV_API void drwav_f64_to_s16(drwav_int16* pOut, const double* pIn, size_t sampleCount)
6222 {
6223  int r;
6224  size_t i;
6225  for (i = 0; i < sampleCount; ++i) {
6226  double x = pIn[i];
6227  double c;
6228  c = ((x < -1) ? -1 : ((x > 1) ? 1 : x));
6229  c = c + 1;
6230  r = (int)(c * 32767.5);
6231  r = r - 32768;
6232  pOut[i] = (short)r;
6233  }
6234 }
6235 
6236 DRWAV_API void drwav_alaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
6237 {
6238  size_t i;
6239  for (i = 0; i < sampleCount; ++i) {
6240  pOut[i] = drwav__alaw_to_s16(pIn[i]);
6241  }
6242 }
6243 
6244 DRWAV_API void drwav_mulaw_to_s16(drwav_int16* pOut, const drwav_uint8* pIn, size_t sampleCount)
6245 {
6246  size_t i;
6247  for (i = 0; i < sampleCount; ++i) {
6248  pOut[i] = drwav__mulaw_to_s16(pIn[i]);
6249  }
6250 }
6251 
6252 
6253 
6254 DRWAV_PRIVATE void drwav__pcm_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample)
6255 {
6256  unsigned int i;
6257 
6258  /* Special case for 8-bit sample data because it's treated as unsigned. */
6259  if (bytesPerSample == 1) {
6260  drwav_u8_to_f32(pOut, pIn, sampleCount);
6261  return;
6262  }
6263 
6264  /* Slightly more optimal implementation for common formats. */
6265  if (bytesPerSample == 2) {
6266  drwav_s16_to_f32(pOut, (const drwav_int16*)pIn, sampleCount);
6267  return;
6268  }
6269  if (bytesPerSample == 3) {
6270  drwav_s24_to_f32(pOut, pIn, sampleCount);
6271  return;
6272  }
6273  if (bytesPerSample == 4) {
6274  drwav_s32_to_f32(pOut, (const drwav_int32*)pIn, sampleCount);
6275  return;
6276  }
6277 
6278 
6279  /* Anything more than 64 bits per sample is not supported. */
6280  if (bytesPerSample > 8) {
6281  DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
6282  return;
6283  }
6284 
6285 
6286  /* Generic, slow converter. */
6287  for (i = 0; i < sampleCount; ++i) {
6288  drwav_uint64 sample = 0;
6289  unsigned int shift = (8 - bytesPerSample) * 8;
6290 
6291  unsigned int j;
6292  for (j = 0; j < bytesPerSample; j += 1) {
6293  DRWAV_ASSERT(j < 8);
6294  sample |= (drwav_uint64)(pIn[j]) << shift;
6295  shift += 8;
6296  }
6297 
6298  pIn += j;
6299  *pOut++ = (float)((drwav_int64)sample / 9223372036854775807.0);
6300  }
6301 }
6302 
6303 DRWAV_PRIVATE void drwav__ieee_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount, unsigned int bytesPerSample)
6304 {
6305  if (bytesPerSample == 4) {
6306  unsigned int i;
6307  for (i = 0; i < sampleCount; ++i) {
6308  *pOut++ = ((const float*)pIn)[i];
6309  }
6310  return;
6311  } else if (bytesPerSample == 8) {
6312  drwav_f64_to_f32(pOut, (const double*)pIn, sampleCount);
6313  return;
6314  } else {
6315  /* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
6316  DRWAV_ZERO_MEMORY(pOut, sampleCount * sizeof(*pOut));
6317  return;
6318  }
6319 }
6320 
6321 
6322 DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6323 {
6324  drwav_uint64 totalFramesRead;
6325  drwav_uint8 sampleData[4096];
6326  drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6327 
6328  if (bytesPerFrame == 0) {
6329  return 0;
6330  }
6331 
6332  totalFramesRead = 0;
6333 
6334  while (framesToRead > 0) {
6335  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6336  if (framesRead == 0) {
6337  break;
6338  }
6339 
6340  drwav__pcm_to_f32(pBufferOut, sampleData, (size_t)framesRead*pWav->channels, bytesPerFrame/pWav->channels);
6341 
6342  pBufferOut += framesRead*pWav->channels;
6343  framesToRead -= framesRead;
6344  totalFramesRead += framesRead;
6345  }
6346 
6347  return totalFramesRead;
6348 }
6349 
6350 DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__msadpcm(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6351 {
6352  /*
6353  We're just going to borrow the implementation from the drwav_read_s16() since ADPCM is a little bit more complicated than other formats and I don't
6354  want to duplicate that code.
6355  */
6356  drwav_uint64 totalFramesRead = 0;
6357  drwav_int16 samples16[2048];
6358 
6359  while (framesToRead > 0) {
6360  drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
6361  if (framesRead == 0) {
6362  break;
6363  }
6364 
6365  drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); /* <-- Safe cast because we're clamping to 2048. */
6366 
6367  pBufferOut += framesRead*pWav->channels;
6368  framesToRead -= framesRead;
6369  totalFramesRead += framesRead;
6370  }
6371 
6372  return totalFramesRead;
6373 }
6374 
6375 DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6376 {
6377  /*
6378  We're just going to borrow the implementation from the drwav_read_s16() since IMA-ADPCM is a little bit more complicated than other formats and I don't
6379  want to duplicate that code.
6380  */
6381  drwav_uint64 totalFramesRead = 0;
6382  drwav_int16 samples16[2048];
6383 
6384  while (framesToRead > 0) {
6385  drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
6386  if (framesRead == 0) {
6387  break;
6388  }
6389 
6390  drwav_s16_to_f32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); /* <-- Safe cast because we're clamping to 2048. */
6391 
6392  pBufferOut += framesRead*pWav->channels;
6393  framesToRead -= framesRead;
6394  totalFramesRead += framesRead;
6395  }
6396 
6397  return totalFramesRead;
6398 }
6399 
6400 DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6401 {
6402  drwav_uint64 totalFramesRead;
6403  drwav_uint8 sampleData[4096];
6404  drwav_uint32 bytesPerFrame;
6405 
6406  /* Fast path. */
6407  if (pWav->translatedFormatTag == DR_WAVE_FORMAT_IEEE_FLOAT && pWav->bitsPerSample == 32) {
6408  return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
6409  }
6410 
6411  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6412  if (bytesPerFrame == 0) {
6413  return 0;
6414  }
6415 
6416  totalFramesRead = 0;
6417 
6418  while (framesToRead > 0) {
6419  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6420  if (framesRead == 0) {
6421  break;
6422  }
6423 
6424  drwav__ieee_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
6425 
6426  pBufferOut += framesRead*pWav->channels;
6427  framesToRead -= framesRead;
6428  totalFramesRead += framesRead;
6429  }
6430 
6431  return totalFramesRead;
6432 }
6433 
6434 DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6435 {
6436  drwav_uint64 totalFramesRead;
6437  drwav_uint8 sampleData[4096];
6438  drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6439 
6440  if (bytesPerFrame == 0) {
6441  return 0;
6442  }
6443 
6444  totalFramesRead = 0;
6445 
6446  while (framesToRead > 0) {
6447  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6448  if (framesRead == 0) {
6449  break;
6450  }
6451 
6452  drwav_alaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
6453 
6454  pBufferOut += framesRead*pWav->channels;
6455  framesToRead -= framesRead;
6456  totalFramesRead += framesRead;
6457  }
6458 
6459  return totalFramesRead;
6460 }
6461 
6462 DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6463 {
6464  drwav_uint64 totalFramesRead;
6465  drwav_uint8 sampleData[4096];
6466  drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6467 
6468  if (bytesPerFrame == 0) {
6469  return 0;
6470  }
6471 
6472  totalFramesRead = 0;
6473 
6474  while (framesToRead > 0) {
6475  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6476  if (framesRead == 0) {
6477  break;
6478  }
6479 
6480  drwav_mulaw_to_f32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
6481 
6482  pBufferOut += framesRead*pWav->channels;
6483  framesToRead -= framesRead;
6484  totalFramesRead += framesRead;
6485  }
6486 
6487  return totalFramesRead;
6488 }
6489 
6490 DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6491 {
6492  if (pWav == NULL || framesToRead == 0) {
6493  return 0;
6494  }
6495 
6496  if (pBufferOut == NULL) {
6497  return drwav_read_pcm_frames(pWav, framesToRead, NULL);
6498  }
6499 
6500  /* Don't try to read more samples than can potentially fit in the output buffer. */
6501  if (framesToRead * pWav->channels * sizeof(float) > DRWAV_SIZE_MAX) {
6502  framesToRead = DRWAV_SIZE_MAX / sizeof(float) / pWav->channels;
6503  }
6504 
6505  if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
6506  return drwav_read_pcm_frames_f32__pcm(pWav, framesToRead, pBufferOut);
6507  }
6508 
6510  return drwav_read_pcm_frames_f32__msadpcm(pWav, framesToRead, pBufferOut);
6511  }
6512 
6514  return drwav_read_pcm_frames_f32__ieee(pWav, framesToRead, pBufferOut);
6515  }
6516 
6518  return drwav_read_pcm_frames_f32__alaw(pWav, framesToRead, pBufferOut);
6519  }
6520 
6522  return drwav_read_pcm_frames_f32__mulaw(pWav, framesToRead, pBufferOut);
6523  }
6524 
6526  return drwav_read_pcm_frames_f32__ima(pWav, framesToRead, pBufferOut);
6527  }
6528 
6529  return 0;
6530 }
6531 
6532 DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6533 {
6534  drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
6535  if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
6536  drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
6537  }
6538 
6539  return framesRead;
6540 }
6541 
6542 DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav* pWav, drwav_uint64 framesToRead, float* pBufferOut)
6543 {
6544  drwav_uint64 framesRead = drwav_read_pcm_frames_f32(pWav, framesToRead, pBufferOut);
6545  if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
6546  drwav__bswap_samples_f32(pBufferOut, framesRead*pWav->channels);
6547  }
6548 
6549  return framesRead;
6550 }
6551 
6552 
6553 DRWAV_API void drwav_u8_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
6554 {
6555  size_t i;
6556 
6557  if (pOut == NULL || pIn == NULL) {
6558  return;
6559  }
6560 
6561 #ifdef DR_WAV_LIBSNDFILE_COMPAT
6562  /*
6563  It appears libsndfile uses slightly different logic for the u8 -> f32 conversion to dr_wav, which in my opinion is incorrect. It appears
6564  libsndfile performs the conversion something like "f32 = (u8 / 256) * 2 - 1", however I think it should be "f32 = (u8 / 255) * 2 - 1" (note
6565  the divisor of 256 vs 255). I use libsndfile as a benchmark for testing, so I'm therefore leaving this block here just for my automated
6566  correctness testing. This is disabled by default.
6567  */
6568  for (i = 0; i < sampleCount; ++i) {
6569  *pOut++ = (pIn[i] / 256.0f) * 2 - 1;
6570  }
6571 #else
6572  for (i = 0; i < sampleCount; ++i) {
6573  float x = pIn[i];
6574  x = x * 0.00784313725490196078f; /* 0..255 to 0..2 */
6575  x = x - 1; /* 0..2 to -1..1 */
6576 
6577  *pOut++ = x;
6578  }
6579 #endif
6580 }
6581 
6582 DRWAV_API void drwav_s16_to_f32(float* pOut, const drwav_int16* pIn, size_t sampleCount)
6583 {
6584  size_t i;
6585 
6586  if (pOut == NULL || pIn == NULL) {
6587  return;
6588  }
6589 
6590  for (i = 0; i < sampleCount; ++i) {
6591  *pOut++ = pIn[i] * 0.000030517578125f;
6592  }
6593 }
6594 
6595 DRWAV_API void drwav_s24_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
6596 {
6597  size_t i;
6598 
6599  if (pOut == NULL || pIn == NULL) {
6600  return;
6601  }
6602 
6603  for (i = 0; i < sampleCount; ++i) {
6604  double x;
6605  drwav_uint32 a = ((drwav_uint32)(pIn[i*3+0]) << 8);
6606  drwav_uint32 b = ((drwav_uint32)(pIn[i*3+1]) << 16);
6607  drwav_uint32 c = ((drwav_uint32)(pIn[i*3+2]) << 24);
6608 
6609  x = (double)((drwav_int32)(a | b | c) >> 8);
6610  *pOut++ = (float)(x * 0.00000011920928955078125);
6611  }
6612 }
6613 
6614 DRWAV_API void drwav_s32_to_f32(float* pOut, const drwav_int32* pIn, size_t sampleCount)
6615 {
6616  size_t i;
6617  if (pOut == NULL || pIn == NULL) {
6618  return;
6619  }
6620 
6621  for (i = 0; i < sampleCount; ++i) {
6622  *pOut++ = (float)(pIn[i] / 2147483648.0);
6623  }
6624 }
6625 
6626 DRWAV_API void drwav_f64_to_f32(float* pOut, const double* pIn, size_t sampleCount)
6627 {
6628  size_t i;
6629 
6630  if (pOut == NULL || pIn == NULL) {
6631  return;
6632  }
6633 
6634  for (i = 0; i < sampleCount; ++i) {
6635  *pOut++ = (float)pIn[i];
6636  }
6637 }
6638 
6639 DRWAV_API void drwav_alaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
6640 {
6641  size_t i;
6642 
6643  if (pOut == NULL || pIn == NULL) {
6644  return;
6645  }
6646 
6647  for (i = 0; i < sampleCount; ++i) {
6648  *pOut++ = drwav__alaw_to_s16(pIn[i]) / 32768.0f;
6649  }
6650 }
6651 
6652 DRWAV_API void drwav_mulaw_to_f32(float* pOut, const drwav_uint8* pIn, size_t sampleCount)
6653 {
6654  size_t i;
6655 
6656  if (pOut == NULL || pIn == NULL) {
6657  return;
6658  }
6659 
6660  for (i = 0; i < sampleCount; ++i) {
6661  *pOut++ = drwav__mulaw_to_s16(pIn[i]) / 32768.0f;
6662  }
6663 }
6664 
6665 
6666 
6667 DRWAV_PRIVATE void drwav__pcm_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
6668 {
6669  unsigned int i;
6670 
6671  /* Special case for 8-bit sample data because it's treated as unsigned. */
6672  if (bytesPerSample == 1) {
6673  drwav_u8_to_s32(pOut, pIn, totalSampleCount);
6674  return;
6675  }
6676 
6677  /* Slightly more optimal implementation for common formats. */
6678  if (bytesPerSample == 2) {
6679  drwav_s16_to_s32(pOut, (const drwav_int16*)pIn, totalSampleCount);
6680  return;
6681  }
6682  if (bytesPerSample == 3) {
6683  drwav_s24_to_s32(pOut, pIn, totalSampleCount);
6684  return;
6685  }
6686  if (bytesPerSample == 4) {
6687  for (i = 0; i < totalSampleCount; ++i) {
6688  *pOut++ = ((const drwav_int32*)pIn)[i];
6689  }
6690  return;
6691  }
6692 
6693 
6694  /* Anything more than 64 bits per sample is not supported. */
6695  if (bytesPerSample > 8) {
6696  DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
6697  return;
6698  }
6699 
6700 
6701  /* Generic, slow converter. */
6702  for (i = 0; i < totalSampleCount; ++i) {
6703  drwav_uint64 sample = 0;
6704  unsigned int shift = (8 - bytesPerSample) * 8;
6705 
6706  unsigned int j;
6707  for (j = 0; j < bytesPerSample; j += 1) {
6708  DRWAV_ASSERT(j < 8);
6709  sample |= (drwav_uint64)(pIn[j]) << shift;
6710  shift += 8;
6711  }
6712 
6713  pIn += j;
6714  *pOut++ = (drwav_int32)((drwav_int64)sample >> 32);
6715  }
6716 }
6717 
6718 DRWAV_PRIVATE void drwav__ieee_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t totalSampleCount, unsigned int bytesPerSample)
6719 {
6720  if (bytesPerSample == 4) {
6721  drwav_f32_to_s32(pOut, (const float*)pIn, totalSampleCount);
6722  return;
6723  } else if (bytesPerSample == 8) {
6724  drwav_f64_to_s32(pOut, (const double*)pIn, totalSampleCount);
6725  return;
6726  } else {
6727  /* Only supporting 32- and 64-bit float. Output silence in all other cases. Contributions welcome for 16-bit float. */
6728  DRWAV_ZERO_MEMORY(pOut, totalSampleCount * sizeof(*pOut));
6729  return;
6730  }
6731 }
6732 
6733 
6735 {
6736  drwav_uint64 totalFramesRead;
6737  drwav_uint8 sampleData[4096];
6738  drwav_uint32 bytesPerFrame;
6739 
6740  /* Fast path. */
6741  if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM && pWav->bitsPerSample == 32) {
6742  return drwav_read_pcm_frames(pWav, framesToRead, pBufferOut);
6743  }
6744 
6745  bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6746  if (bytesPerFrame == 0) {
6747  return 0;
6748  }
6749 
6750  totalFramesRead = 0;
6751 
6752  while (framesToRead > 0) {
6753  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6754  if (framesRead == 0) {
6755  break;
6756  }
6757 
6758  drwav__pcm_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
6759 
6760  pBufferOut += framesRead*pWav->channels;
6761  framesToRead -= framesRead;
6762  totalFramesRead += framesRead;
6763  }
6764 
6765  return totalFramesRead;
6766 }
6767 
6769 {
6770  /*
6771  We're just going to borrow the implementation from the drwav_read_s16() since ADPCM is a little bit more complicated than other formats and I don't
6772  want to duplicate that code.
6773  */
6774  drwav_uint64 totalFramesRead = 0;
6775  drwav_int16 samples16[2048];
6776 
6777  while (framesToRead > 0) {
6778  drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
6779  if (framesRead == 0) {
6780  break;
6781  }
6782 
6783  drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); /* <-- Safe cast because we're clamping to 2048. */
6784 
6785  pBufferOut += framesRead*pWav->channels;
6786  framesToRead -= framesRead;
6787  totalFramesRead += framesRead;
6788  }
6789 
6790  return totalFramesRead;
6791 }
6792 
6794 {
6795  /*
6796  We're just going to borrow the implementation from the drwav_read_s16() since IMA-ADPCM is a little bit more complicated than other formats and I don't
6797  want to duplicate that code.
6798  */
6799  drwav_uint64 totalFramesRead = 0;
6800  drwav_int16 samples16[2048];
6801 
6802  while (framesToRead > 0) {
6803  drwav_uint64 framesRead = drwav_read_pcm_frames_s16(pWav, drwav_min(framesToRead, drwav_countof(samples16)/pWav->channels), samples16);
6804  if (framesRead == 0) {
6805  break;
6806  }
6807 
6808  drwav_s16_to_s32(pBufferOut, samples16, (size_t)(framesRead*pWav->channels)); /* <-- Safe cast because we're clamping to 2048. */
6809 
6810  pBufferOut += framesRead*pWav->channels;
6811  framesToRead -= framesRead;
6812  totalFramesRead += framesRead;
6813  }
6814 
6815  return totalFramesRead;
6816 }
6817 
6819 {
6820  drwav_uint64 totalFramesRead;
6821  drwav_uint8 sampleData[4096];
6822  drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6823 
6824  if (bytesPerFrame == 0) {
6825  return 0;
6826  }
6827 
6828  totalFramesRead = 0;
6829 
6830  while (framesToRead > 0) {
6831  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6832  if (framesRead == 0) {
6833  break;
6834  }
6835 
6836  drwav__ieee_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels), bytesPerFrame/pWav->channels);
6837 
6838  pBufferOut += framesRead*pWav->channels;
6839  framesToRead -= framesRead;
6840  totalFramesRead += framesRead;
6841  }
6842 
6843  return totalFramesRead;
6844 }
6845 
6847 {
6848  drwav_uint64 totalFramesRead;
6849  drwav_uint8 sampleData[4096];
6850  drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6851 
6852  if (bytesPerFrame == 0) {
6853  return 0;
6854  }
6855 
6856  totalFramesRead = 0;
6857 
6858  while (framesToRead > 0) {
6859  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6860  if (framesRead == 0) {
6861  break;
6862  }
6863 
6864  drwav_alaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
6865 
6866  pBufferOut += framesRead*pWav->channels;
6867  framesToRead -= framesRead;
6868  totalFramesRead += framesRead;
6869  }
6870 
6871  return totalFramesRead;
6872 }
6873 
6875 {
6876  drwav_uint64 totalFramesRead;
6877  drwav_uint8 sampleData[4096];
6878  drwav_uint32 bytesPerFrame = drwav_get_bytes_per_pcm_frame(pWav);
6879 
6880  if (bytesPerFrame == 0) {
6881  return 0;
6882  }
6883 
6884  totalFramesRead = 0;
6885 
6886  while (framesToRead > 0) {
6887  drwav_uint64 framesRead = drwav_read_pcm_frames(pWav, drwav_min(framesToRead, sizeof(sampleData)/bytesPerFrame), sampleData);
6888  if (framesRead == 0) {
6889  break;
6890  }
6891 
6892  drwav_mulaw_to_s32(pBufferOut, sampleData, (size_t)(framesRead*pWav->channels));
6893 
6894  pBufferOut += framesRead*pWav->channels;
6895  framesToRead -= framesRead;
6896  totalFramesRead += framesRead;
6897  }
6898 
6899  return totalFramesRead;
6900 }
6901 
6903 {
6904  if (pWav == NULL || framesToRead == 0) {
6905  return 0;
6906  }
6907 
6908  if (pBufferOut == NULL) {
6909  return drwav_read_pcm_frames(pWav, framesToRead, NULL);
6910  }
6911 
6912  /* Don't try to read more samples than can potentially fit in the output buffer. */
6913  if (framesToRead * pWav->channels * sizeof(drwav_int32) > DRWAV_SIZE_MAX) {
6914  framesToRead = DRWAV_SIZE_MAX / sizeof(drwav_int32) / pWav->channels;
6915  }
6916 
6917  if (pWav->translatedFormatTag == DR_WAVE_FORMAT_PCM) {
6918  return drwav_read_pcm_frames_s32__pcm(pWav, framesToRead, pBufferOut);
6919  }
6920 
6922  return drwav_read_pcm_frames_s32__msadpcm(pWav, framesToRead, pBufferOut);
6923  }
6924 
6926  return drwav_read_pcm_frames_s32__ieee(pWav, framesToRead, pBufferOut);
6927  }
6928 
6930  return drwav_read_pcm_frames_s32__alaw(pWav, framesToRead, pBufferOut);
6931  }
6932 
6934  return drwav_read_pcm_frames_s32__mulaw(pWav, framesToRead, pBufferOut);
6935  }
6936 
6938  return drwav_read_pcm_frames_s32__ima(pWav, framesToRead, pBufferOut);
6939  }
6940 
6941  return 0;
6942 }
6943 
6945 {
6946  drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
6947  if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_FALSE) {
6948  drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
6949  }
6950 
6951  return framesRead;
6952 }
6953 
6955 {
6956  drwav_uint64 framesRead = drwav_read_pcm_frames_s32(pWav, framesToRead, pBufferOut);
6957  if (pBufferOut != NULL && drwav__is_little_endian() == DRWAV_TRUE) {
6958  drwav__bswap_samples_s32(pBufferOut, framesRead*pWav->channels);
6959  }
6960 
6961  return framesRead;
6962 }
6963 
6964 
6965 DRWAV_API void drwav_u8_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
6966 {
6967  size_t i;
6968 
6969  if (pOut == NULL || pIn == NULL) {
6970  return;
6971  }
6972 
6973  for (i = 0; i < sampleCount; ++i) {
6974  *pOut++ = ((int)pIn[i] - 128) << 24;
6975  }
6976 }
6977 
6978 DRWAV_API void drwav_s16_to_s32(drwav_int32* pOut, const drwav_int16* pIn, size_t sampleCount)
6979 {
6980  size_t i;
6981 
6982  if (pOut == NULL || pIn == NULL) {
6983  return;
6984  }
6985 
6986  for (i = 0; i < sampleCount; ++i) {
6987  *pOut++ = pIn[i] << 16;
6988  }
6989 }
6990 
6991 DRWAV_API void drwav_s24_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
6992 {
6993  size_t i;
6994 
6995  if (pOut == NULL || pIn == NULL) {
6996  return;
6997  }
6998 
6999  for (i = 0; i < sampleCount; ++i) {
7000  unsigned int s0 = pIn[i*3 + 0];
7001  unsigned int s1 = pIn[i*3 + 1];
7002  unsigned int s2 = pIn[i*3 + 2];
7003 
7004  drwav_int32 sample32 = (drwav_int32)((s0 << 8) | (s1 << 16) | (s2 << 24));
7005  *pOut++ = sample32;
7006  }
7007 }
7008 
7009 DRWAV_API void drwav_f32_to_s32(drwav_int32* pOut, const float* pIn, size_t sampleCount)
7010 {
7011  size_t i;
7012 
7013  if (pOut == NULL || pIn == NULL) {
7014  return;
7015  }
7016 
7017  for (i = 0; i < sampleCount; ++i) {
7018  *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
7019  }
7020 }
7021 
7022 DRWAV_API void drwav_f64_to_s32(drwav_int32* pOut, const double* pIn, size_t sampleCount)
7023 {
7024  size_t i;
7025 
7026  if (pOut == NULL || pIn == NULL) {
7027  return;
7028  }
7029 
7030  for (i = 0; i < sampleCount; ++i) {
7031  *pOut++ = (drwav_int32)(2147483648.0 * pIn[i]);
7032  }
7033 }
7034 
7035 DRWAV_API void drwav_alaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
7036 {
7037  size_t i;
7038 
7039  if (pOut == NULL || pIn == NULL) {
7040  return;
7041  }
7042 
7043  for (i = 0; i < sampleCount; ++i) {
7044  *pOut++ = ((drwav_int32)drwav__alaw_to_s16(pIn[i])) << 16;
7045  }
7046 }
7047 
7048 DRWAV_API void drwav_mulaw_to_s32(drwav_int32* pOut, const drwav_uint8* pIn, size_t sampleCount)
7049 {
7050  size_t i;
7051 
7052  if (pOut == NULL || pIn == NULL) {
7053  return;
7054  }
7055 
7056  for (i= 0; i < sampleCount; ++i) {
7057  *pOut++ = ((drwav_int32)drwav__mulaw_to_s16(pIn[i])) << 16;
7058  }
7059 }
7060 
7061 
7062 
7063 DRWAV_PRIVATE drwav_int16* drwav__read_pcm_frames_and_close_s16(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
7064 {
7065  drwav_uint64 sampleDataSize;
7066  drwav_int16* pSampleData;
7067  drwav_uint64 framesRead;
7068 
7069  DRWAV_ASSERT(pWav != NULL);
7070 
7071  sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int16);
7072  if (sampleDataSize > DRWAV_SIZE_MAX) {
7073  drwav_uninit(pWav);
7074  return NULL; /* File's too big. */
7075  }
7076 
7077  pSampleData = (drwav_int16*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks); /* <-- Safe cast due to the check above. */
7078  if (pSampleData == NULL) {
7079  drwav_uninit(pWav);
7080  return NULL; /* Failed to allocate memory. */
7081  }
7082 
7083  framesRead = drwav_read_pcm_frames_s16(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
7084  if (framesRead != pWav->totalPCMFrameCount) {
7085  drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
7086  drwav_uninit(pWav);
7087  return NULL; /* There was an error reading the samples. */
7088  }
7089 
7090  drwav_uninit(pWav);
7091 
7092  if (sampleRate) {
7093  *sampleRate = pWav->sampleRate;
7094  }
7095  if (channels) {
7096  *channels = pWav->channels;
7097  }
7098  if (totalFrameCount) {
7099  *totalFrameCount = pWav->totalPCMFrameCount;
7100  }
7101 
7102  return pSampleData;
7103 }
7104 
7105 DRWAV_PRIVATE float* drwav__read_pcm_frames_and_close_f32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
7106 {
7107  drwav_uint64 sampleDataSize;
7108  float* pSampleData;
7109  drwav_uint64 framesRead;
7110 
7111  DRWAV_ASSERT(pWav != NULL);
7112 
7113  sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float);
7114  if (sampleDataSize > DRWAV_SIZE_MAX) {
7115  drwav_uninit(pWav);
7116  return NULL; /* File's too big. */
7117  }
7118 
7119  pSampleData = (float*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks); /* <-- Safe cast due to the check above. */
7120  if (pSampleData == NULL) {
7121  drwav_uninit(pWav);
7122  return NULL; /* Failed to allocate memory. */
7123  }
7124 
7125  framesRead = drwav_read_pcm_frames_f32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
7126  if (framesRead != pWav->totalPCMFrameCount) {
7127  drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
7128  drwav_uninit(pWav);
7129  return NULL; /* There was an error reading the samples. */
7130  }
7131 
7132  drwav_uninit(pWav);
7133 
7134  if (sampleRate) {
7135  *sampleRate = pWav->sampleRate;
7136  }
7137  if (channels) {
7138  *channels = pWav->channels;
7139  }
7140  if (totalFrameCount) {
7141  *totalFrameCount = pWav->totalPCMFrameCount;
7142  }
7143 
7144  return pSampleData;
7145 }
7146 
7147 DRWAV_PRIVATE drwav_int32* drwav__read_pcm_frames_and_close_s32(drwav* pWav, unsigned int* channels, unsigned int* sampleRate, drwav_uint64* totalFrameCount)
7148 {
7149  drwav_uint64 sampleDataSize;
7150  drwav_int32* pSampleData;
7151  drwav_uint64 framesRead;
7152 
7153  DRWAV_ASSERT(pWav != NULL);
7154 
7155  sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(drwav_int32);
7156  if (sampleDataSize > DRWAV_SIZE_MAX) {
7157  drwav_uninit(pWav);
7158  return NULL; /* File's too big. */
7159  }
7160 
7161  pSampleData = (drwav_int32*)drwav__malloc_from_callbacks((size_t)sampleDataSize, &pWav->allocationCallbacks); /* <-- Safe cast due to the check above. */
7162  if (pSampleData == NULL) {
7163  drwav_uninit(pWav);
7164  return NULL; /* Failed to allocate memory. */
7165  }
7166 
7167  framesRead = drwav_read_pcm_frames_s32(pWav, (size_t)pWav->totalPCMFrameCount, pSampleData);
7168  if (framesRead != pWav->totalPCMFrameCount) {
7169  drwav__free_from_callbacks(pSampleData, &pWav->allocationCallbacks);
7170  drwav_uninit(pWav);
7171  return NULL; /* There was an error reading the samples. */
7172  }
7173 
7174  drwav_uninit(pWav);
7175 
7176  if (sampleRate) {
7177  *sampleRate = pWav->sampleRate;
7178  }
7179  if (channels) {
7180  *channels = pWav->channels;
7181  }
7182  if (totalFrameCount) {
7183  *totalFrameCount = pWav->totalPCMFrameCount;
7184  }
7185 
7186  return pSampleData;
7187 }
7188 
7189 
7190 
7191 DRWAV_API drwav_int16* drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7192 {
7193  drwav wav;
7194 
7195  if (channelsOut) {
7196  *channelsOut = 0;
7197  }
7198  if (sampleRateOut) {
7199  *sampleRateOut = 0;
7200  }
7201  if (totalFrameCountOut) {
7202  *totalFrameCountOut = 0;
7203  }
7204 
7205  if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
7206  return NULL;
7207  }
7208 
7209  return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7210 }
7211 
7212 DRWAV_API float* drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7213 {
7214  drwav wav;
7215 
7216  if (channelsOut) {
7217  *channelsOut = 0;
7218  }
7219  if (sampleRateOut) {
7220  *sampleRateOut = 0;
7221  }
7222  if (totalFrameCountOut) {
7223  *totalFrameCountOut = 0;
7224  }
7225 
7226  if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
7227  return NULL;
7228  }
7229 
7230  return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7231 }
7232 
7233 DRWAV_API drwav_int32* drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7234 {
7235  drwav wav;
7236 
7237  if (channelsOut) {
7238  *channelsOut = 0;
7239  }
7240  if (sampleRateOut) {
7241  *sampleRateOut = 0;
7242  }
7243  if (totalFrameCountOut) {
7244  *totalFrameCountOut = 0;
7245  }
7246 
7247  if (!drwav_init(&wav, onRead, onSeek, pUserData, pAllocationCallbacks)) {
7248  return NULL;
7249  }
7250 
7251  return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7252 }
7253 
7254 #ifndef DR_WAV_NO_STDIO
7255 DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7256 {
7257  drwav wav;
7258 
7259  if (channelsOut) {
7260  *channelsOut = 0;
7261  }
7262  if (sampleRateOut) {
7263  *sampleRateOut = 0;
7264  }
7265  if (totalFrameCountOut) {
7266  *totalFrameCountOut = 0;
7267  }
7268 
7269  if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
7270  return NULL;
7271  }
7272 
7273  return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7274 }
7275 
7276 DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7277 {
7278  drwav wav;
7279 
7280  if (channelsOut) {
7281  *channelsOut = 0;
7282  }
7283  if (sampleRateOut) {
7284  *sampleRateOut = 0;
7285  }
7286  if (totalFrameCountOut) {
7287  *totalFrameCountOut = 0;
7288  }
7289 
7290  if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
7291  return NULL;
7292  }
7293 
7294  return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7295 }
7296 
7297 DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7298 {
7299  drwav wav;
7300 
7301  if (channelsOut) {
7302  *channelsOut = 0;
7303  }
7304  if (sampleRateOut) {
7305  *sampleRateOut = 0;
7306  }
7307  if (totalFrameCountOut) {
7308  *totalFrameCountOut = 0;
7309  }
7310 
7311  if (!drwav_init_file(&wav, filename, pAllocationCallbacks)) {
7312  return NULL;
7313  }
7314 
7315  return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7316 }
7317 
7318 
7319 DRWAV_API drwav_int16* drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7320 {
7321  drwav wav;
7322 
7323  if (sampleRateOut) {
7324  *sampleRateOut = 0;
7325  }
7326  if (channelsOut) {
7327  *channelsOut = 0;
7328  }
7329  if (totalFrameCountOut) {
7330  *totalFrameCountOut = 0;
7331  }
7332 
7333  if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
7334  return NULL;
7335  }
7336 
7337  return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7338 }
7339 
7340 DRWAV_API float* drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7341 {
7342  drwav wav;
7343 
7344  if (sampleRateOut) {
7345  *sampleRateOut = 0;
7346  }
7347  if (channelsOut) {
7348  *channelsOut = 0;
7349  }
7350  if (totalFrameCountOut) {
7351  *totalFrameCountOut = 0;
7352  }
7353 
7354  if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
7355  return NULL;
7356  }
7357 
7358  return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7359 }
7360 
7361 DRWAV_API drwav_int32* drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7362 {
7363  drwav wav;
7364 
7365  if (sampleRateOut) {
7366  *sampleRateOut = 0;
7367  }
7368  if (channelsOut) {
7369  *channelsOut = 0;
7370  }
7371  if (totalFrameCountOut) {
7372  *totalFrameCountOut = 0;
7373  }
7374 
7375  if (!drwav_init_file_w(&wav, filename, pAllocationCallbacks)) {
7376  return NULL;
7377  }
7378 
7379  return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7380 }
7381 #endif
7382 
7383 DRWAV_API drwav_int16* drwav_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7384 {
7385  drwav wav;
7386 
7387  if (channelsOut) {
7388  *channelsOut = 0;
7389  }
7390  if (sampleRateOut) {
7391  *sampleRateOut = 0;
7392  }
7393  if (totalFrameCountOut) {
7394  *totalFrameCountOut = 0;
7395  }
7396 
7397  if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
7398  return NULL;
7399  }
7400 
7401  return drwav__read_pcm_frames_and_close_s16(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7402 }
7403 
7404 DRWAV_API float* drwav_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7405 {
7406  drwav wav;
7407 
7408  if (channelsOut) {
7409  *channelsOut = 0;
7410  }
7411  if (sampleRateOut) {
7412  *sampleRateOut = 0;
7413  }
7414  if (totalFrameCountOut) {
7415  *totalFrameCountOut = 0;
7416  }
7417 
7418  if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
7419  return NULL;
7420  }
7421 
7422  return drwav__read_pcm_frames_and_close_f32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7423 }
7424 
7425 DRWAV_API drwav_int32* drwav_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drwav_uint64* totalFrameCountOut, const drwav_allocation_callbacks* pAllocationCallbacks)
7426 {
7427  drwav wav;
7428 
7429  if (channelsOut) {
7430  *channelsOut = 0;
7431  }
7432  if (sampleRateOut) {
7433  *sampleRateOut = 0;
7434  }
7435  if (totalFrameCountOut) {
7436  *totalFrameCountOut = 0;
7437  }
7438 
7439  if (!drwav_init_memory(&wav, data, dataSize, pAllocationCallbacks)) {
7440  return NULL;
7441  }
7442 
7443  return drwav__read_pcm_frames_and_close_s32(&wav, channelsOut, sampleRateOut, totalFrameCountOut);
7444 }
7445 #endif /* DR_WAV_NO_CONVERSION_API */
7446 
7447 
7448 DRWAV_API void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks)
7449 {
7450  if (pAllocationCallbacks != NULL) {
7451  drwav__free_from_callbacks(p, pAllocationCallbacks);
7452  } else {
7454  }
7455 }
7456 
7458 {
7459  return ((drwav_uint16)data[0] << 0) | ((drwav_uint16)data[1] << 8);
7460 }
7461 
7463 {
7464  return (drwav_int16)drwav_bytes_to_u16(data);
7465 }
7466 
7468 {
7469  return ((drwav_uint32)data[0] << 0) | ((drwav_uint32)data[1] << 8) | ((drwav_uint32)data[2] << 16) | ((drwav_uint32)data[3] << 24);
7470 }
7471 
7472 DRWAV_API float drwav_bytes_to_f32(const drwav_uint8* data)
7473 {
7474  union {
7475  drwav_uint32 u32;
7476  float f32;
7477  } value;
7478 
7479  value.u32 = drwav_bytes_to_u32(data);
7480  return value.f32;
7481 }
7482 
7484 {
7485  return (drwav_int32)drwav_bytes_to_u32(data);
7486 }
7487 
7489 {
7490  return
7491  ((drwav_uint64)data[0] << 0) | ((drwav_uint64)data[1] << 8) | ((drwav_uint64)data[2] << 16) | ((drwav_uint64)data[3] << 24) |
7492  ((drwav_uint64)data[4] << 32) | ((drwav_uint64)data[5] << 40) | ((drwav_uint64)data[6] << 48) | ((drwav_uint64)data[7] << 56);
7493 }
7494 
7496 {
7497  return (drwav_int64)drwav_bytes_to_u64(data);
7498 }
7499 
7500 
7502 {
7503  int i;
7504  for (i = 0; i < 16; i += 1) {
7505  if (a[i] != b[i]) {
7506  return DRWAV_FALSE;
7507  }
7508  }
7509 
7510  return DRWAV_TRUE;
7511 }
7512 
7513 DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8* a, const char* b)
7514 {
7515  return
7516  a[0] == b[0] &&
7517  a[1] == b[1] &&
7518  a[2] == b[2] &&
7519  a[3] == b[3];
7520 }
7521 
7522 #endif /* dr_wav_c */
7523 #endif /* DR_WAV_IMPLEMENTATION */
7524 
7525 /*
7526 REVISION HISTORY
7527 ================
7528 v0.13.0 - 2021-07-01
7529  - Improve support for reading and writing metadata. Use the `_with_metadata()` APIs to initialize
7530  a WAV decoder and store the metadata within the `drwav` object. Use the `pMetadata` and
7531  `metadataCount` members of the `drwav` object to read the data. The old way of handling metadata
7532  via a callback is still usable and valid.
7533  - API CHANGE: drwav_target_write_size_bytes() now takes extra parameters for calculating the
7534  required write size when writing metadata.
7535  - Add drwav_get_cursor_in_pcm_frames()
7536  - Add drwav_get_length_in_pcm_frames()
7537  - Fix a bug where drwav_read_raw() can call the read callback with a byte count of zero.
7538 
7539 v0.12.20 - 2021-06-11
7540  - Fix some undefined behavior.
7541 
7542 v0.12.19 - 2021-02-21
7543  - Fix a warning due to referencing _MSC_VER when it is undefined.
7544  - Minor improvements to the management of some internal state concerning the data chunk cursor.
7545 
7546 v0.12.18 - 2021-01-31
7547  - Clean up some static analysis warnings.
7548 
7549 v0.12.17 - 2021-01-17
7550  - Minor fix to sample code in documentation.
7551  - Correctly qualify a private API as private rather than public.
7552  - Code cleanup.
7553 
7554 v0.12.16 - 2020-12-02
7555  - Fix a bug when trying to read more bytes than can fit in a size_t.
7556 
7557 v0.12.15 - 2020-11-21
7558  - Fix compilation with OpenWatcom.
7559 
7560 v0.12.14 - 2020-11-13
7561  - Minor code clean up.
7562 
7563 v0.12.13 - 2020-11-01
7564  - Improve compiler support for older versions of GCC.
7565 
7566 v0.12.12 - 2020-09-28
7567  - Add support for RF64.
7568  - Fix a bug in writing mode where the size of the RIFF chunk incorrectly includes the header section.
7569 
7570 v0.12.11 - 2020-09-08
7571  - Fix a compilation error on older compilers.
7572 
7573 v0.12.10 - 2020-08-24
7574  - Fix a bug when seeking with ADPCM formats.
7575 
7576 v0.12.9 - 2020-08-02
7577  - Simplify sized types.
7578 
7579 v0.12.8 - 2020-07-25
7580  - Fix a compilation warning.
7581 
7582 v0.12.7 - 2020-07-15
7583  - Fix some bugs on big-endian architectures.
7584  - Fix an error in s24 to f32 conversion.
7585 
7586 v0.12.6 - 2020-06-23
7587  - Change drwav_read_*() to allow NULL to be passed in as the output buffer which is equivalent to a forward seek.
7588  - Fix a buffer overflow when trying to decode invalid IMA-ADPCM files.
7589  - Add include guard for the implementation section.
7590 
7591 v0.12.5 - 2020-05-27
7592  - Minor documentation fix.
7593 
7594 v0.12.4 - 2020-05-16
7595  - Replace assert() with DRWAV_ASSERT().
7596  - Add compile-time and run-time version querying.
7597  - DRWAV_VERSION_MINOR
7598  - DRWAV_VERSION_MAJOR
7599  - DRWAV_VERSION_REVISION
7600  - DRWAV_VERSION_STRING
7601  - drwav_version()
7602  - drwav_version_string()
7603 
7604 v0.12.3 - 2020-04-30
7605  - Fix compilation errors with VC6.
7606 
7607 v0.12.2 - 2020-04-21
7608  - Fix a bug where drwav_init_file() does not close the file handle after attempting to load an erroneous file.
7609 
7610 v0.12.1 - 2020-04-13
7611  - Fix some pedantic warnings.
7612 
7613 v0.12.0 - 2020-04-04
7614  - API CHANGE: Add container and format parameters to the chunk callback.
7615  - Minor documentation updates.
7616 
7617 v0.11.5 - 2020-03-07
7618  - Fix compilation error with Visual Studio .NET 2003.
7619 
7620 v0.11.4 - 2020-01-29
7621  - Fix some static analysis warnings.
7622  - Fix a bug when reading f32 samples from an A-law encoded stream.
7623 
7624 v0.11.3 - 2020-01-12
7625  - Minor changes to some f32 format conversion routines.
7626  - Minor bug fix for ADPCM conversion when end of file is reached.
7627 
7628 v0.11.2 - 2019-12-02
7629  - Fix a possible crash when using custom memory allocators without a custom realloc() implementation.
7630  - Fix an integer overflow bug.
7631  - Fix a null pointer dereference bug.
7632  - Add limits to sample rate, channels and bits per sample to tighten up some validation.
7633 
7634 v0.11.1 - 2019-10-07
7635  - Internal code clean up.
7636 
7637 v0.11.0 - 2019-10-06
7638  - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
7639  routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
7640  - drwav_init()
7641  - drwav_init_ex()
7642  - drwav_init_file()
7643  - drwav_init_file_ex()
7644  - drwav_init_file_w()
7645  - drwav_init_file_w_ex()
7646  - drwav_init_memory()
7647  - drwav_init_memory_ex()
7648  - drwav_init_write()
7649  - drwav_init_write_sequential()
7650  - drwav_init_write_sequential_pcm_frames()
7651  - drwav_init_file_write()
7652  - drwav_init_file_write_sequential()
7653  - drwav_init_file_write_sequential_pcm_frames()
7654  - drwav_init_file_write_w()
7655  - drwav_init_file_write_sequential_w()
7656  - drwav_init_file_write_sequential_pcm_frames_w()
7657  - drwav_init_memory_write()
7658  - drwav_init_memory_write_sequential()
7659  - drwav_init_memory_write_sequential_pcm_frames()
7660  - drwav_open_and_read_pcm_frames_s16()
7661  - drwav_open_and_read_pcm_frames_f32()
7662  - drwav_open_and_read_pcm_frames_s32()
7663  - drwav_open_file_and_read_pcm_frames_s16()
7664  - drwav_open_file_and_read_pcm_frames_f32()
7665  - drwav_open_file_and_read_pcm_frames_s32()
7666  - drwav_open_file_and_read_pcm_frames_s16_w()
7667  - drwav_open_file_and_read_pcm_frames_f32_w()
7668  - drwav_open_file_and_read_pcm_frames_s32_w()
7669  - drwav_open_memory_and_read_pcm_frames_s16()
7670  - drwav_open_memory_and_read_pcm_frames_f32()
7671  - drwav_open_memory_and_read_pcm_frames_s32()
7672  Set this extra parameter to NULL to use defaults which is the same as the previous behaviour. Setting this NULL will use
7673  DRWAV_MALLOC, DRWAV_REALLOC and DRWAV_FREE.
7674  - Add support for reading and writing PCM frames in an explicit endianness. New APIs:
7675  - drwav_read_pcm_frames_le()
7676  - drwav_read_pcm_frames_be()
7677  - drwav_read_pcm_frames_s16le()
7678  - drwav_read_pcm_frames_s16be()
7679  - drwav_read_pcm_frames_f32le()
7680  - drwav_read_pcm_frames_f32be()
7681  - drwav_read_pcm_frames_s32le()
7682  - drwav_read_pcm_frames_s32be()
7683  - drwav_write_pcm_frames_le()
7684  - drwav_write_pcm_frames_be()
7685  - Remove deprecated APIs.
7686  - API CHANGE: The following APIs now return native-endian data. Previously they returned little-endian data.
7687  - drwav_read_pcm_frames()
7688  - drwav_read_pcm_frames_s16()
7689  - drwav_read_pcm_frames_s32()
7690  - drwav_read_pcm_frames_f32()
7691  - drwav_open_and_read_pcm_frames_s16()
7692  - drwav_open_and_read_pcm_frames_s32()
7693  - drwav_open_and_read_pcm_frames_f32()
7694  - drwav_open_file_and_read_pcm_frames_s16()
7695  - drwav_open_file_and_read_pcm_frames_s32()
7696  - drwav_open_file_and_read_pcm_frames_f32()
7697  - drwav_open_file_and_read_pcm_frames_s16_w()
7698  - drwav_open_file_and_read_pcm_frames_s32_w()
7699  - drwav_open_file_and_read_pcm_frames_f32_w()
7700  - drwav_open_memory_and_read_pcm_frames_s16()
7701  - drwav_open_memory_and_read_pcm_frames_s32()
7702  - drwav_open_memory_and_read_pcm_frames_f32()
7703 
7704 v0.10.1 - 2019-08-31
7705  - Correctly handle partial trailing ADPCM blocks.
7706 
7707 v0.10.0 - 2019-08-04
7708  - Remove deprecated APIs.
7709  - Add wchar_t variants for file loading APIs:
7710  drwav_init_file_w()
7711  drwav_init_file_ex_w()
7712  drwav_init_file_write_w()
7713  drwav_init_file_write_sequential_w()
7714  - Add drwav_target_write_size_bytes() which calculates the total size in bytes of a WAV file given a format and sample count.
7715  - Add APIs for specifying the PCM frame count instead of the sample count when opening in sequential write mode:
7716  drwav_init_write_sequential_pcm_frames()
7717  drwav_init_file_write_sequential_pcm_frames()
7718  drwav_init_file_write_sequential_pcm_frames_w()
7719  drwav_init_memory_write_sequential_pcm_frames()
7720  - Deprecate drwav_open*() and drwav_close():
7721  drwav_open()
7722  drwav_open_ex()
7723  drwav_open_write()
7724  drwav_open_write_sequential()
7725  drwav_open_file()
7726  drwav_open_file_ex()
7727  drwav_open_file_write()
7728  drwav_open_file_write_sequential()
7729  drwav_open_memory()
7730  drwav_open_memory_ex()
7731  drwav_open_memory_write()
7732  drwav_open_memory_write_sequential()
7733  drwav_close()
7734  - Minor documentation updates.
7735 
7736 v0.9.2 - 2019-05-21
7737  - Fix warnings.
7738 
7739 v0.9.1 - 2019-05-05
7740  - Add support for C89.
7741  - Change license to choice of public domain or MIT-0.
7742 
7743 v0.9.0 - 2018-12-16
7744  - API CHANGE: Add new reading APIs for reading by PCM frames instead of samples. Old APIs have been deprecated and
7745  will be removed in v0.10.0. Deprecated APIs and their replacements:
7746  drwav_read() -> drwav_read_pcm_frames()
7747  drwav_read_s16() -> drwav_read_pcm_frames_s16()
7748  drwav_read_f32() -> drwav_read_pcm_frames_f32()
7749  drwav_read_s32() -> drwav_read_pcm_frames_s32()
7750  drwav_seek_to_sample() -> drwav_seek_to_pcm_frame()
7751  drwav_write() -> drwav_write_pcm_frames()
7752  drwav_open_and_read_s16() -> drwav_open_and_read_pcm_frames_s16()
7753  drwav_open_and_read_f32() -> drwav_open_and_read_pcm_frames_f32()
7754  drwav_open_and_read_s32() -> drwav_open_and_read_pcm_frames_s32()
7755  drwav_open_file_and_read_s16() -> drwav_open_file_and_read_pcm_frames_s16()
7756  drwav_open_file_and_read_f32() -> drwav_open_file_and_read_pcm_frames_f32()
7757  drwav_open_file_and_read_s32() -> drwav_open_file_and_read_pcm_frames_s32()
7758  drwav_open_memory_and_read_s16() -> drwav_open_memory_and_read_pcm_frames_s16()
7759  drwav_open_memory_and_read_f32() -> drwav_open_memory_and_read_pcm_frames_f32()
7760  drwav_open_memory_and_read_s32() -> drwav_open_memory_and_read_pcm_frames_s32()
7761  drwav::totalSampleCount -> drwav::totalPCMFrameCount
7762  - API CHANGE: Rename drwav_open_and_read_file_*() to drwav_open_file_and_read_*().
7763  - API CHANGE: Rename drwav_open_and_read_memory_*() to drwav_open_memory_and_read_*().
7764  - Add built-in support for smpl chunks.
7765  - Add support for firing a callback for each chunk in the file at initialization time.
7766  - This is enabled through the drwav_init_ex(), etc. family of APIs.
7767  - Handle invalid FMT chunks more robustly.
7768 
7769 v0.8.5 - 2018-09-11
7770  - Const correctness.
7771  - Fix a potential stack overflow.
7772 
7773 v0.8.4 - 2018-08-07
7774  - Improve 64-bit detection.
7775 
7776 v0.8.3 - 2018-08-05
7777  - Fix C++ build on older versions of GCC.
7778 
7779 v0.8.2 - 2018-08-02
7780  - Fix some big-endian bugs.
7781 
7782 v0.8.1 - 2018-06-29
7783  - Add support for sequential writing APIs.
7784  - Disable seeking in write mode.
7785  - Fix bugs with Wave64.
7786  - Fix typos.
7787 
7788 v0.8 - 2018-04-27
7789  - Bug fix.
7790  - Start using major.minor.revision versioning.
7791 
7792 v0.7f - 2018-02-05
7793  - Restrict ADPCM formats to a maximum of 2 channels.
7794 
7795 v0.7e - 2018-02-02
7796  - Fix a crash.
7797 
7798 v0.7d - 2018-02-01
7799  - Fix a crash.
7800 
7801 v0.7c - 2018-02-01
7802  - Set drwav.bytesPerSample to 0 for all compressed formats.
7803  - Fix a crash when reading 16-bit floating point WAV files. In this case dr_wav will output silence for
7804  all format conversion reading APIs (*_s16, *_s32, *_f32 APIs).
7805  - Fix some divide-by-zero errors.
7806 
7807 v0.7b - 2018-01-22
7808  - Fix errors with seeking of compressed formats.
7809  - Fix compilation error when DR_WAV_NO_CONVERSION_API
7810 
7811 v0.7a - 2017-11-17
7812  - Fix some GCC warnings.
7813 
7814 v0.7 - 2017-11-04
7815  - Add writing APIs.
7816 
7817 v0.6 - 2017-08-16
7818  - API CHANGE: Rename dr_* types to drwav_*.
7819  - Add support for custom implementations of malloc(), realloc(), etc.
7820  - Add support for Microsoft ADPCM.
7821  - Add support for IMA ADPCM (DVI, format code 0x11).
7822  - Optimizations to drwav_read_s16().
7823  - Bug fixes.
7824 
7825 v0.5g - 2017-07-16
7826  - Change underlying type for booleans to unsigned.
7827 
7828 v0.5f - 2017-04-04
7829  - Fix a minor bug with drwav_open_and_read_s16() and family.
7830 
7831 v0.5e - 2016-12-29
7832  - Added support for reading samples as signed 16-bit integers. Use the _s16() family of APIs for this.
7833  - Minor fixes to documentation.
7834 
7835 v0.5d - 2016-12-28
7836  - Use drwav_int* and drwav_uint* sized types to improve compiler support.
7837 
7838 v0.5c - 2016-11-11
7839  - Properly handle JUNK chunks that come before the FMT chunk.
7840 
7841 v0.5b - 2016-10-23
7842  - A minor change to drwav_bool8 and drwav_bool32 types.
7843 
7844 v0.5a - 2016-10-11
7845  - Fixed a bug with drwav_open_and_read() and family due to incorrect argument ordering.
7846  - Improve A-law and mu-law efficiency.
7847 
7848 v0.5 - 2016-09-29
7849  - API CHANGE. Swap the order of "channels" and "sampleRate" parameters in drwav_open_and_read*(). Rationale for this is to
7850  keep it consistent with dr_audio and dr_flac.
7851 
7852 v0.4b - 2016-09-18
7853  - Fixed a typo in documentation.
7854 
7855 v0.4a - 2016-09-18
7856  - Fixed a typo.
7857  - Change date format to ISO 8601 (YYYY-MM-DD)
7858 
7859 v0.4 - 2016-07-13
7860  - API CHANGE. Make onSeek consistent with dr_flac.
7861  - API CHANGE. Rename drwav_seek() to drwav_seek_to_sample() for clarity and consistency with dr_flac.
7862  - Added support for Sony Wave64.
7863 
7864 v0.3a - 2016-05-28
7865  - API CHANGE. Return drwav_bool32 instead of int in onSeek callback.
7866  - Fixed a memory leak.
7867 
7868 v0.3 - 2016-05-22
7869  - Lots of API changes for consistency.
7870 
7871 v0.2a - 2016-05-16
7872  - Fixed Linux/GCC build.
7873 
7874 v0.2 - 2016-05-11
7875  - Added support for reading data as signed 32-bit PCM for consistency with dr_flac.
7876 
7877 v0.1a - 2016-05-07
7878  - Fixed a bug in drwav_open_file() where the file handle would not be closed if the loader failed to initialize.
7879 
7880 v0.1 - 2016-05-04
7881  - Initial versioned release.
7882 */
7883 
7884 /*
7885 This software is available as a choice of the following licenses. Choose
7886 whichever you prefer.
7887 
7888 ===============================================================================
7889 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
7890 ===============================================================================
7891 This is free and unencumbered software released into the public domain.
7892 
7893 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
7894 software, either in source code form or as a compiled binary, for any purpose,
7895 commercial or non-commercial, and by any means.
7896 
7897 In jurisdictions that recognize copyright laws, the author or authors of this
7898 software dedicate any and all copyright interest in the software to the public
7899 domain. We make this dedication for the benefit of the public at large and to
7900 the detriment of our heirs and successors. We intend this dedication to be an
7901 overt act of relinquishment in perpetuity of all present and future rights to
7902 this software under copyright law.
7903 
7904 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7905 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7906 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7907 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
7908 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
7909 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7910 
7911 For more information, please refer to <http://unlicense.org/>
7912 
7913 ===============================================================================
7914 ALTERNATIVE 2 - MIT No Attribution
7915 ===============================================================================
7916 Copyright 2020 David Reid
7917 
7918 Permission is hereby granted, free of charge, to any person obtaining a copy of
7919 this software and associated documentation files (the "Software"), to deal in
7920 the Software without restriction, including without limitation the rights to
7921 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7922 of the Software, and to permit persons to whom the Software is furnished to do
7923 so.
7924 
7925 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7926 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7927 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7928 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7929 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7930 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
7931 SOFTWARE.
7932 */
drwav_seek_origin
drwav_seek_origin
Definition: porcupine/demo/c/dr_libs/dr_wav.h:268
drwav__write_u64ne_to_le
DRWAV_PRIVATE size_t drwav__write_u64ne_to_le(drwav *pWav, drwav_uint64 value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47851
drwav_write_raw
DRWAV_API size_t drwav_write_raw(drwav *pWav, size_t bytesToWrite, const void *pData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49480
DR_WAVE_FORMAT_EXTENSIBLE
#define DR_WAVE_FORMAT_EXTENSIBLE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:260
drwav_acid::reserved1
drwav_uint16 reserved1
Definition: porcupine/demo/c/dr_libs/dr_wav.h:640
drwav_list_info_text
Definition: porcupine/demo/c/dr_libs/dr_wav.h:719
DRWAV_CONNECTION_RESET
#define DRWAV_CONNECTION_RESET
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:243
drwav_read_pcm_frames_f32__ima
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ima(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50222
drwav::delta
drwav_int32 delta[2]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:887
g_drwavMulawTable
static unsigned short g_drwavMulawTable[256]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49836
drwav::bitsPerSample
drwav_uint16 bitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_wav.h:837
DRWAV_BEXT_UMID_BYTES
#define DRWAV_BEXT_UMID_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46888
drwav_min
#define drwav_min(a, b)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46304
drwav_s16_to_f32
DRWAV_API void drwav_s16_to_f32(float *pOut, const drwav_int16 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50371
drwav_init_write__internal
DRWAV_PRIVATE drwav_bool32 drwav_init_write__internal(drwav *pWav, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48300
drwav_fmt::bitsPerSample
drwav_uint16 bitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_wav.h:320
drwav_init_file_write_sequential
DRWAV_API drwav_bool32 drwav_init_file_write_sequential(drwav *pWav, const char *filename, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49034
drwav_smpl_loop::firstSampleByteOffset
drwav_uint32 firstSampleByteOffset
Definition: porcupine/demo/c/dr_libs/dr_wav.h:526
DRWAV_ADDRESS_FAMILY_NOT_SUPPORTED
#define DRWAV_ADDRESS_FAMILY_NOT_SUPPORTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:241
drwav::fmt
drwav_fmt fmt
Definition: porcupine/demo/c/dr_libs/dr_wav.h:828
DRWAV_UNAVAILABLE
#define DRWAV_UNAVAILABLE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:220
DRWAV_API
#define DRWAV_API
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:192
DRWAV_CUE_BYTES
#define DRWAV_CUE_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46882
drwav_get_bytes_per_pcm_frame
DRWAV_PRIVATE drwav_uint32 drwav_get_bytes_per_pcm_frame(drwav *pWav)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47470
drwav_smpl::productId
drwav_uint32 productId
Definition: porcupine/demo/c/dr_libs/dr_wav.h:542
drwav__on_write_memory
DRWAV_PRIVATE size_t drwav__on_write_memory(void *pUserData, const void *pDataIn, size_t bytesToWrite)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49101
DRWAV_FREE
#define DRWAV_FREE(p)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46291
drwav_metadata_type_list_all_info_strings
@ drwav_metadata_type_list_all_info_strings
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:486
DRWAV_INST_BYTES
#define DRWAV_INST_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46880
drwav_init_file_write__internal_FILE
DRWAV_PRIVATE drwav_bool32 drwav_init_file_write__internal_FILE(drwav *pWav, FILE *pFile, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48999
drwav_metadata::bext
drwav_bext bext
Definition: porcupine/demo/c/dr_libs/dr_wav.h:797
drwav_metadata_location_inside_info_list
@ drwav_metadata_location_inside_info_list
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:771
drwav__bswap_samples_s24
static DRWAV_INLINE void drwav__bswap_samples_s24(drwav_uint8 *pSamples, drwav_uint64 sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46493
DRWAV_FALSE
#define DRWAV_FALSE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:165
drwav_bool32
drwav_uint32 drwav_bool32
Definition: porcupine/demo/c/dr_libs/dr_wav.h:163
drwav_metadata::labelledCueRegion
drwav_list_labelled_cue_region labelledCueRegion
Definition: porcupine/demo/c/dr_libs/dr_wav.h:799
drwavGUID_W64_RIFF
static const drwav_uint8 drwavGUID_W64_RIFF[16]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46387
drwav_read_pcm_frames_s16__mulaw
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__mulaw(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49988
drwav_container_riff
@ drwav_container_riff
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:276
drwav_seek_origin_current
@ drwav_seek_origin_current
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:271
drwav_fmt::validBitsPerSample
drwav_uint16 validBitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_wav.h:330
drwav_u8_to_f32
DRWAV_API void drwav_u8_to_f32(float *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50352
drwav_take_ownership_of_metadata
DRWAV_API drwav_metadata * drwav_take_ownership_of_metadata(drwav *pWav)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47814
drwav_list_labelled_cue_region::country
drwav_uint16 country
Definition: porcupine/demo/c/dr_libs/dr_wav.h:746
DRWAV_LIST_LABELLED_TEXT_BYTES
#define DRWAV_LIST_LABELLED_TEXT_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46891
drwav_chunk_header::guid
drwav_uint8 guid[16]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:286
drwav__on_write_stdio
DRWAV_PRIVATE size_t drwav__on_write_stdio(void *pUserData, const void *pData, size_t bytesToWrite)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48935
drwav__metadata_parser::pData
drwav_uint8 * pData
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46906
DRWAV_ALREADY_IN_USE
#define DRWAV_ALREADY_IN_USE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:221
drwav::totalPCMFrameCount
drwav_uint64 totalPCMFrameCount
Definition: porcupine/demo/c/dr_libs/dr_wav.h:843
drwav__bswap_samples_pcm
static DRWAV_INLINE void drwav__bswap_samples_pcm(void *pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46546
drwav_fmt::subFormat
drwav_uint8 subFormat[16]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:336
drwav__malloc_from_callbacks
DRWAV_PRIVATE void * drwav__malloc_from_callbacks(size_t sz, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46632
drwav_free
DRWAV_API void drwav_free(void *p, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51037
DRWAV_NOT_IMPLEMENTED
#define DRWAV_NOT_IMPLEMENTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:227
drwav_list_label_or_note::stringLength
drwav_uint32 stringLength
Definition: porcupine/demo/c/dr_libs/dr_wav.h:667
drwav_metadata_type_list_info_genre
@ drwav_metadata_type_list_info_genre
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:481
drwavGUID_W64_WAVE
static const drwav_uint8 drwavGUID_W64_WAVE[16]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46388
drwav_read_pcm_frames_s32
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50607
DRWAV_MAX_BITS_PER_SAMPLE
#define DRWAV_MAX_BITS_PER_SAMPLE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46385
drwav_guid_equal
DRWAV_API drwav_bool32 drwav_guid_equal(const drwav_uint8 a[16], const drwav_uint8 b[16])
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51080
DRWAV_NO_SPACE
#define DRWAV_NO_SPACE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:216
drwav_acid_flag_one_shot
@ drwav_acid_flag_one_shot
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:624
drwav_init_write
DRWAV_API drwav_bool32 drwav_init_write(drwav *pWav, const drwav_data_format *pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void *pUserData, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48378
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
drwav_metadata_type_unknown
@ drwav_metadata_type_unknown
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:455
drwav__pcm_to_s16
DRWAV_PRIVATE void drwav__pcm_to_s16(drwav_int16 *pOut, const drwav_uint8 *pIn, size_t totalSampleCount, unsigned int bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49862
DRWAV_INTERRUPT
#define DRWAV_INTERRUPT
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:219
drwav__metadata_copy_string
DRWAV_PRIVATE char * drwav__metadata_copy_string(drwav__metadata_parser *pParser, char *str, size_t maxToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47078
drwav_countof
#define drwav_countof(x)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46302
drwav_bytes_to_guid
static DRWAV_INLINE void drwav_bytes_to_guid(const drwav_uint8 *data, drwav_uint8 *guid)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46403
drwav_bext::loudnessRange
drwav_uint16 loudnessRange
Definition: porcupine/demo/c/dr_libs/dr_wav.h:706
drwav_read_pcm_frames_be
DRWAV_API drwav_uint64 drwav_read_pcm_frames_be(drwav *pWav, drwav_uint64 framesToRead, void *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49348
drwav_chunk_header::sizeInBytes
drwav_uint64 sizeInBytes
Definition: porcupine/demo/c/dr_libs/dr_wav.h:290
drwav_smpl_loop::type
drwav_uint32 type
Definition: porcupine/demo/c/dr_libs/dr_wav.h:523
drwav__ieee_to_s16
DRWAV_PRIVATE void drwav__ieee_to_s16(drwav_int16 *pOut, const drwav_uint8 *pIn, size_t totalSampleCount, unsigned int bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49900
drwav_inst::highNote
drwav_int8 highNote
Definition: porcupine/demo/c/dr_libs/dr_wav.h:579
drwav_preinit
DRWAV_PRIVATE drwav_bool32 drwav_preinit(drwav *pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void *pReadSeekUserData, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47489
drwav_bext::loudnessValue
drwav_uint16 loudnessValue
Definition: porcupine/demo/c/dr_libs/dr_wav.h:705
drwav_metadata::labelOrNote
drwav_list_label_or_note labelOrNote
Definition: porcupine/demo/c/dr_libs/dr_wav.h:798
DRWAV_NOT_UNIQUE
#define DRWAV_NOT_UNIQUE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:234
DRWAV_BUSY
#define DRWAV_BUSY
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:217
drwav_metadata::type
drwav_metadata_type type
Definition: porcupine/demo/c/dr_libs/dr_wav.h:789
drwav_f64_to_s16
DRWAV_API void drwav_f64_to_s16(drwav_int16 *pOut, const double *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50105
drwav_smpl::pLoops
drwav_smpl_loop * pLoops
Definition: porcupine/demo/c/dr_libs/dr_wav.h:563
drwav__write_or_count_u32ne_to_le
DRWAV_PRIVATE size_t drwav__write_or_count_u32ne_to_le(drwav *pWav, drwav_uint32 value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47895
drwav::predictor
drwav_uint16 predictor[2]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:886
errno
int errno
DRWAV_CUE_POINT_BYTES
#define DRWAV_CUE_POINT_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46889
drwav_inst::highVelocity
drwav_int8 highVelocity
Definition: porcupine/demo/c/dr_libs/dr_wav.h:581
DRWAV_ERROR
#define DRWAV_ERROR
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:199
drwav_allocation_callbacks::onRealloc
void *(* onRealloc)(void *p, size_t sz, void *pUserData)
Definition: porcupine/demo/c/dr_libs/dr_wav.h:413
DRWAV_BAD_MESSAGE
#define DRWAV_BAD_MESSAGE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:229
drwav_init_file_with_metadata_w
DRWAV_API drwav_bool32 drwav_init_file_with_metadata_w(drwav *pWav, const wchar_t *filename, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48991
drwav__memory_stream_write::dataSize
size_t dataSize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:430
drwav_bext::codingHistorySize
drwav_uint32 codingHistorySize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:699
drwav__riff_chunk_size_riff
DRWAV_PRIVATE drwav_uint32 drwav__riff_chunk_size_riff(drwav_uint64 dataChunkSize, drwav_metadata *pMetadata, drwav_uint32 metadataCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48231
drwav_bext::maxShortTermLoudness
drwav_uint16 maxShortTermLoudness
Definition: porcupine/demo/c/dr_libs/dr_wav.h:709
drwav_smpl_loop
Definition: porcupine/demo/c/dr_libs/dr_wav.h:517
drwav_cue_point::chunkStart
drwav_uint32 chunkStart
Definition: porcupine/demo/c/dr_libs/dr_wav.h:602
DRWAV_SMPL_LOOP_BYTES
#define DRWAV_SMPL_LOOP_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46879
DRWAV_BEXT_BYTES
#define DRWAV_BEXT_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46883
drwav_acid
Definition: porcupine/demo/c/dr_libs/dr_wav.h:631
drwav__chunk_padding_size_riff
DRWAV_PRIVATE unsigned int drwav__chunk_padding_size_riff(drwav_uint64 chunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46695
drwav_result_from_errno
DRWAV_PRIVATE drwav_result drwav_result_from_errno(int e)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48427
drwav_smpl::smpteOffset
drwav_uint32 smpteOffset
Definition: porcupine/demo/c/dr_libs/dr_wav.h:555
drwav__on_read_memory
DRWAV_PRIVATE size_t drwav__on_read_memory(void *pUserData, void *pBufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49061
drwav_open_file_and_read_pcm_frames_s32
DRWAV_API drwav_int32 * drwav_open_file_and_read_pcm_frames_s32(const char *filename, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50916
drwav::allowedMetadataTypes
drwav_metadata_type allowedMetadataTypes
Definition: porcupine/demo/c/dr_libs/dr_wav.h:870
DRWAV_MAX_CHANNELS
#define DRWAV_MAX_CHANNELS
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46382
drwav_f32_to_s32
DRWAV_API void drwav_f32_to_s32(drwav_int32 *pOut, const float *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50688
drwav::stepIndex
drwav_int32 stepIndex[2]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:898
drwav::onWrite
drwav_write_proc onWrite
Definition: porcupine/demo/c/dr_libs/dr_wav.h:811
drwav_smpl_loop_type_forward
@ drwav_smpl_loop_type_forward
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:512
drwav_metadata_type_list_info_album
@ drwav_metadata_type_list_info_album
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:482
drwav_list_labelled_cue_region::codePage
drwav_uint16 codePage
Definition: porcupine/demo/c/dr_libs/dr_wav.h:749
DR_WAVE_FORMAT_DVI_ADPCM
#define DR_WAVE_FORMAT_DVI_ADPCM
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:259
drwav::bytesRemaining
drwav_uint64 bytesRemaining
Definition: porcupine/demo/c/dr_libs/dr_wav.h:853
drwav__on_seek_stdio
DRWAV_PRIVATE drwav_bool32 drwav__on_seek_stdio(void *pUserData, int offset, drwav_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48939
drwav__ieee_to_s32
DRWAV_PRIVATE void drwav__ieee_to_s32(drwav_int32 *pOut, const drwav_uint8 *pIn, size_t totalSampleCount, unsigned int bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50474
drwav__metadata_parser::pMetadata
drwav_metadata * pMetadata
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46904
drwav__read_bext_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_bext_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata, drwav_uint64 chunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47091
drwav_write_proc
size_t(* drwav_write_proc)(void *pUserData, const void *pData, size_t bytesToWrite)
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:367
drwav_open_file_and_read_pcm_frames_s16_w
DRWAV_API drwav_int16 * drwav_open_file_and_read_pcm_frames_s16_w(const wchar_t *filename, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50933
drwav_inst
Definition: porcupine/demo/c/dr_libs/dr_wav.h:573
DRWAV_NO_MESSAGE
#define DRWAV_NO_MESSAGE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:228
drwav_metadata_type_cue
@ drwav_metadata_type_cue
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:460
drwav_init_file_write_w
DRWAV_API drwav_bool32 drwav_init_file_write_w(drwav *pWav, const wchar_t *filename, const drwav_data_format *pFormat, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49045
drwav_metadata_type_list_info_comment
@ drwav_metadata_type_list_info_comment
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:479
drwav__metadata_memory_capacity
DRWAV_PRIVATE size_t drwav__metadata_memory_capacity(drwav__metadata_parser *pParser)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46911
drwav_list_info_text::pString
char * pString
Definition: porcupine/demo/c/dr_libs/dr_wav.h:725
DRWAV_TIMEOUT
#define DRWAV_TIMEOUT
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:232
drwav_s32_to_f32
DRWAV_API void drwav_s32_to_f32(float *pOut, const drwav_int32 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50396
drwav::pMetadata
drwav_metadata * pMetadata
Definition: porcupine/demo/c/dr_libs/dr_wav.h:873
DRWAV_AT_END
#define DRWAV_AT_END
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:251
drwav_init_file_w
DRWAV_API drwav_bool32 drwav_init_file_w(drwav *pWav, const wchar_t *filename, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48971
drwav_smpl::samplePeriodNanoseconds
drwav_uint32 samplePeriodNanoseconds
Definition: porcupine/demo/c/dr_libs/dr_wav.h:545
drwav__chunk_matches
DRWAV_PRIVATE drwav_bool32 drwav__chunk_matches(drwav_uint64 allowedMetadataTypes, const drwav_uint8 *pChunkID, drwav_metadata_type type, const char *pID)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47260
drwav_result
drwav_int32 drwav_result
Definition: porcupine/demo/c/dr_libs/dr_wav.h:197
drwav_metadata_type_all
@ drwav_metadata_type_all
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:500
drwav_init
DRWAV_API drwav_bool32 drwav_init(drwav *pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void *pUserData, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47795
drwav_chunk_proc
drwav_uint64(* drwav_chunk_proc)(void *pChunkUserData, drwav_read_proc onRead, drwav_seek_proc onSeek, void *pReadSeekUserData, const drwav_chunk_header *pChunkHeader, drwav_container container, const drwav_fmt *pFMT)
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:407
drwav::dataChunkDataSizeTargetWrite
drwav_uint64 dataChunkDataSizeTargetWrite
Definition: porcupine/demo/c/dr_libs/dr_wav.h:863
drwav_uint64
unsigned long long drwav_uint64
Definition: porcupine/demo/c/dr_libs/dr_wav.h:152
drwav_acid::numBeats
drwav_uint32 numBeats
Definition: porcupine/demo/c/dr_libs/dr_wav.h:644
drwav__bswap_samples_f64
static DRWAV_INLINE void drwav__bswap_samples_f64(double *pSamples, drwav_uint64 sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46539
drwav__memory_stream::dataSize
size_t dataSize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:421
drwav_chunk_header::fourcc
drwav_uint8 fourcc[4]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:285
drwav__bswap16
static DRWAV_INLINE drwav_uint16 drwav__bswap16(drwav_uint16 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46410
drwav_fopen
DRWAV_PRIVATE drwav_result drwav_fopen(FILE **ppFile, const char *pFilePath, const char *pOpenMode)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48828
drwav_open_and_read_pcm_frames_s32
DRWAV_API drwav_int32 * drwav_open_and_read_pcm_frames_s32(drwav_read_proc onRead, drwav_seek_proc onSeek, void *pUserData, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50864
drwav_init_with_metadata
DRWAV_API drwav_bool32 drwav_init_with_metadata(drwav *pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, void *pUserData, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47806
drwav__seek_forward
DRWAV_PRIVATE drwav_bool32 drwav__seek_forward(drwav_seek_proc onSeek, drwav_uint64 offset, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46733
drwav_read_pcm_frames_f32__mulaw
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__mulaw(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50284
drwav_cue_point::dataChunkId
drwav_uint8 dataChunkId[4]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:599
drwav_fmt::channelMask
drwav_uint32 channelMask
Definition: porcupine/demo/c/dr_libs/dr_wav.h:333
drwav__strlen_clamped
DRWAV_PRIVATE size_t drwav__strlen_clamped(char *str, size_t maxToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47070
drwav_init_file_with_metadata
DRWAV_API drwav_bool32 drwav_init_file_with_metadata(drwav *pWav, const char *filename, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48983
drwav_cue_point::playOrderPosition
drwav_uint32 playOrderPosition
Definition: porcupine/demo/c/dr_libs/dr_wav.h:596
drwav_smpl::pSamplerSpecificData
drwav_uint8 * pSamplerSpecificData
Definition: porcupine/demo/c/dr_libs/dr_wav.h:564
DR_WAVE_FORMAT_PCM
#define DR_WAVE_FORMAT_PCM
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:254
drwav__write_or_count_string_to_fixed_size_buf
DRWAV_PRIVATE size_t drwav__write_or_count_string_to_fixed_size_buf(drwav *pWav, char *str, size_t bufFixedSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47918
drwav__bswap_samples_ieee
static DRWAV_INLINE void drwav__bswap_samples_ieee(void *pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46568
drwav_allocation_callbacks::onFree
void(* onFree)(void *p, void *pUserData)
Definition: porcupine/demo/c/dr_libs/dr_wav.h:414
drwav_read_raw
DRWAV_API size_t drwav_read_raw(drwav *pWav, size_t bytesToRead, void *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49281
drwav__metadata_get_memory
DRWAV_PRIVATE drwav_uint8 * drwav__metadata_get_memory(drwav__metadata_parser *pParser, size_t size, size_t align)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46919
DRWAV_COPY_MEMORY
#define DRWAV_COPY_MEMORY(dst, src, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46294
drwav__pcm_to_f32
DRWAV_PRIVATE void drwav__pcm_to_f32(float *pOut, const drwav_uint8 *pIn, size_t sampleCount, unsigned int bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50133
drwav::sampleRate
drwav_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/dr_wav.h:831
drwav_container
drwav_container
Definition: porcupine/demo/c/dr_libs/dr_wav.h:274
drwav_metadata_type_smpl
@ drwav_metadata_type_smpl
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:458
DRWAV_IS_DIRECTORY
#define DRWAV_IS_DIRECTORY
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:213
DRWAV_DIRECTORY_NOT_EMPTY
#define DRWAV_DIRECTORY_NOT_EMPTY
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:214
drwav_read_pcm_frames
DRWAV_API drwav_uint64 drwav_read_pcm_frames(drwav *pWav, drwav_uint64 framesToRead, void *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49356
drwav_chunk_header
Definition: porcupine/demo/c/dr_libs/dr_wav.h:281
DRWAV_NO_HOST
#define DRWAV_NO_HOST
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:247
drwav__read_smpl_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_smpl_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46960
DR_WAVE_FORMAT_MULAW
#define DR_WAVE_FORMAT_MULAW
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:258
drwav__bswap_samples
static DRWAV_INLINE void drwav__bswap_samples(void *pSamples, drwav_uint64 sampleCount, drwav_uint32 bytesPerSample, drwav_uint16 format)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46592
drwav_smpl_loop::lastSampleByteOffset
drwav_uint32 lastSampleByteOffset
Definition: porcupine/demo/c/dr_libs/dr_wav.h:529
drwavGUID_W64_DATA
static const drwav_uint8 drwavGUID_W64_DATA[16]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46391
drwav::onRead
drwav_read_proc onRead
Definition: porcupine/demo/c/dr_libs/dr_wav.h:808
drwav_open_memory_and_read_pcm_frames_s32
DRWAV_API drwav_int32 * drwav_open_memory_and_read_pcm_frames_s32(const void *data, size_t dataSize, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51019
drwav::metadataCount
drwav_uint32 metadataCount
Definition: porcupine/demo/c/dr_libs/dr_wav.h:874
drwav_bext::pDescription
char * pDescription
Definition: porcupine/demo/c/dr_libs/dr_wav.h:686
drwav_init_file_write_sequential_pcm_frames_w
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames_w(drwav *pWav, const wchar_t *filename, const drwav_data_format *pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49053
drwav__is_little_endian
static DRWAV_INLINE int drwav__is_little_endian(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46392
drwav__bswap32
static DRWAV_INLINE drwav_uint32 drwav__bswap32(drwav_uint32 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46425
drwav_bext::maxTruePeakLevel
drwav_uint16 maxTruePeakLevel
Definition: porcupine/demo/c/dr_libs/dr_wav.h:707
drwav_read_proc
size_t(* drwav_read_proc)(void *pUserData, void *pBufferOut, size_t bytesToRead)
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:354
DR_WAVE_FORMAT_ALAW
#define DR_WAVE_FORMAT_ALAW
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:257
drwav_open_and_read_pcm_frames_f32
DRWAV_API float * drwav_open_and_read_pcm_frames_f32(drwav_read_proc onRead, drwav_seek_proc onSeek, void *pUserData, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50847
drwav_open_file_and_read_pcm_frames_f32
DRWAV_API float * drwav_open_file_and_read_pcm_frames_f32(const char *filename, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50899
f
f
DRWAV_DOES_NOT_EXIST
#define DRWAV_DOES_NOT_EXIST
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:205
drwavGUID_W64_FMT
static const drwav_uint8 drwavGUID_W64_FMT[16]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46389
drwav_init_memory_write__internal
DRWAV_PRIVATE 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, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49184
drwav__mulaw_to_s16
static DRWAV_INLINE drwav_int16 drwav__mulaw_to_s16(drwav_uint8 sampleIn)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49858
drwav__metadata_parser
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46898
drwav__on_read
DRWAV_PRIVATE size_t drwav__on_read(drwav_read_proc onRead, void *pUserData, void *pBufferOut, size_t bytesToRead, drwav_uint64 *pCursor)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46853
drwav_read_pcm_frames_s32__ima
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ima(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50528
drwav_read_pcm_frames_s32le
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32le(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50638
drwav_open_memory_and_read_pcm_frames_f32
DRWAV_API float * drwav_open_memory_and_read_pcm_frames_f32(const void *data, size_t dataSize, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51002
drwav_bytes_to_s32
DRWAV_API drwav_int32 drwav_bytes_to_s32(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51066
drwav_acid_flag_acidizer
@ drwav_acid_flag_acidizer
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:628
drwav_read_pcm_frames_s16__ima
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ima(drwav *pWav, drwav_uint64 samplesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49697
drwav__read_chunk_header
DRWAV_PRIVATE drwav_result drwav__read_chunk_header(drwav_read_proc onRead, void *pUserData, drwav_container container, drwav_uint64 *pRunningBytesReadOut, drwav_chunk_header *pHeaderOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46706
drwav_s24_to_s32
DRWAV_API void drwav_s24_to_s32(drwav_int32 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50674
drwav__read_pcm_frames_and_close_s16
DRWAV_PRIVATE drwav_int16 * drwav__read_pcm_frames_and_close_s16(drwav *pWav, unsigned int *channels, unsigned int *sampleRate, drwav_uint64 *totalFrameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50728
drwav_acid_flag
drwav_acid_flag
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:622
drwav_init_memory_write
DRWAV_API drwav_bool32 drwav_init_memory_write(drwav *pWav, void **ppData, size_t *pDataSize, const drwav_data_format *pFormat, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49201
drwav_allocation_callbacks::pUserData
void * pUserData
Definition: porcupine/demo/c/dr_libs/dr_wav.h:411
drwav__write_or_count_metadata
DRWAV_PRIVATE size_t drwav__write_or_count_metadata(drwav *pWav, drwav_metadata *pMetadatas, drwav_uint32 metadataCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47934
drwav_unknown_metadata::pData
drwav_uint8 * pData
Definition: porcupine/demo/c/dr_libs/dr_wav.h:780
drwav_inst::lowNote
drwav_int8 lowNote
Definition: porcupine/demo/c/dr_libs/dr_wav.h:578
drwav_int32
signed int drwav_int32
Definition: porcupine/demo/c/dr_libs/dr_wav.h:138
DRWAV_ZERO_MEMORY
#define DRWAV_ZERO_MEMORY(p, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46297
drwav_f64_to_s32
DRWAV_API void drwav_f64_to_s32(drwav_int32 *pOut, const double *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50698
drwav_open_memory_and_read_pcm_frames_s16
DRWAV_API drwav_int16 * drwav_open_memory_and_read_pcm_frames_s16(const void *data, size_t dataSize, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50985
DRWAV_INVALID_FILE
#define DRWAV_INVALID_FILE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:208
DRWAV_VERSION_STRING
#define DRWAV_VERSION_STRING
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:129
drwav_metadata::cue
drwav_cue cue
Definition: porcupine/demo/c/dr_libs/dr_wav.h:793
drwav_fmt::channels
drwav_uint16 channels
Definition: porcupine/demo/c/dr_libs/dr_wav.h:308
drwav_copy_allocation_callbacks_or_defaults
DRWAV_PRIVATE drwav_allocation_callbacks drwav_copy_allocation_callbacks_or_defaults(const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46676
DRWAV_BEXT_ORIGINATOR_NAME_BYTES
#define DRWAV_BEXT_ORIGINATOR_NAME_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46885
drwav__write_or_count
DRWAV_PRIVATE size_t drwav__write_or_count(drwav *pWav, const void *pData, size_t dataSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47874
drwav_smpl::manufacturerId
drwav_uint32 manufacturerId
Definition: porcupine/demo/c/dr_libs/dr_wav.h:541
drwav__seek_from_start
DRWAV_PRIVATE drwav_bool32 drwav__seek_from_start(drwav_seek_proc onSeek, drwav_uint64 offset, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46751
drwav_metadata_type
drwav_metadata_type
Definition: porcupine/demo/c/dr_libs/dr_wav.h:444
drwav__on_seek_memory
DRWAV_PRIVATE drwav_bool32 drwav__on_seek_memory(void *pUserData, int offset, drwav_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49077
drwav_fmt::extendedSize
drwav_uint16 extendedSize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:323
drwav_metadata_type_list_info_date
@ drwav_metadata_type_list_info_date
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:480
drwav::dataChunkDataSize
drwav_uint64 dataChunkDataSize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:847
drwav_metadata_type_list_labelled_cue_region
@ drwav_metadata_type_list_labelled_cue_region
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:473
drwav_mulaw_to_s16
DRWAV_API void drwav_mulaw_to_s16(drwav_int16 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50126
drwav_metadata_location
drwav_metadata_location
Definition: porcupine/demo/c/dr_libs/dr_wav.h:767
DRWAV_TOO_MANY_LINKS
#define DRWAV_TOO_MANY_LINKS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:226
drwav_read_pcm_frames_f32
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50305
DRWAV_OUT_OF_MEMORY
#define DRWAV_OUT_OF_MEMORY
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:202
drwav__write
DRWAV_PRIVATE size_t drwav__write(drwav *pWav, const void *pData, size_t dataSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47821
drwav_open_file_and_read_pcm_frames_s16
DRWAV_API drwav_int16 * drwav_open_file_and_read_pcm_frames_s16(const char *filename, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50882
drwav_bext::timeReference
drwav_uint64 timeReference
Definition: porcupine/demo/c/dr_libs/dr_wav.h:691
drwav_fourcc_equal
DRWAV_API drwav_bool32 drwav_fourcc_equal(const drwav_uint8 *a, const char *b)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51090
DRWAV_PATH_TOO_LONG
#define DRWAV_PATH_TOO_LONG
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:210
drwav__bswap_f32
static DRWAV_INLINE float drwav__bswap_f32(float n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46512
drwav_metadata::inst
drwav_inst inst
Definition: porcupine/demo/c/dr_libs/dr_wav.h:796
drwav_fmt
Definition: porcupine/demo/c/dr_libs/dr_wav.h:299
drwav_s16_to_s32
DRWAV_API void drwav_s16_to_s32(drwav_int32 *pOut, const drwav_int16 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50664
drwav__metadata_parser::onRead
drwav_read_proc onRead
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46900
drwav_list_labelled_cue_region::pString
char * pString
Definition: porcupine/demo/c/dr_libs/dr_wav.h:755
DRWAV_CANCELLED
#define DRWAV_CANCELLED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:249
drwav_seek_proc
drwav_bool32(* drwav_seek_proc)(void *pUserData, int offset, drwav_seek_origin origin)
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:381
drwav_data_format::format
drwav_uint32 format
Definition: porcupine/demo/c/dr_libs/dr_wav.h:438
drwav_bytes_to_u32
DRWAV_API drwav_uint32 drwav_bytes_to_u32(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51053
drwav_seek_origin_start
@ drwav_seek_origin_start
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:270
drwav_list_label_or_note
Definition: porcupine/demo/c/dr_libs/dr_wav.h:661
DRWAV_SIZE_MAX
#define DRWAV_SIZE_MAX
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46334
drwav_metadata_type_list_info_copyright
@ drwav_metadata_type_list_info_copyright
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:476
drwav::cachedFrames
drwav_int32 cachedFrames[4]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:888
drwav__metadata_parser::pReadSeekUserData
void * pReadSeekUserData
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46902
drwav_cue_point
Definition: porcupine/demo/c/dr_libs/dr_wav.h:590
drwav__malloc_default
DRWAV_PRIVATE void * drwav__malloc_default(size_t sz, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46617
drwav_read_pcm_frames_s32__mulaw
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__mulaw(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50586
drwav_data_format::channels
drwav_uint32 channels
Definition: porcupine/demo/c/dr_libs/dr_wav.h:439
drwav_bext::pOriginationDate
char pOriginationDate[10]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:689
drwav_smpl_loop::playCount
drwav_uint32 playCount
Definition: porcupine/demo/c/dr_libs/dr_wav.h:535
drwav_metadata::infoText
drwav_list_info_text infoText
Definition: porcupine/demo/c/dr_libs/dr_wav.h:800
DRWAV_METADATA_ALIGNMENT
#define DRWAV_METADATA_ALIGNMENT
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46892
drwav__bswap64
static DRWAV_INLINE drwav_uint64 drwav__bswap64(drwav_uint64 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46454
DRWAV_NOT_DIRECTORY
#define DRWAV_NOT_DIRECTORY
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:212
drwav_chunk_header::paddingSize
unsigned int paddingSize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:296
drwav_read_pcm_frames_s16__pcm
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__pcm(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49913
drwav_fmt::sampleRate
drwav_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/dr_wav.h:311
DRWAV_BEXT_DESCRIPTION_BYTES
#define DRWAV_BEXT_DESCRIPTION_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46884
drwav_inst::midiUnityNote
drwav_int8 midiUnityNote
Definition: porcupine/demo/c/dr_libs/dr_wav.h:575
drwav_metadata_type_list_info_software
@ drwav_metadata_type_list_info_software
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:475
DRWAV_BAD_SEEK
#define DRWAV_BAD_SEEK
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:223
drwav_metadata_type
drwav_metadata_type
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:444
drwav_smpl::samplerSpecificDataSizeInBytes
drwav_uint32 samplerSpecificDataSizeInBytes
Definition: porcupine/demo/c/dr_libs/dr_wav.h:561
DRWAV_SEQUENTIAL
#define DRWAV_SEQUENTIAL
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:263
drwav__bswap_f64
static DRWAV_INLINE double drwav__bswap_f64(double n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46529
drwav_cue_point::id
drwav_uint32 id
Definition: porcupine/demo/c/dr_libs/dr_wav.h:593
drwav_read_pcm_frames_s16__ieee
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__ieee(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49938
drwav_f64_to_f32
DRWAV_API void drwav_f64_to_f32(float *pOut, const double *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50406
drwav_target_write_size_bytes
DRWAV_API drwav_uint64 drwav_target_write_size_bytes(const drwav_data_format *pFormat, drwav_uint64 totalFrameCount, drwav_metadata *pMetadata, drwav_uint32 metadataCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48408
drwav__data_chunk_size_rf64
DRWAV_PRIVATE drwav_uint64 drwav__data_chunk_size_rf64(drwav_uint64 dataChunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48264
DRWAV_CONNECTION_REFUSED
#define DRWAV_CONNECTION_REFUSED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:246
drwav_mulaw_to_f32
DRWAV_API void drwav_mulaw_to_f32(float *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50426
drwav_bext::version
drwav_uint16 version
Definition: porcupine/demo/c/dr_libs/dr_wav.h:692
drwav_metadata_location_top_level
@ drwav_metadata_location_top_level
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:770
drwav__read_inst_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_inst_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47035
DRWAV_OUT_OF_RANGE
#define DRWAV_OUT_OF_RANGE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:203
drwav__write_u16ne_to_le
DRWAV_PRIVATE size_t drwav__write_u16ne_to_le(drwav *pWav, drwav_uint16 value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47833
drwav_metadata_type_all_including_unknown
@ drwav_metadata_type_all_including_unknown
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:501
drwav__metadata_request_extra_memory_for_stage_2
DRWAV_PRIVATE void drwav__metadata_request_extra_memory_for_stage_2(drwav__metadata_parser *pParser, size_t bytes, size_t align)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46933
drwav_init_file_write_sequential_pcm_frames
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_pcm_frames(drwav *pWav, const char *filename, const drwav_data_format *pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49038
drwav_cue::cuePointCount
drwav_uint32 cuePointCount
Definition: porcupine/demo/c/dr_libs/dr_wav.h:613
drwav__memory_stream_write::dataCapacity
size_t dataCapacity
Definition: porcupine/demo/c/dr_libs/dr_wav.h:431
drwav_uint32
unsigned int drwav_uint32
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:139
drwav_int64
signed long long drwav_int64
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:151
DRWAV_NO_DATA_AVAILABLE
#define DRWAV_NO_DATA_AVAILABLE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:230
drwav::isSequentialWrite
drwav_bool32 isSequentialWrite
Definition: porcupine/demo/c/dr_libs/dr_wav.h:866
drwav_bext::pOriginatorReference
char * pOriginatorReference
Definition: porcupine/demo/c/dr_libs/dr_wav.h:688
DRWAV_PROTOCOL_NOT_SUPPORTED
#define DRWAV_PROTOCOL_NOT_SUPPORTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:239
drwav_uninit
DRWAV_API drwav_result drwav_uninit(drwav *pWav)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49216
drwav_list_labelled_cue_region::purposeId
drwav_uint8 purposeId[4]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:743
drwav_metadata_type_none
@ drwav_metadata_type_none
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:446
drwav__alaw_to_s16
static DRWAV_INLINE drwav_int16 drwav__alaw_to_s16(drwav_uint8 sampleIn)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49854
DRWAV_ALREADY_EXISTS
#define DRWAV_ALREADY_EXISTS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:206
drwav_read_pcm_frames_s16
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50013
drwav_fmt::formatTag
drwav_uint16 formatTag
Definition: porcupine/demo/c/dr_libs/dr_wav.h:305
drwav::readCursorInPCMFrames
drwav_uint64 readCursorInPCMFrames
Definition: porcupine/demo/c/dr_libs/dr_wav.h:856
drwav::onSeek
drwav_seek_proc onSeek
Definition: porcupine/demo/c/dr_libs/dr_wav.h:814
drwav_int32
signed int drwav_int32
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:138
drwav__read_list_label_or_note_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_list_label_or_note_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata, drwav_uint64 chunkSize, drwav_metadata_type type)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47147
drwav_uintptr
drwav_uint32 drwav_uintptr
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:160
DRWAV_REALLOC
#define DRWAV_REALLOC(p, sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46288
DRWAV_BEXT_ORIGINATOR_REF_BYTES
#define DRWAV_BEXT_ORIGINATOR_REF_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46886
drwav_list_labelled_cue_region::language
drwav_uint16 language
Definition: porcupine/demo/c/dr_libs/dr_wav.h:747
drwav_write_pcm_frames_be
DRWAV_API drwav_uint64 drwav_write_pcm_frames_be(drwav *pWav, drwav_uint64 framesToWrite, const void *pData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49519
drwav_read_pcm_frames_f32__ieee
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__ieee(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50238
DRWAV_INLINE
#define DRWAV_INLINE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46326
drwav_uint64
unsigned long long drwav_uint64
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:152
drwav::dataChunkDataPos
drwav_uint64 dataChunkDataPos
Definition: porcupine/demo/c/dr_libs/dr_wav.h:850
drwav::memoryStream
drwav__memory_stream memoryStream
Definition: porcupine/demo/c/dr_libs/dr_wav.h:878
drwav__metadata_parser::metadataCursor
drwav_uint64 metadataCursor
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46908
drwav_metadata_type_list_info_title
@ drwav_metadata_type_list_info_title
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:477
drwav_list_labelled_cue_region::dialect
drwav_uint16 dialect
Definition: porcupine/demo/c/dr_libs/dr_wav.h:748
DRWAV_BAD_ADDRESS
#define DRWAV_BAD_ADDRESS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:222
drwav__bswap_samples_f32
static DRWAV_INLINE void drwav__bswap_samples_f32(float *pSamples, drwav_uint64 sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46522
drwav__read_pcm_frames_and_close_s32
DRWAV_PRIVATE drwav_int32 * drwav__read_pcm_frames_and_close_s32(drwav *pWav, unsigned int *channels, unsigned int *sampleRate, drwav_uint64 *totalFrameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50796
drwav__is_compressed_format_tag
static DRWAV_INLINE drwav_bool32 drwav__is_compressed_format_tag(drwav_uint16 formatTag)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46689
drwav__metadata_parser_read
DRWAV_PRIVATE size_t drwav__metadata_parser_read(drwav__metadata_parser *pParser, void *pBufferOut, size_t bytesToRead, drwav_uint64 *pCursor)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46952
drwav_init_memory_write_sequential_pcm_frames
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential_pcm_frames(drwav *pWav, void **ppData, size_t *pDataSize, const drwav_data_format *pFormat, drwav_uint64 totalPCMFrameCount, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49209
drwav_alaw_to_s16
DRWAV_API void drwav_alaw_to_s16(drwav_int16 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50119
DRWAV_ASSERT
#define DRWAV_ASSERT(expression)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46282
drwav_get_length_in_pcm_frames
DRWAV_API drwav_result drwav_get_length_in_pcm_frames(drwav *pWav, drwav_uint64 *pLength)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49468
L
#define L
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/stb_vorbis.c:5102
DRWAV_ZERO_OBJECT
#define DRWAV_ZERO_OBJECT(p)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46300
drwav__bswap_s16
static DRWAV_INLINE drwav_int16 drwav__bswap_s16(drwav_int16 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46475
drwav_list_label_or_note::cuePointId
drwav_uint32 cuePointId
Definition: porcupine/demo/c/dr_libs/dr_wav.h:664
drwav_metadata::smpl
drwav_smpl smpl
Definition: porcupine/demo/c/dr_libs/dr_wav.h:794
drwav_metadata
Definition: porcupine/demo/c/dr_libs/dr_wav.h:786
drwav_data_format::container
drwav_container container
Definition: porcupine/demo/c/dr_libs/dr_wav.h:437
drwav_int16
signed short drwav_int16
Definition: porcupine/demo/c/dr_libs/dr_wav.h:136
drwav_acid::meterDenominator
drwav_uint16 meterDenominator
Definition: porcupine/demo/c/dr_libs/dr_wav.h:647
drwav_uint8
unsigned char drwav_uint8
Definition: porcupine/demo/c/dr_libs/dr_wav.h:135
drwav_metadata_location
drwav_metadata_location
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:767
drwav_bytes_to_s64
DRWAV_API drwav_int64 drwav_bytes_to_s64(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51076
drwav_uintptr
drwav_uint32 drwav_uintptr
Definition: porcupine/demo/c/dr_libs/dr_wav.h:160
drwav_mulaw_to_s32
DRWAV_API void drwav_mulaw_to_s32(drwav_int32 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50718
drwav_init_file_write_w__internal
DRWAV_PRIVATE drwav_bool32 drwav_init_file_write_w__internal(drwav *pWav, const wchar_t *filename, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49022
drwav_metadata_type_list_label
@ drwav_metadata_type_list_label
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:471
drwav_bext::pCodingHistory
char * pCodingHistory
Definition: porcupine/demo/c/dr_libs/dr_wav.h:698
drwav::cachedFrameCount
drwav_uint32 cachedFrameCount
Definition: porcupine/demo/c/dr_libs/dr_wav.h:889
DRWAV_BAD_PIPE
#define DRWAV_BAD_PIPE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:224
drwav_smpl_loop::cuePointId
drwav_uint32 cuePointId
Definition: porcupine/demo/c/dr_libs/dr_wav.h:520
drwav__memory_stream_write::pDataSize
size_t * pDataSize
Definition: porcupine/demo/c/dr_libs/dr_wav.h:429
DRWAV_TOO_BIG
#define DRWAV_TOO_BIG
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:209
drwav_list_labelled_cue_region
Definition: porcupine/demo/c/dr_libs/dr_wav.h:734
drwav_init_write_sequential_pcm_frames
DRWAV_API drwav_bool32 drwav_init_write_sequential_pcm_frames(drwav *pWav, const drwav_data_format *pFormat, drwav_uint64 totalPCMFrameCount, drwav_write_proc onWrite, void *pUserData, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48392
drwav_init_memory_with_metadata
DRWAV_API drwav_bool32 drwav_init_memory_with_metadata(drwav *pWav, const void *data, size_t dataSize, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49170
drwav__riff_chunk_size_w64
DRWAV_PRIVATE drwav_uint64 drwav__riff_chunk_size_w64(drwav_uint64 dataChunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48247
drwav_acid_flag_root_note_set
@ drwav_acid_flag_root_note_set
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:625
DRWAV_ACCESS_DENIED
#define DRWAV_ACCESS_DENIED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:204
drwav__write_or_count_byte
DRWAV_PRIVATE size_t drwav__write_or_count_byte(drwav *pWav, drwav_uint8 byte)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47881
drwav__read_pcm_frames_and_close_f32
DRWAV_PRIVATE float * drwav__read_pcm_frames_and_close_f32(drwav *pWav, unsigned int *channels, unsigned int *sampleRate, drwav_uint64 *totalFrameCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50762
drwav_metadata_location_inside_adtl_list
@ drwav_metadata_location_inside_adtl_list
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:772
drwav_metadata_type_acid
@ drwav_metadata_type_acid
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:461
drwav__metadata_parser_stage
drwav__metadata_parser_stage
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46893
drwav__metadata_process_info_text_chunk
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_info_text_chunk(drwav__metadata_parser *pParser, drwav_uint64 chunkSize, drwav_metadata_type type)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47202
drwav_list_labelled_cue_region::cuePointId
drwav_uint32 cuePointId
Definition: porcupine/demo/c/dr_libs/dr_wav.h:737
drwav_data_format::bitsPerSample
drwav_uint32 bitsPerSample
Definition: porcupine/demo/c/dr_libs/dr_wav.h:441
DRWAV_MALLOC
#define DRWAV_MALLOC(sz)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46285
drwav_metadata_type_list_info_artist
@ drwav_metadata_type_list_info_artist
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:478
drwav__free_default
DRWAV_PRIVATE void drwav__free_default(void *p, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46627
drwav::channels
drwav_uint16 channels
Definition: porcupine/demo/c/dr_libs/dr_wav.h:834
drwav_u8_to_s16
DRWAV_API void drwav_u8_to_s16(drwav_int16 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50060
drwav_int8
signed char drwav_int8
Definition: porcupine/demo/c/dr_libs/dr_wav.h:134
drwav_fmt_get_format
DRWAV_API drwav_uint16 drwav_fmt_get_format(const drwav_fmt *pFMT)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47478
drwav_init_file__internal_FILE
DRWAV_PRIVATE drwav_bool32 drwav_init_file__internal_FILE(drwav *pWav, FILE *pFile, drwav_chunk_proc onChunk, void *pChunkUserData, drwav_uint32 flags, drwav_metadata_type allowedMetadataTypes, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48947
DR_WAVE_FORMAT_IEEE_FLOAT
#define DR_WAVE_FORMAT_IEEE_FLOAT
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:256
drwav_smpl::midiPitchFraction
drwav_uint32 midiPitchFraction
Definition: porcupine/demo/c/dr_libs/dr_wav.h:551
drwav_init_file
DRWAV_API drwav_bool32 drwav_init_file(drwav *pWav, const char *filename, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48943
drwav_alaw_to_f32
DRWAV_API void drwav_alaw_to_f32(float *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50416
drwav_cue_point::blockStart
drwav_uint32 blockStart
Definition: porcupine/demo/c/dr_libs/dr_wav.h:605
DRWAV_NOT_CONNECTED
#define DRWAV_NOT_CONNECTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:245
drwav_list_labelled_cue_region::stringLength
drwav_uint32 stringLength
Definition: porcupine/demo/c/dr_libs/dr_wav.h:752
drwav_bytes_to_f32
DRWAV_API float drwav_bytes_to_f32(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51057
drwav__read_list_labelled_cue_region_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_list_labelled_cue_region_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata, drwav_uint64 chunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47170
drwav_smpl::midiUnityNote
drwav_uint32 midiUnityNote
Definition: porcupine/demo/c/dr_libs/dr_wav.h:548
drwav_smpl_loop::sampleFraction
drwav_uint32 sampleFraction
Definition: porcupine/demo/c/dr_libs/dr_wav.h:532
drwav_clamp
#define drwav_clamp(x, lo, hi)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46306
drwav_smpl_loop_type_backward
@ drwav_smpl_loop_type_backward
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:514
drwav__on_seek_memory_write
DRWAV_PRIVATE drwav_bool32 drwav__on_seek_memory_write(void *pUserData, int offset, drwav_seek_origin origin)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49129
drwav_bytes_to_s16
DRWAV_API drwav_int16 drwav_bytes_to_s16(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51049
drwav_metadata_type_bext
@ drwav_metadata_type_bext
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:462
drwav_uint32
unsigned int drwav_uint32
Definition: porcupine/demo/c/dr_libs/dr_wav.h:139
drwav_smpl
Definition: porcupine/demo/c/dr_libs/dr_wav.h:538
drwav_read_pcm_frames_s16__msadpcm
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__msadpcm(drwav *pWav, drwav_uint64 samplesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49566
DRWAV_IO_ERROR
#define DRWAV_IO_ERROR
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:218
drwav_acid_flag_disk_based
@ drwav_acid_flag_disk_based
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:627
drwav_read_pcm_frames_f32__msadpcm
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__msadpcm(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50206
drwav__read_cue_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_cue_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47001
drwav_seek_to_pcm_frame
DRWAV_API drwav_bool32 drwav_seek_to_pcm_frame(drwav *pWav, drwav_uint64 targetFrameIndex)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49385
DRWAV_SUCCESS
#define DRWAV_SUCCESS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:198
DRWAV_BAD_PROTOCOL
#define DRWAV_BAD_PROTOCOL
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:237
DRWAV_DEADLOCK
#define DRWAV_DEADLOCK
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:225
drwav_init_memory
DRWAV_API drwav_bool32 drwav_init_memory(drwav *pWav, const void *data, size_t dataSize, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49153
drwav_fmt::blockAlign
drwav_uint16 blockAlign
Definition: porcupine/demo/c/dr_libs/dr_wav.h:317
drwav_read_pcm_frames_s32be
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s32be(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50646
DRWAV_VERSION_REVISION
#define DRWAV_VERSION_REVISION
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:128
drwav_allocation_callbacks
Definition: porcupine/demo/c/dr_libs/dr_wav.h:409
DRWAV_VERSION_MAJOR
#define DRWAV_VERSION_MAJOR
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:126
DRWAV_IN_PROGRESS
#define DRWAV_IN_PROGRESS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:248
drwav_bext::maxMomentaryLoudness
drwav_uint16 maxMomentaryLoudness
Definition: porcupine/demo/c/dr_libs/dr_wav.h:708
drwav__memory_stream::data
const drwav_uint8 * data
Definition: porcupine/demo/c/dr_libs/dr_wav.h:420
drwav_init_memory_write_sequential
DRWAV_API drwav_bool32 drwav_init_memory_write_sequential(drwav *pWav, void **ppData, size_t *pDataSize, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49205
drwav_get_cursor_in_pcm_frames
DRWAV_API drwav_result drwav_get_cursor_in_pcm_frames(drwav *pWav, drwav_uint64 *pCursor)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49456
drwav
Definition: porcupine/demo/c/dr_libs/dr_wav.h:805
DRWAV_INVALID_DATA
#define DRWAV_INVALID_DATA
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:231
drwav_bext::pUMID
drwav_uint8 * pUMID
Definition: porcupine/demo/c/dr_libs/dr_wav.h:702
drwav_init_memory_ex
DRWAV_API drwav_bool32 drwav_init_memory_ex(drwav *pWav, const void *data, size_t dataSize, drwav_chunk_proc onChunk, void *pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49157
drwav__write_or_count_f32ne_to_le
DRWAV_PRIVATE size_t drwav__write_or_count_f32ne_to_le(drwav *pWav, float value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47911
drwav_read_pcm_frames_s32__alaw
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__alaw(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50565
DRWAV_SMPL_BYTES
#define DRWAV_SMPL_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46878
drwav_read_pcm_frames_s16__alaw
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s16__alaw(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49963
drwav_init_file_write__internal
DRWAV_PRIVATE drwav_bool32 drwav_init_file_write__internal(drwav *pWav, const char *filename, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, drwav_bool32 isSequential, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49014
drwav_init_file_ex
DRWAV_API drwav_bool32 drwav_init_file_ex(drwav *pWav, const char *filename, drwav_chunk_proc onChunk, void *pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48963
drwav_write_pcm_frames
DRWAV_API drwav_uint64 drwav_write_pcm_frames(drwav *pWav, drwav_uint64 framesToWrite, const void *pData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49558
drwav__metadata_parser::extraCapacity
drwav_uint64 extraCapacity
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46909
drwav_read_pcm_frames_f32le
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32le(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50336
drwav__ieee_to_f32
DRWAV_PRIVATE void drwav__ieee_to_f32(float *pOut, const drwav_uint8 *pIn, size_t sampleCount, unsigned int bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50169
drwav_read_pcm_frames_f32__alaw
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__alaw(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50263
drwav_inst::lowVelocity
drwav_int8 lowVelocity
Definition: porcupine/demo/c/dr_libs/dr_wav.h:580
drwav_bool8
drwav_uint8 drwav_bool8
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:162
drwav__bswap_s32
static DRWAV_INLINE drwav_int32 drwav__bswap_s32(drwav_int32 n)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46501
drwav_uint16
unsigned short drwav_uint16
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:137
drwav_open_file_and_read_pcm_frames_f32_w
DRWAV_API float * drwav_open_file_and_read_pcm_frames_f32_w(const wchar_t *filename, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50950
drwav_acid::meterNumerator
drwav_uint16 meterNumerator
Definition: porcupine/demo/c/dr_libs/dr_wav.h:648
DRWAV_TRUE
#define DRWAV_TRUE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:164
drwavGUID_W64_FACT
static const drwav_uint8 drwavGUID_W64_FACT[16]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46390
drwav__metadata_parser::metadataCount
drwav_uint32 metadataCount
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46905
drwav_read_pcm_frames_s32__msadpcm
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__msadpcm(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50512
drwav__metadata_parser_stage_count
@ drwav__metadata_parser_stage_count
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46895
drwav__read_fmt
DRWAV_PRIVATE drwav_bool32 drwav__read_fmt(drwav_read_proc onRead, drwav_seek_proc onSeek, void *pUserData, drwav_container container, drwav_uint64 *pRunningBytesReadOut, drwav_fmt *fmtOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46770
DRWAV_BEXT_RESERVED_BYTES
#define DRWAV_BEXT_RESERVED_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46887
drwav_open_file_and_read_pcm_frames_s32_w
DRWAV_API drwav_int32 * drwav_open_file_and_read_pcm_frames_s32_w(const wchar_t *filename, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50967
DRWAV_ACID_BYTES
#define DRWAV_ACID_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46881
drwav_f32_to_s16
DRWAV_API void drwav_f32_to_s16(drwav_int16 *pOut, const float *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50091
drwav__metadata_parser::stage
drwav__metadata_parser_stage stage
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46903
drwav_u8_to_s32
DRWAV_API void drwav_u8_to_s32(drwav_int32 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50654
drwav_inst::fineTuneCents
drwav_int8 fineTuneCents
Definition: porcupine/demo/c/dr_libs/dr_wav.h:576
python.setup.version
version
Definition: porcupine/binding/python/setup.py:70
drwav_init_file_ex_w
DRWAV_API drwav_bool32 drwav_init_file_ex_w(drwav *pWav, const wchar_t *filename, drwav_chunk_proc onChunk, void *pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48975
DRWAV_PRIVATE
#define DRWAV_PRIVATE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:193
drwav_init_write_sequential
DRWAV_API drwav_bool32 drwav_init_write_sequential(drwav *pWav, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, drwav_write_proc onWrite, void *pUserData, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48385
DRWAV_NO_NETWORK
#define DRWAV_NO_NETWORK
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:233
drwav__on_read_stdio
DRWAV_PRIVATE size_t drwav__on_read_stdio(void *pUserData, void *pBufferOut, size_t bytesToRead)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48931
drwav_unknown_metadata::dataSizeInBytes
drwav_uint32 dataSizeInBytes
Definition: porcupine/demo/c/dr_libs/dr_wav.h:779
drwav_bext
Definition: porcupine/demo/c/dr_libs/dr_wav.h:679
DRWAV_LIST_LABEL_OR_NOTE_BYTES
#define DRWAV_LIST_LABEL_OR_NOTE_BYTES
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46890
drwav_bytes_to_u16
DRWAV_API drwav_uint16 drwav_bytes_to_u16(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51045
drwav_metadata_type_list_note
@ drwav_metadata_type_list_note
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:472
drwav_read_pcm_frames_s16be
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16be(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50052
drwav::prevFrames
drwav_int32 prevFrames[2][2]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:890
drwav_uint16
unsigned short drwav_uint16
Definition: porcupine/demo/c/dr_libs/dr_wav.h:137
drwav_cue::pCuePoints
drwav_cue_point * pCuePoints
Definition: porcupine/demo/c/dr_libs/dr_wav.h:614
drwav__write_f32ne_to_le
DRWAV_PRIVATE size_t drwav__write_f32ne_to_le(drwav *pWav, float value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47860
drwav_bool32
drwav_uint32 drwav_bool32
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:163
drwav_bytes_to_u64
DRWAV_API drwav_uint64 drwav_bytes_to_u64(const drwav_uint8 *data)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:51070
drwav__riff_chunk_size_rf64
DRWAV_PRIVATE drwav_uint64 drwav__riff_chunk_size_rf64(drwav_uint64 dataChunkSize, drwav_metadata *metadata, drwav_uint32 numMetadata)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48256
DRWAV_INVALID_ARGS
#define DRWAV_INVALID_ARGS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:200
drwav_data_format::sampleRate
drwav_uint32 sampleRate
Definition: porcupine/demo/c/dr_libs/dr_wav.h:440
drwav__metadata_process_chunk
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_chunk(drwav__metadata_parser *pParser, const drwav_chunk_header *pChunkHeader, drwav_uint64 allowedMetadataTypes)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47264
drwav_list_labelled_cue_region::sampleLength
drwav_uint32 sampleLength
Definition: porcupine/demo/c/dr_libs/dr_wav.h:740
drwav_metadata_type_inst
@ drwav_metadata_type_inst
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:459
drwav_unknown_metadata
Definition: porcupine/demo/c/dr_libs/dr_wav.h:775
drwav_allocation_callbacks::onMalloc
void *(* onMalloc)(size_t sz, void *pUserData)
Definition: porcupine/demo/c/dr_libs/dr_wav.h:412
drwav_acid::midiUnityNote
drwav_uint16 midiUnityNote
Definition: porcupine/demo/c/dr_libs/dr_wav.h:637
drwav_uint8
unsigned char drwav_uint8
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:135
drwav__metadata_process_unknown_chunk
DRWAV_PRIVATE drwav_uint64 drwav__metadata_process_unknown_chunk(drwav__metadata_parser *pParser, const drwav_uint8 *pChunkId, drwav_uint64 chunkSize, drwav_metadata_location location)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47229
drwav__free_from_callbacks
DRWAV_PRIVATE void drwav__free_from_callbacks(void *p, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46667
drwav_seek_origin
drwav_seek_origin
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:268
drwav__metadata_parser::pDataCursor
drwav_uint8 * pDataCursor
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46907
drwav__memory_stream::currentReadPos
size_t currentReadPos
Definition: porcupine/demo/c/dr_libs/dr_wav.h:422
DRWAV_NOT_SOCKET
#define DRWAV_NOT_SOCKET
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:235
drwav_read_pcm_frames_le
DRWAV_API drwav_uint64 drwav_read_pcm_frames_le(drwav *pWav, drwav_uint64 framesToRead, void *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49325
drwav::ima
struct drwav::@11 ima
drwav::bytesRemainingInBlock
drwav_uint32 bytesRemainingInBlock
Definition: porcupine/demo/c/dr_libs/dr_wav.h:885
drwav_init_write_with_metadata
DRWAV_API drwav_bool32 drwav_init_write_with_metadata(drwav *pWav, const drwav_data_format *pFormat, drwav_write_proc onWrite, drwav_seek_proc onSeek, void *pUserData, const drwav_allocation_callbacks *pAllocationCallbacks, drwav_metadata *pMetadata, drwav_uint32 metadataCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48399
drwav_acid::reserved2
float reserved2
Definition: porcupine/demo/c/dr_libs/dr_wav.h:641
DRWAV_PROTOCOL_FAMILY_NOT_SUPPORTED
#define DRWAV_PROTOCOL_FAMILY_NOT_SUPPORTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:240
drwav::allocationCallbacks
drwav_allocation_callbacks allocationCallbacks
Definition: porcupine/demo/c/dr_libs/dr_wav.h:820
drwav_fmt::avgBytesPerSec
drwav_uint32 avgBytesPerSec
Definition: porcupine/demo/c/dr_libs/dr_wav.h:314
DR_WAVE_FORMAT_ADPCM
#define DR_WAVE_FORMAT_ADPCM
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:255
drwav_init_ex
DRWAV_API drwav_bool32 drwav_init_ex(drwav *pWav, drwav_read_proc onRead, drwav_seek_proc onSeek, drwav_chunk_proc onChunk, void *pReadSeekUserData, void *pChunkUserData, drwav_uint32 flags, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47799
drwav_init_file_write_sequential_w
DRWAV_API drwav_bool32 drwav_init_file_write_sequential_w(drwav *pWav, const wchar_t *filename, const drwav_data_format *pFormat, drwav_uint64 totalSampleCount, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49049
drwav_metadata::acid
drwav_acid acid
Definition: porcupine/demo/c/dr_libs/dr_wav.h:795
DRWAV_NO_ADDRESS
#define DRWAV_NO_ADDRESS
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:236
drwav::container
drwav_container container
Definition: porcupine/demo/c/dr_libs/dr_wav.h:824
drwav_list_info_text::stringLength
drwav_uint32 stringLength
Definition: porcupine/demo/c/dr_libs/dr_wav.h:722
drwav__data_chunk_size_w64
DRWAV_PRIVATE drwav_uint64 drwav__data_chunk_size_w64(drwav_uint64 dataChunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48252
drwav_metadata::unknown
drwav_unknown_metadata unknown
Definition: porcupine/demo/c/dr_libs/dr_wav.h:801
drwav_int8
signed char drwav_int8
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:134
drwav__write_or_count_u16ne_to_le
DRWAV_PRIVATE size_t drwav__write_or_count_u16ne_to_le(drwav *pWav, drwav_uint16 value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47888
drwav_init__internal
DRWAV_PRIVATE drwav_bool32 drwav_init__internal(drwav *pWav, drwav_chunk_proc onChunk, void *pChunkUserData, drwav_uint32 flags)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47504
drwav__realloc_default
DRWAV_PRIVATE void * drwav__realloc_default(void *p, size_t sz, void *pUserData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46622
drwav_unknown_metadata::id
drwav_uint8 id[4]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:777
DRWAV_TOO_MANY_OPEN_FILES
#define DRWAV_TOO_MANY_OPEN_FILES
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:207
drwav__bswap_s24
static DRWAV_INLINE void drwav__bswap_s24(drwav_uint8 *p)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46486
drwav_cue
Definition: porcupine/demo/c/dr_libs/dr_wav.h:611
drwav_read_pcm_frames_f32__pcm
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_f32__pcm(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50185
drwav__realloc_from_callbacks
DRWAV_PRIVATE void * drwav__realloc_from_callbacks(void *p, size_t szNew, size_t szOld, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46645
drwav__read_acid_to_metadata_obj
DRWAV_PRIVATE drwav_uint64 drwav__read_acid_to_metadata_obj(drwav__metadata_parser *pParser, drwav_metadata *pMetadata)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47052
drwav_result
drwav_int32 drwav_result
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:197
header
const std::string header
drwav_metadata_location_invalid
@ drwav_metadata_location_invalid
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:769
assert.h
drwav_read_pcm_frames_s32__pcm
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__pcm(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50487
drwav_alaw_to_s32
DRWAV_API void drwav_alaw_to_s32(drwav_int32 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50708
DRWAV_SOCKET_NOT_SUPPORTED
#define DRWAV_SOCKET_NOT_SUPPORTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:242
drwav__memory_stream
Definition: porcupine/demo/c/dr_libs/dr_wav.h:418
drwav_inst::gainDecibels
drwav_int8 gainDecibels
Definition: porcupine/demo/c/dr_libs/dr_wav.h:577
drwav_metadata::data
union drwav_metadata::@9 data
drwav_acid::tempo
float tempo
Definition: porcupine/demo/c/dr_libs/dr_wav.h:651
drwav_acid_flag_stretch
@ drwav_acid_flag_stretch
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:626
drwav__metadata_parser_stage_read
@ drwav__metadata_parser_stage_read
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46896
drwav__write_u32ne_to_le
DRWAV_PRIVATE size_t drwav__write_u32ne_to_le(drwav *pWav, drwav_uint32 value)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47842
drwav_bext::pOriginationTime
char pOriginationTime[8]
Definition: porcupine/demo/c/dr_libs/dr_wav.h:690
drwav_metadata_type_list_info_tracknumber
@ drwav_metadata_type_list_info_tracknumber
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:483
drwav::pUserData
void * pUserData
Definition: porcupine/demo/c/dr_libs/dr_wav.h:817
drwav__bswap_samples_s32
static DRWAV_INLINE void drwav__bswap_samples_s32(drwav_int32 *pSamples, drwav_uint64 sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46505
drwav_smpl_loop_type_pingpong
@ drwav_smpl_loop_type_pingpong
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:513
drwav_smpl::sampleLoopCount
drwav_uint32 sampleLoopCount
Definition: porcupine/demo/c/dr_libs/dr_wav.h:558
drwav_int16
signed short drwav_int16
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:136
drwav__memory_stream_write
Definition: porcupine/demo/c/dr_libs/dr_wav.h:426
drwav_int64
signed long long drwav_int64
Definition: porcupine/demo/c/dr_libs/dr_wav.h:151
drwav_metadata_type_list_all_adtl
@ drwav_metadata_type_list_all_adtl
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:496
drwav_data_format
Definition: porcupine/demo/c/dr_libs/dr_wav.h:435
drwav_s24_to_s16
DRWAV_API void drwav_s24_to_s16(drwav_int16 *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50071
drwav_wfopen
DRWAV_PRIVATE drwav_result drwav_wfopen(FILE **ppFile, const wchar_t *pFilePath, const wchar_t *pOpenMode, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48869
drwav_read_pcm_frames_s16le
DRWAV_API drwav_uint64 drwav_read_pcm_frames_s16le(drwav *pWav, drwav_uint64 framesToRead, drwav_int16 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50044
drwav_container_w64
@ drwav_container_w64
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:277
drwav::translatedFormatTag
drwav_uint16 translatedFormatTag
Definition: porcupine/demo/c/dr_libs/dr_wav.h:840
drwav_write_pcm_frames_le
DRWAV_API drwav_uint64 drwav_write_pcm_frames_le(drwav *pWav, drwav_uint64 framesToWrite, const void *pData)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49490
drwav_init_file_write
DRWAV_API drwav_bool32 drwav_init_file_write(drwav *pWav, const char *filename, const drwav_data_format *pFormat, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49030
drwav_s32_to_s16
DRWAV_API void drwav_s32_to_s16(drwav_int16 *pOut, const drwav_int32 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50081
drwav__data_chunk_size_riff
DRWAV_PRIVATE drwav_uint32 drwav__data_chunk_size_riff(drwav_uint64 dataChunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48239
drwav__metadata_alloc
DRWAV_PRIVATE drwav_result drwav__metadata_alloc(drwav__metadata_parser *pParser, drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46938
DRWAV_MAX_SAMPLE_RATE
#define DRWAV_MAX_SAMPLE_RATE
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46379
drwav_s24_to_f32
DRWAV_API void drwav_s24_to_f32(float *pOut, const drwav_uint8 *pIn, size_t sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50381
drwav_version_string
const DRWAV_API char * drwav_version_string(void)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46374
drwav_preinit_write
DRWAV_PRIVATE drwav_bool32 drwav_preinit_write(drwav *pWav, const drwav_data_format *pFormat, drwav_bool32 isSequential, drwav_write_proc onWrite, drwav_seek_proc onSeek, void *pUserData, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:48268
drwav__chunk_padding_size_w64
DRWAV_PRIVATE unsigned int drwav__chunk_padding_size_w64(drwav_uint64 chunkSize)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46699
g_drwavAlawTable
static unsigned short g_drwavAlawTable[256]
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49818
DRWAV_ALREADY_CONNECTED
#define DRWAV_ALREADY_CONNECTED
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:244
drwav_read_pcm_frames_s32__ieee
DRWAV_PRIVATE drwav_uint64 drwav_read_pcm_frames_s32__ieee(drwav *pWav, drwav_uint64 framesToRead, drwav_int32 *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50544
drwav_acid::flags
drwav_uint32 flags
Definition: porcupine/demo/c/dr_libs/dr_wav.h:634
drwav_container
drwav_container
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:274
drwav__bswap_samples_s16
static DRWAV_INLINE void drwav__bswap_samples_s16(drwav_int16 *pSamples, drwav_uint64 sampleCount)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46479
drwav_smpl::smpteFormat
drwav_uint32 smpteFormat
Definition: porcupine/demo/c/dr_libs/dr_wav.h:554
drwav_read_pcm_frames_f32be
DRWAV_API drwav_uint64 drwav_read_pcm_frames_f32be(drwav *pWav, drwav_uint64 framesToRead, float *pBufferOut)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50344
DRWAV_VERSION_MINOR
#define DRWAV_VERSION_MINOR
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:127
DRWAV_PROTOCOL_UNAVAILABLE
#define DRWAV_PROTOCOL_UNAVAILABLE
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:238
drwav__pcm_to_s32
DRWAV_PRIVATE void drwav__pcm_to_s32(drwav_int32 *pOut, const drwav_uint8 *pIn, size_t totalSampleCount, unsigned int bytesPerSample)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50436
drwav_list_label_or_note::pString
char * pString
Definition: porcupine/demo/c/dr_libs/dr_wav.h:670
drwav_smpl_loop_type
drwav_smpl_loop_type
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:510
drwav_version
DRWAV_API void drwav_version(drwav_uint32 *pMajor, drwav_uint32 *pMinor, drwav_uint32 *pRevision)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46362
drwav::memoryStreamWrite
drwav__memory_stream_write memoryStreamWrite
Definition: porcupine/demo/c/dr_libs/dr_wav.h:879
drwav__metadata_parser::onSeek
drwav_seek_proc onSeek
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:46901
drwav_seek_to_first_pcm_frame
DRWAV_PRIVATE drwav_bool32 drwav_seek_to_first_pcm_frame(drwav *pWav)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:49364
drwav_chunk_header::id
union drwav_chunk_header::@8 id
drwav_container_rf64
@ drwav_container_rf64
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:278
drwav_cue_point::sampleByteOffset
drwav_uint32 sampleByteOffset
Definition: porcupine/demo/c/dr_libs/dr_wav.h:608
drwav_open_and_read_pcm_frames_s16
DRWAV_API drwav_int16 * drwav_open_and_read_pcm_frames_s16(drwav_read_proc onRead, drwav_seek_proc onSeek, void *pUserData, unsigned int *channelsOut, unsigned int *sampleRateOut, drwav_uint64 *totalFrameCountOut, const drwav_allocation_callbacks *pAllocationCallbacks)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:50830
drwav_unknown_metadata::chunkLocation
drwav_metadata_location chunkLocation
Definition: porcupine/demo/c/dr_libs/dr_wav.h:778
drwav__memory_stream_write::ppData
void ** ppData
Definition: porcupine/demo/c/dr_libs/dr_wav.h:428
DRWAV_INVALID_OPERATION
#define DRWAV_INVALID_OPERATION
Definition: rhino/demo/c/pvrecorder/src/miniaudio/extras/dr_wav.h:201
drwav__memory_stream_write::currentWritePos
size_t currentWritePos
Definition: porcupine/demo/c/dr_libs/dr_wav.h:432
drwav__write_byte
DRWAV_PRIVATE size_t drwav__write_byte(drwav *pWav, drwav_uint8 byte)
Definition: porcupine/demo/c/pvrecorder/src/miniaudio/extras/miniaudio_split/miniaudio.c:47827
drwav_bext::pOriginatorName
char * pOriginatorName
Definition: porcupine/demo/c/dr_libs/dr_wav.h:687
drwav::msadpcm
struct drwav::@10 msadpcm


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:55