qzdoom/src/timidity/sf2.h
Randy Heit e64586d86f - Reduced volume, expression, and panning controllers back to 7 bits.
- Added very basic Soundfont support to the internal TiMidity. Things missing:
  filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or
  may not be compatible with TiMidity++'s soundfont extensions.
- Added support for quoted strings to the TiMidity config parser.


SVN r957 (trunk)
2008-05-09 03:54:06 +00:00

318 lines
6.8 KiB
C

typedef WORD SFGenerator;
struct SFRange
{
BYTE Lo;
BYTE Hi;
};
struct SFPreset
{
char Name[21];
BYTE LoadOrder:7;
BYTE bHasGlobalZone:1;
WORD Program;
WORD Bank;
WORD BagIndex;
/* Don't care about library, genre, and morphology */
};
struct SFBag
{
WORD GenIndex;
// WORD ModIndex; // If I am feeling ambitious, I might add support for modulators some day.
SFRange KeyRange;
SFRange VelRange;
int Target; // Either an instrument or sample index
};
struct SFInst
{
char Name[21];
BYTE Pad:7;
BYTE bHasGlobalZone:1;
WORD BagIndex;
};
struct SFSample
{
float *InMemoryData;
DWORD Start;
DWORD End;
DWORD StartLoop;
DWORD EndLoop;
DWORD SampleRate;
BYTE OriginalPitch;
SBYTE PitchCorrection;
WORD SampleLink;
WORD SampleType;
char Name[21];
};
// Sample type bit fields (all but ROM are mutually exclusive)
enum
{
SFST_Mono = 1,
SFST_Right = 2,
SFST_Left = 4,
SFST_Linked = 8, /* SF2.04 defines this bit but not its function */
SFST_Bad = 16384, /* Used internally */
SFST_ROM = 32768
};
// Generator definitions
struct SFGenList
{
SFGenerator Oper;
union
{
SFRange Range;
SWORD Amount;
WORD uAmount;
};
};
enum
{
GEN_startAddrsOffset,
GEN_endAddrsOffset,
GEN_startloopAddrsOffset,
GEN_endloopAddrsOffset,
GEN_startAddrsCoarseOffset,
GEN_modLfoToPitch,
GEN_vibLfoToPitch,
GEN_modEnvToPitch,
GEN_initialFilterFC,
GEN_initialFilterQ,
GEN_modLfoToFilterFc,
GEN_modEnvToFilterFc,
GEN_endAddrsCoarseOffset,
GEN_modLfoToVolume,
GEN_unused1,
GEN_chorusEffectsSend,
GEN_reverbEffectsSend,
GEN_pan,
GEN_unused2,
GEN_unused3,
GEN_unused4,
GEN_delayModLFO,
GEN_freqModLFO,
GEN_delayVibLFO,
GEN_freqVibLFO,
GEN_delayModEnv,
GEN_attackModEnv,
GEN_holdModEnv,
GEN_decayModEnv,
GEN_sustainModEnv,
GEN_releaseModEnv,
GEN_keynumToModEnvHold,
GEN_keynumToModEnvDecay,
GEN_delayVolEnv,
GEN_attackVolEnv,
GEN_holdVolEnv,
GEN_decayVolEnv,
GEN_sustainVolEnv,
GEN_releaseVolEnv,
GEN_keynumToVolEnvHold,
GEN_keynumToVolEnvDecay,
GEN_instrument,
GEN_reserved1,
GEN_keyRange,
GEN_velRange,
GEN_startloopAddrsCoarseOffset,
GEN_keynum,
GEN_velocity,
GEN_initialAttenuation,
GEN_reserved2,
GEN_endloopAddrsCoarseOffset,
GEN_coarseTune,
GEN_fineTune,
GEN_sampleID,
GEN_sampleModes,
GEN_reserved3,
GEN_scaleTuning,
GEN_exclusiveClass,
GEN_overridingRootKey,
GEN_NumGenerators
};
// Modulator definitions
struct SFModulator
{
WORD Index:7;
WORD CC:1;
WORD Dir:1; /* 0 = min->max, 1 = max->min */
WORD Polarity:1; /* 0 = unipolar, 1 = bipolar */
WORD Type:6;
};
struct SFModList
{
SFModulator SrcOper;
SFGenerator DestOper;
SWORD Amount;
SFModulator AmtSrcOper;
WORD Transform;
};
// Modulator sources when CC is 0
enum
{
SFMod_One = 0, // Psuedo-controller that always has the value 1
SFMod_NoteVelocity = 2,
SFMod_KeyNumber = 3,
SFMod_PolyPressure = 10,
SFMod_ChannelPressure = 13,
SFMod_PitchWheel = 14,
SFMod_PitchSens = 16,
SFMod_Link = 127
};
// Modulator types
enum
{
SFModType_Linear,
SFModType_Concave, // log(fabs(value)/(max value)^2)
SFModType_Convex,
SFModType_Switch
};
// Modulator transforms
enum
{
SFModTrans_Linear = 0,
SFModTrans_Abs = 2
};
// All possible generators in a single structure
struct SFGenComposite
{
union
{
SFRange keyRange; // For normal use
struct // For intermediate percussion use
{
BYTE drumset;
BYTE key;
};
};
SFRange velRange;
union
{
WORD instrument; // At preset level
WORD sampleID; // At instrument level
};
SWORD modLfoToPitch;
SWORD vibLfoToPitch;
SWORD modEnvToPitch;
SWORD initialFilterFc;
SWORD initialFilterQ;
SWORD modLfoToFilterFc;
SWORD modEnvToFilterFc;
SWORD modLfoToVolume;
SWORD chorusEffectsSend;
SWORD reverbEffectsSend;
SWORD pan;
SWORD delayModLFO;
SWORD freqModLFO;
SWORD delayVibLFO;
SWORD freqVibLFO;
SWORD delayModEnv;
SWORD attackModEnv;
SWORD holdModEnv;
SWORD decayModEnv;
SWORD sustainModEnv;
SWORD releaseModEnv;
SWORD keynumToModEnvHold;
SWORD keynumToModEnvDecay;
SWORD delayVolEnv;
SWORD attackVolEnv;
SWORD holdVolEnv;
SWORD decayVolEnv;
SWORD sustainVolEnv;
SWORD releaseVolEnv;
SWORD keynumToVolEnvHold;
SWORD keynumToVolEnvDecay;
SWORD initialAttenuation;
SWORD coarseTune;
SWORD fineTune;
SWORD scaleTuning;
// The following are only for instruments:
SWORD startAddrsOffset, startAddrsCoarseOffset;
SWORD endAddrsOffset, endAddrsCoarseOffset;
SWORD startLoopAddrsOffset, startLoopAddrsCoarseOffset;
SWORD endLoopAddrsOffset, endLoopAddrsCoarseOffset;
SWORD keynum;
SWORD velocity;
WORD sampleModes;
SWORD exclusiveClass;
SWORD overridingRootKey;
};
// Intermediate percussion representation
struct SFPerc
{
SFPreset *Preset;
SFGenComposite Generators;
BYTE LoadOrder;
};
// Container for all parameters from a SoundFont file
struct SFFile : public Timidity::FontFile
{
SFFile(FString filename);
~SFFile();
Timidity::Instrument *LoadInstrument(struct Timidity::Renderer *song, int drum, int bank, int program);
Timidity::Instrument *LoadInstrumentOrder(struct Timidity::Renderer *song, int order, int drum, int bank, int program);
void SetOrder(int order, int drum, int bank, int program);
void SetAllOrders(int order);
bool FinalStructureTest();
void CheckBags();
void CheckZones(int start, int stop, bool instr);
void TranslatePercussions();
void TranslatePercussionPreset(SFPreset *preset);
void TranslatePercussionPresetZone(SFPreset *preset, SFBag *zone);
void SetInstrumentGenerators(SFGenComposite *composite, int start, int stop);
void AddPresetGenerators(SFGenComposite *composite, int start, int stop, SFPreset *preset);
void AddPresetGenerators(SFGenComposite *composite, int start, int stop, bool gen_set[GEN_NumGenerators]);
Timidity::Instrument *LoadPercussion(Timidity::Renderer *song, SFPerc *perc);
Timidity::Instrument *LoadPreset(Timidity::Renderer *song, SFPreset *preset);
void LoadSample(SFSample *sample);
void ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Timidity::Renderer *song, Timidity::Sample *sp);
SFPreset *Presets;
SFBag *PresetBags;
SFGenList *PresetGenerators;
SFInst *Instruments;
SFBag *InstrBags;
SFGenList *InstrGenerators;
SFSample *Samples;
TArray<SFPerc> Percussion;
int MinorVersion;
DWORD SampleDataOffset;
DWORD SampleDataLSBOffset;
DWORD SizeSampleData;
DWORD SizeSampleDataLSB;
int NumPresets;
int NumPresetBags;
int NumPresetGenerators;
int NumInstruments;
int NumInstrBags;
int NumInstrGenerators;
int NumSamples;
};
SFFile *ReadSF2(const char *filename, FileReader *f);