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);
	
	}
}