LMMS
Loading...
Searching...
No Matches
juce_MidiKeyboardState.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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
30
31//==============================================================================
33{
34 const ScopedLock sl (lock);
36 eventsToAdd.clear();
37}
38
39bool MidiKeyboardState::isNoteOn (const int midiChannel, const int n) const noexcept
40{
41 jassert (midiChannel > 0 && midiChannel <= 16);
42
43 return isPositiveAndBelow (n, 128)
44 && (noteStates[n] & (1 << (midiChannel - 1))) != 0;
45}
46
47bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const noexcept
48{
49 return isPositiveAndBelow (n, 128)
50 && (noteStates[n] & midiChannelMask) != 0;
51}
52
53void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity)
54{
55 jassert (midiChannel > 0 && midiChannel <= 16);
56 jassert (isPositiveAndBelow (midiNoteNumber, 128));
57
58 const ScopedLock sl (lock);
59
60 if (isPositiveAndBelow (midiNoteNumber, 128))
61 {
62 const int timeNow = (int) Time::getMillisecondCounter();
63 eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow);
64 eventsToAdd.clear (0, timeNow - 500);
65
66 noteOnInternal (midiChannel, midiNoteNumber, velocity);
67 }
68}
69
70void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity)
71{
72 if (isPositiveAndBelow (midiNoteNumber, 128))
73 {
74 noteStates[midiNoteNumber] = static_cast<uint16> (noteStates[midiNoteNumber] | (1 << (midiChannel - 1)));
75 listeners.call ([&] (Listener& l) { l.handleNoteOn (this, midiChannel, midiNoteNumber, velocity); });
76 }
77}
78
79void MidiKeyboardState::noteOff (const int midiChannel, const int midiNoteNumber, const float velocity)
80{
81 const ScopedLock sl (lock);
82
83 if (isNoteOn (midiChannel, midiNoteNumber))
84 {
85 const int timeNow = (int) Time::getMillisecondCounter();
86 eventsToAdd.addEvent (MidiMessage::noteOff (midiChannel, midiNoteNumber), timeNow);
87 eventsToAdd.clear (0, timeNow - 500);
88
89 noteOffInternal (midiChannel, midiNoteNumber, velocity);
90 }
91}
92
93void MidiKeyboardState::noteOffInternal (const int midiChannel, const int midiNoteNumber, const float velocity)
94{
95 if (isNoteOn (midiChannel, midiNoteNumber))
96 {
97 noteStates[midiNoteNumber] = static_cast<uint16> (noteStates[midiNoteNumber] & ~(1 << (midiChannel - 1)));
98 listeners.call ([&] (Listener& l) { l.handleNoteOff (this, midiChannel, midiNoteNumber, velocity); });
99 }
100}
101
102void MidiKeyboardState::allNotesOff (const int midiChannel)
103{
104 const ScopedLock sl (lock);
105
106 if (midiChannel <= 0)
107 {
108 for (int i = 1; i <= 16; ++i)
109 allNotesOff (i);
110 }
111 else
112 {
113 for (int i = 0; i < 128; ++i)
114 noteOff (midiChannel, i, 0.0f);
115 }
116}
117
119{
120 if (message.isNoteOn())
121 {
122 noteOnInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity());
123 }
124 else if (message.isNoteOff())
125 {
126 noteOffInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity());
127 }
128 else if (message.isAllNotesOff())
129 {
130 for (int i = 0; i < 128; ++i)
131 noteOffInternal (message.getChannel(), i, 0.0f);
132 }
133}
134
136 const int startSample,
137 const int numSamples,
138 const bool injectIndirectEvents)
139{
140 const ScopedLock sl (lock);
141
142 for (const auto metadata : buffer)
143 processNextMidiEvent (metadata.getMessage());
144
145 if (injectIndirectEvents)
146 {
147 const int firstEventToAdd = eventsToAdd.getFirstEventTime();
148 const double scaleFactor = numSamples / (double) (eventsToAdd.getLastEventTime() + 1 - firstEventToAdd);
149
150 for (const auto metadata : eventsToAdd)
151 {
152 const auto pos = jlimit (0, numSamples - 1, roundToInt ((metadata.samplePosition - firstEventToAdd) * scaleFactor));
153 buffer.addEvent (metadata.getMessage(), startSample + pos);
154 }
155 }
156
157 eventsToAdd.clear();
158}
159
160//==============================================================================
162{
163 const ScopedLock sl (lock);
164 listeners.add (listener);
165}
166
168{
169 const ScopedLock sl (lock);
170 listeners.remove (listener);
171}
172
173} // namespace juce
static void message(int level, const char *fmt,...)
Definition adplugdb.cpp:120
Definition juce_MidiBuffer.h:145
Definition juce_MidiKeyboardState.h:139
void processNextMidiBuffer(MidiBuffer &buffer, int startSample, int numSamples, bool injectIndirectEvents)
Definition juce_MidiKeyboardState.cpp:135
MidiBuffer eventsToAdd
Definition juce_MidiKeyboardState.h:184
void addListener(Listener *listener)
Definition juce_MidiKeyboardState.cpp:161
void noteOff(int midiChannel, int midiNoteNumber, float velocity)
Definition juce_MidiKeyboardState.cpp:79
void allNotesOff(int midiChannel)
Definition juce_MidiKeyboardState.cpp:102
void processNextMidiEvent(const MidiMessage &message)
Definition juce_MidiKeyboardState.cpp:118
void removeListener(Listener *listener)
Definition juce_MidiKeyboardState.cpp:167
CriticalSection lock
Definition juce_MidiKeyboardState.h:182
bool isNoteOn(int midiChannel, int midiNoteNumber) const noexcept
Definition juce_MidiKeyboardState.cpp:39
void noteOnInternal(int midiChannel, int midiNoteNumber, float velocity)
Definition juce_MidiKeyboardState.cpp:70
void noteOffInternal(int midiChannel, int midiNoteNumber, float velocity)
Definition juce_MidiKeyboardState.cpp:93
ListenerList< Listener > listeners
Definition juce_MidiKeyboardState.h:185
MidiKeyboardState()
Definition juce_MidiKeyboardState.cpp:26
void noteOn(int midiChannel, int midiNoteNumber, float velocity)
Definition juce_MidiKeyboardState.cpp:53
std::atomic< uint16 > noteStates[128]
Definition juce_MidiKeyboardState.h:183
void reset()
Definition juce_MidiKeyboardState.cpp:32
bool isNoteOnForChannels(int midiChannelMask, int midiNoteNumber) const noexcept
Definition juce_MidiKeyboardState.cpp:47
Definition juce_MidiMessage.h:35
static MidiMessage noteOn(int channel, int noteNumber, float velocity) noexcept
Definition juce_MidiMessage.cpp:604
static MidiMessage noteOff(int channel, int noteNumber, float velocity) noexcept
Definition juce_MidiMessage.cpp:618
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
int * l
Definition inflate.c:1579
register unsigned i
Definition inflate.c:1575
#define jassert(expression)
Definition carla_juce.cpp:31
void zerostruct(Type &structure) noexcept
Definition juce_Memory.h:32
CriticalSection::ScopedLockType ScopedLock
Definition juce_CriticalSection.h:186
unsigned short uint16
Definition juce_MathsFunctions.h:41
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Definition juce_MathsFunctions.h:262
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Definition juce_MathsFunctions.h:279
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
int n
Definition crypt.c:458
typedef int(UZ_EXP MsgFn)()