/*
* Copyright (c) 1997-2004 Alexandros Eleftheriadis, Danny Hong and
* Yuntai Kyong.
*
* This file is part of Flavor, developed at Columbia University
* (www.ee.columbia.edu/flavor).
*
* Flavor is free software; you can redistribute it and/or modify
* it under the terms of the Flavor Artistic License as described in
* the file COPYING.txt.
*
*/
/*
* Authors:
* Danny Hong <danny@ee.columbia.edu>
*
*/
/*
* AIFF/AIFC File Format
*
* This example reads audio files in the Audio Interchange File Format
* or in the AIFC format. This example uses FORM AIFF/AIFC and it only
* reads the 2 required chunks: Common Chunk and Sound Data Chunk. Other
* chunks are simply ignored.
*
*/
const signed int FORM_ID = 0x464F524D; // "FORM" in big-endian form
const signed int COMM_ID = 0x434F4D4D; // "COMM" in big-endian form
const signed int SSND_ID = 0x53534E44; // "SSND" in big-endian form
const signed int AIFF_ID = 0x41494646; // "AIFF" in big-endian form
const signed int AIFC_ID = 0x41494643; // "AIFC" in big-endian form
const signed int MARK_ID = 0x4D41524B; // "MARK" in big-endian form
const signed int INST_ID = 0x494E5354; // "INST" in big-endian form
const signed int COMT_ID = 0x434F4D54; // "COMT" in big-endian form
const signed int NAME_ID = 0x4E414D45; // "NAME" in big-endian form
const signed int AUTH_ID = 0x41555448; // "AUTH" in big-endian form
const signed int COPY_ID = 0x28632920; // "(c) " in big-endian form
const signed int ANNO_ID = 0x414E4E4F; // "ANNO" in big-endian form
const signed int AESD_ID = 0x41455344; // "AESD" in big-endian form
const signed int MIDI_ID = 0x4D494449; // "MIDI" in big-endian form
const signed int APPL_ID = 0x4150504C; // "APPL" in big-endian form
// For AIFC only
const signed int FVER_ID = 0x46564552; // "FVER" in big-endian form
/*
* ExtendedFloat
*
* IEEE 80-bit floating point
*
*/
class ExtendedFloat {
bit(1) sign;
unsigned int(15) exponent;
double(64) mantissa;
}
/*
* PString
*
* Pascal-style string, a one-byte count followed by that many text bytes.
* The total number of bytes in this data type should be even. If not, a
* pad byte is added. However, the pad byte is not reflected in the count.
*
*/
class PString {
unsigned int(8) count;
if ((count % 2) == 0)
char(8) text[count+1];
else
char(8) text[count];
}
/*
* Common Chunk
*
* Describes fundamental parameters of the waveform data.
*
*/
class CommonChunk {
int(32) ckID = COMM_ID;
int(32) ckSize;
int(16) numChannels;
unsigned int(32) numSampleFrames;
int(16) sampleSize;
ExtendedFloat sampleRate;
}
class AIFCCommonChunkExt {
int(32) compressionType;
PString compressionName;
}
/*
* Sound Data Chunk
*
* Contains the actual data.
*
*/
class SoundChunk {
int(32) ckID = SSND_ID;
int(32) ckSize;
int i;
for (i = 0; i < ckSize; i++) {
char(8) data;
/* Here we can use verbatim code to manipulate data */
}
}
/*
* Other Chunk
*
*/
class OtherChunk {
int(32) ckID;
int(32) ckSize;
skipbits(8*ckSize);
}
/*
* AIFF/AIFC File (FORM AIFF/AIFC File)
*
*/
class AIFF {
int(32) ckID = FORM_ID;
int(32) ckSize;
int(32) formType;
bit isInvalid_id = 0;
do {
// Read ahead
signed int(32)* id;
switch (id)
{
case COMM_ID:
CommonChunk ckCommon;
if (formType == AIFC_ID)
AIFCCommonChunkExt ckCommonExt;
break;
case SSND_ID:
SoundChunk ckSound;
break;
case MARK_ID:
case INST_ID:
case COMT_ID:
case NAME_ID:
case AUTH_ID:
case COPY_ID:
case ANNO_ID:
case AESD_ID:
case MIDI_ID:
case APPL_ID:
case FVER_ID:
OtherChunk ckOther;
break;
default:
isInvalid_id = 1;
}
} while(isInvalid_id != 1);
}
|