Пример #1
0
//-----------------------------------------------------------------------------------------
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;
}
Пример #2
0
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++;
}
Пример #3
0
NotePlayHandle::~NotePlayHandle()
{
	noteOff( 0 );
	
	if( hasParent() == false )
	{
		delete m_baseDetuning;
		m_instrumentTrack->m_processHandles.removeAll( this );
	}

	if( m_pluginData != NULL )
	{
		m_instrumentTrack->deleteNotePluginData( this );
	}

	if( m_instrumentTrack->m_notes[key()] == this )
	{
		m_instrumentTrack->m_notes[key()] = NULL;
	}

	for( NotePlayHandleList::Iterator it = m_subNotes.begin(); it != m_subNotes.end(); ++it )
	{
		delete *it;
	}
	m_subNotes.clear();

	delete m_filter;
}
Пример #4
0
// Functions for handling midi events and meta events
void handleNoteOff(uint32_t tics, int channel, int note, int velocity) {

    logger(LOG_INFO, "Note Off at: %d for Channel: %d, Note: %d, Velocity: %d\n", tics, channel, note, velocity);

    waitForTicCount(tics);
    noteOff(channel, note);
}
Пример #5
0
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;
    }
Пример #6
0
void NotePlayHandle::done()
{
	lock();
	noteOff( 0 );

	if( hasParent() == false )
	{
		delete m_baseDetuning;
		m_instrumentTrack->m_processHandles.removeAll( this );
	}
	else
	{
		m_parent->m_subNotes.removeOne( this );
	}

	if( m_pluginData != NULL )
	{
		m_instrumentTrack->deleteNotePluginData( this );
	}

	if( m_instrumentTrack->m_notes[key()] == this )
	{
		m_instrumentTrack->m_notes[key()] = NULL;
	}

	m_subNotes.clear();

	delete m_filter;

	if( buffer() ) releaseBuffer();

	unlock();
}
Пример #7
0
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());
    }
}
Пример #8
0
void OPN2::silenceAll() // Silence all OPL channels.
{
    for(size_t c = 0; c < m_numChannels; ++c)
    {
        noteOff(c);
        touchNote(c, 0);
    }
}
Пример #9
0
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;
}
Пример #10
0
void sf2Instrument::deleteNotePluginData( NotePlayHandle * _n )
{
	SF2PluginData * pluginData = static_cast<SF2PluginData *>( _n->m_pluginData );
	if( ! pluginData->noteOffSent ) // if we for some reason haven't noteoffed the note before it gets deleted,
									// do it here
	{
		noteOff( pluginData );
	}
	delete pluginData;
}
Пример #11
0
void PianoScene::triggerNoteOff( 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->noteOff(n, vel);
        } else {
            emit noteOff(n, vel);
        }
    }
}
Пример #12
0
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;
    }
   
    
    
}
Пример #13
0
/**
 * @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);
}
Пример #14
0
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;
	}
}
Пример #15
0
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
    }
    
  }
}
Пример #16
0
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;
}
Пример #17
0
void PixmapKeyboard::sendNoteOff(int note, bool sendSignal)
{
    if (note >= 0 && note <= 127 && fEnabledKeys.contains(note))
    {
        fEnabledKeys.removeOne(note);

        if (sendSignal)
            emit noteOff(note);

        update();
    }

    if (fEnabledKeys.count() == 0)
        emit notesOff();
}
Пример #18
0
void MidiKeyboardState::allNotesOff (const int midiChannel)
{
    const ScopedLock sl (lock);

    if (midiChannel <= 0)
    {
        for (int i = 1; i <= 16; ++i)
            allNotesOff (i);
    }
    else
    {
        for (int i = 0; i < 128; ++i)
            noteOff (midiChannel, i, 0.0f);
    }
}
Пример #19
0
void sf2Instrument::deleteNotePluginData( NotePlayHandle * _n )
{
	SF2PluginData * pluginData = static_cast<SF2PluginData *>( _n->m_pluginData );
	if( ! pluginData->noteOffSent ) // if we for some reason haven't noteoffed the note before it gets deleted,
									// do it here
	{
		noteOff( pluginData );
		m_playingNotesMutex.lock();
		if( m_playingNotes.indexOf( _n ) >= 0 )
		{
			m_playingNotes.remove( m_playingNotes.indexOf( _n ) );
		}
		m_playingNotesMutex.unlock();
	}
	delete pluginData;
}
Пример #20
0
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;

        }
    }
}
Пример #21
0
void musicBlock::noteOn(uint32_t channel, uint8_t key, int volume)
{
	if (volume <= 0)
	{
		noteOff(channel, key);
		return;
	}
	GenMidiInstrument *instrument;

	// Percussion channel is treated differently.
	if (channel == CHAN_PERCUSSION)
	{
		if (key < GENMIDI_FIST_PERCUSSION || key >= GENMIDI_FIST_PERCUSSION + GENMIDI_NUM_PERCUSSION)
		{
			return;
		}

		instrument = &OPLinstruments[key + (GENMIDI_NUM_INSTRS - GENMIDI_FIST_PERCUSSION)];
	}
	else
	{
		auto inst = oplchannels[channel].Instrument;
		if (inst >= GENMIDI_NUM_TOTAL) return;	// better safe than sorry.
		instrument = &OPLinstruments[inst];
	}

	bool double_voice = ((instrument->flags) & GENMIDI_FLAG_2VOICE) && !opl_singlevoice;

	int i = findFreeVoice();
	if (i < 0) i = replaceExistingVoice();

	if (i >= 0)
	{
		voiceKeyOn(i, channel, instrument, 0, key, volume);
		if (double_voice)
		{
			i = findFreeVoice();
			if (i > 0)
			{
				voiceKeyOn(i, channel, instrument, 1, key, volume);
			}
		}
	}
}
Пример #22
0
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();
    }
}
Пример #23
0
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;
}
Пример #24
0
void InstrumentTrack::deleteNotePluginData( notePlayHandle * _n )
{
	if( m_instrument != NULL )
	{
		m_instrument->deleteNotePluginData( _n );
	}

	// Notes deleted when keys still pressed
	if( m_notes[_n->key()] == _n )
	{
		note done_note( midiTime( static_cast<f_cnt_t>(
						_n->totalFramesPlayed() /
						engine::framesPerTick() ) ),
					0, _n->key(),
					_n->getVolume(), _n->getPanning() );
		_n->noteOff();
		m_notes[_n->key()] = NULL;
		emit noteOff( done_note );
	}
}
Пример #25
0
/** 
 Sends system resets: all controllers, all sounds off, all notes off
*/
void MIDI::reset() {
    send(0xb0 | channel); // system reset for channel
    send(121); // reset all controllers
    send(0x00);

    send(0xb0 | channel); // system reset for channel
    send(120); // sound off
    send(0x00);

    send(0xb0 | channel); // system reset for channel
    send(123); // all notes off
    send(0x00);

    for(int c=0; c<16; c++) {
        for(int i=0; i<128; i++) {
            noteOff(i, c, 0);
        }
    }
    if(verbose) {
        std::cout << "MIDI   RESET" << std::endl;
    }
}
Пример #26
0
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());
    }
}
Пример #27
0
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));
    }
}
Пример #28
0
void Player_AD::stopMusic() {
	if (_soundPlaying == -1) {
		return;
	}

	// Unlock the music resource if present
	_vm->_res->unlock(rtSound, _soundPlaying);
	_soundPlaying = -1;

	// Stop the music playback
	_curOffset = 0;

	// Stop all music voice channels
	for (int i = 0; i < ARRAYSIZE(_voiceChannels); ++i) {
		if (_voiceChannels[i].lastEvent) {
			noteOff(i);
		}
	}

	// Reset rhythm state
	writeReg(0xBD, 0x00);
	limitHWChannels(9);
}
Пример #29
0
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();
}
Пример #30
0
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 );
}