OpenShot Audio Library | OpenShotAudio 0.3.2

Loading...
Searching...
No Matches
juce_MidiKeyboardState.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26MidiKeyboardState::MidiKeyboardState()
27{
28 zerostruct (noteStates);
29}
30
31MidiKeyboardState::~MidiKeyboardState()
32{
33}
34
35//==============================================================================
36 void MidiKeyboardState::reset()
37{
38 const ScopedLock sl (lock);
39 zerostruct (noteStates);
40 eventsToAdd.clear();
41}
42
43 bool MidiKeyboardState::isNoteOn (const int midiChannel, const int n) const noexcept
44{
45 jassert (midiChannel >= 0 && midiChannel <= 16);
46
47 return isPositiveAndBelow (n, 128)
48 && (noteStates[n] & (1 << (midiChannel - 1))) != 0;
49}
50
51 bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const noexcept
52{
53 return isPositiveAndBelow (n, 128)
54 && (noteStates[n] & midiChannelMask) != 0;
55}
56
57 void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity)
58{
59 jassert (midiChannel >= 0 && midiChannel <= 16);
60 jassert (isPositiveAndBelow (midiNoteNumber, 128));
61
62 const ScopedLock sl (lock);
63
64 if (isPositiveAndBelow (midiNoteNumber, 128))
65 {
66 const int timeNow = (int) Time::getMillisecondCounter();
67 eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow);
68 eventsToAdd.clear (0, timeNow - 500);
69
70 noteOnInternal (midiChannel, midiNoteNumber, velocity);
71 }
72}
73
74 void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity)
75{
76 if (isPositiveAndBelow (midiNoteNumber, 128))
77 {
78 noteStates [midiNoteNumber] |= (1 << (midiChannel - 1));
79
80 for (int i = listeners.size(); --i >= 0;)
81 listeners.getUnchecked(i)->handleNoteOn (this, midiChannel, midiNoteNumber, velocity);
82 }
83}
84
85 void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber, const float velocity)
86{
87 const ScopedLock sl (lock);
88
89 if (isNoteOn (midiChannel, midiNoteNumber))
90 {
91 const int timeNow = (int) Time::getMillisecondCounter();
92 eventsToAdd.addEvent (MidiMessage::noteOff (midiChannel, midiNoteNumber), timeNow);
93 eventsToAdd.clear (0, timeNow - 500);
94
95 noteOffInternal (midiChannel, midiNoteNumber, velocity);
96 }
97}
98
99 void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiNoteNumber, const float velocity)
100{
101 if (isNoteOn (midiChannel, midiNoteNumber))
102 {
103 noteStates [midiNoteNumber] &= ~(1 << (midiChannel - 1));
104
105 for (int i = listeners.size(); --i >= 0;)
106 listeners.getUnchecked(i)->handleNoteOff (this, midiChannel, midiNoteNumber, velocity);
107 }
108}
109
110 void MidiKeyboardState::allNotesOff (const int midiChannel)
111{
112 const ScopedLock sl (lock);
113
114 if (midiChannel <= 0)
115 {
116 for (int i = 1; i <= 16; ++i)
117 allNotesOff (i);
118 }
119 else
120 {
121 for (int i = 0; i < 128; ++i)
122 noteOff (midiChannel, i, 0.0f);
123 }
124}
125
126 void MidiKeyboardState::processNextMidiEvent (const MidiMessage& message)
127{
128 if (message.isNoteOn())
129 {
130 noteOnInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity());
131 }
132 else if (message.isNoteOff())
133 {
134 noteOffInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity());
135 }
136 else if (message.isAllNotesOff())
137 {
138 for (int i = 0; i < 128; ++i)
139 noteOffInternal (message.getChannel(), i, 0.0f);
140 }
141}
142
143 void MidiKeyboardState::processNextMidiBuffer (MidiBuffer& buffer,
144 const int startSample,
145 const int numSamples,
146 const bool injectIndirectEvents)
147{
148 MidiBuffer::Iterator i (buffer);
149 MidiMessage message;
150 int time;
151
152 const ScopedLock sl (lock);
153
154 while (i.getNextEvent (message, time))
155 processNextMidiEvent (message);
156
157 if (injectIndirectEvents)
158 {
159 MidiBuffer::Iterator i2 (eventsToAdd);
160 const int firstEventToAdd = eventsToAdd.getFirstEventTime();
161 const double scaleFactor = numSamples / (double) (eventsToAdd.getLastEventTime() + 1 - firstEventToAdd);
162
163 while (i2.getNextEvent (message, time))
164 {
165 const int pos = jlimit (0, numSamples - 1, roundToInt ((time - firstEventToAdd) * scaleFactor));
166 buffer.addEvent (message, startSample + pos);
167 }
168 }
169
170 eventsToAdd.clear();
171}
172
173//==============================================================================
174 void MidiKeyboardState::addListener (MidiKeyboardStateListener* const listener)
175{
176 const ScopedLock sl (lock);
177 listeners.addIfNotAlreadyThere (listener);
178}
179
180 void MidiKeyboardState::removeListener (MidiKeyboardStateListener* const listener)
181{
182 const ScopedLock sl (lock);
183 listeners.removeFirstMatchingValue (listener);
184}
185
186} // namespace juce
juce::GenericScopedLock
Definition: juce_ScopedLock.h:55
juce::MidiBuffer::Iterator
Definition: juce_MidiBuffer.h:171
juce::MidiBuffer::Iterator::getNextEvent
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
Definition: juce_MidiBuffer.cpp:219
juce::MidiBuffer
Definition: juce_MidiBuffer.h:43
juce::MidiBuffer::getFirstEventTime
int getFirstEventTime() const noexcept
Definition: juce_MidiBuffer.cpp:165
juce::MidiBuffer::addEvent
void addEvent(const MidiMessage &midiMessage, int sampleNumber)
Definition: juce_MidiBuffer.cpp:113
juce::MidiBuffer::getLastEventTime
int getLastEventTime() const noexcept
Definition: juce_MidiBuffer.cpp:170
juce::MidiBuffer::clear
void clear() noexcept
Definition: juce_MidiBuffer.cpp:101
juce::MidiKeyboardStateListener
Definition: juce_MidiKeyboardState.h:38
juce::MidiKeyboardState::processNextMidiBuffer
void processNextMidiBuffer(MidiBuffer &buffer, int startSample, int numSamples, bool injectIndirectEvents)
Definition: juce_MidiKeyboardState.cpp:143
juce::MidiKeyboardState::noteOff
void noteOff(int midiChannel, int midiNoteNumber, float velocity)
Definition: juce_MidiKeyboardState.cpp:85
juce::MidiKeyboardState::allNotesOff
void allNotesOff(int midiChannel)
Definition: juce_MidiKeyboardState.cpp:110
juce::MidiKeyboardState::processNextMidiEvent
void processNextMidiEvent(const MidiMessage &message)
Definition: juce_MidiKeyboardState.cpp:126
juce::MidiKeyboardState::addListener
void addListener(MidiKeyboardStateListener *listener)
Definition: juce_MidiKeyboardState.cpp:174
juce::MidiKeyboardState::isNoteOn
bool isNoteOn(int midiChannel, int midiNoteNumber) const noexcept
Definition: juce_MidiKeyboardState.cpp:43
juce::MidiKeyboardState::noteOn
void noteOn(int midiChannel, int midiNoteNumber, float velocity)
Definition: juce_MidiKeyboardState.cpp:57
juce::MidiKeyboardState::reset
void reset()
Definition: juce_MidiKeyboardState.cpp:36
juce::MidiKeyboardState::isNoteOnForChannels
bool isNoteOnForChannels(int midiChannelMask, int midiNoteNumber) const noexcept
Definition: juce_MidiKeyboardState.cpp:51
juce::MidiKeyboardState::removeListener
void removeListener(MidiKeyboardStateListener *listener)
Definition: juce_MidiKeyboardState.cpp:180
juce::MidiMessage
Definition: juce_MidiMessage.h:35
juce::MidiMessage::isNoteOn
bool isNoteOn(bool returnTrueForVelocity0=false) const noexcept
Definition: juce_MidiMessage.cpp:390
juce::MidiMessage::getFloatVelocity
float getFloatVelocity() const noexcept
Definition: juce_MidiMessage.cpp:431
juce::MidiMessage::getChannel
int getChannel() const noexcept
Definition: juce_MidiMessage.cpp:359
juce::MidiMessage::isNoteOff
bool isNoteOff(bool returnTrueForNoteOnVelocity0=true) const noexcept
Definition: juce_MidiMessage.cpp:398
juce::MidiMessage::noteOn
static MidiMessage noteOn(int channel, int noteNumber, float velocity) noexcept
Definition: juce_MidiMessage.cpp:584
juce::MidiMessage::getNoteNumber
int getNoteNumber() const noexcept
Definition: juce_MidiMessage.cpp:412
juce::MidiMessage::isAllNotesOff
bool isAllNotesOff() const noexcept
Definition: juce_MidiMessage.cpp:616
juce::MidiMessage::noteOff
static MidiMessage noteOff(int channel, int noteNumber, float velocity) noexcept
Definition: juce_MidiMessage.cpp:598
juce::Time::getMillisecondCounter
static uint32 getMillisecondCounter() noexcept
Definition: juce_Time.cpp:226