To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / CollidoscopeApp / src / MIDI.cpp @ 4:ab6db404403a

History | View | Annotate | Download (3.47 KB)

1
#include "MIDI.h"
2
#include "Config.h"
3

    
4

    
5
collidoscope::MIDI::MIDI()
6
{
7
}
8

    
9

    
10
collidoscope::MIDI::~MIDI()
11
{
12
    // FIXME check cause destructor of RTInput might throw 
13
    for ( auto & input : mInputs )
14
        input->closePort();
15
}
16

    
17
void collidoscope::MIDI::RtMidiInCallback( double deltatime, std::vector<unsigned char> *message, void *userData )
18
{
19
    collidoscope::MIDI* midi = ((collidoscope::MIDI*)userData);
20
    std::lock_guard< std::mutex > lock( midi->mMutex );
21

    
22
    MIDIMessage msg = midi->parseRtMidiMessage( message );
23

    
24
    switch ( msg.getVoice() ){
25
    case MIDIMessage::Voice::ePitchBend:
26
        midi->mPitchBendMessages[msg.getChannel()] = msg;
27
        break;
28

    
29
    case MIDIMessage::Voice::eControlChange:
30
        if ( msg.getChannel() == 7 ) // FIXME no harcoded 
31
            midi->mFilterMessages[msg.getChannel()] = msg;
32
        else
33
            midi->mMIDIMessages.push_back( msg );
34
        break;
35

    
36
    default:
37
        midi->mMIDIMessages.push_back( msg );
38
        break;
39
    }
40
}
41

    
42
void collidoscope::MIDI::setup( const Config& config )
43
{
44
    unsigned int numPorts = 0; 
45

    
46
    try {
47
        RtMidiIn in;
48
        numPorts = in.getPortCount();
49
    }
50
    catch ( RtMidiError &error ) {
51
        throw MIDIException( error.getMessage() );
52
    }
53

    
54
    if ( numPorts == 0 ){
55
        throw MIDIException(" no MIDI input found ");
56
    }
57

    
58
    for ( unsigned int portNum = 0; portNum < numPorts; portNum++ ) {
59
        try {
60
            std::unique_ptr< RtMidiIn > input ( new RtMidiIn() );
61
            input->openPort( portNum, "Collidoscope Input" );
62
            input->setCallback( &RtMidiInCallback, this );
63
            mInputs.push_back( std::move(input) );
64

    
65
        }
66
        catch ( RtMidiError &error ) {
67
            throw MIDIException( error.getMessage() );
68
        }
69
    }
70
}
71

    
72

    
73
void collidoscope::MIDI::checkMessages( std::vector<MIDIMessage> & midiMessages )
74
{
75
    std::lock_guard<std::mutex> lock( mMutex );
76
    midiMessages.swap( mMIDIMessages );
77
    
78
    for ( int i = 0; i < NUM_WAVES; i++ ){
79
        if ( mPitchBendMessages[i].mVoice != MIDIMessage::Voice::eIgnore ){
80
            midiMessages.push_back( mPitchBendMessages[i] );
81
            mPitchBendMessages[i].mVoice = MIDIMessage::Voice::eIgnore;
82
        }
83

    
84
        if ( mFilterMessages[i].mVoice != MIDIMessage::Voice::eIgnore ){
85
            midiMessages.push_back( mFilterMessages[i] );
86
            mFilterMessages[i].mVoice = MIDIMessage::Voice::eIgnore;
87
        }
88
    }
89
}
90

    
91
// only call this function when the size of mRtMidiMessage != 0
92
collidoscope::MIDIMessage collidoscope::MIDI::parseRtMidiMessage( std::vector<unsigned char> *rtMidiMessage )
93
{
94
    collidoscope::MIDIMessage msg;
95

    
96
    size_t numBytes = rtMidiMessage->size();
97
    
98
    // voice is the 4 most significant bits
99
    unsigned char voice = (*rtMidiMessage)[0] >> 4;
100

    
101
    switch ( voice ){
102
    case 0x9 :
103
        msg.mVoice = MIDIMessage::Voice::eNoteOn;
104
        break;
105

    
106
    case 0x8:
107
        msg.mVoice = MIDIMessage::Voice::eNoteOff;
108
        break;
109

    
110
    case 0xB:
111
        msg.mVoice = MIDIMessage::Voice::eControlChange;
112
        break;
113

    
114
    case 0xE:
115
        msg.mVoice = MIDIMessage::Voice::ePitchBend;
116
        break;
117

    
118
    default:
119
        msg.mVoice = MIDIMessage::Voice::eIgnore;
120
        return msg;
121
    }
122

    
123
    // channel is 4 less significant bits
124
    unsigned char channel = (*rtMidiMessage)[0] & 0x0f;
125
    msg.mChannel = channel;
126
    
127
    //data byte 1
128
    msg.mData1 = (*rtMidiMessage)[1];
129

    
130
    // data byte 2 if it exists 
131
    msg.mData2 = (numBytes == 3 ? (*rtMidiMessage)[2] : 0);
132

    
133
    return msg;
134
}