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
23namespace juce
24{
25
26MidiKeyboardState::MidiKeyboardState()
27{
28 zerostruct (noteStates);
29}
30
31MidiKeyboardState::~MidiKeyboardState()
32{
33}
34
35//==============================================================================
37{
38 const ScopedLock sl (lock);
39 zerostruct (noteStates);
40 eventsToAdd.clear();
41}
42
43bool 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
51bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const noexcept
52{
53 return isPositiveAndBelow (n, 128)
54 && (noteStates[n] & midiChannelMask) != 0;
55}
56
57void 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 {
67 eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow);
68 eventsToAdd.clear (0, timeNow - 500);
69
70 noteOnInternal (midiChannel, midiNoteNumber, velocity);
71 }
72}
73
74void 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
85void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber, const float velocity)
86{
87 const ScopedLock sl (lock);
88
89 if (isNoteOn (midiChannel, midiNoteNumber))
90 {
92 eventsToAdd.addEvent (MidiMessage::noteOff (midiChannel, midiNoteNumber), timeNow);
93 eventsToAdd.clear (0, timeNow - 500);
94
95 noteOffInternal (midiChannel, midiNoteNumber, velocity);
96 }
97}
98
99void 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
110void 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
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
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
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//==============================================================================
175{
176 const ScopedLock sl (lock);
177 listeners.addIfNotAlreadyThere (listener);
178}
179
181{
182 const ScopedLock sl (lock);
183 listeners.removeFirstMatchingValue (listener);
184}
185
186} // namespace juce
ElementType getUnchecked(int index) const
Definition juce_Array.h:252
int size() const noexcept
Definition juce_Array.h:215
void removeFirstMatchingValue(ParameterType valueToRemove)
Definition juce_Array.h:834
bool addIfNotAlreadyThere(ParameterType newElement)
Definition juce_Array.h:522
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
int getFirstEventTime() const noexcept
void addEvent(const MidiMessage &midiMessage, int sampleNumber)
int getLastEventTime() const noexcept
void clear() noexcept
void processNextMidiBuffer(MidiBuffer &buffer, int startSample, int numSamples, bool injectIndirectEvents)
void noteOff(int midiChannel, int midiNoteNumber, float velocity)
void allNotesOff(int midiChannel)
void processNextMidiEvent(const MidiMessage &message)
void addListener(MidiKeyboardStateListener *listener)
bool isNoteOn(int midiChannel, int midiNoteNumber) const noexcept
void noteOn(int midiChannel, int midiNoteNumber, float velocity)
bool isNoteOnForChannels(int midiChannelMask, int midiNoteNumber) const noexcept
void removeListener(MidiKeyboardStateListener *listener)
bool isNoteOn(bool returnTrueForVelocity0=false) const noexcept
float getFloatVelocity() const noexcept
int getChannel() const noexcept
bool isNoteOff(bool returnTrueForNoteOnVelocity0=true) const noexcept
static MidiMessage noteOn(int channel, int noteNumber, float velocity) noexcept
int getNoteNumber() const noexcept
bool isAllNotesOff() const noexcept
static MidiMessage noteOff(int channel, int noteNumber, float velocity) noexcept
static uint32 getMillisecondCounter() noexcept