void main(void) { //All Var declarations unsigned char cmd = 0; unsigned char instrument = 1; unsigned char note = 0x40; int i = 0; unsigned char buf[] = {0xB0, 0x07, 0x79, 0xB0, 0x00, 0x78, 0xD0, 0x00, 0x00, 0x90, 0x40, 0x3C}; init_all(); EA=TRUE; midiReset(); midiVolSet(120); //set channel volume to near max (127) midiBankSet(MELODY); //0x79 = melodious instruments //talkMIDI(0xD0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command midiPatchSet(PIANO_AC); noteOn(0, note, 0x3D); while(1) { cmd = getchar(); if (cmd == '`') { putchar('1'); instrument = getchar(); midiPatchSet(instrument-0x30); } else { noteOn(0, cmd, 0x3D); } } }
void loop() { // play notes from F#-0 (30) to F#-5 (90): for (note = 30; note < 90; note ++) { //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0x90, note, 0x45); delay(100); //Note on channel 1 (0x90), some note value (note), silent velocity (0x00): noteOn(0x90, note, 0x00); delay(100); } }
void loop() { // play notes from F#-0 (30) to F#-5 (90): for (note = 0; note < 5; note ++) { mul=random(3)+4; n=penta[note]*mul; //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0x90, n, 0x45); delay(50); //Note on channel 1 (0x90), some note value (note), silent velocity (0x00): noteOn(0x90, n, 0x00); delay(50); } }
void MIDIReceiver::advance() { while (!mMidiQueue.Empty()) { IMidiMsg* midiMessage = mMidiQueue.Peek(); if (midiMessage->mOffset > mOffset) break; IMidiMsg::EStatusMsg status = midiMessage->StatusMsg(); int noteNumber = midiMessage->NoteNumber(); int velocity = midiMessage->Velocity(); // There are only note on/off messages in the queue, see ::OnMessageReceived if (status == IMidiMsg::kNoteOn && velocity) { if (mKeyStatus[noteNumber] == false) { mKeyStatus[noteNumber] = true; mNumKeys += 1; noteOn(noteNumber, velocity); } } else { if (mKeyStatus[noteNumber] == true) { mKeyStatus[noteNumber] = false; mNumKeys -= 1; noteOff(noteNumber, velocity); } } mMidiQueue.Remove(); } mOffset++; }
int main(void){ mPORTBSetPinsAnalogIn(0xFFFF); //Enable all analog mPORTDClearBits(BIT_0 |BIT_1 | BIT_8); mPORTDSetPinsDigitalOut(BIT_0 | BIT_1 | BIT_8); SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); CloseADC10(); SetChanADC10(INITCH); OpenADC10(CONFIG1, CONFIG2, CONFIG3, CFGPORT, CFGSCAN); ConfigIntADC10(CFGINT); EnableADC10(); mPMPOpen(PMP_CONTROL, PMP_MODE, PMP_PORT, PMP_INT); mPMPEnable(); //mPORTDClearBits(BIT_0 |BIT_1 | BIT_8); INTEnableSystemMultiVectoredInt(); OpenTimer2(T2_ON | T2_PS_1_64, 256); ConfigIntTimer2(T2_INT_ON | T2_INT_PRIOR_5 | T2_INT_SUB_PRIOR_2); EnableIntT2; mPORTDToggleBits(BIT_0); while(1){ //Blink so we know we're still running noteOn(67, 100); //delayMs(1000); mPORTDToggleBits(BIT_0); //noteOff(67); DelayMs(1000); //mPORTDToggleBits(BIT_0); } return 0; }
void handleNoteOn(uint32_t tics, int channel, int note, int velocity) { logger(LOG_INFO, "Note On at: %d for Channel: %d, Note: %d, Velocity: %d\n", tics, channel, note, velocity); waitForTicCount(tics); noteOn(channel, note, velocity); }
void Synthesiser::handleMidiEvent (const MidiMessage& m) { if (m.isNoteOn()) { noteOn (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity()); } else if (m.isNoteOff()) { noteOff (m.getChannel(), m.getNoteNumber(), true); } else if (m.isAllNotesOff() || m.isAllSoundOff()) { allNotesOff (m.getChannel(), true); } else if (m.isPitchWheel()) { const int channel = m.getChannel(); const int wheelPos = m.getPitchWheelValue(); lastPitchWheelValues [channel - 1] = wheelPos; handlePitchWheel (channel, wheelPos); } else if (m.isController()) { handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue()); } }
void QMidiSequencer::run() { while(true) { if (Pm_Poll(m_midi) == TRUE) { int size = Pm_Read(m_midi,m_buffer, 256); for(int i=0; i<size; i++) { int type = Pm_MessageStatus(m_buffer[i].message); int chan = Pm_MessageData1(m_buffer[i].message); int value = Pm_MessageData2(m_buffer[i].message); //std::cout << "midi : " << QString::number(type).toStdString() << " | " << QString::number(chan).toStdString() << " | " << QString::number(value).toStdString() << std::endl; /*qDebug(QString::number(type).toStdString().c_str()); qDebug(QString::number(chan).toStdString().c_str()); qDebug(QString::number(value).toStdString().c_str()); qDebug("\n");*/ if( chan == 74 || chan == 10 || chan == 7 ) emit controllerValueChanged(type*chan,value); else if( (chan == 72 || chan == 73) ) emit noteOn(type,type+chan,value); /*else if( type == 144 && value == 0 ) emit noteOff(type, chan);*/ } } this->msleep(10); } }
//----------------------------------------------------------------------------------------- VstInt32 VstXSynth::processEvents (VstEvents* ev) { for (VstInt32 i = 0; i < ev->numEvents; i++) { if ((ev->events[i])->type != kVstMidiType) continue; VstMidiEvent* event = (VstMidiEvent*)ev->events[i]; char* midiData = event->midiData; VstInt32 status = midiData[0] & 0xf0; // ignoring channel if (status == 0x90 || status == 0x80) // we only look at notes { VstInt32 note = midiData[1] & 0x7f; VstInt32 velocity = midiData[2] & 0x7f; if (status == 0x80) velocity = 0; // note off by velocity 0 if (!velocity && (note == currentNote)) noteOff (); else noteOn (note, velocity, event->deltaFrames); } else if (status == 0xb0) { if (midiData[1] == 0x7e || midiData[1] == 0x7b) // all notes off noteOff (); } event++; } return 1; }
void MidiReader::onMidiMessage(double deltaTime, std::vector<unsigned char> *message) { size_t bytesCount = message->size(); if (bytesCount == 1 && message->at(0) == 254) return; // Skip 'Active sense' bytes for (size_t i = 0; i < bytesCount; ++i) qdbg << "Byte " << i << " = " << (int)message->at(i) << ", "; if (bytesCount > 0) qdbg << "stamp = " << deltaTime << endl; if (bytesCount >= 3) { quint8 byte1 = (*message)[0]; int channel = byte1 & 0b1111; int cmd = byte1 >> 4; qdbg << "[Channel " << channel << "] "; if (cmd == 0b1000) { // Note Off int key = (*message)[1]; int velocity = (*message)[2]; qdbg << "Note off: key=" << key << ", velocity=" << velocity; emit noteOff(key, velocity); } else if (cmd == 0b1001) { // Note On int key = (*message)[1]; int velocity = (*message)[2]; qdbg << "Note on: key=" << key << ", velocity=" << velocity; emit noteOn(key, velocity); } qdbg << endl; }
sound_type snd_make_mandolin(time_type t0, double freq, time_type d, double body_size, double detune, rate_type sr) { register mandolin_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, mandolin_susp_node, "snd_make_mandolin"); susp->mymand = initInstrument(MANDOLIN, round(sr)); controlChange(susp->mymand, 1, detune); controlChange(susp->mymand, 2, MAND_CONTROL_CHANGE_CONST * body_size);; susp->temp_ret_value = noteOn(susp->mymand, freq, 1.0); susp->susp.fetch = mandolin__fetch; susp->terminate_cnt = round((d) * sr); /* initialize susp state */ susp->susp.free = mandolin_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = mandolin_print_tree; susp->susp.name = "mandolin"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
void PianoScene::triggerNoteOn( const int note, const int vel ) { int n = m_baseOctave*12 + note + m_transpose; if ((n >= m_minNote) && (n <= m_maxNote)) { if (m_handler != NULL) { m_handler->noteOn(n, vel); } else { emit noteOn(n, vel); } } }
sound_type snd_make_flute_freq(double freq, sound_type breath_env, sound_type freq_env, rate_type sr) { register flute_freq_susp_type susp; /* sr specified as input parameter */ time_type t0 = breath_env->t0; sample_type scale_factor = 1.0F; time_type t0_min = t0; falloc_generic(susp, flute_freq_susp_node, "snd_make_flute_freq"); susp->myflute = initInstrument(FLUTE, round(sr)); controlChange(susp->myflute, 1, 0.0);; susp->temp_ret_value = noteOn(susp->myflute, freq, 1.0); susp->breath_scale = breath_env->scale * FLUTE_CONTROL_CHANGE_CONST; susp->frequency = freq; /* make sure no sample rate is too high */ if (breath_env->sr > sr) { sound_unref(breath_env); snd_badsr(); } else if (breath_env->sr < sr) breath_env = snd_make_up(sr, breath_env); if (freq_env->sr > sr) { sound_unref(freq_env); snd_badsr(); } else if (freq_env->sr < sr) freq_env = snd_make_up(sr, freq_env); susp->susp.fetch = flute_freq_ns_fetch; susp->terminate_cnt = UNKNOWN; /* handle unequal start times, if any */ if (t0 < breath_env->t0) sound_prepend_zeros(breath_env, t0); if (t0 < freq_env->t0) sound_prepend_zeros(freq_env, t0); /* minimum start time over all inputs: */ t0_min = min(breath_env->t0, min(freq_env->t0, t0)); /* how many samples to toss before t0: */ susp->susp.toss_cnt = (long) ((t0 - t0_min) * sr + 0.5); if (susp->susp.toss_cnt > 0) { susp->susp.keep_fetch = susp->susp.fetch; susp->susp.fetch = flute_freq_toss_fetch; } /* initialize susp state */ susp->susp.free = flute_freq_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = flute_freq_mark; susp->susp.print_tree = flute_freq_print_tree; susp->susp.name = "flute_freq"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; susp->breath_env = breath_env; susp->breath_env_cnt = 0; susp->freq_env = freq_env; susp->freq_env_cnt = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
void MIDISeq::BuildMIDIMessages() { if(note_num_set) { MidiMessage noteOn(midi_channel, note_num, 127); midi_messages[0] = noteOn; MidiMessage noteOff(midi_channel,note_num,0); midi_messages[1] = noteOff; } }
void MMidi::midiHandler() { //midiTime = millis(); uint8_t midiChannel = (midiBuffer[0] & 0x0F); switch(midiBuffer[0] & 0xF0) { // bit mask with &0xF0 ? case 0x80: noteOff (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F, // note value 0-127 midiBuffer[2] & 0x7F); // note velocity 0-127 break; case 0x90: noteOn (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F, // note value 0-127 midiBuffer[2] & 0x7F); // note velocity 0-127 break; case 0xA0: aftertouch (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F, // note value 0-127 midiBuffer[2] & 0x7F);// note velocity 0-127 break; case 0xB0: controller (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F, // controller number 0-127 midiBuffer[2] & 0x7F);// controller value 0-127 break; case 0xC0: programChange (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F); // program number 0-127 break; case 0xD0: channelPressure (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F); // pressure amount 0-127 break; case 0xE0: pitchWheel (midiBuffer[0] & 0x0F, // midi channel 0-16 midiBuffer[1] & 0x7F, // higher bits 0-6 midiBuffer[2] & 0x7F);// lower bits 7-13 break; default: break; } }
/** * @short Gets the audio signals for both channels (actually a copy) */ void Polybase::getAudio(float *audio[2], unsigned int nsamples, const MidiEventList &list){ if (nsamples>chunksize){ if (chunk){ delete chunk; } chunk=new float[nsamples]; } unsigned int uptoSample=0; unsigned int i; foreach(MidiEvent ev, list){ if (ev.sampleOffset>uptoSample){ calculateChunk(&audio[0][uptoSample], ev.sampleOffset-uptoSample); uptoSample=ev.sampleOffset; } switch (ev.type){ case MidiEvent::noteOn: noteOn(ev.data[0], ev.data[1]); break; case MidiEvent::noteOff: noteOff(ev.data[0], ev.data[1]); break; case MidiEvent::controller: controller(ev.data[0], ev.data[1]); break; default: break; } } calculateChunk(&audio[0][uptoSample], nsamples-uptoSample); for (i=0;i<nsamples;i++){ float s=audio[0][i]*volume; if (s>1.0 || s<-1.0){ volume*=0.9; if (s<0.0) s=-1.0; else s=1.0; WARNING("Clip %f! lowering volume to %f", s, volume); emit sendController(0, volume*127); } audio[0][i]=s; } // no stereo by the moment memcpy(audio[1],audio[0],sizeof(float)*nsamples); }
boolean Instrument::evHandler( obEvent ev ) { evType evtype = ev.type(); switch ( evtype ) { case KEY_DOWN: // note On case KEY_UP: // note Off { if ( ! keybrd.muted() ) { key k = ev.getKey(); if ( ! ev.octOn() ) k.setOctave( keybrd.octave ); if ( evtype == KEY_DOWN ) noteOn( k ); else noteOff( k ); } else return false; break; } case BUT0_TAP: // octave down (if keybrd active) if ( ! keybrd.muted() ) keybrd.downOctave(); else return false; break; case BUT1_TAP: // octave up (if keybrd active) if ( ! keybrd.muted() ) keybrd.upOctave(); else return false; break; default: return super::evHandler( ev ); } return true; }
void PixmapKeyboard::sendNoteOn(int note, bool sendSignal) { if (0 <= note && note <= 127 && ! fEnabledKeys.contains(note)) { fEnabledKeys.append(note); if (sendSignal) emit noteOn(note); update(); } if (fEnabledKeys.count() == 1) emit notesOn(); }
void DrumSet() { int drumNo = 0; char cmd = 0; Intitialize_Drumset(); while(1) { cmd = getchar_pc_nb(); if (cmd == 27) { break; } else { if(P0 & 0x3F) { tmp_port = P0; for(inn=0;inn<6;inn++) { if((tmp_port>>inn) & 0x01) break; } if(inn<6 && timerID_DR[inn] == TimerId_INVALID) { timerID_DR[inn] = SetTimerReq(&Drum_ISR,200); //halLedToggle(1); P0IFG &= ~(1<<inn); Capture_DR[inn] = 0; } } if(Print_Flag == 1) { //1-40; 2-36; 3-48; 4-41; 5-51; drum notes if (tx1_buf[1]==0) drumNo=48; else if (tx1_buf[1]==1) drumNo=41; else if (tx1_buf[1]==2) drumNo=51; else if (tx1_buf[1]==3) drumNo=40; else if (tx1_buf[1]==4) drumNo=36; noteOn(0, drumNo, (tx1_buf[2]+0x40)&0x7F); //noteOn(0, drumNo, 0x7F); //tx1_send(tx1_buf,3); Print_Flag = 0; } }//else of nblk getchar }
void __ISR(_ADC_VECTOR, IPL7AUTO) ADCHandle(void){ mAD1ClearIntFlag(); int i=0; for(i; i<16; i++){ adcread = ReadADC10(i); switch(keyState[i]){ case GET_ON: // Previous force value moved into bin 0 // Bin 1 gets new value from ADC forceData[i][0] = forceData[i][1]; forceData[i][1] = adcread; // Previous slope bit moved into bin 0 // New slope bit determined from backward differentiator // if y[n] - y[n-1] is positive --> slope in bin 1 is '1' // else, negative slope gets '0' slopeData[i][0] = slopeData[i][1]; if(forceData[i][1]>forceData[i][0]){ slopeData[i][1]=1; }else{ slopeData[i][1]=0; } // Slope in bin 1 will be less than bin 0 if the slope changes from // Positive to negative, meaning a peak has been found // If so, send out noteOn signal // Else keep searching for noteOn conditions if (slopeData[i][1]<slopeData[i][0] && forceData[i][0] > threshold){ noteOn(i, forceData[i][0]); keyState[i] = GET_OFF; }else{ keyState[i] = GET_ON; } break; case GET_OFF: //TODO: Change this to digital input from comparator if(1){ noteOff(i); keyState[i] = GET_ON; } break; } } }
//============================================================================== // TEST //============================================================================== void* thread_test(void* arg) { int v=1; int n=strtol(arg,NULL,10); while(1) { sleep(1); if(run) { noteOn(n,v); printf("test(%i,%i)\n",n,v); v=(v+2)%127; } } return NULL; }
VstInt32 SorolletVSTi::processEvents(VstEvents* ev) { for (VstInt32 i = 0; i < ev->numEvents; i++) { if ((ev->events[i])->type != kVstMidiType) continue; VstMidiEvent* event = (VstMidiEvent*) ev->events[i]; char* midiData = event->midiData; VstInt32 status = midiData[0] & 0xf0; // ignoring channel if (status == 0x90 || status == 0x80) // we only look at notes { VstInt32 note = midiData[1] & 0x7f; VstInt32 velocity = midiData[2] & 0x7f; if (status == 0x80) velocity = 0; // note off by velocity 0 if (!velocity && (note == currentNote)) noteOff(event->deltaFrames); else noteOn(note, velocity, event->deltaFrames); }/*else if(status == 0xA0) { printf("polyphonic Aftertouch\n"); } else if(status == 0xD0) { printf("channel Aftertouch\n"); }*/ else if (0xC0 == status) { // Control change int number = midiData[1] & 0x7F; float value = (float) ((midiData[2] & 0x7F)); printf("CC %d value = %d , float = %f\n", number, midiData[2] & 0x7F, value); } else if (status == 0xb0) { if (midiData[1] == 0x7e || midiData[1] == 0x7b) // all notes off noteOff(event->deltaFrames); } event++; } return 1; }
void VPiano::customEvent ( QEvent *event ) { if (event->type() == NoteOnEventType ) { NoteOnEvent *ev = static_cast<NoteOnEvent*>(event); ui.pianokeybd->showNoteOn(ev->getNote()); if (m_midiThru) noteOn(ev->getNote()); event->accept(); } else if (event->type() == NoteOffEventType ) { NoteOffEvent *ev = static_cast<NoteOffEvent*>(event); ui.pianokeybd->showNoteOff(ev->getNote()); if (m_midiThru) noteOff(ev->getNote()); event->accept(); } else if (event->type() == ControllerEventType ) { ControllerEvent *ev = static_cast<ControllerEvent*>(event); updateController(ev->getController(), ev->getValue()); if (m_midiThru) sendController(ev->getController(), ev->getValue()); event->accept(); } }
int MainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QMainWindow::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: noteOn((*reinterpret_cast< const int(*)>(_a[1]))); break; case 1: noteOff((*reinterpret_cast< const int(*)>(_a[1]))); break; case 2: pauseActive((*reinterpret_cast< int(*)>(_a[1]))); break; case 3: setChannelChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 4: setVelocityChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 5: setBase_octaveChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 6: setTransposeChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 7: setEditEnable((*reinterpret_cast< bool(*)>(_a[1]))); break; case 8: editChord((*reinterpret_cast< QPoint(*)>(_a[1]))); break; case 9: on_actionOpenMidi_triggered(); break; case 10: on_actionOpen_triggered(); break; case 11: on_actionPlayMidi_triggered(); break; case 12: on_btn_9_clicked(); break; case 13: on_btn_8_clicked(); break; case 14: on_btn_7_clicked(); break; case 15: on_btn_6_clicked(); break; case 16: on_btn_5_clicked(); break; case 17: on_btn_4_clicked(); break; case 18: on_btn_3_clicked(); break; case 19: on_btn_2_clicked(); break; case 20: on_btn_1_clicked(); break; case 21: on_btn_0_clicked(); break; case 22: on_chordAnalyse_triggered(); break; case 23: on_redoAction_triggered(); break; case 24: on_undoAction_triggered(); break; case 25: on_actionSave_triggered(); break; case 26: on_actionMIDI_controller_triggered((*reinterpret_cast< bool(*)>(_a[1]))); break; case 27: saveStaff(); break; case 28: loadStaff((*reinterpret_cast< QString(*)>(_a[1]))); break; case 29: processFinished((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< QProcess::ExitStatus(*)>(_a[2]))); break; default: ; } _id -= 30; } return _id; }
void Synthesiser::handleMidiEvent (const MidiMessage& m) { const int channel = m.getChannel(); if (m.isNoteOn()) { noteOn (channel, m.getNoteNumber(), m.getFloatVelocity()); } else if (m.isNoteOff()) { noteOff (channel, m.getNoteNumber(), m.getFloatVelocity(), true); } else if (m.isAllNotesOff() || m.isAllSoundOff()) { allNotesOff (channel, true); } else if (m.isPitchWheel()) { const int wheelPos = m.getPitchWheelValue(); lastPitchWheelValues [channel - 1] = wheelPos; handlePitchWheel (channel, wheelPos); } else if (m.isAftertouch()) { handleAftertouch (channel, m.getNoteNumber(), m.getAfterTouchValue()); } else if (m.isChannelPressure()) { handleChannelPressure (channel, m.getChannelPressureValue()); } else if (m.isController()) { handleController (channel, m.getControllerNumber(), m.getControllerValue()); } else if (m.isProgramChange()) { handleProgramChange (channel, m.getProgramChangeNumber()); } }
sound_type snd_make_sitar(time_type t0, double freq, time_type dur, rate_type sr) { register sitar_susp_type susp; /* sr specified as input parameter */ /* t0 specified as input parameter */ sample_type scale_factor = 1.0F; falloc_generic(susp, sitar_susp_node, "snd_make_sitar"); susp->mysitar = initInstrument(SITAR, round(sr)); susp->temp_ret_value = noteOn(susp->mysitar, freq, 1.0); susp->susp.fetch = sitar__fetch; susp->terminate_cnt = round((dur) * sr); /* initialize susp state */ susp->susp.free = sitar_free; susp->susp.sr = sr; susp->susp.t0 = t0; susp->susp.mark = NULL; susp->susp.print_tree = sitar_print_tree; susp->susp.name = "sitar"; susp->susp.log_stop_cnt = UNKNOWN; susp->susp.current = 0; return sound_create((snd_susp_type)susp, t0, sr, scale_factor); }
void MidiSequencer::eventReceived(drumstick::SequencerEvent *ev) { static QChar fill('0'); drumstick::KeyEvent *kev; if (!(kev = static_cast<drumstick::KeyEvent*>(ev))) return; if (kev->getSequencerType() == SND_SEQ_EVENT_NOTEON && kev->getTag() == 1) emit noteOn(kev->getChannel(), kev->getKey(), kev->getVelocity()); if (kev->getSequencerType() == SND_SEQ_EVENT_NOTEOFF && kev->getTag() == 1) { if (m_eventSchedulingMode == FROM_ENGINE) emit noteOff(kev->getChannel(), kev->getKey(), kev->getVelocity()); else emit noteHighlight(kev->getChannel(), kev->getKey(), kev->getVelocity(), QStringLiteral("#B3CADB")); } if (m_tick != 0 && m_midiSequencerOutputThread->isRunning()) { const snd_seq_real_time_t *rt = m_queue->getStatus().getRealtime(); int mins = rt->tv_sec / 60; int secs = rt->tv_sec % 60; int cnts = qFloor( rt->tv_nsec / 1.0e7 ); emit timeLabelChanged(QString("%1:%2.%3").arg(mins,2,10,fill).arg(secs,2,10,fill).arg(cnts,2,10,fill)); } }
void updateMidi() { int b = Serial.read(); if(b!=-1) { midiByte2 = midiByte1; midiByte1 = midiByte0; midiByte0 = b; // only work if we've got a status byte // of some sort if(!(midiByte2 & B10000000)) return; int st = HI_NIBBLE(midiByte2); int channel = LO_NIBBLE(midiByte2); // channel += 1; // we're doing this with defines // now check to see if we have a midi if(st==NOTE_ON_STATUS) { if(midiByte0==0) { // if the volume is zero, it's a note off noteOff(channel, midiByte1); } else { noteOn(channel, midiByte1, midiByte0); } } else if(st==NOTE_OFF_STATUS) { noteOff(channel, midiByte1); #ifdef USING_CC } else if(st==CC_STATUS) { cc(channel, midiByte1, midiByte0); } else if(st==PITCHBEND_STATUS) { cc(channel, -1, midiByte0); #endif } } }
void InstrumentTrack::processInEvent( const midiEvent & _me, const midiTime & _time ) { engine::getMixer()->lock(); switch( _me.m_type ) { // we don't send MidiNoteOn, MidiNoteOff and MidiKeyPressure // events to instrument as notePlayHandle will send them on its // own case MidiNoteOn: if( _me.velocity() > 0 ) { if( m_notes[_me.key()] == NULL ) { if( !configManager::inst()->value( "ui", "manualchannelpiano" ).toInt() ) { m_piano.setKeyState( _me.key(), true ); } // create temporary note note n; n.setKey( _me.key() ); n.setVolume( _me.getVolume() ); // create (timed) note-play-handle notePlayHandle * nph = new notePlayHandle( this, _time.frames( engine::framesPerTick() ), typeInfo<f_cnt_t>::max() / 2, n ); if( engine::getMixer()->addPlayHandle( nph ) ) { m_notes[_me.key()] = nph; } emit noteOn( n ); } break; } case MidiNoteOff: { notePlayHandle * n = m_notes[_me.key()]; if( n != NULL ) { // create dummy-note which has the same length // as the played note for sending it later // to all slots connected to signal noteOff() // this is for example needed by piano-roll for // recording notes into a pattern note done_note( midiTime( static_cast<f_cnt_t>( n->totalFramesPlayed() / engine::framesPerTick() ) ), 0, n->key(), n->getVolume(), n->getPanning() ); n->noteOff(); m_notes[_me.key()] = NULL; emit noteOff( done_note ); } break; } case MidiKeyPressure: if( m_notes[_me.key()] != NULL ) { m_notes[_me.key()]->setVolume( _me.getVolume() ); } break; case MidiPitchBend: // updatePitch() is connected to // m_pitchModel::dataChanged() which will send out // MidiPitchBend events m_pitchModel.setValue( m_pitchModel.minValue() + _me.m_data.m_param[0] * m_pitchModel.range() / 16384 ); break; case MidiControlChange: case MidiProgramChange: m_instrument->handleMidiEvent( _me, _time ); break; case MidiMetaEvent: // handle special cases such as note panning switch( _me.m_metaEvent ) { case MidiNotePanning: if( m_notes[_me.key()] != NULL ) { m_notes[_me.key()]->setPanning( _me.getPanning() ); } break; default: printf( "instrument-track: unhandled " "MIDI meta event: %i\n", _me.m_metaEvent ); break; } break; default: if( !m_instrument->handleMidiEvent( _me, _time ) ) { printf( "instrument-track: unhandled " "MIDI event %d\n", _me.m_type ); } break; } engine::getMixer()->unlock(); }
void sf2Instrument::play( sampleFrame * _working_buffer ) { const fpp_t frames = Engine::mixer()->framesPerPeriod(); // set midi pitch for this period const int currentMidiPitch = instrumentTrack()->midiPitch(); if( m_lastMidiPitch != currentMidiPitch ) { m_lastMidiPitch = currentMidiPitch; m_synthMutex.lock(); fluid_synth_pitch_bend( m_synth, m_channel, m_lastMidiPitch ); m_synthMutex.unlock(); } const int currentMidiPitchRange = instrumentTrack()->midiPitchRange(); if( m_lastMidiPitchRange != currentMidiPitchRange ) { m_lastMidiPitchRange = currentMidiPitchRange; m_synthMutex.lock(); fluid_synth_pitch_wheel_sens( m_synth, m_channel, m_lastMidiPitchRange ); m_synthMutex.unlock(); } // if we have no new noteons/noteoffs, just render a period and call it a day if( m_playingNotes.isEmpty() ) { renderFrames( frames, _working_buffer ); instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL ); return; } // processing loop // go through noteplayhandles in processing order f_cnt_t currentFrame = 0; while( ! m_playingNotes.isEmpty() ) { // find the note with lowest offset NotePlayHandle * currentNote = m_playingNotes[0]; for( int i = 1; i < m_playingNotes.size(); ++i ) { SF2PluginData * currentData = static_cast<SF2PluginData *>( currentNote->m_pluginData ); SF2PluginData * iData = static_cast<SF2PluginData *>( m_playingNotes[i]->m_pluginData ); if( currentData->offset > iData->offset ) { currentNote = m_playingNotes[i]; } } // process the current note: // first see if we're synced in frame count SF2PluginData * currentData = static_cast<SF2PluginData *>( currentNote->m_pluginData ); if( currentData->offset > currentFrame ) { renderFrames( currentData->offset - currentFrame, _working_buffer + currentFrame ); currentFrame = currentData->offset; } if( currentData->isNew ) { noteOn( currentData ); if( currentNote->isReleased() ) // if the note is released during the same period, we have to process it again for noteoff { currentData->isNew = false; currentData->offset = currentNote->framesBeforeRelease(); } else // otherwise remove the handle { m_playingNotesMutex.lock(); m_playingNotes.remove( m_playingNotes.indexOf( currentNote ) ); m_playingNotesMutex.unlock(); } } else { noteOff( currentData ); m_playingNotesMutex.lock(); m_playingNotes.remove( m_playingNotes.indexOf( currentNote ) ); m_playingNotesMutex.unlock(); } } if( currentFrame < frames ) { renderFrames( frames - currentFrame, _working_buffer + currentFrame ); } instrumentTrack()->processAudioBuffer( _working_buffer, frames, NULL ); }