headers/WAVE.h

/*
**  Apple Macintosh Developer Technical Support
**
**  Header information needed to parse Microsoft's WAVE formatted sounds.
**
**  by Mark Cookson, Apple Developer Technical Support
**
**  File:   WAVE.h
**
**  Copyright ©1996 Apple Computer, Inc.
**  All rights reserved.
**
**  You may incorporate this sample code into your applications without
**  restriction, though the sample code has been provided "AS IS" and the
**  responsibility for its operation is 100% yours.  However, what you are
**  not permitted to do is to redistribute the source as "Apple Sample
**  Code" after having made changes. If you're going to re-distribute the
**  source, we require that you make it clear in the source that the code
**  was descended from Apple Sample Code, but that you've made changes.
*/
 
/* This was made from reading a document called wave.pdf which is an excerpt from
   RIFFMCI.RTF, "Multimedia Programming Interface and Data Specification v1.0".
 
   This code does what I need, and worked with the WAVE files I had handy.
   It may not work in all cases.
*/
 
#ifndef __WAVE__
#define __WAVE__
 
#include <Errors.h>
#include <Files.h>
#include <Sound.h>
#include <Types.h>
 
#ifndef __SOUNDSTRUCT__
#include "SoundStruct.h"
#endif
 
#ifndef __DBFFERRORS__
#include "DBFF_Errors.h"
#endif
 
#ifndef __SETUPDBHEADER__
#include "SetupDBHeader.h"
#endif
 
#ifndef __DEFINES__
#include "Defines.h"
#endif
 
#define kWAVEFORMID             (1<<0)
#define kWAVEID                 (1<<1)
#define kFormatID               (1<<2)
#define kWAVEListID             (1<<3)
#define kSilenceID              (1<<4)
#define kCueID                  (1<<5)
#define kFactID                 (1<<6)
#define kPlaylistID             (1<<7)
#define kAssocDataID            (1<<8)
#define kLabelID                (1<<9)
#define kNoteID                 (1<<10)
#define kTextWithLenID          (1<<12)
#define kEmbededFileID          (1<<13)
#define kWAVEDataID             (1<<14)
 
enum {
    WAVEFORMID                  = 'RIFF',
    WAVEID                      = 'WAVE',
    FormatID                    = 'fmt ',
    WAVEListID                  = 'wavl',
    SilenceID                   = 'slnt',
    CueID                       = 'cue ',
    FactID                      = 'fact',
    PlaylistID                  = 'plst',
    AssocDataID                 = 'adtl',
    LabelID                     = 'labl',
    NoteID                      = 'note',
    TextWithLenID               = 'ltxt',
    EmbededFileID               = 'file',
    WAVEDataID                  = 'data'
};
 
#define WAVE_FORMAT_PCM     (0x0001)        /* Microsoft Pulse Code Modulation (PCM) format */
#define WAVE_FORMAT_ADPCM   (0x0002)        /* A WAVE Adaptive Differential Pulse Code Modulation file I saw once */
#define WAVE_FORMAT_MULAW   (0x0007)        /* A WAVE mu-law file that I saw once */
#define WAVE_FORMAT_IMA     (0x0011)        /* A WAVE IMA4 file that I saw once */
#define IBM_FORMAT_MULAW    (0x0101)        /* IBM mu-law format */
#define IBM_FORMAT_ALAW     (0x0102)        /* IBM a-law format */
#define IBM_FORMAT_ADPCM    (0x0103)        /* IBM AVC Adaptive Differential Pulse Code Modulation format */
#define kWAVEChunkBufferSize    128
 
// typedef unsigned long ID;
 
#pragma options align=mac68k
typedef struct WAVEChunkHeader {
    ID                  ckID;
    long                fileSize;
}WAVEChunkHeader;
 
typedef struct WAVEContainerChunk {
    ID                  ckID;
    long                ckSize;
    ID                  formType;
}WAVEContainerChunk;
 
