tahoma2d/toonz/sources/common/flash/FDTSounds.cpp
Toshihiro Shimizu 890dddabbd first commit
2016-03-19 02:57:51 +09:00

483 lines
12 KiB
C++

// 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 = (S16)soundData.sampleCount;
sound.samples = const_cast<U8 *>(wavData); // it won't change it - so we cast (lee)
sound.dataLen = (S16)wavDataSize;
sound.delay = 0;
FSoundComp compress(&sound, compression);
compress.Compress(const_cast<U8 *>(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 = (S16)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)
{
TUINT32 nextseek;
TUINT32 filesize;
TUINT32 fileTag;
TUINT32 typeTag;
TUINT32 chunkSize;
TUINT32 chunkId;
TUINT32 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 (nextseek < filesize) {
fseek(fp, (TINT32)nextseek, 0);
chunkId = read32(fp);
chunkSize = read32(fp);
nextseek = chunkSize + ftell(fp);
#ifndef __LP64__
FLASHOUTPUT("\n----- Chunk ID %d, Size %d -----\n", chunkId, chunkSize);
#else
FLASHOUTPUT("\n----- Chunk ID %d, Size %d -----\n", chunkId, chunkSize);
#endif
switch (chunkId) {
case 0x20746D66: //Format Chunk
{
FLASHOUTPUT("Format Chunk\n");
FLASHOUTPUT("Common Fields:\n");
formatTag = read16(fp);
#ifndef __LP64__
FLASHOUTPUT(" Format Tag %04lXh: ", (long unsigned int)formatTag);
#else
FLASHOUTPUT(" Format Tag %04Xh: ", formatTag);
#endif
switch (formatTag) {
default:
case 0x0000:
FLASHOUTPUT("WAVE_FORMAT_UNKNOWN");
break;
case 0x0001:
FLASHOUTPUT("WAVE_FORMAT_PCM\n");
break;
case 0x0002:
FLASHOUTPUT("WAVE_FORMAT_ADPCM\n");
break;
case 0x0005:
FLASHOUTPUT("WAVE_FORMAT_IBM_CVSD\n");
break;
case 0x0006:
FLASHOUTPUT("WAVE_FORMAT_ALAW\n");
break;
case 0x0007:
FLASHOUTPUT("WAVE_FORMAT_MULAW\n");
break;
case 0x0010:
FLASHOUTPUT("WAVE_FORMAT_OKI_ADPCM");
break;
case 0x0011:
FLASHOUTPUT("WAVE_FORMAT_DVI_ADPCM or WAVE_FORMAT_IMA_ADPCM\n");
break;
case 0x0015:
FLASHOUTPUT("WAVE_FORMAT_DIGISTD\n");
break;
case 0x0016:
FLASHOUTPUT("WAVE_FORMAT_DIGIFIX\n");
break;
case 0x0020:
FLASHOUTPUT("WAVE_FORMAT_YAMAHA_ADPCM\n");
break;
case 0x0021:
FLASHOUTPUT("WAVE_FORMAT_SONARC\n");
break;
case 0x0022:
FLASHOUTPUT("WAVE_FORMAT_DSPGROUP_TRUESPEECH\n");
break;
case 0x0023:
FLASHOUTPUT("WAVE_FORMAT_ECHOSC1\n");
break;
case 0x0024:
FLASHOUTPUT("WAVE_FORMAT_AUDIOFILE_AF18\n");
break;
case 0x0101:
FLASHOUTPUT("IBM_FORMAT_MULAW\n");
break;
case 0x0102:
FLASHOUTPUT("IBM_FORMAT_ALAW\n");
break;
case 0x0103:
FLASHOUTPUT("IBM_FORMAT_ADPCM\n");
break;
case 0x0200:
FLASHOUTPUT("WAVE_FORMAT_CREATIVE_ADPCM\n");
break;
}
int channels = (int)read16(fp);
soundData->type = channels - 1;
FLASHOUTPUT(" %u Channels\n", channels);
int samplesPerSec = (int)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 = (int)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 = (int)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;
rate = 0;
size = _size;
soundType = _soundType;
count = _count;
}
FDTSoundStreamHead2::FDTSoundStreamHead2(U8 _mixFormat, U8 _compression, U8 _rate, U8 _size, U8 _soundType, U16 _count)
{
mixFormat = _mixFormat;
compression = _compression;
rate = _rate;
size = _size;
soundType = _soundType;
count = _count;
}
void FDTSoundStreamHead2::WriteToSWFStream(FSWFStream *_SWFStream)
{
FSWFStream body;
body.WriteByte((U32)mixFormat);
body.WriteBits((U32)compression, 4);
body.WriteBits((U32)rate, 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);
}
}