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 CtEvent::getEventList(EventList& event_list) { DEB_MEMBER_FUNCT(); AutoMutex l = lock(); DEB_PARAM() << DEB_VAR2(event_list.size(), m_event_list.size()); if (!event_list.empty()) THROW_CTL_ERROR(InvalidValue) << "Not empty event_list (" << DEB_VAR1(event_list.size()) << "): " << "Where all the events deleted?"; else if (hasRegisteredCallback()) DEB_WARNING() << "An EventCallback is registered, events are dispatched"; event_list = m_event_list; m_event_list.clear(); }
void Craze::EventManager::Update() { PROFILE("EventManager::Update"); m_CurrentQue++; if (m_CurrentQue == 2) { m_CurrentQue = 0; } EventList* pProcQue = GetLastQue(); while(!pProcQue->empty()) { EventItem itm = pProcQue->front(); EventListenerMap::iterator typeIt = m_Listeners.find(itm.pEvent->VGetType()); if (typeIt != m_Listeners.end()) { for (EventListenerList::iterator i = typeIt->second.begin(); i != typeIt->second.end(); ++i) { (*i).second(itm.pEvent); } } if (itm.autoDelete) { delete itm.pEvent; itm.pEvent = 0; } pProcQue->pop_front(); } }
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 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 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; } }