OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_MPEMessages.cpp
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
23 namespace juce
24{
25
26 MidiBuffer MPEMessages::setLowerZone (int numMemberChannels, int perNotePitchbendRange, int masterPitchbendRange)
27{
28 auto buffer = MidiRPNGenerator::generate (1, zoneLayoutMessagesRpnNumber, numMemberChannels, false, false);
29
30 buffer.addEvents (setLowerZonePerNotePitchbendRange (perNotePitchbendRange), 0, -1, 0);
31 buffer.addEvents (setLowerZoneMasterPitchbendRange (masterPitchbendRange), 0, -1, 0);
32
33 return buffer;
34}
35
36 MidiBuffer MPEMessages::setUpperZone (int numMemberChannels, int perNotePitchbendRange, int masterPitchbendRange)
37{
38 auto buffer = MidiRPNGenerator::generate (16, zoneLayoutMessagesRpnNumber, numMemberChannels, false, false);
39
40 buffer.addEvents (setUpperZonePerNotePitchbendRange (perNotePitchbendRange), 0, -1, 0);
41 buffer.addEvents (setUpperZoneMasterPitchbendRange (masterPitchbendRange), 0, -1, 0);
42
43 return buffer;
44}
45
46 MidiBuffer MPEMessages::setLowerZonePerNotePitchbendRange (int perNotePitchbendRange)
47{
48 return MidiRPNGenerator::generate (2, 0, perNotePitchbendRange, false, false);
49}
50
51 MidiBuffer MPEMessages::setUpperZonePerNotePitchbendRange (int perNotePitchbendRange)
52{
53 return MidiRPNGenerator::generate (15, 0, perNotePitchbendRange, false, false);
54}
55
56 MidiBuffer MPEMessages::setLowerZoneMasterPitchbendRange (int masterPitchbendRange)
57{
58 return MidiRPNGenerator::generate (1, 0, masterPitchbendRange, false, false);
59}
60
61 MidiBuffer MPEMessages::setUpperZoneMasterPitchbendRange (int masterPitchbendRange)
62{
63 return MidiRPNGenerator::generate (16, 0, masterPitchbendRange, false, false);
64}
65
66 MidiBuffer MPEMessages::clearLowerZone()
67{
68 return MidiRPNGenerator::generate (1, zoneLayoutMessagesRpnNumber, 0, false, false);
69}
70
71 MidiBuffer MPEMessages::clearUpperZone()
72{
73 return MidiRPNGenerator::generate (16, zoneLayoutMessagesRpnNumber, 0, false, false);
74}
75
76 MidiBuffer MPEMessages::clearAllZones()
77{
78 MidiBuffer buffer;
79
80 buffer.addEvents (clearLowerZone(), 0, -1, 0);
81 buffer.addEvents (clearUpperZone(), 0, -1, 0);
82
83 return buffer;
84}
85
86 MidiBuffer MPEMessages::setZoneLayout (MPEZoneLayout layout)
87{
88 MidiBuffer buffer;
89
90 buffer.addEvents (clearAllZones(), 0, -1, 0);
91
92 auto lowerZone = layout.getLowerZone();
93 if (lowerZone.isActive())
94 buffer.addEvents (setLowerZone (lowerZone.numMemberChannels,
95 lowerZone.perNotePitchbendRange,
96 lowerZone.masterPitchbendRange),
97 0, -1, 0);
98
99 auto upperZone = layout.getUpperZone();
100 if (upperZone.isActive())
101 buffer.addEvents (setUpperZone (upperZone.numMemberChannels,
102 upperZone.perNotePitchbendRange,
103 upperZone.masterPitchbendRange),
104 0, -1, 0);
105
106 return buffer;
107}
108
109
110//==============================================================================
111//==============================================================================
112#if JUCE_UNIT_TESTS
113
114 class MPEMessagesTests final : public UnitTest
115{
116 public:
117 MPEMessagesTests()
118 : UnitTest ("MPEMessages class", UnitTestCategories::midi)
119 {}
120
121 void runTest() override
122 {
123 beginTest ("add zone");
124 {
125 {
126 MidiBuffer buffer = MPEMessages::setLowerZone (7);
127
128 const uint8 expectedBytes[] =
129 {
130 0xb0, 0x64, 0x06, 0xb0, 0x65, 0x00, 0xb0, 0x06, 0x07, // set up zone
131 0xb1, 0x64, 0x00, 0xb1, 0x65, 0x00, 0xb1, 0x06, 0x30, // per-note pbrange (default = 48)
132 0xb0, 0x64, 0x00, 0xb0, 0x65, 0x00, 0xb0, 0x06, 0x02 // master pbrange (default = 2)
133 };
134
135 testMidiBuffer (buffer, expectedBytes, sizeof (expectedBytes));
136 }
137 {
138 MidiBuffer buffer = MPEMessages::setUpperZone (5, 96, 0);
139
140 const uint8 expectedBytes[] =
141 {
142 0xbf, 0x64, 0x06, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x05, // set up zone
143 0xbe, 0x64, 0x00, 0xbe, 0x65, 0x00, 0xbe, 0x06, 0x60, // per-note pbrange (custom)
144 0xbf, 0x64, 0x00, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x00 // master pbrange (custom)
145 };
146
147 testMidiBuffer (buffer, expectedBytes, sizeof (expectedBytes));
148 }
149 }
150
151 beginTest ("set per-note pitchbend range");
152 {
153 MidiBuffer buffer = MPEMessages::setLowerZonePerNotePitchbendRange (96);
154
155 const uint8 expectedBytes[] = { 0xb1, 0x64, 0x00, 0xb1, 0x65, 0x00, 0xb1, 0x06, 0x60 };
156
157 testMidiBuffer (buffer, expectedBytes, sizeof (expectedBytes));
158 }
159
160
161 beginTest ("set master pitchbend range");
162 {
163 MidiBuffer buffer = MPEMessages::setUpperZoneMasterPitchbendRange (60);
164
165 const uint8 expectedBytes[] = { 0xbf, 0x64, 0x00, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x3c };
166
167 testMidiBuffer (buffer, expectedBytes, sizeof (expectedBytes));
168 }
169
170 beginTest ("clear all zones");
171 {
172 MidiBuffer buffer = MPEMessages::clearAllZones();
173
174 const uint8 expectedBytes[] = { 0xb0, 0x64, 0x06, 0xb0, 0x65, 0x00, 0xb0, 0x06, 0x00, // clear lower zone
175 0xbf, 0x64, 0x06, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x00 // clear upper zone
176 };
177
178 testMidiBuffer (buffer, expectedBytes, sizeof (expectedBytes));
179 }
180
181 beginTest ("set complete state");
182 {
183 MPEZoneLayout layout;
184
185 layout.setLowerZone (7, 96, 0);
186 layout.setUpperZone (7);
187
188 MidiBuffer buffer = MPEMessages::setZoneLayout (layout);
189
190 const uint8 expectedBytes[] = {
191 0xb0, 0x64, 0x06, 0xb0, 0x65, 0x00, 0xb0, 0x06, 0x00, // clear lower zone
192 0xbf, 0x64, 0x06, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x00, // clear upper zone
193 0xb0, 0x64, 0x06, 0xb0, 0x65, 0x00, 0xb0, 0x06, 0x07, // set lower zone
194 0xb1, 0x64, 0x00, 0xb1, 0x65, 0x00, 0xb1, 0x06, 0x60, // per-note pbrange (custom)
195 0xb0, 0x64, 0x00, 0xb0, 0x65, 0x00, 0xb0, 0x06, 0x00, // master pbrange (custom)
196 0xbf, 0x64, 0x06, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x07, // set upper zone
197 0xbe, 0x64, 0x00, 0xbe, 0x65, 0x00, 0xbe, 0x06, 0x30, // per-note pbrange (default = 48)
198 0xbf, 0x64, 0x00, 0xbf, 0x65, 0x00, 0xbf, 0x06, 0x02 // master pbrange (default = 2)
199 };
200
201 testMidiBuffer (buffer, expectedBytes, sizeof (expectedBytes));
202 }
203 }
204
205 private:
206 //==============================================================================
207 void testMidiBuffer (MidiBuffer& buffer, const uint8* expectedBytes, int expectedBytesSize)
208 {
209 uint8 actualBytes[128] = { 0 };
210 extractRawBinaryData (buffer, actualBytes, sizeof (actualBytes));
211
212 expectEquals (std::memcmp (actualBytes, expectedBytes, (std::size_t) expectedBytesSize), 0);
213 }
214
215 //==============================================================================
216 void extractRawBinaryData (const MidiBuffer& midiBuffer, const uint8* bufferToCopyTo, std::size_t maxBytes)
217 {
218 std::size_t pos = 0;
219
220 for (const auto metadata : midiBuffer)
221 {
222 const uint8* data = metadata.data;
223 std::size_t dataSize = (std::size_t) metadata.numBytes;
224
225 if (pos + dataSize > maxBytes)
226 return;
227
228 std::memcpy ((void*) (bufferToCopyTo + pos), data, dataSize);
229 pos += dataSize;
230 }
231 }
232};
233
234 static MPEMessagesTests MPEMessagesUnitTests;
235
236#endif
237
238} // namespace juce
juce::MPEMessages::setUpperZone
static MidiBuffer setUpperZone(int numMemberChannels=0, int perNotePitchbendRange=48, int masterPitchbendRange=2)
Definition juce_MPEMessages.cpp:36
juce::MPEMessages::setUpperZoneMasterPitchbendRange
static MidiBuffer setUpperZoneMasterPitchbendRange(int masterPitchbendRange=2)
Definition juce_MPEMessages.cpp:61
juce::MPEMessages::clearAllZones
static MidiBuffer clearAllZones()
Definition juce_MPEMessages.cpp:76
juce::MPEMessages::setZoneLayout
static MidiBuffer setZoneLayout(MPEZoneLayout layout)
Definition juce_MPEMessages.cpp:86
juce::MPEMessages::setLowerZone
static MidiBuffer setLowerZone(int numMemberChannels=0, int perNotePitchbendRange=48, int masterPitchbendRange=2)
Definition juce_MPEMessages.cpp:26
juce::MPEMessages::clearUpperZone
static MidiBuffer clearUpperZone()
Definition juce_MPEMessages.cpp:71
juce::MPEMessages::clearLowerZone
static MidiBuffer clearLowerZone()
Definition juce_MPEMessages.cpp:66
juce::MPEMessages::zoneLayoutMessagesRpnNumber
static const int zoneLayoutMessagesRpnNumber
Definition juce_MPEMessages.h:113
juce::MPEMessages::setLowerZoneMasterPitchbendRange
static MidiBuffer setLowerZoneMasterPitchbendRange(int masterPitchbendRange=2)
Definition juce_MPEMessages.cpp:56
juce::MPEMessages::setLowerZonePerNotePitchbendRange
static MidiBuffer setLowerZonePerNotePitchbendRange(int perNotePitchbendRange=48)
Definition juce_MPEMessages.cpp:46
juce::MPEMessages::setUpperZonePerNotePitchbendRange
static MidiBuffer setUpperZonePerNotePitchbendRange(int perNotePitchbendRange=48)
Definition juce_MPEMessages.cpp:51
juce::MPEZoneLayout
Definition juce_MPEZoneLayout.h:123
juce::MPEZoneLayout::getUpperZone
MPEZone getUpperZone() const noexcept
Definition juce_MPEZoneLayout.h:146
juce::MPEZoneLayout::getLowerZone
MPEZone getLowerZone() const noexcept
Definition juce_MPEZoneLayout.h:143
juce::MidiBuffer
Definition juce_MidiBuffer.h:145
juce::MidiBuffer::addEvents
void addEvents(const MidiBuffer &otherBuffer, int startSample, int numSamples, int sampleDeltaToAdd)
Definition juce_MidiBuffer.cpp:155
juce::MidiRPNGenerator::generate
static MidiBuffer generate(MidiRPNMessage message)
Definition juce_MidiRPN.cpp:114
juce::UnitTest
Definition juce_UnitTest.h:70