12using namespace Tempest;
22 const uint32_t ppq = uint32_t(600*(100.0/tempo));
23 const uint32_t mult = (ppq*4)/timeSig.
bBeat;
24 return uint32_t(nTimeOffset) +
30 return uint32_t(duration*100.0/tempo);
33static bool offsetFromScale(
const uint8_t degree,
const uint32_t scale, uint8_t& offset) {
35 for(uint8_t i=0; i<24; i++) {
36 if(scale & (1 << i)) {
47 const uint32_t& chord,
48 const std::vector<DMUS_IO_SUBCHORD>& subchords,
55 uint32_t dwChordPattern = 0x00000091;
56 uint32_t dwScalePattern = 0x00AB5AB5;
58 if(subchords.size()>0) {
59 dwChordPattern = subchords[0].dwChordPattern;
60 dwScalePattern = subchords[0].dwScalePattern;
63 uint8_t octave = uint8_t((note.
wMusicValue & 0xF000) >> 12);
64 uint8_t chordTone = uint8_t((note.
wMusicValue & 0x0F00) >> 8);
65 uint8_t scaleTone = uint8_t((note.
wMusicValue & 0x00F0) >> 4);
67 int accidentals = int8_t(note.
wMusicValue & 0x000F);
69 accidentals = (accidentals - 16);
71 int noteValue = ((chord & 0xFF000000) >> 24) + 12 * octave;
72 uint8_t chordOffset = 0;
73 uint8_t scaleOffset = 0;
75 noteValue += chordOffset;
77 noteValue += chordOffset+4;
81 if(scaleTone &&
offsetFromScale(scaleTone, dwScalePattern >> chordOffset, scaleOffset)) {
82 noteValue += scaleOffset;
85 noteValue += accidentals;
91 value = uint8_t(noteValue);
96 :owner(&owner), intern(std::make_shared<Internal>()) {
97 for(
const auto& track : s.track) {
98 if(track.sttr!=
nullptr) {
99 auto& sttr = *track.sttr;
100 for(
const auto& style : sttr.styles){
101 auto& stl = owner.
style(style.reference);
103 for(
auto& band:stl.band) {
104 for(
auto& r:band.intrument){
105 if(r.reference.file.empty())
111 ins.volume = r.header.bVolume/127.f;
else
114 ins.pan = r.header.bPan/127.f;
else
117 ins.dwPatch = r.header.dwPatch;
122 instruments[r.header.dwPChannel] = ins;
127 else if(track.cord!=
nullptr) {
128 cordHeader = track.cord->header;
129 subchord = track.cord->subchord;
131 else if(track.cmnd!=
nullptr) {
132 commands = track.cmnd->commands;
138void PatternList::index() {
141 const Style& stl = *style;
142 intern->pptn.resize(stl.
patterns.size());
143 for(
size_t i=0;i<stl.
patterns.size();++i){
144 index(stl,intern->pptn[i],stl.
patterns[i]);
145 intern->pptn[i].styh = stl.
styh;
148 for(
auto& i:commands) {
152 gr.bGrooveLevel = i.bGrooveLevel;
153 gr.bGrooveRange = i.bGrooveRange;
154 intern->groove.push_back(gr);
159void PatternList::index(
const Style& stl,PatternInternal &inst,
const Dx8::Pattern &pattern) {
164 inst.ptnh = pattern.
header;
166 auto& instument = inst.instruments;
167 instument.resize(pattern.
partref.size());
170 for(
size_t i=0;i<pattern.
partref.size();++i) {
171 const auto& pref = pattern.
partref[i];
172 auto pinst = instruments.find(pref.io.wLogicalPartID);
173 if(pinst==instruments.end())
175 if(pref.io.wLogicalPartID!=22)
177 auto& pr = instument[i];
178 const Instrument& ins = ((*pinst).second);
179 pr.key = pref.io.wLogicalPartID;
180 pr.font = ins.dls->toSoundfont(ins.dwPatch);
182 pr.font.setVolume(ins.volume);
183 pr.font.setPan(ins.pan);
185 pr.volume = ins.volume;
188 auto part = stl.
findPart(pref.io.guidPartID);
190 std::memcpy(pr.dwVariationChoices,part->header.dwVariationChoices,
sizeof(pr.dwVariationChoices));
191 for(
auto& i:pr.dwVariationChoices)
197 for(
size_t i=0;i<pattern.
partref.size();++i) {
198 const auto& pref = pattern.
partref[i];
199 auto part = stl.
findPart(pref.io.guidPartID);
202 index(inst,&instument[i],stl,*part);
205 std::sort(inst.waves.begin(),inst.waves.end(),[](
const Note& a,
const Note& b){
208 std::sort(inst.volume.begin(),inst.volume.end(),[](
const Curve& a,
const Curve& b){
215void PatternList::index(PatternInternal &idx, InsInternal* inst,
217 for(
auto& i:part.notes) {
229 rec.velosity = i.bVelocity;
231 rec.dwVariation = i.dwVariation;
233 idx.waves.push_back(rec);
236 for(
auto& i:part.curves) {
239 if(i.nStartValue>127 || i.nEndValue>127)
245 c.shape = i.bCurveShape;
247 c.startV = float(i.nStartValue&0x7F)/127.f;
248 c.endV = float(i.nEndValue &0x7F)/127.f;
249 c.dwVariation = i.dwVariation;
252 idx.volume.push_back(c);
257 return intern->pptn.size();
262 std::string st(i.info.unam.begin(),i.info.unam.end());
263 Log::i(
"pattern: ",st);
269 if(!style || patternId>=style->
patterns.size())
271 const Style& stl = *style;
276 for(
size_t i=0;i<p.
partref.size();++i) {
278 auto part = stl.
findPart(pref.io.guidPartID);
282 if(part->
notes.size()>0 || part->
curves.size()>0) {
283 std::string st(pref.unfo.unam.begin(),pref.unfo.unam.end());
284 Log::i(
"part: ",i,
" ",st,
" partid=",pref.io.wLogicalPartID);
288 std::snprintf(buf,
sizeof(buf),
"%#010x",i);
289 Log::i(
" var: ",buf);
298 for(
auto& i:part.notes) {
306 if(inst!=instruments.end()) {
307 float vol = inst->second.volume;
308 float vel = i.bVelocity;
309 auto w = (*inst).second.dls->findWave(note);
310 const char* name = w==
nullptr ?
"" : w->info.inam.c_str();
311 Log::i(
" note:[C",cId,
" ", note,
"] {",
312 time,
" - ",time+i.mtDuration,
"} ",
"vol = ",vol,
" var=",i.dwVariation,
" vel=",vel,
" ",name);
316 for(
auto& i:part.curves) {
317 const char* name =
"";
325 Log::i(
" curve:[", name,
"] ",time,
" - ",time+i.mtDuration,
" var=",i.dwVariation);
const DlsCollection & dlsCollection(const Reference &id)
const Style & style(const Reference &id)
void dbgDumpPatternList() const
void dbgDump(const size_t patternId) const
std::vector< PartRef > partref
uint32_t timeLength(double tempo) const
std::vector< Pattern > patterns
const Part * findPart(const GUID &guid) const
static bool offsetFromScale(const uint8_t degree, const uint32_t scale, uint8_t &offset)
static bool musicValueToMIDI(const DMUS_IO_STYLENOTE ¬e, const uint32_t &chord, const std::vector< DMUS_IO_SUBCHORD > &subchords, uint8_t &value)
static uint32_t musicOffset(uint32_t mtGridStart, int16_t nTimeOffset, const DMUS_IO_TIMESIG &timeSig, double tempo)
static uint32_t musicDuration(uint32_t duration, double tempo)
DMUS_PLAYMODE_FLAGS bPlayModeFlags
uint32_t dwVariationChoices[32]
std::vector< DMUS_IO_STYLECURVE > curves
std::vector< DMUS_IO_STYLENOTE > notes