typedef struct fmtChunk {
    ID                  ckID;
    long                ckSize;
    short               wFormatTag;         /* Number indicating WAVE format category */
    short               wChannels;          /* Number of channels 1 for mono 2 for stereo */
    long                dwSamplesPerSec;    /* Sampling rate in samples per second */
    long                dwAvgBytesPerSec;   /* Average number of bytes per second (could be used to estimate buffer sizes) */
    short               wBlockAlign;        /* Block alignment in bytes of the waveform data, always process an integer multiple of this number */
}fmtChunk;
 
typedef struct PCMFmtSpecChunk {
    ID                  ckID;
    long                ckSize;
    short               wBitsPerSample;     /* Sample size */
}PCMFmtSpecChunk;
 
typedef struct factChunk {
    ID                  ckID;
    long                ckSize;
    long                dwFileSize;         /* Number of samples */
}factChunk;
 
typedef struct cuePointsChunk {
    ID                  ckID;
    long                ckSize;
    long                dwCuePoints;        /* Count of cue points */
    /* There may be multiple number of these */
    long                dwName;
    long                dwPosition;
    long                fccChunk;
    long                dwChunkStart;
    long                dwBlockStart;
    long                dwSampleOffset;
}cuePointsChunk;
 
typedef struct playlistChunk {
    ID                  ckID;
    long                ckSize;
    long                dwSegments;         /* Count of play segments */
    /* There may be multiple number of these */
    long                dwName;
    long                dwLength;
    long                dwLoops;
}playlistChunk;
 
//typedef struct waveDataChunk {
//  ID                  ckID;
//  short               something;          /* I don't know what this is */
//}waveDataChunk;
 
typedef struct labelChunk {
    ID                  ckID;
    long                ckSize;
    long                dwName;
    char                data[1];            /* This is a null terminated string */
}labelChunk;
 
typedef struct noteChunk {
    ID                  ckID;
    long                ckSize;
    long                dwName;
    char                data[1];            /* This is a null terminated string */
}noteChunk;
 
typedef struct ltxtChunk {
    ID                  ckID;
    long                ckSize;
    long                dwName;
    long                dwSampleLength;
    long                dwPurpose;
    short               wCountry;
    short               wLanguage;
    short               wDialect;
    short               wCodePage;
    char                data[1];            /* This is a null terminated string */
}ltxtChunk;
 
typedef struct fileChunk {
    ID                  ckID;
    long                ckSize;
    long                dwName;
    long                dwMedType;
    char                data[1];            /* This is a null terminated string */
}fileChunk;
 
typedef struct assocDataListChunk {
    ID                  ckID;
    long                ckSize;
    labelChunk          labelInfo;
    noteChunk           noteInfo;
    ltxtChunk           ltxtInfo;
    fileChunk           fileInfo;
}assocDataListChunk;
 
typedef union {
    WAVEChunkHeader         generic;
    WAVEContainerChunk      container;
    fmtChunk                fmt;
    factChunk               fact;
    cuePointsChunk          cuePoints;
    playlistChunk           playList;
    assocDataListChunk      assocData;
//  waveDataChunk           waveData;
    PCMFmtSpecChunk         waveData;
    fileChunk               file;
    ltxtChunk               ltxt;
    noteChunk               note;
    labelChunk              label;
}WAVETemplate, *WAVETemplatePtr;
#pragma options align=reset
 
OSErr   ASoundGetWAVEHeader     (SoundInfoPtr theSoundInfo, long *len, fmtChunk *formatChunk);
 
short       SwapShort               (const short theShort);
long        SwapLong                (const long theLong);
long        ReverseLong             (const long theLong);
 
#define stillMoreDataWAVEToRead     ((chunkFlags & kWAVEFORMID) && (!(chunkFlags & kFormatID) || !(chunkFlags & kWAVEDataID)) && (err == noErr))
 
#endif