OpenShot Library | OpenShotAudio  0.2.1
juce_MPESynthesiserBase.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 
27  : instrument (new MPEInstrument)
28 {
29  instrument->addListener (this);
30 }
31 
33  : instrument (inst)
34 {
35  jassert (instrument != nullptr);
36  instrument->addListener (this);
37 }
38 
39 //==============================================================================
41 {
42  return instrument->getZoneLayout();
43 }
44 
46 {
47  instrument->setZoneLayout (newLayout);
48 }
49 
50 //==============================================================================
51 void MPESynthesiserBase::enableLegacyMode (int pitchbendRange, Range<int> channelRange)
52 {
53  instrument->enableLegacyMode (pitchbendRange, channelRange);
54 }
55 
57 {
58  return instrument->isLegacyModeEnabled();
59 }
60 
62 {
63  return instrument->getLegacyModeChannelRange();
64 }
65 
67 {
68  instrument->setLegacyModeChannelRange (channelRange);
69 }
70 
72 {
73  return instrument->getLegacyModePitchbendRange();
74 }
75 
77 {
78  instrument->setLegacyModePitchbendRange (pitchbendRange);
79 }
80 
81 //==============================================================================
83 {
84  instrument->setPressureTrackingMode (modeToUse);
85 }
86 
88 {
89  instrument->setPitchbendTrackingMode (modeToUse);
90 }
91 
93 {
94  instrument->setTimbreTrackingMode (modeToUse);
95 }
96 
97 //==============================================================================
99 {
100  instrument->processNextMidiEvent (m);
101 }
102 
103 //==============================================================================
104 template <typename floatType>
106  const MidiBuffer& inputMidi,
107  int startSample,
108  int numSamples)
109 {
110  // you must set the sample rate before using this!
111  jassert (sampleRate != 0);
112 
113  MidiBuffer::Iterator midiIterator (inputMidi);
114  midiIterator.setNextSamplePosition (startSample);
115 
116  bool firstEvent = true;
117  int midiEventPos;
118  MidiMessage m;
119 
120  const ScopedLock sl (noteStateLock);
121 
122  while (numSamples > 0)
123  {
124  if (! midiIterator.getNextEvent (m, midiEventPos))
125  {
126  renderNextSubBlock (outputAudio, startSample, numSamples);
127  return;
128  }
129 
130  auto samplesToNextMidiMessage = midiEventPos - startSample;
131 
132  if (samplesToNextMidiMessage >= numSamples)
133  {
134  renderNextSubBlock (outputAudio, startSample, numSamples);
135  handleMidiEvent (m);
136  break;
137  }
138 
139  if (samplesToNextMidiMessage < ((firstEvent && ! subBlockSubdivisionIsStrict) ? 1 : minimumSubBlockSize))
140  {
141  handleMidiEvent (m);
142  continue;
143  }
144 
145  firstEvent = false;
146 
147  renderNextSubBlock (outputAudio, startSample, samplesToNextMidiMessage);
148  handleMidiEvent (m);
149  startSample += samplesToNextMidiMessage;
150  numSamples -= samplesToNextMidiMessage;
151  }
152 
153  while (midiIterator.getNextEvent (m, midiEventPos))
154  handleMidiEvent (m);
155 }
156 
157 // explicit instantiation for supported float types:
158 template void MPESynthesiserBase::renderNextBlock<float> (AudioBuffer<float>&, const MidiBuffer&, int, int);
159 template void MPESynthesiserBase::renderNextBlock<double> (AudioBuffer<double>&, const MidiBuffer&, int, int);
160 
161 //==============================================================================
163 {
164  if (sampleRate != newRate)
165  {
166  const ScopedLock sl (noteStateLock);
167  instrument->releaseAllNotes();
168  sampleRate = newRate;
169  }
170 }
171 
172 //==============================================================================
173 void MPESynthesiserBase::setMinimumRenderingSubdivisionSize (int numSamples, bool shouldBeStrict) noexcept
174 {
175  jassert (numSamples > 0); // it wouldn't make much sense for this to be less than 1
176  minimumSubBlockSize = numSamples;
177  subBlockSubdivisionIsStrict = shouldBeStrict;
178 }
179 
180 } // namespace juce
void setNextSamplePosition(int samplePosition) noexcept
Repositions the iterator so that the next event retrieved will be the first one whose sample position...
This class represents the current MPE zone layout of a device capable of handling MPE...
void setZoneLayout(MPEZoneLayout newLayout)
Re-sets the synthesiser&#39;s internal MPE zone layout to the one passed in.
Encapsulates a MIDI message.
bool isLegacyModeEnabled() const noexcept
Returns true if the instrument is in legacy mode, false otherwise.
void setLegacyModePitchbendRange(int pitchbendRange)
Re-sets the pitchbend range in semitones (0-96) to be used for notes when in legacy mode...
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
Retrieves a copy of the next event from the buffer.
virtual void handleMidiEvent(const MidiMessage &)
Handle incoming MIDI events (called from renderNextBlock).
virtual void renderNextSubBlock(AudioBuffer< float > &outputAudio, int startSample, int numSamples)=0
Implement this method to render your audio inside.
void setPitchbendTrackingMode(TrackingMode modeToUse)
Set the MPE tracking mode for the pitchbend dimension.
void renderNextBlock(AudioBuffer< floatType > &outputAudio, const MidiBuffer &inputMidi, int startSample, int numSamples)
Creates the next block of audio output.
void setLegacyModeChannelRange(Range< int > channelRange)
Re-sets the range of MIDI channels (1-16) to be used for notes when in legacy mode.
std::unique_ptr< MPEInstrument > instrument
void setTimbreTrackingMode(TrackingMode modeToUse)
Set the MPE tracking mode for the timbre dimension.
A multi-channel buffer containing floating point audio samples.
Range< int > getLegacyModeChannelRange() const noexcept
Returns the range of MIDI channels (1-16) to be used for notes when in legacy mode.
TrackingMode
The MPE note tracking mode.
void setMinimumRenderingSubdivisionSize(int numSamples, bool shouldBeStrict=false) noexcept
Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering.
void setPressureTrackingMode(TrackingMode modeToUse)
Set the MPE tracking mode for the pressure dimension.
Holds a sequence of time-stamped midi events.
virtual void setCurrentPlaybackSampleRate(double sampleRate)
Tells the synthesiser what the sample rate is for the audio it&#39;s being used to render.
int getLegacyModePitchbendRange() const noexcept
Returns the pitchbend range in semitones (0-96) to be used for notes when in legacy mode...
Used to iterate through the events in a MidiBuffer.
This class represents an instrument handling MPE.
Automatically locks and unlocks a mutex object.
MPEZoneLayout getZoneLayout() const noexcept
Returns the synthesiser&#39;s internal MPE zone layout.
void enableLegacyMode(int pitchbendRange=2, Range< int > channelRange=Range< int >(1, 17))
Puts the synthesiser into legacy mode.