1 /* 2 * Adplug - Replayer for many OPL2/OPL3 audio file formats. 3 * Copyright (C) 1999 - 2009 Simon Peter, <dn.tlp@gmx.net>, et al. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * cmf.h - CMF player by Adam Nielsen <malvineous@shikadi.net> 20 */ 21 22 #include <stdint.h> // for uintxx_t 23 #include "player.h" 24 25 typedef struct { 26 uint16_t iInstrumentBlockOffset; 27 uint16_t iMusicOffset; 28 uint16_t iTicksPerQuarterNote; 29 uint16_t iTicksPerSecond; 30 uint16_t iTagOffsetTitle; 31 uint16_t iTagOffsetComposer; 32 uint16_t iTagOffsetRemarks; 33 uint8_t iChannelsInUse[16]; 34 uint16_t iNumInstruments; 35 uint16_t iTempo; 36 } CMFHEADER; 37 38 typedef struct { 39 uint8_t iCharMult; 40 uint8_t iScalingOutput; 41 uint8_t iAttackDecay; 42 uint8_t iSustainRelease; 43 uint8_t iWaveSel; 44 } OPERATOR; 45 46 typedef struct { 47 OPERATOR op[2]; // 0 == modulator, 1 == carrier 48 uint8_t iConnection; 49 } SBI; 50 51 typedef struct { 52 int iPatch; // MIDI patch for this channel 53 int iPitchbend; // Current pitchbend amount for this channel 54 int iTranspose; // Transpose amount for this channel (between -128 and +128) 55 } MIDICHANNEL; 56 57 typedef struct { 58 int iNoteStart; // When the note started playing (longest notes get cut first, 0 == channel free) 59 int iMIDINote; // MIDI note number currently being played on this OPL channel 60 int iMIDIChannel; // Source MIDI channel where this note came from 61 int iMIDIPatch; // Current MIDI patch set on this OPL channel 62 } OPLCHANNEL; 63 64 class CcmfPlayer: public CPlayer 65 { 66 private: 67 uint8_t *data; // song data (CMF music block) 68 int iPlayPointer; // Current location of playback pointer 69 int iSongLen; // Max value for iPlayPointer 70 CMFHEADER cmfHeader; 71 SBI *pInstruments; 72 bool bPercussive; // are rhythm-mode instruments enabled? 73 uint8_t iCurrentRegs[256]; // Current values in the OPL chip 74 uint8_t iPrevCommand; // Previous command (used for repeated MIDI commands, as the seek and playback code need to share this) 75 uint8_t iNotePlaying[16]; // Last note turned on, used for duplicate note check 76 bool bNoteFix[16]; // Fix duplicated Note On / Note Off 77 78 int iNoteCount; // Used to count how long notes have been playing for 79 MIDICHANNEL chMIDI[16]; 80 OPLCHANNEL chOPL[9]; 81 82 // Additions for AdPlug's design 83 int iDelayRemaining; 84 bool bSongEnd; 85 std::string strTitle, strComposer, strRemarks; 86 87 public: 88 static CPlayer *factory(Copl *newopl); 89 90 CcmfPlayer(Copl *newopl); 91 ~CcmfPlayer(); 92 93 bool load(const std::string &filename, const CFileProvider &fp); 94 bool update(); 95 void rewind(int subsong); 96 float getrefresh(); 97 gettype()98 std::string gettype() 99 { return std::string("Creative Music File (CMF)"); }; 100 std::string gettitle(); 101 std::string getauthor(); 102 std::string getdesc(); 103 104 protected: 105 uint32_t readMIDINumber(); 106 void writeInstrumentSettings(uint8_t iChannel, uint8_t iOperatorSource, uint8_t iOperatorDest, uint8_t iInstrument); 107 void writeOPL(uint8_t iRegister, uint8_t iValue); 108 void getFreq(uint8_t iChannel, uint8_t iNote, uint8_t * iBlock, uint16_t * iOPLFNum); 109 void cmfNoteOn(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity); 110 void cmfNoteOff(uint8_t iChannel, uint8_t iNote, uint8_t iVelocity); 111 void cmfNoteUpdate(uint8_t iChannel); 112 uint8_t getPercChannel(uint8_t iChannel); 113 void MIDIchangeInstrument(uint8_t iOPLChannel, uint8_t iMIDIChannel, uint8_t iNewInstrument); 114 void MIDIcontroller(uint8_t iChannel, uint8_t iController, uint8_t iValue); 115 116 }; 117