Logo Search packages:      
Sourcecode: canorus version File versions  Download package

void CAKeybdInput::midiInEventToScore ( CAScoreViewPort v,
QVector< unsigned char >  m 
) [private]

This is the entry point the midi input device. All note on events are passed over here.

Definition at line 79 of file keybdinput.cpp.

References CAScoreViewPort::addToSelection(), CAVoice::append(), CAScoreViewPort::clearSelection(), CAMusElementFactory::configureRest(), CAMusElementFactory::configureSlur(), CAVoice::contains(), CAScoreViewPort::currentContext(), CAMainWin::currentScoreViewPort(), CAMainWin::currentSheet(), CAMainWin::currentVoice(), CAMainWin::document(), CATuplet::firstNote(), CAVoice::getChord(), CAVoice::insert(), CAVoice::insertInTupletAndVoiceAt(), CAPlayable::isFirstInTuplet(), CAVoice::lastMusElement(), CAVoice::lastPlayableElt(), CAVoice::lastTimeEnd(), CAVoice::lastTimeStart(), matchPitchToKey(), CAPlayableLength::matchToBars(), CAMidiDevice::midiPitchToDiatonicPitch(), CAMusElementFactory::musElement(), CAMainWin::musElementFactory(), CATuplet::nextTimed(), CAMusElementFactory::placeAutoBar(), CAMusElementFactory::playableLength(), CAVoice::previousByType(), CAScoreViewPort::setWorldCoords(), CAVoice::synchronizeMusElements(), CAMusElement::timeStart(), CAScoreViewPort::timeToCoordsSimpleVersion(), CAPlayable::tuplet(), CAMainWin::uiTupletActualNumber, CAMainWin::uiTupletNumber, CAMainWin::uiTupletType, CAScoreViewPort::updateHelpers(), and CAScoreViewPort::worldCoords().

                                                                                  {

      int i;
      CADiatonicPitch p = CAMidiDevice::midiPitchToDiatonicPitch( m[1] );
      CADiatonicPitch nonenharmonicPitch;

      CAVoice *voice = _mw->currentVoice();
      if (voice) {
      
            int cpitch = m[1];

            // will publish this only when it's configurable. Habe only a four octave keyboard ...
/*
            CAPlayableLength plength = CAPlayableLength::Undefined;
            switch (cpitch) {
            case 39:    plength = CAPlayableLength::Whole;        break;
            case 40:    plength = CAPlayableLength::Half;         break;
            case 41:    plength = CAPlayableLength::Quarter;      break;
            case 42:    plength = CAPlayableLength::Eighth;       break;
            case 43:    plength = CAPlayableLength::Sixteenth;    break;
            default:    ;
            }
            if (plength !=  CAPlayableLength::Undefined) {
                  _mw->uiPlayableLength->setCurrentId( plength.musicLength(), true );
                  _mw->musElementFactory()->playableLength().setDotted( 0 );
                  v->setShadowNoteLength( _mw->musElementFactory()->playableLength() );
                  v->updateHelpers();
                  v->repaint();
                  return;
            }
*/

            CADrawableContext *drawableContext = v->currentContext();
            CAStaff *staff=0;
            CADrawableStaff *drawableStaff = 0;
            if (drawableContext) {
                  drawableStaff = dynamic_cast<CADrawableStaff*>(drawableContext);
                  staff = dynamic_cast<CAStaff*>(drawableContext->context());
            }

            CANote *note = 0;
            CARest *rest = 0;

            switch (cpitch) {
//          case 37:    std::cout << "  Pause" << std::endl;
//                            rest = new CARest( CARest::Normal, _mw->musElementFactory()->playableLength(), voice, 0, -1 );
//                            break;
//          case 38:    _mw->uiTupletType->defaultAction()->setChecked( !_mw->uiTupletType->isChecked() );
//                            return;
            default:    nonenharmonicPitch = matchPitchToKey( voice, p );
                              note = new CANote( nonenharmonicPitch, _mw->musElementFactory()->playableLength(), voice, -1 );
            }

            CACanorus::undo()->createUndoCommand( _mw->document(), QObject::tr("insert midi note", "undo") );

            // if notes come in sufficiently close together we make a chord of them
            bool appendToChord = _midiInChordTimer.isActive();

            // If we are still in the processing of a tuplet, check if it's still there.
            // Possibly editing on the GUI could have moved it around or away, and no crash please.
            if ( _tupPla && ( !voice->contains(_tupPla) || _tupPla->tuplet() != _tup )) _tupPla = 0;

            // Where to put the note? When in a tuplet, do a chord in the tuplet or the nex not in the tuplet.
            if ( _tupPla &&!appendToChord ) {
                  _tupPla = _tup->nextTimed( _tupPla );
            }

            if ( _tupPla ) {
                  // next note in tuplet
                  if (note) {
                        _tupPla = voice->insertInTupletAndVoiceAt( _tupPla, note );
                        _tup = _tupPla->tuplet();
                  }
            } else if ( _mw->uiTupletType->isChecked() ) {
                  // start a new tuplet
                  QList<CAPlayable*> elements;
                  if (note) {
                        elements << static_cast<CAPlayable*>(note);
                  } else
                        elements << static_cast<CAPlayable*>(rest);
                  for (int i=1; i<_mw->uiTupletNumber->value(); i++) {
                        _mw->musElementFactory()->configureRest( voice, 0 );
                        elements << static_cast<CAPlayable*>(_mw->musElementFactory()->musElement());
                  }
                  _tup = new CATuplet( _mw->uiTupletNumber->value(), _mw->uiTupletActualNumber->value(), elements );
                  _tupPla = _tup->firstNote();
            } else {
                  // insert just a note
                  if (note) {

                        //voice->append( note, appendToChord );
                        if (appendToChord && _noteLayout.size()) {
                              CANote *prevNote = 0;
                              for (i=0;i<_noteLayout.size();i++) {
                                    note = new CANote( nonenharmonicPitch, static_cast<CAPlayable*>(_noteLayout[i])->playableLength(), voice, -1 );
                                    voice->insert( _noteLayout[i], note, appendToChord );
                                    if (i>0) {
                                          _mw->musElementFactory()->configureSlur( staff, prevNote, note );
                                    }
                                    prevNote = note;
                              }
                        } else {
                              if (note) {
                                    delete note;
                              }

                              CAMusElement *elt = voice->lastMusElement();
                              CABarline *b = static_cast<CABarline*>( voice->previousByType( CAMusElement::Barline,
                                                                                    voice->lastMusElement()));
                              //CABarline *b = static_cast<CABarline*>(
                              //    voice->lastPlayableElt()->voice()->previousByType( CAMusElement::Barline, voice->lastMusElement() ));
                              CATimeSignature *ts = static_cast<CATimeSignature*>(
                                    voice->previousByType( CAMusElement::TimeSignature, voice->lastPlayableElt() ));
                              QList<CAPlayableLength> lll;
                              CAPlayableLength px;
                              lll << px.matchToBars( _mw->musElementFactory()->playableLength(), voice->lastTimeEnd(), b, ts );
                              CANote *prevNote = 0;
                              _noteLayout.clear();
                              for (i=0;i<lll.size();i++) {
                                    
                                    note = new CANote( nonenharmonicPitch, lll[i], voice, -1 );
                                    voice->append( note, appendToChord );
                                    _noteLayout.append( voice->lastMusElement());
                                    std::cout<<" -- "<<lll[i].musicLength()<<"."<<lll[i].dotted();
                                    _mw->musElementFactory()->placeAutoBar( note );
                                    if (i>0) {
                                          _mw->musElementFactory()->configureSlur( staff, prevNote, note );
                                    }
                                    prevNote = note;
                              }
                        std::cout<<" -- "<<std::endl;
                        }

                  } else {
                        delete rest;
                        CABarline *b = static_cast<CABarline*>( voice->previousByType( CAMusElement::Barline,
                                                      voice->lastMusElement()));
                        CATimeSignature *ts = static_cast<CATimeSignature*>(
                                                      voice->previousByType( CAMusElement::TimeSignature, voice->lastPlayableElt() ));
                        CAPlayableLength pr;
                        QList<CAPlayableLength> rests;
                        rests << pr.matchToBars( _mw->musElementFactory()->playableLength(), voice->lastTimeEnd(), b, ts );
                        for (i=0;i<rests.size();i++) {
                              rest = new CARest( CARest::Normal, rests[i], voice, 0, -1 );
                              voice->append( rest, false );
                        }
                  }
            }

            // We make shure not to try to place a barline inside a chord or inside a tuplet
            if ( CACanorus::settings()->autoBar() && !appendToChord && (!_tupPla || _tupPla->isFirstInTuplet())) {
                  if (note)
                        _mw->musElementFactory()->placeAutoBar( note );
                  else
                        _mw->musElementFactory()->placeAutoBar( rest );
            }

            voice->synchronizeMusElements();    // probably not needed

            CACanorus::undo()->pushUndoCommand();

            // now we try to highlight the inserted note/chord by selection:
            if (!appendToChord) {
                  v->clearSelection();    // remove old note/chord from selection
            }
            QList<CAPlayable*> lp = voice->getChord(voice->lastMusElement()->timeStart());
            QList<CAMusElement*> lme;
            for (int i=0;i<lp.size();i++) lme << static_cast<CAMusElement*>(lp[i]);
            _mw->currentScoreViewPort()->addToSelection(lme);

            // When I looking the last appended note is note showing up. Where goes it missing?
            // Still without a clue. georg
            // QList<CADrawableMusElement*> list = v->selection();
            // std::cout << " Selektierte Elemente: " << list.size() << " Stück, oben "<<lp.size()<<" und "<<lme.size() << std::endl;

            // scene tracking
            QRect scene = v->worldCoords();
            int xlast = v->timeToCoordsSimpleVersion( voice->lastTimeStart() );
            if ( ((xlast+50) > scene.right()) ) {     // the magic number 50 should be defined, ist the width of an element
                  scene.translate( scene.width()/2, 0 );
                  v->setWorldCoords(scene, false, true );
            }
            v->updateHelpers();
            v->repaint();
            CACanorus::rebuildUI(_mw->document(), _mw->currentSheet());

            // start timer eventually for chord detection
            if ( !_midiInChordTimer.isActive() ) {
                  _midiInChordTimer.start( 100 );           // Notes max 100 ms apart will form a chord
            }
      }
}


Generated by  Doxygen 1.6.0   Back to index