mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-08 14:01:32 +00:00
e64586d86f
- 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)
318 lines
6.8 KiB
C
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);
|