1 /*
2 * Copyright (C) 2018-2020 Rerrah
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "bank.hpp"
27 #include <stdio.h>
28 #include <utility>
29 #include "instrument_io.hpp"
30 #include "format/wopn_file.h"
31
BtBank(std::vector<int> ids,std::vector<std::string> names)32 BtBank::BtBank(std::vector<int> ids, std::vector<std::string> names)
33 : ids_(std::move(ids)),
34 names_(std::move(names))
35 {
36 }
37
BtBank(std::vector<int> ids,std::vector<std::string> names,std::vector<BinaryContainer> instSecs,BinaryContainer propSec,uint32_t version)38 BtBank::BtBank(std::vector<int> ids, std::vector<std::string> names,
39 std::vector<BinaryContainer> instSecs, BinaryContainer propSec, uint32_t version)
40 : instCtrs_(std::move(instSecs)),
41 propCtr_(std::move(propSec)),
42 ids_(std::move(ids)),
43 names_(std::move(names)),
44 version_(version)
45 {
46 }
47
~BtBank()48 BtBank::~BtBank()
49 {
50 }
51
getNumInstruments() const52 size_t BtBank::getNumInstruments() const
53 {
54 return ids_.size();
55 }
56
getInstrumentIdentifier(size_t index) const57 std::string BtBank::getInstrumentIdentifier(size_t index) const
58 {
59 return std::to_string(ids_.at(index));
60 }
61
getInstrumentName(size_t index) const62 std::string BtBank::getInstrumentName(size_t index) const
63 {
64 return names_.at(index);
65 }
66
loadInstrument(size_t index,std::weak_ptr<InstrumentsManager> instMan,int instNum) const67 AbstractInstrument* BtBank::loadInstrument(size_t index, std::weak_ptr<InstrumentsManager> instMan, int instNum) const
68 {
69 return InstrumentIO::loadBTBInstrument(instCtrs_.at(static_cast<size_t>(index)), propCtr_, instMan, instNum, version_);
70 }
71
72 /******************************/
operator ()(WOPNFile * x)73 void WopnBank::WOPNDeleter::operator()(WOPNFile *x)
74 {
75 WOPN_Free(x);
76 }
77
78 struct WopnBank::InstEntry
79 {
80 WOPNInstrument *inst;
81 struct ValuesType
82 {
83 bool percussive : 1;
84 unsigned msb : 7;
85 unsigned lsb : 7;
86 unsigned nth : 7;
87 } vals;
88 };
89
WopnBank(WOPNFile * wopn)90 WopnBank::WopnBank(WOPNFile *wopn)
91 : wopn_(wopn)
92 {
93 unsigned numM = wopn->banks_count_melodic;
94 unsigned numP = wopn->banks_count_percussion;
95
96 size_t instMax = 128 * (numP + numM);
97 entries_.reserve(instMax);
98
99 for (size_t i = 0; i < instMax; ++i) {
100 InstEntry ent;
101 ent.vals.percussive = (i / 128) >= numM;
102 WOPNBank& bank = ent.vals.percussive
103 ? wopn->banks_percussive[(i / 128) - numM]
104 : wopn->banks_melodic[i / 128];
105 ent.vals.msb = bank.bank_midi_msb;
106 ent.vals.lsb = bank.bank_midi_lsb;
107 ent.vals.nth = i % 128;
108 ent.inst = &bank.ins[ent.vals.nth];
109 if ((ent.inst->inst_flags & WOPN_Ins_IsBlank) == 0)
110 entries_.push_back(ent);
111 }
112
113 entries_.shrink_to_fit();
114 }
115
~WopnBank()116 WopnBank::~WopnBank()
117 {
118 }
119
getNumInstruments() const120 size_t WopnBank::getNumInstruments() const
121 {
122 return entries_.size();
123 }
124
getInstrumentIdentifier(size_t index) const125 std::string WopnBank::getInstrumentIdentifier(size_t index) const
126 {
127 const InstEntry &ent = entries_.at(index);
128 char identifier[64];
129 sprintf(identifier, "%c%03d:%03d:%03d", "MP"[ent.vals.percussive],
130 ent.vals.msb, ent.vals.lsb, ent.vals.nth);
131 return identifier;
132 }
133
getInstrumentName(size_t index) const134 std::string WopnBank::getInstrumentName(size_t index) const
135 {
136 const InstEntry &ent = entries_.at(index);
137 return ent.inst->inst_name;
138 }
139
loadInstrument(size_t index,std::weak_ptr<InstrumentsManager> instMan,int instNum) const140 AbstractInstrument* WopnBank::loadInstrument(size_t index, std::weak_ptr<InstrumentsManager> instMan, int instNum) const
141 {
142 const InstEntry &ent = entries_.at(index);
143 return InstrumentIO::loadWOPNInstrument(*ent.inst, instMan, instNum);
144 }
145
146 /******************************/
FfBank(std::vector<int> ids,std::vector<std::string> names,std::vector<BinaryContainer> ctrs)147 FfBank::FfBank(std::vector<int> ids, std::vector<std::string> names, std::vector<BinaryContainer> ctrs)
148 : ids_(ids), names_(names), instCtrs_(ctrs)
149 {
150 }
151
getNumInstruments() const152 size_t FfBank::getNumInstruments() const
153 {
154 return ids_.size();
155 }
156
getInstrumentIdentifier(size_t index) const157 std::string FfBank::getInstrumentIdentifier(size_t index) const
158 {
159 return std::to_string(ids_.at(index));
160 }
161
getInstrumentName(size_t index) const162 std::string FfBank::getInstrumentName(size_t index) const
163 {
164 return names_.at(index);
165 }
166
loadInstrument(size_t index,std::weak_ptr<InstrumentsManager> instMan,int instNum) const167 AbstractInstrument* FfBank::loadInstrument(size_t index, std::weak_ptr<InstrumentsManager> instMan, int instNum) const
168 {
169 return InstrumentIO::loadFFInstrument(instCtrs_.at(index), names_.at(index), instMan, instNum);
170 }
171
setInstrumentName(size_t index,const std::string & name)172 void FfBank::setInstrumentName(size_t index, const std::string& name)
173 {
174 names_.at(index) = name;
175 }
176
177 /******************************/
PpcBank(std::vector<int> ids,std::vector<std::vector<uint8_t>> samples)178 PpcBank::PpcBank(std::vector<int> ids, std::vector<std::vector<uint8_t> > samples)
179 : ids_(ids), samples_(samples)
180 {
181 }
182
getNumInstruments() const183 size_t PpcBank::getNumInstruments() const
184 {
185 return samples_.size();
186 }
187
getInstrumentIdentifier(size_t index) const188 std::string PpcBank::getInstrumentIdentifier(size_t index) const
189 {
190 return std::to_string(ids_.at(index));
191 }
192
getInstrumentName(size_t index) const193 std::string PpcBank::getInstrumentName(size_t index) const
194 {
195 (void)index;
196 return "";
197 }
198
loadInstrument(size_t index,std::weak_ptr<InstrumentsManager> instMan,int instNum) const199 AbstractInstrument* PpcBank::loadInstrument(size_t index, std::weak_ptr<InstrumentsManager> instMan, int instNum) const
200 {
201 return InstrumentIO::loadPPCInstrument(samples_.at(index), instMan, instNum);
202 }
203
204 /******************************/
PviBank(std::vector<int> ids,std::vector<std::vector<uint8_t>> samples)205 PviBank::PviBank(std::vector<int> ids, std::vector<std::vector<uint8_t> > samples)
206 : ids_(ids), samples_(samples)
207 {
208 }
209
getNumInstruments() const210 size_t PviBank::getNumInstruments() const
211 {
212 return samples_.size();
213 }
214
getInstrumentIdentifier(size_t index) const215 std::string PviBank::getInstrumentIdentifier(size_t index) const
216 {
217 return std::to_string(ids_.at(index));
218 }
219
getInstrumentName(size_t index) const220 std::string PviBank::getInstrumentName(size_t index) const
221 {
222 (void)index;
223 return "";
224 }
225
loadInstrument(size_t index,std::weak_ptr<InstrumentsManager> instMan,int instNum) const226 AbstractInstrument* PviBank::loadInstrument(size_t index, std::weak_ptr<InstrumentsManager> instMan, int instNum) const
227 {
228 return InstrumentIO::loadPVIInstrument(samples_.at(index), instMan, instNum);
229 }
230
231 /******************************/
Mucom88Bank(std::vector<int> ids,std::vector<std::string> names,std::vector<BinaryContainer> ctrs)232 Mucom88Bank::Mucom88Bank(std::vector<int> ids, std::vector<std::string> names, std::vector<BinaryContainer> ctrs)
233 : ids_(ids), names_(names), instCtrs_(ctrs)
234 {
235 }
236
getNumInstruments() const237 size_t Mucom88Bank::getNumInstruments() const
238 {
239 return ids_.size();
240 }
241
getInstrumentIdentifier(size_t index) const242 std::string Mucom88Bank::getInstrumentIdentifier(size_t index) const
243 {
244 return std::to_string(ids_.at(index));
245 }
246
getInstrumentName(size_t index) const247 std::string Mucom88Bank::getInstrumentName(size_t index) const
248 {
249 return names_.at(index);
250 }
251
loadInstrument(size_t index,std::weak_ptr<InstrumentsManager> instMan,int instNum) const252 AbstractInstrument* Mucom88Bank::loadInstrument(size_t index, std::weak_ptr<InstrumentsManager> instMan, int instNum) const
253 {
254 return InstrumentIO::loadMUCOM88Instrument(instCtrs_.at(index), names_.at(index), instMan, instNum);
255 }
256
setInstrumentName(size_t index,const std::string & name)257 void Mucom88Bank::setInstrumentName(size_t index, const std::string& name)
258 {
259 names_.at(index) = name;
260 }
261