1 /*
2  * SoundFX Macs Opera CMF Player -- Copyright (c) 2017 Sebastian Kienzl <seb@knzl.de>
3  *
4  * Part of Adplug - Replayer for many OPL2/OPL3 audio file formats.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 #ifndef H_ADPLUG_CMFMACSOPERAPLAYER
22 #define H_ADPLUG_CMFMACSOPERAPLAYER
23 
24 #include <vector>
25 #include <stdint.h>
26 #include "player.h"
27 
28 class CcmfmacsoperaPlayer: public CPlayer
29 {
30 public:
31 	static CPlayer* factory(Copl* newopl);
32 
33 	CcmfmacsoperaPlayer(Copl* newopl);
34 
35 	bool load(const std::string& filename, const CFileProvider& fp);
36 	bool update();
37 	void rewind(int subsong);
getrefresh()38 	float getrefresh() { return speedRowsPerSec; };
39 
40 	virtual std::string gettype();
getpatterns()41 	virtual unsigned int getpatterns()    { return nrOfPatterns; }
getpattern()42 	virtual unsigned int getpattern()     { return patternOrder[currentOrderIndex]; }
getorders()43 	virtual unsigned int getorders()      { return nrOfOrders; }
getorder()44 	virtual unsigned int getorder()       { return currentOrderIndex; }
getrow()45 	virtual unsigned int getrow()         { return currentRow; }
getspeed()46 	virtual unsigned int getspeed()       { return 1; }
getinstruments()47 	virtual unsigned int getinstruments() { return instruments.size(); }
getinstrument(unsigned int n)48 	virtual std::string getinstrument(unsigned int n) { return instruments[n].name; }
49 
50  protected:
51 	struct SlotSettings {
52 		int16_t ksl;
53 		int16_t multiple;
54 		int16_t attackRate;
55 		int16_t sustainLevel;
56 		int16_t egType;
57 		int16_t decayRate;
58 		int16_t releaseRate;
59 		int16_t totalLevel;
60 		int16_t ampMod;
61 		int16_t vib;
62 		int16_t ksr;
63 		int16_t waveSelect;
64 	};
65 
66 	struct Instrument {
67 		SlotSettings op[2];
68 		int16_t      feedback;
69 		int16_t      connection;
70 		char         name[14];
71 	};
72 
73 	struct NoteEvent {
74 		uint8_t row;
75 		uint8_t col;
76 		uint8_t note;    // 4: release, 1: end of pattern, 24: C-0, 119: H-7/B#7
77 		uint8_t instrument;
78 		uint8_t volume;
79 		uint8_t pitch;
80 	};
81 
82 	typedef std::vector<NoteEvent> Pattern;
83 
84 	float   speedRowsPerSec;
85 	bool    rhythmMode;
86 	bool    songDone;
87 
88 	int     nrOfPatterns;
89 	int16_t patternOrder[99];
90 	int     nrOfOrders;
91 
92 	std::vector<Instrument> instruments;
93 	std::vector<Pattern> patterns;
94 
95 	int currentOrderIndex;
96 	int currentRow;
97 	int currentPatternIndex;
98 
99     const Instrument* channelCurrentInstrument[11];
100 	int current0xBx[9];
101 	int current0xBD;
102 
103 
104 	bool loadInstruments(binistream* f, int nrOfInstruments);
105 	bool loadPatterns(binistream* f);
106 
107 	bool isValidChannel(int channelNr) const;
108 	bool isRhythmChannel(int channelNr) const;
109 
110 	void setSlot(int slotNr, const SlotSettings& settings);
111 	bool setInstrument(int channelNr, const Instrument& inst);
112 	void setAxBx(int channelNr, int Ax, int Bx);
113 	bool setNote(int channelNr, int note);
114 	void setVolume(int channelNr, int vol);
115 
116 	void keyOn(int channelNr);
117 	void keyOff(int channelNr);
118 
119 	bool advanceRow();
120 	void processNoteEvent(const NoteEvent &n);
121 
122 	void resetPlayer();
123 };
124 
125 #endif
126