1 /* 2 * DLSBank.h 3 * --------- 4 * Purpose: Sound bank loading. 5 * Notes : Supported sound bank types: DLS (including embedded DLS in MSS & RMI), SF2 6 * Authors: Olivier Lapicque 7 * OpenMPT Devs 8 * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. 9 */ 10 11 12 #pragma once 13 14 #include "openmpt/all/BuildSettings.hpp" 15 16 OPENMPT_NAMESPACE_BEGIN 17 class CSoundFile; 18 OPENMPT_NAMESPACE_END 19 #include "Snd_defs.h" 20 21 OPENMPT_NAMESPACE_BEGIN 22 23 #ifdef MODPLUG_TRACKER 24 25 26 struct DLSREGION 27 { 28 uint32 ulLoopStart; 29 uint32 ulLoopEnd; 30 uint16 nWaveLink; 31 uint16 uPercEnv; 32 uint16 usVolume; // 0..256 33 uint16 fuOptions; // flags + key group 34 int16 sFineTune; // +128 = +1 semitone 35 int16 panning = -1; // -1= unset (DLS), otherwise 0...256 36 uint8 uKeyMin; 37 uint8 uKeyMax; 38 uint8 uUnityNote; 39 uint8 tuning = 100; 40 IsDummyDLSREGION41 constexpr bool IsDummy() const noexcept { return uKeyMin == 0xFF || nWaveLink == Util::MaxValueOfType(nWaveLink); } 42 }; 43 44 struct DLSENVELOPE 45 { 46 // Volume Envelope 47 uint16 wVolAttack; // Attack Time: 0-1000, 1 = 20ms (1/50s) -> [0-20s] 48 uint16 wVolDecay; // Decay Time: 0-1000, 1 = 20ms (1/50s) -> [0-20s] 49 uint16 wVolRelease; // Release Time: 0-1000, 1 = 20ms (1/50s) -> [0-20s] 50 uint8 nVolSustainLevel; // Sustain Level: 0-128, 128=100% 51 uint8 nDefPan; // Default Pan 52 }; 53 54 // Special Bank bits 55 #define F_INSTRUMENT_DRUMS 0x80000000 56 57 struct DLSINSTRUMENT 58 { 59 uint32 ulBank = 0, ulInstrument = 0; 60 uint32 nMelodicEnv = 0; 61 std::vector<DLSREGION> Regions; 62 char szName[32]; 63 // SF2 stuff (DO NOT USE! -> used internally by the SF2 loader) 64 uint16 wPresetBagNdx = 0, wPresetBagNum = 0; 65 }; 66 67 struct DLSSAMPLEEX 68 { 69 char szName[20]; 70 uint32 dwLen; 71 uint32 dwStartloop; 72 uint32 dwEndloop; 73 uint32 dwSampleRate; 74 uint8 byOriginalPitch; 75 int8 chPitchCorrection; 76 bool compressed = false; 77 }; 78 79 80 #define SOUNDBANK_TYPE_INVALID 0 81 #define SOUNDBANK_TYPE_DLS 0x01 82 #define SOUNDBANK_TYPE_SF2 0x02 83 84 struct SOUNDBANKINFO 85 { 86 std::string szBankName, 87 szCopyRight, 88 szComments, 89 szEngineer, 90 szSoftware, // ISFT: Software 91 szDescription; // ISBJ: Subject 92 }; 93 94 struct IFFCHUNK; 95 struct SF2LoaderInfo; 96 97 class CDLSBank 98 { 99 protected: 100 SOUNDBANKINFO m_BankInfo; 101 mpt::PathString m_szFileName; 102 size_t m_dwWavePoolOffset; 103 uint32 m_nType; 104 // DLS Information 105 uint32 m_nMaxWaveLink; 106 uint32 m_sf2version = 0; 107 std::vector<size_t> m_WaveForms; 108 std::vector<DLSINSTRUMENT> m_Instruments; 109 std::vector<DLSSAMPLEEX> m_SamplesEx; 110 std::vector<DLSENVELOPE> m_Envelopes; 111 112 public: 113 CDLSBank(); 114 static bool IsDLSBank(const mpt::PathString &filename); MakeMelodicCode(uint32 bank,uint32 instr)115 static uint32 MakeMelodicCode(uint32 bank, uint32 instr) { return ((bank << 16) | (instr));} MakeDrumCode(uint32 rgn,uint32 instr)116 static uint32 MakeDrumCode(uint32 rgn, uint32 instr) { return (0x80000000 | (rgn << 16) | (instr));} 117 118 public: 119 bool Open(const mpt::PathString &filename); 120 bool Open(FileReader file); GetFileName()121 mpt::PathString GetFileName() const { return m_szFileName; } GetBankType()122 uint32 GetBankType() const { return m_nType; } GetBankInfo()123 const SOUNDBANKINFO &GetBankInfo() const { return m_BankInfo; } 124 125 public: GetNumInstruments()126 uint32 GetNumInstruments() const { return static_cast<uint32>(m_Instruments.size()); } GetNumSamples()127 uint32 GetNumSamples() const { return static_cast<uint32>(m_WaveForms.size()); } GetInstrument(uint32 iIns)128 const DLSINSTRUMENT *GetInstrument(uint32 iIns) const { return iIns < m_Instruments.size() ? &m_Instruments[iIns] : nullptr; } 129 const DLSINSTRUMENT *FindInstrument(bool isDrum, uint32 bank = 0xFF, uint32 program = 0xFF, uint32 key = 0xFF, uint32 *pInsNo = nullptr) const; 130 bool FindAndExtract(CSoundFile &sndFile, const INSTRUMENTINDEX ins, const bool isDrum) const; 131 uint32 GetRegionFromKey(uint32 nIns, uint32 nKey) const; 132 bool ExtractWaveForm(uint32 nIns, uint32 nRgn, std::vector<uint8> &waveData, uint32 &length) const; 133 bool ExtractSample(CSoundFile &sndFile, SAMPLEINDEX nSample, uint32 nIns, uint32 nRgn, int transpose = 0) const; 134 bool ExtractInstrument(CSoundFile &sndFile, INSTRUMENTINDEX nInstr, uint32 nIns, uint32 nDrumRgn) const; 135 const char *GetRegionName(uint32 nIns, uint32 nRgn) const; 136 uint16 GetPanning(uint32 ins, uint32 region) const; 137 138 // Internal Loader Functions 139 protected: 140 bool UpdateInstrumentDefinition(DLSINSTRUMENT *pDlsIns, FileReader chunk); 141 bool UpdateSF2PresetData(SF2LoaderInfo &sf2info, const IFFCHUNK &header, FileReader &chunk); 142 bool ConvertSF2ToDLS(SF2LoaderInfo &sf2info); 143 144 public: 145 // DLS Unit conversion 146 static int32 DLS32BitTimeCentsToMilliseconds(int32 lTimeCents); 147 static int32 DLS32BitRelativeGainToLinear(int32 lCentibels); // 0dB = 0x10000 148 static int32 DLS32BitRelativeLinearToGain(int32 lGain); // 0dB = 0x10000 149 static int32 DLSMidiVolumeToLinear(uint32 nMidiVolume); // [0-127] -> [0-0x10000] 150 }; 151 152 153 #endif // MODPLUG_TRACKER 154 155 156 OPENMPT_NAMESPACE_END 157