Exemple #1
0
void CTrackList::refresh()
{
    int chan;
    int rowCount = 0;
    m_trackQtList.clear();

    for (chan = 0; chan < MAX_MIDI_CHANNELS; chan++)
    {
        if (m_midiActiveChannels[chan] == true)
        {
           CTrackListItem trackItem;
            trackItem.midiChannel =  chan;
            m_trackQtList.append(trackItem);
            rowCount++;
        }
    }
    if (pianoPartConvetionTest())
    {
        if (CNote::bothHandsChan() == -2 ) // -2 for not set -1 for not used
            CNote::setChannelHands(CONVENTION_LEFT_HAND_CHANNEL, CONVENTION_RIGHT_HAND_CHANNEL);
        m_song->setActiveChannel(CNote::bothHandsChan());
        ppLogInfo("Active both");
    }
    else
    {
        if (m_trackQtList.count() > 0)
        {
            m_song->setActiveChannel(m_trackQtList[0].midiChannel);
        }
    }

    if (CStavePos::getKeySignature() == NOT_USED)
        CStavePos::setKeySignature(guessKeySignature(CNote::rightHandChan(),CNote::leftHandChan()), 0);

    int goodChan = -1;
    // Find an unused channel that we can use for the keyboard
    for (chan = 0; chan < MAX_MIDI_CHANNELS; chan++)
    {
        if (m_midiActiveChannels[chan] == false)
        {
            if (goodChan != -1)
            {
                m_song->setPianistChannels(goodChan,chan);
                ppLogInfo("Using Pianist Channels %d + %d", goodChan +1, chan +1);
                return;
            }
            goodChan = chan;
        }
    }
    // As we have not returned we have not found to empty channels to use
    if (goodChan == -1)
        goodChan = 15 -1;
    m_song->setPianistChannels(goodChan,16-1);
}
Exemple #2
0
void CSong::loadSong(const QString & filename)
{
    CNote::setChannelHands(-2, -2);  // -2 for not set -1 for none

    m_songTitle = filename;
    int index = m_songTitle.lastIndexOf("/");
    if (index >= 0)
        m_songTitle = m_songTitle.right( m_songTitle.length() - index - 1);

    QString fn = filename;
#ifdef _WIN32
     fn = fn.replace('/','\\');
#endif
    m_midiFile->setLogLevel(3);
    m_midiFile->openMidiFile(string(fn.toLatin1()));
    ppLogInfo("Opening song %s",  string(fn.toLatin1()).c_str());
    transpose(0);
    midiFileInfo();
    m_midiFile->setLogLevel(99);
    playMusic(false);
    rewind();
    setPlayFromBar(0.0);
    setLoopingBars(0.0);
    setEventBits(EVENT_BITS_playingStopped);
    if (!m_midiFile->getSongTitle().isEmpty())
        m_songTitle = m_midiFile->getSongTitle();

}
// reads the real midi event
CMidiEvent CMidiDeviceRt::readMidiInput()
{
    CMidiEvent midiEvent;
    unsigned int channel;


    if (Cfg::midiInputDump)
    {
        QString str;

        for (unsigned int i = 0; i < m_inputMessage.size(); i++)
            str += " 0x" + QString::number(m_inputMessage[i], 16) + ',';
        ppLogInfo("midi input %s", qPrintable(str));
    }

    channel = m_inputMessage[0] & 0x0f;
    switch (m_inputMessage[0] & 0xf0 )
    {
    case MIDI_NOTE_ON:
        if (m_inputMessage[2] != 0 )
            midiEvent.noteOnEvent(0, channel, m_inputMessage[1], m_inputMessage[2]);
        else
            midiEvent.noteOffEvent(0,channel, m_inputMessage[1], m_inputMessage[2]);
        break;

    case MIDI_NOTE_OFF:
        midiEvent.noteOffEvent(0, channel, m_inputMessage[1], m_inputMessage[2]);
        break;

    case MIDI_NOTE_PRESSURE: //MIDI_CMD_NOTE_PRESSURE: //POLY_AFTERTOUCH:
        // fixme fill in the blanks
        //midi_input_bytes[midi_input_length++] = channel | MIDI_CMD_NOTE_PRESSURE;
        //midi_input_bytes[midi_input_length++] = ev->data.note.note;
        //midi_input_bytes[midi_input_length++] = ev->data.note.velocity;
        break;

    case MIDI_CONTROL_CHANGE:  //CONTROL_CHANGE:
        midiEvent.controlChangeEvent(0, channel, m_inputMessage[1], m_inputMessage[2]);
        break;

    case MIDI_PROGRAM_CHANGE: //PROGRAM_CHANGE:
        //midiEvent.programChangeEvent(0, ev->data.control.channel, ev->data.control.value);
        break;

    case MIDI_CHANNEL_PRESSURE: //AFTERTOUCH:
        // fixme fill in the blanks
        //midi_input_bytes[midi_input_length++] = ev->data.control.channel | MIDI_CMD_CHANNEL_PRESSURE;
        //midi_input_bytes[midi_input_length++] = ev->data.control.value;
        break;

    case MIDI_PITCH_BEND: //PITCH_BEND:
        // fixme fill in the blanks
        //midi_input_bytes[midi_input_length++] = ev->data.control.channel | MIDI_CMD_CHANNEL_PRESSURE;
        //midi_input_bytes[midi_input_length++] = ev->data.control.value;
        break;
    }

    m_inputMessage.clear();
    return midiEvent;
}
Exemple #4
0
void CConductor::realTimeEngine(int mSecTicks)
{
    int type;
    int ticks; // Midi ticks

    //mSecTicks = 2; // for debugging only

    ticks = m_tempo.mSecToTicks(mSecTicks);

    if (!m_followPlayingTimeOut)
        m_pianistTiming += ticks;

    while (checkMidiInput() > 0)
        expandPianistInput(readMidiInput());

    if (getfollowState() == PB_FOLLOW_waiting )
    {
        if (m_silenceTimeOut > 0)
        {
            m_silenceTimeOut -= mSecTicks;
            if (m_silenceTimeOut <= 0)
            {
                allSoundOff();
                m_silenceTimeOut = 0;
            }
        }

        m_tempo.insertPlayingTicks(ticks);


        if (m_pianistTiming > m_cfg_playZoneLate)
        {
            if (m_followPlayingTimeOut == false)
            {
                m_followPlayingTimeOut = true;

                m_tempo.clearPlayingTicks();
                m_rating.lateNotes(m_wantedChord.length() - m_goodPlayedNotes.length());
                setEventBits( EVENT_BITS_forceRatingRedraw);

                missedNotesColour(Cfg::playedStoppedColour());
                findImminentNotesOff();
                // Don't keep any saved notes off if there are no notes down
                if (m_piano->pianistAllNotesDown() == 0)
                    outputSavedNotesOff();
                m_silenceTimeOut = Cfg::silenceTimeOut();
            }
        }
        return;
    }

    m_silenceTimeOut = 0;
    if (m_playing == false)
        return;

    if (seekingBarNumber())
        ticks = 0;

    m_tempo.adjustTempo(&ticks);


    ticks = m_bar.addDeltaTime(ticks);

    if (seekingBarNumber())
        ticks = m_bar.goToBarNumer();

    setEventBits( m_bar.readEventBits());

#if OPTION_DEBUG_CONDUCTOR
    if (m_realTimeEventBits | EVENT_BITS_newBarNumber)
    {
        ppDEBUG_CONDUCTOR(("m_savedNoteQueue %d m_playingDeltaTime %d",m_savedNoteQueue->space() , m_playingDeltaTime ));
        ppDEBUG_CONDUCTOR(("getfollowState() %d  %d %d",getfollowState() , m_leadLagAdjust, m_songEventQueue->length() ));
    }
#endif

    addDeltaTime(ticks);

    followPlaying();
    while ( m_playingDeltaTime >= m_leadLagAdjust)
    {
        type = m_nextMidiEvent.type();

        if (m_songEventQueue->length() == 0 && type == MIDI_PB_EOF)
        {
            ppLogInfo("The End of the song");
            setEventBits(EVENT_BITS_playingStopped);
            m_playing = false;
            break;
        }

        if (type == MIDI_PB_tempo)
        {
            m_tempo.setMidiTempo(m_nextMidiEvent.data1());
            m_leadLagAdjust = m_tempo.mSecToTicks( -getLatencyFix() );
        }
        else if (type == MIDI_PB_timeSignature)
        {
            m_bar.setTimeSig(m_nextMidiEvent.data1(), m_nextMidiEvent.data2());
            ppLogDebug("Midi Time Signature %d/%d", m_nextMidiEvent.data1(),m_nextMidiEvent.data2());

        }
        else if ( type != MIDI_NONE )   // this marks the end of the piece of music
        {
            int channel = m_nextMidiEvent.channel();

            // Is this this channel_muted
            if (!hasPianistKeyboardChannel(channel))
            {
                if (getfollowState() >= PB_FOLLOW_earlyNotes &&
                        (m_playMode == PB_PLAY_MODE_followYou || m_playMode == PB_PLAY_MODE_rhythmTapping) &&
                        !seekingBarNumber() &&
                        m_followSkillAdvanced == false)
                {
                    // Save up the notes until the pianist presses the right key
                    if (m_savedNoteQueue->space()>0)
                        m_savedNoteQueue->push(m_nextMidiEvent);
                    else
                        ppLogWarn("Warning the m_savedNoteQueue is full");

                    if (type == MIDI_NOTE_OFF)
                    {
                        if (m_savedNoteOffQueue->space()>0)
                            m_savedNoteOffQueue->push(m_nextMidiEvent);
                        else
                            ppLogDebug("Warning the m_savedNoteOffQueue is full");
                    }
                }
                else
                {
                    playTransposeEvent(m_nextMidiEvent); // Play the midi note or event
                    ppDEBUG_CONDUCTOR(("playEvent() chan %d type %d note %d", m_nextMidiEvent.channel() , m_nextMidiEvent.type() , m_nextMidiEvent.note(), m_songEventQueue->length() ));
                }
            }
        }
        if (m_songEventQueue->length() > 0)
            m_nextMidiEvent = m_songEventQueue->pop();
        else
        {
            ppDEBUG_CONDUCTOR(("no data in song queue"));
            m_nextMidiEvent.clear();
            break;
        }

        m_playingDeltaTime -= m_nextMidiEvent.deltaTime() * SPEED_ADJUST_FACTOR;
        followPlaying();
    }
}
QtWindow::QtWindow()
{
    QCoreApplication::setOrganizationName("Instrument-Trainer");
    QCoreApplication::setOrganizationDomain("github.com/joshelser/Instrument-Trainer");
    QCoreApplication::setApplicationName("Instrument Trainer");
    m_settings = new CSettings(this);
    setWindowIcon(QIcon(":/images/Logo32x32.png"));
    setWindowTitle(tr("Instrument Trainer"));

    decodeCommandLine();

    if (Cfg::experimentalSwapInterval != -1)
    {
        QGLFormat fmt;
        fmt.setSwapInterval(Cfg::experimentalSwapInterval);
        int value = fmt.swapInterval();
        ppLogInfo("Open GL Swap Interval %d", value);
        QGLFormat::setDefaultFormat(fmt);
    }


#if USE_REALTIME_PRIORITY
    int rt_prio = sched_get_priority_max(SCHED_FIFO);
    set_realtime_priority(SCHED_FIFO, rt_prio);
#endif

    m_glWidget = new CGLView(this, m_settings);

    m_song = m_glWidget->getSongObject();
    m_score = m_glWidget->getScoreObject();


    QHBoxLayout *mainLayout = new QHBoxLayout;
    QVBoxLayout *columnLayout = new QVBoxLayout;

    m_sidePanel = new GuiSidePanel(this, m_settings);
    m_topBar = new GuiTopBar(this, m_settings);

    m_settings->init(m_song, m_sidePanel, m_topBar);

    mainLayout->addWidget(m_sidePanel);
    columnLayout->addWidget(m_topBar);
    columnLayout->addWidget(m_glWidget);
    mainLayout->addLayout(columnLayout);

    m_song->init(m_score, m_settings);
    m_glWidget->init();

    m_sidePanel->init(m_song, m_song->getTrackList(), m_topBar);
    m_topBar->init(m_song, m_song->getTrackList());
    createActions();
    createMenus();
    readSettings();

    QWidget *centralWin = new QWidget();
    centralWin->setLayout(mainLayout);

    setCentralWidget(centralWin);

    m_glWidget->setFocus(Qt::ActiveWindowFocusReason);

    m_song->setPianoSoundPatches(m_settings->value("Keyboard/RightSound", Cfg::defaultRightPatch()).toInt() - 1,
                                 m_settings->value("Keyboard/WrongSound", Cfg::defaultWrongPatch()).toInt() - 1, true);

    QString midiInputName = m_settings->value("Midi/Input").toString();
    if (midiInputName.startsWith("None"))
        CChord::setPianoRange(PC_KEY_LOWEST_NOTE, PC_KEY_HIGHEST_NOTE);
    else
        CChord::setPianoRange(m_settings->value("Keyboard/LowestNote", 0).toInt(),
                          m_settings->value("Keyboard/HighestNote", 127).toInt());

    m_song->setLatencyFix(m_settings->value("Midi/Latency", 0).toInt());


#ifdef _WIN32
    m_glWidget->m_cfg_openGlOptimise = true; // don't default to true on windows
#else
    m_glWidget->m_cfg_openGlOptimise = true; // changed to default to false on platforms
#endif

    m_glWidget->m_cfg_openGlOptimise = m_settings->value("Display/OpenGlOptimise", m_glWidget->m_cfg_openGlOptimise ).toBool();
    m_song->cfg_timingMarkersFlag = m_settings->value("Score/TimingMarkers", m_song->cfg_timingMarkersFlag ).toBool();
    m_song->cfg_stopPointMode = static_cast<stopPointMode_t> (m_settings->value("Score/StopPointMode", m_song->cfg_stopPointMode ).toInt());

    m_song->openMidiPort(CMidiDevice::MIDI_INPUT, midiInputName);
    m_song->openMidiPort(CMidiDevice::MIDI_OUTPUT,m_settings->value("midi/output").toString());

    m_settings->loadSettings();

    show();
}