/// Обновление void UpdateEvent (const char* name, ResourceState state) { EventMap::iterator iter = event_map.find (name); if (iter == event_map.end ()) { EventPtr event = EventPtr (new EventDesc (name, state), false); EventList::iterator iter = event_list.insert (event_list.end (), event); event_map.insert_pair (name, iter); } else { EventPtr event = *iter->second; if (state == event->state) return; if (event->state == ResourceState_Ignore) { event_list.splice (event_list.end (), event_list, iter->second); event->state = state; return; } switch (state) { case ResourceState_Unloaded: event->state = ResourceState_Ignore; break; case ResourceState_Prefetched: if (event->state != ResourceState_Unloaded) return; event_list.splice (event_list.end (), event_list, iter->second); event->state = state; break; case ResourceState_Loaded: if (event->state == ResourceState_Unloaded) event->state = ResourceState_Ignore; else { event_list.splice (event_list.end (), event_list, iter->second); event->state = state; } break; default: break; } } }
void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len)/*{{{*/ { { startUndo(); MidiPart* nPart = new MidiPart(*(MidiPart*) oPart); nPart->setLenTick(len); // Indicate no undo, and do port controller values but not clone parts. audio->msgChangePart(oPart, nPart, false, true, false); // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if (nPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do port controller values and clone parts. audio->msgDeleteEvent(i->second, nPart, false, true, true); } } } /* // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if(oPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(i->second, nPart, false); audio->msgDeleteEvent(i->second, nPart, false, false, false); } } } // Indicate no undo, and do port controller values but not clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, true, false); */ endUndo(SC_PART_MODIFIED); } }/*}}}*/
HINLINE void operator()( T_SpeciesStorage& speciesStorage, const uint32_t currentStep, const EventTask& eventInt, EventTask& pushEvent, EventTask& commEvent ) const { typedef std::list<EventTask> EventList; EventList updateEventList; EventList commEventList; /* push all species */ typedef typename PMacc::particles::traits::FilterByFlag < VectorAllSpecies, particlePusher<> >::type VectorSpeciesWithPusher; ForEach<VectorSpeciesWithPusher, particles::PushSpecies<bmpl::_1>, MakeIdentifier<bmpl::_1> > pushSpecies; pushSpecies(forward(speciesStorage), currentStep, eventInt, forward(updateEventList)); /* join all push events */ for (typename EventList::iterator iter = updateEventList.begin(); iter != updateEventList.end(); ++iter) { pushEvent += *iter; } /* call communication for all species */ ForEach<VectorSpeciesWithPusher, particles::CommunicateSpecies<bmpl::_1>, MakeIdentifier<bmpl::_1> > communicateSpecies; communicateSpecies(forward(speciesStorage), forward(updateEventList), forward(commEventList)); /* join all communication events */ for (typename EventList::iterator iter = commEventList.begin(); iter != commEventList.end(); ++iter) { commEvent += *iter; } }
void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) { int l1 = 0; // len of first new part (ticks or samples) int l2 = 0; // len of second new part int samplepos = tempomap.tick2frame(tickpos); { l1 = tickpos - part->tick(); l2 = part->lenTick() - l1; } if (l1 <= 0 || l2 <= 0) return; p1 = newPart(part); // new left part p2 = newPart(part); // new right part // Added by Tim. p3.3.6 //printf("Track::splitPart part ev %p sz:%d ref:%d p1 %p sz:%d ref:%d p2 %p sz:%d ref:%d\n", part->events(), part->events()->size(), part->events()->arefCount(), p1->events(), p1->events()->size(), p1->events()->arefCount(), p2->events(), p2->events()->size(), p2->events()->arefCount()); { p1->setLenTick(l1); p2->setTick(tickpos); p2->setLenTick(l2); } p2->setSn(p2->newSn()); EventList* se = part->events(); EventList* de1 = p1->events(); EventList* de2 = p2->events(); p1->setColorIndex(part->colorIndex()); p2->setColorIndex(part->colorIndex()); { for (iEvent ie = se->begin(); ie != se->end(); ++ie) { Event event = ie->second.clone(); int t = event.tick(); if (t >= l1) { event.move(-l1); de2->add(event); } else de1->add(event); } } }
std::vector<double> beatTrack(const AgentParameters ¶ms, const EventList &events, const EventList &beats) { AgentList agents; int count = 0; double beatTime = -1; if (!beats.empty()) { count = beats.size() - 1; EventList::const_iterator itr = beats.end(); --itr; beatTime = itr->time; } if (count > 0) { // tempo given by mean of initial beats double ioi = (beatTime - beats.begin()->time) / count; agents.push_back(new Agent(params, ioi)); } else // tempo not given; use tempo induction agents = Induction::beatInduction(params, events); if (!beats.empty()) { for (AgentList::iterator itr = agents.begin(); itr != agents.end(); ++itr) { (*itr)->beatTime = beatTime; (*itr)->beatCount = count; (*itr)->events = beats; } } agents.beatTrack(events, params, -1); Agent *best = agents.bestAgent(); std::vector<double> resultBeatTimes; if (best) { best->fillBeats(beatTime); for (EventList::const_iterator itr = best->events.begin(); itr != best->events.end(); ++itr) { resultBeatTimes.push_back(itr->time); } } for (AgentList::iterator ai = agents.begin(); ai != agents.end(); ++ai) { delete *ai; } return resultBeatTimes; }
void AgentList::beatTrack(const EventList &el, const AgentParameters ¶ms, double stop) { EventList::const_iterator ei = el.begin(); bool phaseGiven = !empty() && ((*begin())->beatTime >= 0); // if given for one, assume given for others while (ei != el.end()) { Event ev = *ei; ++ei; if ((stop > 0) && (ev.time > stop)) break; bool created = phaseGiven; double prevBeatInterval = -1.0; // cc: Duplicate our list of agents, and scan through the // copy. This means we can safely add agents to our own // list while scanning without disrupting our scan. Each // agent needs to be re-added to our own list explicitly // (since it is modified by e.g. considerAsBeat) Container currentAgents = list; list.clear(); for (Container::iterator ai = currentAgents.begin(); ai != currentAgents.end(); ++ai) { Agent *currentAgent = *ai; if (currentAgent->beatInterval != prevBeatInterval) { if ((prevBeatInterval >= 0) && !created && (ev.time < 5.0)) { // Create new agent with different phase Agent *newAgent = new Agent(params, prevBeatInterval); // This may add another agent to our list as well newAgent->considerAsBeat(ev, *this); add(newAgent); } prevBeatInterval = currentAgent->beatInterval; created = phaseGiven; } if (currentAgent->considerAsBeat(ev, *this)) created = true; add(currentAgent); } // loop for each agent removeDuplicates(); } // loop for each event }
void EventCanvas::songChanged(int flags)/*{{{*/ { // Is it simply a midi controller value adjustment? Forget it. if (flags == SC_MIDI_CONTROLLER) return; if (flags & ~SC_SELECTION) { _items.clear(); start_tick = MAXINT; end_tick = 0; _curPart = 0; for (iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) { MidiPart* part = (MidiPart*) (p->second); if (part->sn() == _curPartId) _curPart = part; unsigned stick = part->tick(); unsigned len = part->lenTick(); unsigned etick = stick + len; if (stick < start_tick) start_tick = stick; if (etick > end_tick) end_tick = etick; EventList* el = part->events(); for (iEvent i = el->begin(); i != el->end(); ++i) { Event e = i->second; if (e.isNote()) { addItem(part, e); } } } } Event event; MidiPart* part = 0; int x = 0; CItem* nevent = 0; int n = 0; // count selections for (iCItem k = _items.begin(); k != _items.end(); ++k) { Event ev = k->second->event(); bool selected = ev.selected(); if (selected) { k->second->setSelected(true); ++n; if (!nevent) { nevent = k->second; Event mi = nevent->event(); curVelo = mi.velo(); } } } start_tick = song->roundDownBar(start_tick); end_tick = song->roundUpBar(end_tick); if (n == 1) { x = nevent->x(); event = nevent->event(); part = (MidiPart*) nevent->part(); if (_curPart != part) { _curPart = part; _curPartId = _curPart->sn(); curPartChanged(); } } emit selectionChanged(x, event, part); if (_curPart == 0) { _curPart = (MidiPart*) (editor->parts()->begin()->second); if(_curPart) { editor->setCurCanvasPart(_curPart); } } updateCItemsZValues(); redraw(); }/*}}}*/
AgentList Induction::beatInduction(const AgentParameters ¶ms, const EventList &events) { int i, j, b, bestCount; bool submult; int intervals = 0; // number of interval clusters std::vector<int> bestn; // count of high-scoring clusters bestn.resize(topN); double ratio, err; int degree; int maxClusterCount = (int) ceil((maxIOI - minIOI) / clusterWidth); std::vector<double> clusterMean; clusterMean.resize(maxClusterCount); std::vector<int> clusterSize; clusterSize.resize(maxClusterCount); std::vector<int> clusterScore; clusterScore.resize(maxClusterCount); EventList::const_iterator ptr1, ptr2; Event e1, e2; ptr1 = events.begin(); while (ptr1 != events.end()) { e1 = *ptr1; ++ptr1; ptr2 = events.begin(); e2 = *ptr2; ++ptr2; while (e2 != e1 && ptr2 != events.end()) { e2 = *ptr2; ++ptr2; } while (ptr2 != events.end()) { e2 = *ptr2; ++ptr2; double ioi = e2.time - e1.time; if (ioi < minIOI) // skip short intervals continue; if (ioi > maxIOI) // ioi too long break; for (b = 0; b < intervals; b++) // assign to nearest cluster if (std::fabs(clusterMean[b] - ioi) < clusterWidth) { if ((b < intervals - 1) && (std::fabs(clusterMean[b + 1] - ioi) < std::fabs(clusterMean[b] - ioi))) { b++; // next cluster is closer } clusterMean[b] = (clusterMean[b] * clusterSize[b] + ioi) / (clusterSize[b] + 1); clusterSize[b]++; break; } if (b == intervals) { // no suitable cluster; create new one if (intervals == maxClusterCount) { // System.err.println("Warning: Too many clusters"); continue; // ignore this IOI } intervals++; for ( ; (b > 0) && (clusterMean[b - 1] > ioi); b--) { clusterMean[b] = clusterMean[b - 1]; clusterSize[b] = clusterSize[b - 1]; } clusterMean[b] = ioi; clusterSize[b] = 1; } } } for (b = 0; b < intervals; b++) // merge similar intervals // TODO: they are now in order, so don't need the 2nd loop // TODO: check BOTH sides before averaging or upper gps don't work for (i = b + 1; i < intervals; i++) if (std::fabs(clusterMean[b] - clusterMean[i]) < clusterWidth) { clusterMean[b] = (clusterMean[b] * clusterSize[b] + clusterMean[i] * clusterSize[i]) / (clusterSize[b] + clusterSize[i]); clusterSize[b] = clusterSize[b] + clusterSize[i]; --intervals; for (j = i + 1; j <= intervals; j++) { clusterMean[j - 1] = clusterMean[j]; clusterSize[j - 1] = clusterSize[j]; } } if (intervals == 0) return AgentList(); for (b = 0; b < intervals; b++) clusterScore[b] = 10 * clusterSize[b]; bestn[0] = 0; bestCount = 1; for (b = 0; b < intervals; b++) { for (i = 0; i <= bestCount; i++) { if (i < topN && (i == bestCount || clusterScore[b] > clusterScore[bestn[i]])) { if (bestCount < topN) bestCount++; for (j = bestCount - 1; j > i; j--) bestn[j] = bestn[j - 1]; bestn[i] = b; break; } } } for (b = 0; b < intervals; b++) { // score intervals for (i = b + 1; i < intervals; i++) { ratio = clusterMean[b] / clusterMean[i]; submult = ratio < 1; if (submult) degree = (int) nearbyint(1 / ratio); else degree = (int) nearbyint(ratio); if ((degree >= 2) && (degree <= 8)) { if (submult) err = std::fabs(clusterMean[b] * degree - clusterMean[i]); else err = std::fabs(clusterMean[b] - clusterMean[i] * degree); if (err < (submult ? clusterWidth : clusterWidth * degree)) { if (degree >= 5) degree = 1; else degree = 6 - degree; clusterScore[b] += degree * clusterSize[i]; clusterScore[i] += degree * clusterSize[b]; } } } } AgentList a; for (int index = 0; index < bestCount; index++) { b = bestn[index]; // Adjust it, using the size of super- and sub-intervals double newSum = clusterMean[b] * clusterScore[b]; int newCount = clusterSize[b]; int newWeight = clusterScore[b]; for (i = 0; i < intervals; i++) { if (i == b) continue; ratio = clusterMean[b] / clusterMean[i]; if (ratio < 1) { degree = (int) nearbyint(1 / ratio); if ((degree >= 2) && (degree <= 8)) { err = std::fabs(clusterMean[b] * degree - clusterMean[i]); if (err < clusterWidth) { newSum += clusterMean[i] / degree * clusterScore[i]; newCount += clusterSize[i]; newWeight += clusterScore[i]; } } } else { degree = (int) nearbyint(ratio); if ((degree >= 2) && (degree <= 8)) { err = std::fabs(clusterMean[b] - degree * clusterMean[i]); if (err < clusterWidth * degree) { newSum += clusterMean[i] * degree * clusterScore[i]; newCount += clusterSize[i]; newWeight += clusterScore[i]; } } } } double beat = newSum / newWeight; // Scale within range ... hope the grouping isn't ternary :( while (beat < minIBI) // Maximum speed beat *= 2.0; while (beat > maxIBI) // Minimum speed beat /= 2.0; if (beat >= minIBI) { a.push_back(new Agent(params, beat)); } } return a; }
void Audio::initDevices() { // // mark all used ports // bool activePorts[MIDI_PORTS]; for (int i = 0; i < MIDI_PORTS; ++i) activePorts[i] = false; MidiTrackList* tracks = song->midis(); for (iMidiTrack it = tracks->begin(); it != tracks->end(); ++it) { MidiTrack* track = *it; activePorts[track->outPort()] = true; } if (song->click()) activePorts[clickPort] = true; // // test for explicit instrument initialization // for (int i = 0; i < MIDI_PORTS; ++i) { if (!activePorts[i]) continue; MidiPort* port = &midiPorts[i]; MidiInstrument* instr = port->instrument(); MidiDevice* md = port->device(); if (instr && md) { EventList* events = instr->midiInit(); if (events->empty()) continue; for (iEvent ie = events->begin(); ie != events->end(); ++ie) { MidiPlayEvent ev(0, i, 0, ie->second); md->putEvent(ev); } activePorts[i] = false; // no standard initialization } } // // damit Midi-Devices, die mehrere Ports besitzen, wie z.B. // das Korg NS5R, nicht mehrmals zwischen GM und XG/GS hin und // hergeschaltet werden, wird zun�hst auf allen Ports GM // initialisiert, und dann erst XG/GS // // Standard initialization... for (int i = 0; i < MIDI_PORTS; ++i) { if (!activePorts[i]) continue; MidiPort* port = &midiPorts[i]; switch (song->mtype()) { case MT_GS: case MT_UNKNOWN: break; case MT_GM: case MT_XG: port->sendGmOn(); break; } } for (int i = 0; i < MIDI_PORTS; ++i) { if (!activePorts[i]) continue; MidiPort* port = &midiPorts[i]; switch (song->mtype()) { case MT_UNKNOWN: break; case MT_GM: port->sendGmInitValues(); break; case MT_GS: port->sendGsOn(); port->sendGsInitValues(); break; case MT_XG: port->sendXgOn(); port->sendXgInitValues(); break; } } }
void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, int div, bool addSysexMeta, bool doLoops) { int hbank = 0xff; int lbank = 0xff; int rpnh = -1; int rpnl = -1; int datah = 0; int datal = 0; int dataType = 0; // 0 : disabled, 0x20000 : rpn, 0x30000 : nrpn EventList mel; for (iMPEvent i = el->begin(); i != el->end(); ++i) { MidiPlayEvent ev = *i; if (!addSysexMeta && (ev.type() == ME_SYSEX || ev.type() == ME_META)) continue; if (!(ev.type() == ME_SYSEX || ev.type() == ME_META || ((ev.channel() == track->outChannel()) && (ev.port() == track->outPort())))) continue; unsigned tick = ev.time(); // Added by Tim. p3.3.8 // Added by T356. if (doLoops) { if (tick >= song->lPos().tick() && tick < song->rPos().tick()) { int loopn = ev.loopNum(); int loopc = audio->loopCount(); int cmode = song->cycleMode(); // CYCLE_NORMAL, CYCLE_MIX, CYCLE_REPLACE // If we want REPLACE and the event was recorded in a previous loop, // just ignore it. This will effectively ignore ALL previous loop events inside // the left and right markers, regardless of where recording was started or stopped. // We want to keep any loop 0 note-offs from notes which crossed over the left marker. // To avoid more searching here, just keep ALL note-offs from loop 0, and let code below // sort out and keep which ones had note-ons. if (!(ev.isNoteOff() && loopn == 0)) { if (cmode == Song::CYCLE_REPLACE && loopn < loopc) { // Added by Tim. p3.3.8 //printf("buildMidiEventList: CYCLE_REPLACE t:%d type:%d A:%d B:%d ln:%d lc:%d\n", tick, ev.type(), ev.dataA(), ev.dataB(), loopn, loopc); continue; } // If we want NORMAL, same as REPLACE except keep all events from the previous loop // from rec stop position to right marker (and beyond). if (cmode == Song::CYCLE_NORMAL) { // Not sure of accuracy here. Adjust? Adjusted when used elsewhere? unsigned endRec = audio->getEndRecordPos().tick(); if ((tick < endRec && loopn < loopc) || (tick >= endRec && loopn < (loopc - 1))) { // Added by Tim. p3.3.8 //printf("buildMidiEventList: CYCLE_NORMAL t:%d type:%d A:%d B:%d ln:%d lc:%d\n", tick, ev.type(), ev.dataA(), ev.dataB(), loopn, loopc); continue; } } } } } Event e; switch (ev.type()) { case ME_NOTEON: e.setType(Note); if (track->type() == Track::DRUM) { int instr = drumInmap[ev.dataA()]; e.setPitch(instr); } else { e.setPitch(ev.dataA()); } e.setVelo(ev.dataB()); e.setLenTick(0); break; case ME_NOTEOFF: e.setType(Note); if (track->type() == Track::DRUM) { int instr = drumInmap[ev.dataA()]; e.setPitch(instr); } else e.setPitch(ev.dataA()); e.setVelo(0); e.setVeloOff(ev.dataB()); e.setLenTick(0); break; case ME_POLYAFTER: e.setType(PAfter); e.setA(ev.dataA()); e.setB(ev.dataB()); break; case ME_CONTROLLER: { int val = ev.dataB(); switch (ev.dataA()) { case CTRL_HBANK: hbank = val; break; case CTRL_LBANK: lbank = val; break; case CTRL_HDATA: datah = val; // check if a CTRL_LDATA follows // e.g. wie have a 14 bit controller: { iMPEvent ii = i; ++ii; bool found = false; for (; ii != el->end(); ++ii) { MidiPlayEvent ev = *ii; if (ev.type() == ME_CONTROLLER) { if (ev.dataA() == CTRL_LDATA) { // handle later found = true; } break; } } if (!found) { if (rpnh == -1 || rpnl == -1) { printf("parameter number not defined, data 0x%x\n", datah); } else { int ctrl = dataType | (rpnh << 8) | rpnl; e.setType(Controller); e.setA(ctrl); e.setB(datah); } } } break; case CTRL_LDATA: datal = val; if (rpnh == -1 || rpnl == -1) { printf("parameter number not defined, data 0x%x 0x%x, tick %d, channel %d\n", datah, datal, tick, track->outChannel()); break; } // assume that the sequence is always // CTRL_HDATA - CTRL_LDATA // eg. that LDATA is always send last e.setType(Controller); // 14 Bit RPN/NRPN e.setA((dataType + 0x30000) | (rpnh << 8) | rpnl); e.setB((datah << 7) | datal); break; case CTRL_HNRPN: rpnh = val; dataType = 0x30000; break; case CTRL_LNRPN: rpnl = val; dataType = 0x30000; break; case CTRL_HRPN: rpnh = val; dataType = 0x20000; break; case CTRL_LRPN: rpnl = val; dataType = 0x20000; break; default: e.setType(Controller); int ctl = ev.dataA(); e.setA(ctl); if (track->type() == Track::DRUM) { // Is it a drum controller event, according to the track port's instrument? MidiController *mc = midiPorts[track->outPort()].drumController(ctl); if (mc) // Store an index into the drum map. e.setA((ctl & ~0xff) | drumInmap[ctl & 0x7f]); } e.setB(val); break; } } break; case ME_PROGRAM: e.setType(Controller); e.setA(CTRL_PROGRAM); e.setB((hbank << 16) | (lbank << 8) | ev.dataA()); break; case ME_AFTERTOUCH: e.setType(CAfter); e.setA(ev.dataA()); break; case ME_PITCHBEND: e.setType(Controller); e.setA(CTRL_PITCH); e.setB(ev.dataA()); break; case ME_SYSEX: e.setType(Sysex); e.setData(ev.data(), ev.len()); break; case ME_META: { const unsigned char* data = ev.data(); switch (ev.dataA()) { case 0x01: // Text if (track->comment().isEmpty()) track->setComment(QString((const char*) data)); else track->setComment(track->comment() + "\n" + QString((const char*) data)); break; case 0x03: // Sequence-/TrackName track->setName(QString((char*) data)); break; case 0x6: // Marker { unsigned ltick = CALC_TICK(tick); //(tick * config.division + div/2) / div; song->addMarker(QString((const char*) (data)), ltick, false); } break; case 0x5: // Lyrics case 0x8: // text case 0x9: case 0xa: break; case 0x0f: // Track Comment track->setComment(QString((char*) data)); break; case 0x51: // Tempo { unsigned tempo = data[2] + (data[1] << 8) + (data[0] << 16); unsigned ltick = CALC_TICK(tick); // (unsigned(tick) * unsigned(config.division) + unsigned(div/2)) / unsigned(div); // After ca 10 mins 32 bits will not be enough... This expression has to be changed/factorized or so in some "sane" way... tempomap.addTempo(ltick, tempo); } break; case 0x58: // Time Signature { int timesig_z = data[0]; int n = data[1]; int timesig_n = 1; for (int i = 0; i < n; i++) timesig_n *= 2; int ltick = CALC_TICK(tick); //(tick * config.division + div/2) / div; ///sigmap.add(ltick, timesig_z, timesig_n); AL::sigmap.add(ltick, AL::TimeSignature(timesig_z, timesig_n)); } break; case 0x59: // Key Signature // track->scale.set(data[0]); // track->scale.setMajorMinor(data[1]); break; default: printf("unknown Meta 0x%x %d\n", ev.dataA(), ev.dataA()); } } break; } // switch(ev.type() if (!e.empty()) { e.setTick(tick); // Added by Tim. p3.3.8 //printf("buildMidiEventList: mel adding t:%d type:%d A:%d B:%d C:%d\n", tick, e.type(), e.dataA(), e.dataB(), e.dataC()); mel.add(e); } } // i != el->end() //--------------------------------------------------- // resolve NoteOff events //--------------------------------------------------- // for (iEvent i = mel.begin(); i != mel.end(); ++i) { // Event event = i->second; // if (event.isNote()) // event.setLenTick(0); // } // Added by Tim. p3.3.8 // The loop is a safe way to delete while iterating. bool loop; do { loop = false; for (iEvent i = mel.begin(); i != mel.end(); ++i) { Event ev = i->second; if (ev.isNote()) { if (ev.isNoteOff()) { iEvent k; bool found = false; for (k = i; k != mel.end(); ++k) { Event event = k->second; if (event.tick() > ev.tick()) break; if (event.isNoteOff(ev)) { ev.setLenTick(1); ev.setVelo(event.velo()); ev.setVeloOff(0); // Added by Tim. p3.3.8 //printf("buildMidiEventList: found note off: event t:%d len:%d type:%d A:%d B:%d C:%d ev t:%d len:%d type:%d A:%d B:%d C:%d\n", event.tick(), event.lenTick(), event.type(), event.dataA(), event.dataB(), event.dataC(), ev.tick(), ev.lenTick(), ev.type(), ev.dataA(), ev.dataB(), ev.dataC()); found = true; break; } } if (!found) { printf("NOTE OFF without Note ON tick %d type %d %d %d\n", ev.tick(), ev.type(), ev.pitch(), ev.velo()); } else { mel.erase(k); // Changed by Tim. p3.3.8 //continue; loop = true; break; } } // Added by Tim. p3.3.8 // If the event length is not zero, it means the event and its // note on/off have already been taken care of. So ignore it. if (ev.lenTick() != 0) { continue; } iEvent k; for (k = mel.lower_bound(ev.tick()); k != mel.end(); ++k) { Event event = k->second; if (ev.isNoteOff(event)) { int t = k->first - i->first; if (t <= 0) { if (debugMsg) { printf("Note len is (%d-%d)=%d, set to 1\n", k->first, i->first, k->first - i->first); ev.dump(); event.dump(); } t = 1; } ev.setLenTick(t); ev.setVeloOff(event.veloOff()); // Added by Tim. p3.3.8 //printf("buildMidiEventList: set len and velOff: event t:%d len:%d type:%d A:%d B:%d C:%d ev t:%d len:%d type:%d A:%d B:%d C:%d\n", event.tick(), event.lenTick(), event.type(), event.dataA(), event.dataB(), event.dataC(), ev.tick(), ev.lenTick(), ev.type(), ev.dataA(), ev.dataB(), ev.dataC()); break; } } if (k == mel.end()) { printf("-no note-off! %d pitch %d velo %d\n", ev.tick(), ev.pitch(), ev.velo()); // // switch off at end of measure // int endTick = song->roundUpBar(ev.tick() + 1); ev.setLenTick(endTick - ev.tick()); } else { mel.erase(k); // Added by Tim. p3.3.8 loop = true; break; } } } } while (loop); // DEBUG: any note offs left? // Removed by Tim. p3.3.8 //for (iEvent i = mel.begin(); i != mel.end(); ++i) { // Event ev = i->second; // if (ev.isNoteOff()) { // printf("+extra note-off! %d pitch %d velo %d\n", // i->first, ev.pitch(), ev.velo()); // ev.dump(); // } // } for (iEvent i = mel.begin(); i != mel.end(); ++i) { Event ev = i->second; if (ev.isNoteOff()) { printf("+extra note-off! %d pitch %d velo %d\n", i->first, ev.pitch(), ev.velo()); // ev.dump(); continue; } int tick = CALC_TICK(ev.tick()); //(ev.tick() * config.division + div/2) / div; if (ev.isNote()) { int lenTick = CALC_TICK(ev.lenTick()); //(ev.lenTick() * config.division + div/2) / div; ev.setLenTick(lenTick); } ev.setTick(tick); del->add(ev); } }
void Audio::preloadControllers()/*{{{*/ { midiBusy = true; MidiTrackList* tracks = song->midis(); for (iMidiTrack it = tracks->begin(); it != tracks->end(); ++it) { MidiTrack* track = *it; //activePorts[track->outPort()] = true; QList<ProcessList*> pcevents; int port = track->outPort(); int channel = track->outChannel(); int defaultPort = port; MidiDevice* md = midiPorts[port].device(); if (!md) { continue; } MPEventList* playEvents = md->playEvents(); playEvents->erase(playEvents->begin(), playEvents->end()); PartList* pl = track->parts(); for (iPart p = pl->begin(); p != pl->end(); ++p) { MidiPart* part = (MidiPart*) (p->second); EventList* events = part->events(); unsigned partTick = part->tick(); //unsigned partLen = part->lenTick(); int delay = track->delay; unsigned offset = delay + partTick; for (iEvent ie = events->begin(); ie != events->end(); ++ie) { Event ev = ie->second; port = defaultPort; unsigned tick = ev.tick() + offset; //unsigned frame = tempomap.tick2frame(tick) + frameOffset; switch (ev.dataA()) { case CTRL_PROGRAM: { ProcessList *pl = new ProcessList; pl->port = port; pl->channel = channel; pl->dataB = ev.dataB(); bool addEvent = true; for(int i = 0; i < pcevents.size(); ++i) { ProcessList* ipl = pcevents.at(i); if(ipl->port == pl->port && ipl->channel == pl->channel && ipl->dataB == pl->dataB) { addEvent = false; break; } } if(addEvent) { printf("Audio::preloadControllers() Loading event @ tick: %d - on channel: %d - on port: %d - dataA: %d - dataB: %d\n", tick, channel, port, ev.dataA(), ev.dataB()); pcevents.append(pl); playEvents->add(MidiPlayEvent(tick, port, channel, ev)); } } break; default: break; } } } md->setNextPlayEvent(playEvents->begin()); } midiBusy = false; }/*}}}*/
void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) { int l1 = 0; // len of first new part (ticks or samples) int l2 = 0; // len of second new part int samplepos = tempomap.tick2frame(tickpos); switch (type()) { case WAVE: l1 = samplepos - part->frame(); l2 = part->lenFrame() - l1; break; case MIDI: case DRUM: l1 = tickpos - part->tick(); l2 = part->lenTick() - l1; break; default: return; } if (l1 <= 0 || l2 <= 0) return; p1 = newPart(part); // new left part p2 = newPart(part); // new right part // Added by Tim. p3.3.6 //printf("Track::splitPart part ev %p sz:%d ref:%d p1 %p sz:%d ref:%d p2 %p sz:%d ref:%d\n", part->events(), part->events()->size(), part->events()->arefCount(), p1->events(), p1->events()->size(), p1->events()->arefCount(), p2->events(), p2->events()->size(), p2->events()->arefCount()); switch (type()) { case WAVE: p1->setLenFrame(l1); p2->setFrame(samplepos); p2->setLenFrame(l2); break; case MIDI: case DRUM: p1->setLenTick(l1); p2->setTick(tickpos); p2->setLenTick(l2); break; default: break; } p2->setSn(p2->newSn()); EventList* se = part->events(); EventList* de1 = p1->events(); EventList* de2 = p2->events(); if (type() == WAVE) { int ps = part->frame(); int d1p1 = p1->frame(); int d2p1 = p1->endFrame(); int d1p2 = p2->frame(); int d2p2 = p2->endFrame(); for (iEvent ie = se->begin(); ie != se->end(); ++ie) { Event event = ie->second; int s1 = event.frame() + ps; int s2 = event.endFrame() + ps; if ((s2 > d1p1) && (s1 < d2p1)) { Event si = event.mid(d1p1 - ps, d2p1 - ps); de1->add(si); } if ((s2 > d1p2) && (s1 < d2p2)) { Event si = event.mid(d1p2 - ps, d2p2 - ps); de2->add(si); } } } else { for (iEvent ie = se->begin(); ie != se->end(); ++ie) { Event event = ie->second.clone(); int t = event.tick(); if (t >= l1) { event.move(-l1); de2->add(event); } else de1->add(event); } } }
void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len) { switch (track->type()) { case Track::WAVE: { WavePart* nPart = new WavePart(*(WavePart*) oPart); EventList* el = nPart->events(); unsigned new_partlength = tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len); //printf("new partlength in frames: %d\n", new_partlength); // If new nr of frames is less than previous what can happen is: // - 0 or more events are beginning after the new final position. Those are removed from the part // - The last event begins before new final position and ends after it. If so, it will be resized to end at new part length if (new_partlength < oPart->lenFrame()) { startUndo(); for (iEvent i = el->begin(); i != el->end(); i++) { Event e = i->second; unsigned event_startframe = e.frame(); unsigned event_endframe = event_startframe + e.lenFrame(); //printf("Event frame=%d, length=%d\n", event_startframe, event_length); if (event_endframe < new_partlength) continue; if (event_startframe > new_partlength) { // If event start was after the new length, remove it from part // Indicate no undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(e, nPart, false); audio->msgDeleteEvent(e, nPart, false, false, false); continue; } if (event_endframe > new_partlength) { // If this event starts before new length and ends after, shrink it Event newEvent = e.clone(); newEvent.setLenFrame(new_partlength - event_startframe); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangeEvent(e, newEvent, nPart, false); audio->msgChangeEvent(e, newEvent, nPart, false, false, false); } } nPart->setLenFrame(new_partlength); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, false, false); endUndo(SC_PART_MODIFIED); } // If the part is expanded there can be no additional events beginning after the previous final position // since those are removed if the part has been shrunk at some time (see above) // The only thing we need to check is the final event: If it has data after the previous final position, // we'll expand that event else { if (!el->empty()) { iEvent i = el->end(); i--; Event last = i->second; unsigned last_start = last.frame(); SndFileR file = last.sndFile(); if (file.isNull()) return; unsigned clipframes = (file.samples() - last.spos()); // / file.channels(); Event newEvent = last.clone(); //printf("SndFileR samples=%d channels=%d event samplepos=%d clipframes=%d\n", file.samples(), file.channels(), last.spos(), clipframes); unsigned new_eventlength = new_partlength - last_start; if (new_eventlength > clipframes) // Shrink event length if new partlength exceeds last clip new_eventlength = clipframes; newEvent.setLenFrame(new_eventlength); startUndo(); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangeEvent(last, newEvent, nPart, false); audio->msgChangeEvent(last, newEvent, nPart, false, false, false); } else { startUndo(); } nPart->setLenFrame(new_partlength); // Indicate no undo, and do not do port controller values and clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, false, false); endUndo(SC_PART_MODIFIED); } } break; case Track::MIDI: case Track::DRUM: { startUndo(); MidiPart* nPart = new MidiPart(*(MidiPart*) oPart); nPart->setLenTick(len); // Indicate no undo, and do port controller values but not clone parts. audio->msgChangePart(oPart, nPart, false, true, false); // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if (nPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do port controller values and clone parts. audio->msgDeleteEvent(i->second, nPart, false, true, true); } } } /* // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. // The other clones might be longer than this one and need these events. if(oPart->cevents()->arefCount() <= 1) { if (oPart->lenTick() > len) { EventList* el = nPart->events(); iEvent ie = el->lower_bound(len); for (; ie != el->end();) { iEvent i = ie; ++ie; // Indicate no undo, and do not do port controller values and clone parts. //audio->msgDeleteEvent(i->second, nPart, false); audio->msgDeleteEvent(i->second, nPart, false, false, false); } } } // Indicate no undo, and do port controller values but not clone parts. //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, true, false); */ endUndo(SC_PART_MODIFIED); break; } default: break; } }
PyObject* getParts(PyObject*, PyObject* args) { TrackList* tracks = song->tracks(); const char* trackname; if (!PyArg_ParseTuple(args, "s", &trackname)) { return NULL; } PyObject* pyparts = Py_BuildValue("[]"); for (ciTrack t = tracks->begin(); t != tracks->end(); ++t) { Track* track = *t; if (track->name() != trackname) continue; PartList* parts = track->parts(); for (ciPart p = parts->begin(); p != parts->end(); p++) { Part* part = p->second; MidiPart* mpart = (MidiPart*) part; PyObject* pypart = PyDict_New(); int tick = mpart->tick(); int lentick = mpart->lenTick(); int serialnr = mpart->sn(); PyObject* pstrtick = Py_BuildValue("s", "tick"); PyObject* pitick = Py_BuildValue("i", tick); PyObject* pstrid = Py_BuildValue("s", "id"); PyObject* pstrserial = Py_BuildValue("i", serialnr); PyObject* pstrlen = Py_BuildValue("s", "len"); PyObject* pstrtick2 = Py_BuildValue("i", lentick); PyDict_SetItem(pypart, pstrtick, pitick); PyDict_SetItem(pypart, pstrid, pstrserial); PyDict_SetItem(pypart, pstrlen, pstrtick2); Py_DECREF(pstrtick); Py_DECREF(pitick); Py_DECREF(pstrid); Py_DECREF(pstrserial); Py_DECREF(pstrlen); Py_DECREF(pstrtick2); // Pack midi events into list before wrapping it all up EventList* events = mpart->events(); PyObject* pyevents = Py_BuildValue("[]"); for (ciEvent e = events->begin(); e != events->end(); e++) { PyObject* pyevent = PyDict_New(); // The event structure - a dictionary with keys 'type','tick','data' const Event& event = e->second; unsigned tick = e->first; PyObject* eventdata = Py_BuildValue("[i,i,i]", event.dataA(), event.dataB(), event.dataC()); PyObject* pstrdata = Py_BuildValue("s", "data"); pstrtick = Py_BuildValue("s", "tick"); PyObject* pitickval = Py_BuildValue("i", tick); PyDict_SetItem(pyevent, pstrdata, eventdata); PyDict_SetItem(pyevent, pstrtick, pitickval); Py_DECREF(eventdata); Py_DECREF(pstrdata); Py_DECREF(pstrtick); Py_DECREF(pitickval); switch (event.type()) { case Note: { PyObject* pstrtype = Py_BuildValue("s", "type"); PyObject* pstrnote = Py_BuildValue("s", "note"); PyObject* pstrlen = Py_BuildValue("s", "len"); PyObject* pilentick = Py_BuildValue("i", event.lenTick()); PyDict_SetItem(pyevent, pstrtype, pstrnote); PyDict_SetItem(pyevent, pstrlen, pilentick); Py_DECREF(pstrtype); Py_DECREF(pstrnote); Py_DECREF(pstrlen); Py_DECREF(pilentick); break; } case Controller: { PyObject* pstrtype = Py_BuildValue("s", "type"); PyObject* pstrctrl = Py_BuildValue("s", "ctrl"); PyDict_SetItem(pyevent, pstrtype, pstrctrl); Py_DECREF(pstrtype); Py_DECREF(pstrctrl); break; } default: printf("Event type not supported yet: %d\n", event.type()); break; } PyList_Append(pyevents, pyevent); Py_DECREF(pyevent); } Py_DECREF(pyevents); // Add the event list to the pypart dictionary PyObject* pystrevents = Py_BuildValue("s", "events"); PyDict_SetItem(pypart, pystrevents, pyevents); Py_DECREF(pystrevents); PyList_Append(pyparts, pypart); Py_DECREF(pypart); } return pyparts; } return NULL; }
QMimeData* EventCanvas::getTextDrag() { //--------------------------------------------------- // generate event list from selected events //--------------------------------------------------- EventList el; unsigned startTick = MAXINT; for (iCItem i = _items.begin(); i != _items.end(); ++i) { if (!i->second->isSelected()) continue; ///NEvent* ne = (NEvent*)(i->second); CItem* ne = i->second; Event e = ne->event(); if (startTick == MAXINT) startTick = e.tick(); el.add(e); } //--------------------------------------------------- // write events as XML into tmp file //--------------------------------------------------- FILE* tmp = tmpfile(); if (tmp == 0) { fprintf(stderr, "EventCanvas::getTextDrag() fopen failed: %s\n", strerror(errno)); return 0; } Xml xml(tmp); int level = 0; xml.tag(level++, "eventlist"); for (ciEvent e = el.begin(); e != el.end(); ++e) e->second.write(level, xml, -startTick); xml.etag(--level, "eventlist"); //--------------------------------------------------- // read tmp file into drag Object //--------------------------------------------------- fflush(tmp); struct stat f_stat; if (fstat(fileno(tmp), &f_stat) == -1) { fprintf(stderr, "PianorollCanvas::copy() fstat failes:<%s>\n", strerror(errno)); fclose(tmp); return 0; } int n = f_stat.st_size; char* fbuf = (char*) mmap(0, n + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fileno(tmp), 0); fbuf[n] = 0; QByteArray data(fbuf); QMimeData* md = new QMimeData(); //QDrag* drag = new QDrag(parent); md->setData("text/x-los-eventlist", data); //drag->setMimeData(md); munmap(fbuf, n); fclose(tmp); //return drag; return md; }
void LOS::processTrack(MidiTrack* track) { EventList* tevents = track->events(); if (tevents->empty()) return; //--------------------------------------------------- // Identify Parts // The MIDI tracks are broken up into parts // A new Part will be located based on track. // Events will be aligned on new track //--------------------------------------------------- PartList* pl = track->parts(); int lastTick = 0; for (iEvent i = tevents->begin(); i != tevents->end(); ++i) { Event event = i->second; int epos = event.tick() + event.lenTick(); if (epos > lastTick) lastTick = epos; } QString partname = track->name(); int len = song->roundUpBar(lastTick + 1); // p3.3.27 if (config.importMidiSplitParts) { int bar2, beat; unsigned tick; sigmap.tickValues(len, &bar2, &beat, &tick); int lastOff = 0; int st = -1; // start tick current part int x1 = 0; // start tick current measure int x2 = 0; // end tick current measure for (int bar = 0; bar < bar2; ++bar, x1 = x2) { ///x2 = sigmap.bar2tick(bar+1, 0, 0); x2 = sigmap.bar2tick(bar + 1, 0, 0); if (lastOff > x2) { // this measure is busy! continue; } iEvent i1 = tevents->lower_bound(x1); iEvent i2 = tevents->lower_bound(x2); if (i1 == i2) { // empty? if (st != -1) { MidiPart* part = new MidiPart(track); part->setTick(st); part->setLenTick(x1 - st); // printf("new part %d len: %d\n", st, x1-st); part->setName(partname); pl->add(part); st = -1; } } else { if (st == -1) st = x1; // begin new part //HACK: //lastOff: for (iEvent i = i1; i != i2; ++i) { Event event = i->second; if (event.type() == Note) { int off = event.tick() + event.lenTick(); if (off > lastOff) lastOff = off; } } } } if (st != -1) { MidiPart* part = new MidiPart(track); part->setTick(st); // printf("new part %d len: %d\n", st, x2-st); part->setLenTick(x2 - st); part->setName(partname); pl->add(part); } } else { // Just one long part... MidiPart* part = new MidiPart(track); //part->setTick(st); part->setTick(0); part->setLenTick(len); part->setName(partname); pl->add(part); } //------------------------------------------------------------- // assign events to parts //------------------------------------------------------------- for (iPart p = pl->begin(); p != pl->end(); ++p) { MidiPart* part = (MidiPart*) (p->second); int stick = part->tick(); int etick = part->tick() + part->lenTick(); iEvent r1 = tevents->lower_bound(stick); iEvent r2 = tevents->lower_bound(etick); int startTick = part->tick(); EventList* el = part->events(); for (iEvent i = r1; i != r2; ++i) { Event ev = i->second; int ntick = ev.tick() - startTick; ev.setTick(ntick); el->add(ev); } tevents->erase(r1, r2); } if (tevents->size()) printf("-----------events left: %zd\n", tevents->size()); for (iEvent i = tevents->begin(); i != tevents->end(); ++i) { printf("%d===\n", i->first); i->second.dump(); } // all events should be processed: assert(tevents->empty()); }
void EventCanvas::pasteAt(const QString& pt, int pos) { QByteArray ba = pt.toLatin1(); const char* p = ba.constData(); Xml xml(p); for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::TagStart: if (tag == "eventlist") { song->startUndo(); EventList* el = new EventList(); el->read(xml, "eventlist"); int modified = SC_EVENT_INSERTED; for (iEvent i = el->begin(); i != el->end(); ++i) { Event e = i->second; int tick = e.tick() + pos - _curPart->tick(); if (tick < 0) { printf("ERROR: trying to add event before current part!\n"); song->endUndo(SC_EVENT_INSERTED); delete el; return; } e.setTick(tick); int diff = e.endTick() - _curPart->lenTick(); if (diff > 0) {// too short part? extend it Part* newPart = _curPart->clone(); newPart->setLenTick(newPart->lenTick() + diff); // Indicate no undo, and do port controller values but not clone parts. audio->msgChangePart(_curPart, newPart, false, true, false); modified = modified | SC_PART_MODIFIED; _curPart = newPart; // reassign } // Indicate no undo, and do not do port controller values and clone parts. audio->msgAddEvent(e, _curPart, false, false, false); } song->endUndo(modified); delete el; return; } else xml.unknown("pasteAt"); break; case Xml::Attribut: case Xml::TagEnd: default: break; } } }
bool LOS::importMidi(const QString name, bool merge)/*{{{*/ { bool popenFlag; FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag); if (fp == 0) return true; MidiFile mf(fp); bool rv = mf.read(); popenFlag ? pclose(fp) : fclose(fp); if (rv) { QString s(tr("reading midifile\n ")); s += name; s += tr("\nfailed: "); s += mf.error(); QMessageBox::critical(this, QString("LOS"), s); return rv; } // // evaluate song Type (GM, XG, GS, unknown) // MType t = song->midiType(); if (!merge) { t = mf.mtype(); song->setMType(t); } MidiInstrument* instr = 0; for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) { MidiInstrument* mi = *i; if ((mi->iname() == "GM" && ((t == MT_UNKNOWN) || (t == MIDI_TYPE_GM))) || ((mi->iname() == "GS") && (t == MT_GS)) || ((mi->iname() == "XG") && (t == MT_XG))) { instr = mi; break; } } if (instr == 0) { // the standard instrument files (GM, GS, XG) must be present printf("no instrument, type %d\n", t); return true; //abort(); } MidiFileTrackList* etl = mf.trackList(); int division = mf.division(); // // create MidiTrack and copy events to ->events() // - combine note on/off events // - calculate tick value for internal resolution // for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t) { MPEventList* el = &((*t)->events); if (el->empty()) continue; // // if we split the track, SYSEX and META events go into // the first target track bool first = true; // somewhat silly and slooow: for (int port = 0; port < kMaxMidiPorts; ++port) { for (int channel = 0; channel < kMaxMidiChannels; ++channel) { // // check if there are any events for port/channel in track: // iMPEvent i; for (i = el->begin(); i != el->end(); ++i) { MidiPlayEvent ev = *i; if (ev.type() != ME_SYSEX && ev.type() != ME_META && ev.channel() == channel && ev.port() == port) break; } if (i == el->end()) continue; MidiTrack* track = new MidiTrack(); if ((*t)->isDrumTrack) { track->setType(Track::DRUM); } track->setOutChannel(channel); track->setOutPort(port); MidiPort* mport = &midiPorts[track->outPort()]; // this overwrites any instrument set for this port: mport->setInstrument(instr); EventList* mel = track->events(); //buildMidiEventList(mel, el, track, division, first); // Don't do loops. buildMidiEventList(mel, el, track, division, first, false); first = false; // Hmm. buildMidiEventList already takes care of this. // But it seems to work. How? Must test. if (channel == 9 && song->midiType() != MT_UNKNOWN) { track->setType(Track::DRUM); // // remap drum pitch with drumInmap // EventList* tevents = track->events(); for (iEvent i = tevents->begin(); i != tevents->end(); ++i) { Event ev = i->second; if (ev.isNote()) { int pitch = drumInmap[ev.pitch()]; ev.setPitch(pitch); } else if (ev.type() == Controller) { int ctl = ev.dataA(); MidiController *mc = mport->drumController(ctl); if (mc) ev.setA((ctl & ~0xff) | drumInmap[ctl & 0x7f]); } } } processTrack(track); song->insertTrack(track, -1); } } if (first) { // // track does only contain non-channel messages // (SYSEX or META) // MidiTrack* track = new MidiTrack(); track->setOutChannel(0); track->setOutPort(0); EventList* mel = track->events(); //buildMidiEventList(mel, el, track, division, true); // Do SysexMeta. Don't do loops. buildMidiEventList(mel, el, track, division, true, false); processTrack(track); song->insertTrack(track, -1); } } if (!merge) { TrackList* tl = song->tracks(); if (!tl->empty()) { Track* track = tl->front(); track->setSelected(true); } song->initLen(); int z, n; ///sigmap.timesig(0, z, n); sigmap.timesig(0, z, n); int tempo = tempomap.tempo(0); transport->setTimesig(z, n); transport->setTempo(tempo); bool masterF = !tempomap.empty(); song->setMasterFlag(masterF); transport->setMasterFlag(masterF); song->updatePos(); composer->reset(); ///composer->setMode(int(song->midiType())); // p4.0.7 Tim } else { song->initLen(); } return false; }/*}}}*/
void CSystemEvents::ExecuteEvents() { EventList Events; { CGuard Guard(m_CS); m_bDoSomething = false; if (m_Events.size() == 0) { return; } Events = m_Events; m_Events.clear(); } bool bPause = false, bLoadedSave = false; for (EventList::const_iterator iter = Events.begin(); !bLoadedSave && iter != Events.end(); iter++ ) { switch (*iter) { case SysEvent_CloseCPU: m_System->m_EndEmulation = true; break; case SysEvent_ResetCPU_Soft: m_System->GameReset(); break; case SysEvent_ResetCPU_SoftDone: m_System->Reset(true,false); break; case SysEvent_ResetCPU_Hard: m_System->Reset(true,true); break; case SysEvent_Profile_GenerateLogs: m_System->m_Profile.GenerateLog(); break; case SysEvent_Profile_StartStop: case SysEvent_Profile_ResetLogs: m_System->m_Profile.ResetCounters(); break; case SysEvent_ExecuteInterrupt: g_Reg->DoIntrException(false); break; case SysEvent_Interrupt_SP: g_Reg->MI_INTR_REG |= MI_INTR_SP; g_Reg->DoIntrException(false); break; case SysEvent_Interrupt_SI: g_Reg->MI_INTR_REG |= MI_INTR_SI; g_Reg->DoIntrException(false); break; case SysEvent_Interrupt_AI: g_Reg->MI_INTR_REG |= MI_INTR_AI; g_Reg->DoIntrException(false); break; case SysEvent_Interrupt_VI: g_Reg->MI_INTR_REG |= MI_INTR_VI; g_Reg->DoIntrException(false); break; case SysEvent_Interrupt_PI: g_Reg->MI_INTR_REG |= MI_INTR_PI; g_Reg->DoIntrException(false); break; case SysEvent_Interrupt_DP: g_Reg->MI_INTR_REG |= MI_INTR_DP; g_Reg->DoIntrException(false); break; case SysEvent_SaveMachineState: if (!m_System->SaveState()) { m_Events.push_back(SysEvent_SaveMachineState); m_bDoSomething = true; } break; case SysEvent_LoadMachineState: if (m_System->LoadState()) { bLoadedSave = true; } break; case SysEvent_ChangePlugins: ChangePluginFunc(); break; case SysEvent_ChangingFullScreen: Notify().ChangeFullScreen(); break; case SysEvent_GSButtonPressed: if (m_System->m_Cheats.CheatsSlectionChanged()) { m_System->m_Cheats.LoadCheats(false, m_Plugins); } m_System->m_Cheats.ApplyGSButton(g_MMU); break; case SysEvent_PauseCPU_FromMenu: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_FromMenu); bPause = true; } break; case SysEvent_PauseCPU_AppLostFocus: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostFocus); bPause = true; } break; case SysEvent_PauseCPU_AppLostActive: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_AppLostActive); bPause = true; } break; case SysEvent_PauseCPU_SaveGame: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_SaveGame); bPause = true; } break; case SysEvent_PauseCPU_LoadGame: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_LoadGame); bPause = true; } break; case SysEvent_PauseCPU_DumpMemory: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_DumpMemory); bPause = true; } break; case SysEvent_PauseCPU_SearchMemory: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_SearchMemory); bPause = true; } break; case SysEvent_PauseCPU_Settings: if (!g_Settings->LoadBool(GameRunning_CPU_Paused)) { g_Settings->SaveBool(GameRunning_CPU_Paused,true); g_Settings->SaveDword(GameRunning_CPU_PausedType, PauseType_Settings); bPause = true; } break; default: g_Notify->BreakPoint(__FILEW__,__LINE__); break; } } if (bPause) { m_System->Pause(); } }
void ListEdit::songChanged(int type) { if (type == 0) return; if (type & (SC_PART_REMOVED | SC_PART_MODIFIED | SC_PART_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED | SC_EVENT_INSERTED | SC_SELECTION)) { if (type & (SC_PART_REMOVED | SC_PART_INSERTED)) genPartlist(); // close window if editor has no parts anymore if (parts()->empty()) { close(); return; } liste->setSortingEnabled(false); if (type == SC_SELECTION) { bool update = false; QTreeWidgetItem* ci = 0; liste->blockSignals(true); for (int row = 0; row < liste->topLevelItemCount(); ++row) { QTreeWidgetItem* i = liste->topLevelItem(row); if (i->isSelected() ^ ((EventListItem*) i)->event.selected()) { i->setSelected(((EventListItem*) i)->event.selected()); if (i->isSelected()) ci = i; update = true; } } if (update) { if (ci) { liste->setCurrentItem(ci); liste->scrollToItem(ci, QAbstractItemView::EnsureVisible); } //liste->update(); } liste->blockSignals(false); } else { curPart = 0; curTrack = 0; liste->clear(); for (iPart p = parts()->begin(); p != parts()->end(); ++p) { MidiPart* part = (MidiPart*) (p->second); if (part->sn() == curPartId) curPart = part; EventList* el = part->events(); for (iEvent i = el->begin(); i != el->end(); ++i) { EventListItem* item = new EventListItem(liste, i->second, part); for (int col = 0; col < liste->columnCount(); ++col) item->setText(col, item->text(col)); item->setSelected(i->second.selected()); if (item->event.tick() == (unsigned) selectedTick) { //prevent compiler warning: comparison of signed/unsigned) liste->setCurrentItem(item); item->setSelected(true); liste->scrollToItem(item, QAbstractItemView::EnsureVisible); } } } } // p3.3.34 //if (curPart == 0) // curPart = (MidiPart*)(parts()->begin()->second); //curTrack = curPart->track(); if (!curPart) { if (!parts()->empty()) { curPart = (MidiPart*) (parts()->begin()->second); if (curPart) curTrack = curPart->track(); else curPart = 0; } } } liste->setSortingEnabled(true); }