152 lines
5.3 KiB
C
152 lines
5.3 KiB
C
/*
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
#include "SDL_internal.h"
|
|
|
|
/* RIFF WAVE files are little-endian */
|
|
|
|
/*******************************************/
|
|
/* Define values for Microsoft WAVE format */
|
|
/*******************************************/
|
|
/* FOURCC */
|
|
#define RIFF 0x46464952 /* "RIFF" */
|
|
#define WAVE 0x45564157 /* "WAVE" */
|
|
#define FACT 0x74636166 /* "fact" */
|
|
#define LIST 0x5453494c /* "LIST" */
|
|
#define BEXT 0x74786562 /* "bext" */
|
|
#define JUNK 0x4B4E554A /* "JUNK" */
|
|
#define FMT 0x20746D66 /* "fmt " */
|
|
#define DATA 0x61746164 /* "data" */
|
|
/* Format tags */
|
|
#define UNKNOWN_CODE 0x0000
|
|
#define PCM_CODE 0x0001
|
|
#define MS_ADPCM_CODE 0x0002
|
|
#define IEEE_FLOAT_CODE 0x0003
|
|
#define ALAW_CODE 0x0006
|
|
#define MULAW_CODE 0x0007
|
|
#define IMA_ADPCM_CODE 0x0011
|
|
#define MPEG_CODE 0x0050
|
|
#define MPEGLAYER3_CODE 0x0055
|
|
#define EXTENSIBLE_CODE 0xFFFE
|
|
|
|
/* Stores the WAVE format information. */
|
|
typedef struct WaveFormat
|
|
{
|
|
Uint16 formattag; /* Raw value of the first field in the fmt chunk data. */
|
|
Uint16 encoding; /* Actual encoding, possibly from the extensible header. */
|
|
Uint16 channels; /* Number of channels. */
|
|
Uint32 frequency; /* Sampling rate in Hz. */
|
|
Uint32 byterate; /* Average bytes per second. */
|
|
Uint16 blockalign; /* Bytes per block. */
|
|
Uint16 bitspersample; /* Currently supported are 8, 16, 24, 32, and 4 for ADPCM. */
|
|
|
|
/* Extra information size. Number of extra bytes starting at byte 18 in the
|
|
* fmt chunk data. This is at least 22 for the extensible header.
|
|
*/
|
|
Uint16 extsize;
|
|
|
|
/* Extensible WAVE header fields */
|
|
Uint16 validsamplebits;
|
|
Uint32 samplesperblock; /* For compressed formats. Can be zero. Actually 16 bits in the header. */
|
|
Uint32 channelmask;
|
|
Uint8 subformat[16]; /* A format GUID. */
|
|
} WaveFormat;
|
|
|
|
/* Stores information on the fact chunk. */
|
|
typedef struct WaveFact
|
|
{
|
|
/* Represents the state of the fact chunk in the WAVE file.
|
|
* Set to -1 if the fact chunk is invalid.
|
|
* Set to 0 if the fact chunk is not present
|
|
* Set to 1 if the fact chunk is present and valid.
|
|
* Set to 2 if samplelength is going to be used as the number of sample frames.
|
|
*/
|
|
Sint32 status;
|
|
|
|
/* Version 1 of the RIFF specification calls the field in the fact chunk
|
|
* dwFileSize. The Standards Update then calls it dwSampleLength and specifies
|
|
* that it is 'the length of the data in samples'. WAVE files from Windows
|
|
* with this chunk have it set to the samples per channel (sample frames).
|
|
* This is useful to truncate compressed audio to a specific sample count
|
|
* because a compressed block is usually decoded to a fixed number of
|
|
* sample frames.
|
|
*/
|
|
Uint32 samplelength; /* Raw sample length value from the fact chunk. */
|
|
} WaveFact;
|
|
|
|
/* Generic struct for the chunks in the WAVE file. */
|
|
typedef struct WaveChunk
|
|
{
|
|
Uint32 fourcc; /* FOURCC of the chunk. */
|
|
Uint32 length; /* Size of the chunk data. */
|
|
Sint64 position; /* Position of the data in the stream. */
|
|
Uint8 *data; /* When allocated, this points to the chunk data. length is used for the memory allocation size. */
|
|
size_t size; /* Number of bytes in data that could be read from the stream. Can be smaller than length. */
|
|
} WaveChunk;
|
|
|
|
/* Controls how the size of the RIFF chunk affects the loading of a WAVE file. */
|
|
typedef enum WaveRiffSizeHint
|
|
{
|
|
RiffSizeNoHint,
|
|
RiffSizeForce,
|
|
RiffSizeIgnoreZero,
|
|
RiffSizeIgnore,
|
|
RiffSizeMaximum
|
|
} WaveRiffSizeHint;
|
|
|
|
/* Controls how a truncated WAVE file is handled. */
|
|
typedef enum WaveTruncationHint
|
|
{
|
|
TruncNoHint,
|
|
TruncVeryStrict,
|
|
TruncStrict,
|
|
TruncDropFrame,
|
|
TruncDropBlock
|
|
} WaveTruncationHint;
|
|
|
|
/* Controls how the fact chunk affects the loading of a WAVE file. */
|
|
typedef enum WaveFactChunkHint
|
|
{
|
|
FactNoHint,
|
|
FactTruncate,
|
|
FactStrict,
|
|
FactIgnoreZero,
|
|
FactIgnore
|
|
} WaveFactChunkHint;
|
|
|
|
typedef struct WaveFile
|
|
{
|
|
WaveChunk chunk;
|
|
WaveFormat format;
|
|
WaveFact fact;
|
|
|
|
/* Number of sample frames that will be decoded. Calculated either with the
|
|
* size of the data chunk or, if the appropriate hint is enabled, with the
|
|
* sample length value from the fact chunk.
|
|
*/
|
|
Sint64 sampleframes;
|
|
|
|
void *decoderdata; /* Some decoders require extra data for a state. */
|
|
|
|
WaveRiffSizeHint riffhint;
|
|
WaveTruncationHint trunchint;
|
|
WaveFactChunkHint facthint;
|
|
} WaveFile;
|