www.pudn.com > FlashFormat.rar > FDTSounds.cpp
// Copyright © 1999 Middlesoft, Inc. All rights reserved.
// First Created By Lee Thomason.
// First Created On 09/08/1999.
// Last Modified On 11/09/1999.
/****************************************************************************************
File Summary: FDTSounds.cpp
This source file contains the definition for all low-level sound-related functions,
grouped by classes:
Class Member Function
FDTDefineSound FDTDefineSound()
void WriteToSWFStream(FSWFStream*);
FDTDefineSoundADPCM FDTDefineSoundADPCM(U8, U8, U8, U32, U8*, U32, int);
FDTDefineSoundWAV FDTDefineSoundWAV(FILE*, int);
bool loadWavFile(FILE*, SSound*, U8**, int*);
FDTSoundStreamBlock FDTSoundStreamBlock(U32, U8*);
void WriteToSWFStream(FSWFStream*);
FDTSoundStreamHead FDTSoundStreamHead(U8, U8, U16);
void WriteToSWFStream(FSWFStream*);
FDTSoundStreamHead2 FDTSoundStreamHead2(U8, U8, U8, U8, U16);
void WriteToSWFStream(FSWFStream*);
FSndEnv FSndEnv(U32, U16, U16);
void WriteToSWFStream(FSWFStream*);
FSoundInfo FSoundInfo(U8, U8, U8, U8, U8, U32, U32, U16, U8, FSndEnv*);
~FSoundInfo();
void WriteToSWFStream(FSWFStream*);
****************************************************************************************/
#include "FDTSounds.h"
#include "FSound.h"
#include "FSWFStream.h"
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTDefineSound --------------------------------------------------------
FDTDefineSound::FDTDefineSound()
{
soundID = FObjCollection::Increment();
memset( &soundData, 0, sizeof( soundData ) );
}
void FDTDefineSound::WriteToSWFStream(FSWFStream* _SWFStream){
FSWFStream tempBuffer;
tempBuffer.WriteWord((U32) soundID);
tempBuffer.WriteBits((U32)soundData.format, 4);
tempBuffer.WriteBits((U32)soundData.rate, 2);
tempBuffer.WriteBits((U32)soundData.size, 1);
tempBuffer.WriteBits((U32)soundData.type, 1);
tempBuffer.WriteDWord(soundData.sampleCount);
tempBuffer.WriteLargeData(soundData.sound, soundData.soundSize);
_SWFStream->AppendTag( stagDefineSound, tempBuffer.Size(), &tempBuffer );
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTDefineSoundADPCM ---------------------------------------------------
FDTDefineSoundADPCM::FDTDefineSoundADPCM( U8 rate,
U8 size,
U8 type,
U32 sampleCount,
const U8* wavData,
U32 wavDataSize,
int compression )
{
// clear the vector to write to
pcmData.clear();
soundData.format = 1; //a 1 indicates ADPCM
soundData.rate = rate;
soundData.size = size;
soundData.type = type;
soundData.sampleCount = sampleCount;
// Construct a FSound object
FSound sound;
sound.format = Format();
sound.nSamples = soundData.sampleCount;
sound.samples = const_cast( wavData ); // it won't change it - so we cast (lee)
sound.dataLen = wavDataSize;
sound.delay = 0;
FSoundComp compress( &sound, compression );
compress.Compress( const_cast( wavData ), sound.nSamples, &pcmData ); // it won't change it - so we cast (lee)
compress.Flush( &pcmData );
// store the compressed data to the sound structure
soundData.sound = &pcmData[0];
soundData.soundSize = pcmData.size();
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTDefineSoundWAV -----------------------------------------------------
FDTDefineSoundWAV::FDTDefineSoundWAV( FILE* fp, int comp )
{
U8* wavData; // memory where the WAV file is stored
int wavDataSize; // the number of bytes in the WAV file
// clear the vector to write to
pcmData.clear();
// fp = fopen( waveFile, "rb" );
if ( !fp )
{
return;
}
if ( loadWavFile( fp, &soundData, &wavData, &wavDataSize ) == false )
{
// there was an error
return;
}
// Construct a FSound object
FSound sound;
sound.format = Format();
sound.nSamples = soundData.sampleCount;
sound.samples = wavData;
sound.dataLen = wavDataSize;
sound.delay = 0;
FSoundComp compress( &sound, comp );
compress.Compress( wavData, sound.nSamples, &pcmData );
compress.Flush( &pcmData );
// fclose( fp );
// store the compressed data to the sound structure
soundData.sound = &pcmData[0];
soundData.soundSize = pcmData.size();
// delete the wav data
delete [] wavData;
}
//------------------------------------------------------------------------------
bool FDTDefineSoundWAV::loadWavFile( FILE* fp, SSound* soundData, U8** wavData, int* wavDataSize )
{
unsigned long nextseek;
unsigned long filesize;
unsigned long fileTag;
unsigned long typeTag;
unsigned long chunkSize;
unsigned long chunkId;
unsigned long formatTag = 0;
assert( fp );
memset( soundData, 0, sizeof( SSound ) );
soundData->format = 1; // ADPCM compressed
fileTag = read32( fp );
if ( fileTag != 0x46464952 )
{
FLASHOUTPUT("Not a RIFF format file\n");
return false;
}
filesize = read32( fp );
filesize += ftell( fp );
typeTag = read32( fp );
if ( typeTag != 0x45564157 )
{
FLASHOUTPUT("Not a WAVE file\n");
return false;
}
nextseek = ftell( fp );
while ( nextseektype = channels - 1;
FLASHOUTPUT(" %u Channels\n", channels );
int samplesPerSec = read32( fp );
FLASHOUTPUT(" %u Samples Per Second\n",samplesPerSec);
switch ( samplesPerSec / 5000 )
{
case 1: // 5k
soundData->rate = Snd5k;
break;
case 2: // 11k
soundData->rate = Snd11k;
break;
case 4: // 22k
soundData->rate = Snd22k;
break;
case 8: // 44k
soundData->rate = Snd44k;
break;
default:
FLASHOUTPUT("Sample rate %d unsupported\n",samplesPerSec);
return false;
}
int bytesPerSec = read32( fp );
FLASHOUTPUT(" %u Average Bytes Per Second\n",bytesPerSec);
int blockAlign = read16( fp );
FLASHOUTPUT(" Block Align %u\n", blockAlign );
FLASHOUTPUT("Format Specific Fields:\n");
int bits = read16( fp );
FLASHOUTPUT(" %u Bits Per Sample\n",bits);
//store the size of the chunks of data (8v16 bit)
if ( bits == 8 )
soundData->size = 0;
else if ( bits == 16 )
soundData->size = 1;
else
FLASHASSERT( 0 );
if ( formatTag != 0x0001 )
{
int extra = read16( fp );
FLASHOUTPUT(" %d Bytes of extra information\n", extra);
FLASHOUTPUT(" NOT YET SUPPORTED\n");
return false;
}
}
break;
case 0x61746164: //Data Chunk
{
FLASHOUTPUT("Data Chunk\n");
if ( !formatTag ) {
FLASHOUTPUT("Warning Format Chunk not defined before Data Chunk\n");
return false;
}
*wavDataSize = chunkSize;
soundData->sampleCount = chunkSize / (soundData->size + 1);
*wavData = new U8[ chunkSize ];
int read = fread( *wavData, 1, *wavDataSize, fp );
if ( read != (*wavDataSize) )
{
FLASHOUTPUT("Warning Read %d of %d bytes\n", read, (*wavDataSize) );
return false;
}
return true;
}
default:
FLASHOUTPUT("Unknown Chunk\n");
return false;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTSoundStreamBlock ---------------------------------------------------
FDTSoundStreamBlock::FDTSoundStreamBlock(U32 _size, U8* _data){
size = _size;
data = _data;
}
void FDTSoundStreamBlock::WriteToSWFStream(FSWFStream* _SWFStream){
FSWFStream body;
body.WriteLargeData(data, size);
_SWFStream->AppendTag( stagSoundStreamBlock, body.Size(), &body );
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTSoundStreamHead ----------------------------------------------------
FDTSoundStreamHead::FDTSoundStreamHead(U8 _mixFormat, U8 _soundType, U16 _count){
mixFormat = _mixFormat;
soundType = _soundType;
count = _count;
}
void FDTSoundStreamHead::WriteToSWFStream(FSWFStream* _SWFStream){
FSWFStream body;
body.WriteByte((U32)mixFormat);
body.WriteBits(1, 4);
body.WriteBits(0, 2);
body.WriteBits(1, 1);
body.WriteBits((U32)soundType, 1);
body.WriteWord((U32)count);
_SWFStream->AppendTag( stagSoundStreamHead, body.Size(), &body );
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FDTSoundStreamHead2 ---------------------------------------------------
FDTSoundStreamHead2::FDTSoundStreamHead2(U8 _mixFormat, U8 _compression, U8 _size, U8 _soundType, U16 _count){
mixFormat = _mixFormat;
compression = _compression;
size = _size;
soundType = _soundType;
count = _count;
}
void FDTSoundStreamHead2::WriteToSWFStream(FSWFStream* _SWFStream){
FSWFStream body;
body.WriteByte((U32)mixFormat);
body.WriteBits((U32)compression, 4);
body.WriteBits(0, 2);
body.WriteBits((U32)size, 1);
body.WriteBits((U32)soundType, 1);
body.WriteWord((U32)count);
_SWFStream->AppendTag( stagSoundStreamHead2, body.Size(), &body );
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FSndEnv ---------------------------------------------------------------
FSndEnv::FSndEnv(U32 mark44, U16 level0, U16 level1){
mark44 = mark44;
level0 = level0;
level1 = level1;
}
void FSndEnv::WriteToSWFStream(FSWFStream *_SWFStream){
_SWFStream->WriteDWord(mark44);
_SWFStream->WriteWord((U32)level0);
_SWFStream->WriteWord((U32)level1);
}
//////////////////////////////////////////////////////////////////////////////////////
// -------- FSoundInfo ------------------------------------------------------------
FSoundInfo::FSoundInfo(U8 _syncFlags, U8 _hasEnvelope, U8 _hasLoops, U8 _hasOutPoint,
U8 _hasInPoint, U32 _inPoint, U32 _outPoint, U16 _loopCount,
U8 _nPoints, FSndEnv* _soundEnvelope){
syncFlags = _syncFlags;
hasEnvelope = _hasEnvelope;
hasLoops = _hasLoops;
hasOutPoint = _hasOutPoint;
hasInPoint = _hasInPoint;
inPoint = _inPoint;
outPoint = _outPoint;
loopCount = _loopCount;
nPoints = _nPoints;
soundEnvelope = _soundEnvelope;
}
FSoundInfo::~FSoundInfo(){
delete soundEnvelope;
}
void FSoundInfo::WriteToSWFStream(FSWFStream* _SWFStream){
_SWFStream->WriteBits((U32)syncFlags, 4);
_SWFStream->WriteBits((U32)hasEnvelope, 1);
_SWFStream->WriteBits((U32)hasLoops, 1);
_SWFStream->WriteBits((U32)hasOutPoint, 1);
_SWFStream->WriteBits((U32)hasInPoint, 1);
if (hasInPoint)
_SWFStream->WriteDWord(inPoint);
if (hasOutPoint)
_SWFStream->WriteDWord(outPoint);
if (hasLoops)
_SWFStream->WriteWord(loopCount);
if (hasEnvelope){
_SWFStream->WriteByte(nPoints);
soundEnvelope->WriteToSWFStream(_SWFStream);
}
}