1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | #include "SDL_internal.h" |
22 | |
23 | // RIFF WAVE files are little-endian |
24 | |
25 | /*******************************************/ |
26 | // Define values for Microsoft WAVE format |
27 | /*******************************************/ |
28 | // FOURCC |
29 | #define RIFF 0x46464952 // "RIFF" |
30 | #define WAVE 0x45564157 // "WAVE" |
31 | #define FACT 0x74636166 // "fact" |
32 | #define LIST 0x5453494c // "LIST" |
33 | #define BEXT 0x74786562 // "bext" |
34 | #define JUNK 0x4B4E554A // "JUNK" |
35 | #define FMT 0x20746D66 // "fmt " |
36 | #define DATA 0x61746164 // "data" |
37 | // Format tags |
38 | #define UNKNOWN_CODE 0x0000 |
39 | #define PCM_CODE 0x0001 |
40 | #define MS_ADPCM_CODE 0x0002 |
41 | #define IEEE_FLOAT_CODE 0x0003 |
42 | #define ALAW_CODE 0x0006 |
43 | #define MULAW_CODE 0x0007 |
44 | #define IMA_ADPCM_CODE 0x0011 |
45 | #define MPEG_CODE 0x0050 |
46 | #define MPEGLAYER3_CODE 0x0055 |
47 | #define EXTENSIBLE_CODE 0xFFFE |
48 | |
49 | // Stores the WAVE format information. |
50 | typedef struct WaveFormat |
51 | { |
52 | Uint16 formattag; // Raw value of the first field in the fmt chunk data. |
53 | Uint16 encoding; // Actual encoding, possibly from the extensible header. |
54 | Uint16 channels; // Number of channels. |
55 | Uint32 frequency; // Sampling rate in Hz. |
56 | Uint32 byterate; // Average bytes per second. |
57 | Uint16 blockalign; // Bytes per block. |
58 | Uint16 bitspersample; // Currently supported are 8, 16, 24, 32, and 4 for ADPCM. |
59 | |
60 | /* Extra information size. Number of extra bytes starting at byte 18 in the |
61 | * fmt chunk data. This is at least 22 for the extensible header. |
62 | */ |
63 | Uint16 extsize; |
64 | |
65 | // Extensible WAVE header fields |
66 | Uint16 validsamplebits; |
67 | Uint32 samplesperblock; // For compressed formats. Can be zero. Actually 16 bits in the header. |
68 | Uint32 channelmask; |
69 | Uint8 subformat[16]; // A format GUID. |
70 | } WaveFormat; |
71 | |
72 | // Stores information on the fact chunk. |
73 | typedef struct WaveFact |
74 | { |
75 | /* Represents the state of the fact chunk in the WAVE file. |
76 | * Set to -1 if the fact chunk is invalid. |
77 | * Set to 0 if the fact chunk is not present |
78 | * Set to 1 if the fact chunk is present and valid. |
79 | * Set to 2 if samplelength is going to be used as the number of sample frames. |
80 | */ |
81 | Sint32 status; |
82 | |
83 | /* Version 1 of the RIFF specification calls the field in the fact chunk |
84 | * dwFileSize. The Standards Update then calls it dwSampleLength and specifies |
85 | * that it is 'the length of the data in samples'. WAVE files from Windows |
86 | * with this chunk have it set to the samples per channel (sample frames). |
87 | * This is useful to truncate compressed audio to a specific sample count |
88 | * because a compressed block is usually decoded to a fixed number of |
89 | * sample frames. |
90 | */ |
91 | Uint32 samplelength; // Raw sample length value from the fact chunk. |
92 | } WaveFact; |
93 | |
94 | // Generic struct for the chunks in the WAVE file. |
95 | typedef struct WaveChunk |
96 | { |
97 | Uint32 fourcc; // FOURCC of the chunk. |
98 | Uint32 length; // Size of the chunk data. |
99 | Sint64 position; // Position of the data in the stream. |
100 | Uint8 *data; // When allocated, this points to the chunk data. length is used for the memory allocation size. |
101 | size_t size; // Number of bytes in data that could be read from the stream. Can be smaller than length. |
102 | } WaveChunk; |
103 | |
104 | // Controls how the size of the RIFF chunk affects the loading of a WAVE file. |
105 | typedef enum WaveRiffSizeHint |
106 | { |
107 | RiffSizeNoHint, |
108 | RiffSizeForce, |
109 | RiffSizeIgnoreZero, |
110 | RiffSizeIgnore, |
111 | RiffSizeMaximum |
112 | } WaveRiffSizeHint; |
113 | |
114 | // Controls how a truncated WAVE file is handled. |
115 | typedef enum WaveTruncationHint |
116 | { |
117 | TruncNoHint, |
118 | TruncVeryStrict, |
119 | TruncStrict, |
120 | TruncDropFrame, |
121 | TruncDropBlock |
122 | } WaveTruncationHint; |
123 | |
124 | // Controls how the fact chunk affects the loading of a WAVE file. |
125 | typedef enum WaveFactChunkHint |
126 | { |
127 | FactNoHint, |
128 | FactTruncate, |
129 | FactStrict, |
130 | FactIgnoreZero, |
131 | FactIgnore |
132 | } WaveFactChunkHint; |
133 | |
134 | typedef struct WaveFile |
135 | { |
136 | WaveChunk chunk; |
137 | WaveFormat format; |
138 | WaveFact fact; |
139 | |
140 | /* Number of sample frames that will be decoded. Calculated either with the |
141 | * size of the data chunk or, if the appropriate hint is enabled, with the |
142 | * sample length value from the fact chunk. |
143 | */ |
144 | Sint64 sampleframes; |
145 | |
146 | void *decoderdata; // Some decoders require extra data for a state. |
147 | |
148 | WaveRiffSizeHint riffhint; |
149 | WaveTruncationHint trunchint; |
150 | WaveFactChunkHint facthint; |
151 | } WaveFile; |
152 | |