Initial commit
This commit is contained in:
397
audio/soundfont/sf2file.h
Normal file
397
audio/soundfont/sf2file.h
Normal file
@@ -0,0 +1,397 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* VGMTrans (c) 2002-2019
|
||||
* Licensed under the zlib license,
|
||||
* refer to the included VGMTrans_LICENSE.txt file
|
||||
*/
|
||||
#ifndef AUDIO_SOUNDFONT_SF2FILE_H
|
||||
#define AUDIO_SOUNDFONT_SF2FILE_H
|
||||
|
||||
#include "common/endian.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
#include "rifffile.h"
|
||||
|
||||
typedef enum {
|
||||
// Oscillator
|
||||
startAddrsOffset, // sample start address -4 (0 to 0xffffff) 0
|
||||
endAddrsOffset,
|
||||
startloopAddrsOffset, // loop start address -4 (0 to 0xffffff)
|
||||
endloopAddrsOffset, // loop end address -3 (0 to 0xffffff)
|
||||
|
||||
// Pitch
|
||||
startAddrsCoarseOffset, // CHANGED FOR SF2
|
||||
modLfoToPitch, // main fm: lfo1-> pitch 5
|
||||
vibLfoToPitch, // aux fm: lfo2-> pitch
|
||||
modEnvToPitch, // pitch env: env1(aux)-> pitch
|
||||
|
||||
// Filter
|
||||
initialFilterFc, // initial filter cutoff
|
||||
initialFilterQ, // filter Q
|
||||
modLfoToFilterFc, // filter modulation: lfo1 -> filter cutoff 10
|
||||
modEnvToFilterFc, // filter env: env1(aux)-> filter cutoff
|
||||
|
||||
// Amplifier
|
||||
endAddrsCoarseOffset, // CHANGED FOR SF2
|
||||
modLfoToVolume, // tremolo: lfo1-> volume
|
||||
unused1,
|
||||
|
||||
// Effects
|
||||
chorusEffectsSend, // chorus 15
|
||||
reverbEffectsSend, // reverb
|
||||
pan,
|
||||
unused2,
|
||||
unused3,
|
||||
unused4, // 20
|
||||
|
||||
// Main lfo1
|
||||
delayModLFO, // delay 0x8000-n*(725us)
|
||||
freqModLFO, // frequency
|
||||
|
||||
// Aux lfo2
|
||||
delayVibLFO, // delay 0x8000-n*(725us)
|
||||
freqVibLFO, // frequency
|
||||
|
||||
// Env1(aux/value)
|
||||
delayModEnv, // delay 0x8000 - n(725us) 25
|
||||
attackModEnv, // attack
|
||||
holdModEnv, // hold
|
||||
decayModEnv, // decay
|
||||
sustainModEnv, // sustain
|
||||
releaseModEnv, // release 30
|
||||
keynumToModEnvHold,
|
||||
keynumToModEnvDecay,
|
||||
|
||||
// Env2(ampl/vol)
|
||||
delayVolEnv, // delay 0x8000 - n(725us)
|
||||
attackVolEnv, // attack
|
||||
holdVolEnv, // hold 35
|
||||
decayVolEnv, // decay
|
||||
sustainVolEnv, // sustain
|
||||
releaseVolEnv, // release
|
||||
keynumToVolEnvHold,
|
||||
keynumToVolEnvDecay, // 40
|
||||
|
||||
// Preset
|
||||
instrument,
|
||||
reserved1,
|
||||
keyRange,
|
||||
velRange,
|
||||
startloopAddrCoarseOffset, // CHANGED FOR SF2 45
|
||||
keynum,
|
||||
velocity,
|
||||
initialAttenuation, // CHANGED FOR SF2
|
||||
reserved2,
|
||||
endloopAddrsCoarseOffset, // CHANGED FOR SF2 50
|
||||
coarseTune,
|
||||
fineTune,
|
||||
sampleID,
|
||||
sampleModes, // CHANGED FOR SF2
|
||||
reserved3, // 55
|
||||
scaleTuning,
|
||||
exclusiveClass,
|
||||
overridingRootKey,
|
||||
unused5,
|
||||
endOper // 60
|
||||
} SFGeneratorType;
|
||||
|
||||
typedef uint16 SFGenerator;
|
||||
|
||||
typedef enum {
|
||||
/* Start of MIDI modulation operators */
|
||||
cc1_Mod,
|
||||
cc7_Vol,
|
||||
cc10_Pan,
|
||||
cc64_Sustain,
|
||||
cc91_Reverb,
|
||||
cc93_Chorus,
|
||||
|
||||
ccPitchBend,
|
||||
ccIndirectModX,
|
||||
ccIndirectModY,
|
||||
|
||||
endMod
|
||||
} SFModulatorType;
|
||||
|
||||
typedef uint16 SFModulator;
|
||||
|
||||
typedef enum {
|
||||
linear
|
||||
} SFTransformType;
|
||||
|
||||
typedef uint16 SFTransform;
|
||||
/*
|
||||
#define monoSample 0x0001
|
||||
#define rightSample 0x0002
|
||||
#define leftSample 0x0004
|
||||
#define linkedSample 0x0008
|
||||
|
||||
#define ROMSample 0x8000 //32768
|
||||
#define ROMMonoSample 0x8001 //32769
|
||||
#define ROMRightSample 0x8002 //32770
|
||||
#define ROMLeftSample 0x8004 //32772
|
||||
#define ROMLinkedSample 0x8008 //32776
|
||||
*/
|
||||
|
||||
// enum scaleTuning
|
||||
//{
|
||||
// equalTemp,
|
||||
// fiftyCents
|
||||
//};
|
||||
//
|
||||
// enum SFSampleField //used by Sample Read Module
|
||||
//{
|
||||
// NAME_FIELD = 1,
|
||||
// START_FIELD,
|
||||
// END_FIELD,
|
||||
// START_LOOP_FIELD,
|
||||
// END_LOOP_FIELD,
|
||||
// SMPL_RATE_FIELD,
|
||||
// ORG_KEY_FIELD,
|
||||
// CORRECTION_FIELD,
|
||||
// SMPL_LINK_FIELD,
|
||||
// SMPL_TYPE_FIELD
|
||||
//};
|
||||
//
|
||||
// enum SFInfoChunkField //used by Bank Read Module
|
||||
//{
|
||||
// IFIL_FIELD = 1,
|
||||
// IROM_FIELD,
|
||||
// IVER_FIELD,
|
||||
// ISNG_FIELD,
|
||||
// INAM_FIELD,
|
||||
// IPRD_FIELD,
|
||||
// IENG_FIELD,
|
||||
// ISFT_FIELD,
|
||||
// ICRD_FIELD,
|
||||
// ICMT_FIELD,
|
||||
// ICOP_FIELD
|
||||
//};
|
||||
|
||||
static inline void uint16Write(uint8 **buffer, uint16 value) {
|
||||
WRITE_LE_UINT16(*buffer, value);
|
||||
*buffer += 2;
|
||||
}
|
||||
|
||||
static inline void uint32Write(uint8 **buffer, uint32 value) {
|
||||
WRITE_LE_UINT32(*buffer, value);
|
||||
*buffer += 4;
|
||||
}
|
||||
|
||||
static inline void writeBytes(uint8 **buffer, byte *bytes, uint32 size) {
|
||||
memcpy(*buffer, bytes, size);
|
||||
*buffer += size;
|
||||
}
|
||||
|
||||
#pragma pack(push) /* push current alignment to stack */
|
||||
#pragma pack(2) /* set alignment to 2 byte boundary */
|
||||
|
||||
struct sfVersionTag {
|
||||
uint16 wMajor;
|
||||
uint16 wMinor;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
uint16Write(&buffer, wMajor);
|
||||
uint16Write(&buffer, wMinor);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
struct sfPresetHeader {
|
||||
char achPresetName[20];
|
||||
uint16 wPreset;
|
||||
uint16 wBank;
|
||||
uint16 wPresetBagNdx;
|
||||
uint32 dwLibrary;
|
||||
uint32 dwGenre;
|
||||
uint32 dwMorphology;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
writeBytes(&buffer, (byte *)achPresetName, 20);
|
||||
uint16Write(&buffer, wPreset);
|
||||
uint16Write(&buffer, wBank);
|
||||
uint16Write(&buffer, wPresetBagNdx);
|
||||
uint32Write(&buffer, dwLibrary);
|
||||
uint32Write(&buffer, dwGenre);
|
||||
uint32Write(&buffer, dwMorphology);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
struct sfPresetBag {
|
||||
uint16 wGenNdx;
|
||||
uint16 wModNdx;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
uint16Write(&buffer, wGenNdx);
|
||||
uint16Write(&buffer, wModNdx);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
struct sfModList {
|
||||
SFModulator sfModSrcOper;
|
||||
SFGenerator sfModDestOper;
|
||||
int16 modAmount;
|
||||
SFModulator sfModAmtSrcOper;
|
||||
SFTransform sfModTransOper;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
uint16Write(&buffer, sfModSrcOper);
|
||||
uint16Write(&buffer, sfModDestOper);
|
||||
uint16Write(&buffer, modAmount);
|
||||
uint16Write(&buffer, sfModAmtSrcOper);
|
||||
uint16Write(&buffer, sfModTransOper);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
struct genAmountType {
|
||||
byte data[2];
|
||||
|
||||
void setRangeLo(uint8 lo) { data[0] = lo; }
|
||||
void setRangeHi(uint8 hi) { data[1] = hi; }
|
||||
void setShAmount(int16 shAmount) { WRITE_LE_INT16(data, shAmount); }
|
||||
void setwAmount(int16 wAmount) { WRITE_LE_UINT16(data, wAmount); }
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
writeBytes(&buffer, (byte *)data, 2);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
struct sfGenList {
|
||||
SFGenerator sfGenOper;
|
||||
genAmountType genAmount;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
uint16Write(&buffer, sfGenOper);
|
||||
return genAmount.write(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct sfInstGenList {
|
||||
SFGenerator sfGenOper;
|
||||
genAmountType genAmount;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
uint16Write(&buffer, sfGenOper);
|
||||
return genAmount.write(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct sfInst {
|
||||
char achInstName[20];
|
||||
uint16 wInstBagNdx;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
writeBytes(&buffer, (byte *)achInstName, 20);
|
||||
uint16Write(&buffer, wInstBagNdx);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
struct sfInstBag {
|
||||
uint16 wInstGenNdx;
|
||||
uint16 wInstModNdx;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
uint16Write(&buffer, wInstGenNdx);
|
||||
uint16Write(&buffer, wInstModNdx);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
monoSample = 1,
|
||||
rightSample = 2,
|
||||
leftSample = 4,
|
||||
linkedSample = 8,
|
||||
RomMonoSample = 0x8001,
|
||||
RomRightSample = 0x8002,
|
||||
RomLeftSample = 0x8004,
|
||||
RomLinkedSample = 0x8008
|
||||
} SFSampleLinkType;
|
||||
|
||||
typedef uint16 SFSampleLink;
|
||||
|
||||
struct sfSample {
|
||||
char achSampleName[20];
|
||||
uint32 dwStart;
|
||||
uint32 dwEnd;
|
||||
uint32 dwStartloop;
|
||||
uint32 dwEndloop;
|
||||
uint32 dwSampleRate;
|
||||
uint8 byOriginalKey;
|
||||
char chCorrection;
|
||||
uint16 wSampleLink;
|
||||
SFSampleLink sfSampleType;
|
||||
|
||||
uint8 *write(uint8 *buffer) {
|
||||
writeBytes(&buffer, (byte *)achSampleName, 20);
|
||||
uint32Write(&buffer, dwStart);
|
||||
uint32Write(&buffer, dwEnd);
|
||||
uint32Write(&buffer, dwStartloop);
|
||||
uint32Write(&buffer, dwEndloop);
|
||||
uint32Write(&buffer, dwSampleRate);
|
||||
*buffer++ = byOriginalKey;
|
||||
*buffer++ = chCorrection;
|
||||
uint16Write(&buffer, wSampleLink);
|
||||
uint16Write(&buffer, sfSampleType);
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pack(pop) /* restore original alignment from stack */
|
||||
|
||||
class SF2StringChunk : public Chunk {
|
||||
public:
|
||||
SF2StringChunk(Common::String ckSig, Common::String info) : Chunk(ckSig) {
|
||||
SetData(info.c_str(), (uint32) info.size());
|
||||
}
|
||||
};
|
||||
|
||||
class SF2InfoListChunk : public LISTChunk {
|
||||
public:
|
||||
SF2InfoListChunk(Common::String name);
|
||||
};
|
||||
|
||||
class SF2sdtaChunk : public LISTChunk {
|
||||
public:
|
||||
SF2sdtaChunk();
|
||||
};
|
||||
|
||||
inline void WriteLIST(Common::Array<uint8> &buf, Common::String listName, uint32 listSize);
|
||||
inline void AlignName(Common::String &name);
|
||||
|
||||
class SynthFile;
|
||||
|
||||
class SF2File : public RiffFile {
|
||||
public:
|
||||
SF2File(SynthFile *synthfile);
|
||||
~SF2File(void);
|
||||
|
||||
const void *SaveToMem();
|
||||
};
|
||||
|
||||
#endif // AUDIO_SOUNDFONT_SF2FILE_H
|
||||
Reference in New Issue
Block a user