Browse Source

Update to latest juce

tags/2018-04-16
falkTX 10 years ago
parent
commit
25e35e3ceb
12 changed files with 162 additions and 65 deletions
  1. +54
    -19
      libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  2. +10
    -1
      libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  3. +37
    -33
      libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  4. +5
    -0
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h
  5. +1
    -0
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp
  6. +5
    -0
      libs/juce/source/modules/juce_core/files/juce_File.cpp
  7. +2
    -2
      libs/juce/source/modules/juce_core/memory/juce_Memory.h
  8. +2
    -2
      libs/juce/source/modules/juce_core/native/juce_posix_SharedCode.h
  9. +2
    -2
      libs/juce/source/modules/juce_core/text/juce_String.h
  10. +4
    -2
      libs/juce/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp
  11. +6
    -3
      libs/juce/source/modules/juce_gui_basics/components/juce_Component.cpp
  12. +34
    -1
      libs/juce/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp

+ 54
- 19
libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -32,6 +32,7 @@ SynthesiserVoice::SynthesiserVoice()
currentPlayingMidiChannel (0),
noteOnTime (0),
keyIsDown (false),
sustainPedalDown (false),
sostenutoPedalDown (false)
{
}
@@ -296,6 +297,7 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
voice->currentlyPlayingSound = sound;
voice->keyIsDown = true;
voice->sostenutoPedalDown = false;
voice->sustainPedalDown = sustainPedalsDown[midiChannel];
voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]);
@@ -331,9 +333,11 @@ void Synthesiser::noteOff (const int midiChannel,
if (sound->appliesToNote (midiNoteNumber)
&& sound->appliesToChannel (midiChannel))
{
jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]);
voice->keyIsDown = false;
if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown))
if (! (voice->sustainPedalDown || voice->sostenutoPedalDown))
stopVoice (voice, velocity, allowTailOff);
}
}
@@ -427,6 +431,14 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
if (isDown)
{
sustainPedalsDown.setBit (midiChannel);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown())
voice->sustainPedalDown = true;
}
}
else
{
@@ -434,8 +446,13 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown)
stopVoice (voice, 1.0f, true);
if (voice->isPlayingChannel (midiChannel))
{
voice->sustainPedalDown = false;
if (! voice->isKeyDown())
stopVoice (voice, 1.0f, true);
}
}
sustainPedalsDown.clearBit (midiChannel);
@@ -505,8 +522,13 @@ struct VoiceAgeSorter
SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
int /*midiChannel*/, int midiNoteNumber) const
{
SynthesiserVoice* bottom = nullptr;
SynthesiserVoice* top = nullptr;
// This voice-stealing algorithm applies the following heuristics:
// - Re-use the oldest notes first
// - Protect the lowest & topmost notes, even if sustained, but not if they've been released.
// These are the voices we want to protect (ie: only steal if unavoidable)
SynthesiserVoice* low = nullptr; // Lowest sounding note, might be sustained, but NOT in release phase
SynthesiserVoice* top = nullptr; // Highest sounding note, might be sustained, but NOT in release phase
// this is a list of voices we can steal, sorted by how long they've been running
Array<SynthesiserVoice*> usableVoices;
@@ -516,24 +538,33 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
jassert (voice->isVoiceActive()); // We wouldn't be here otherwise
if (voice->canPlaySound (soundToPlay))
{
VoiceAgeSorter sorter;
usableVoices.addSorted (sorter, voice);
const int note = voice->getCurrentlyPlayingNote();
if (! voice->isPlayingButReleased()) // Don't protect released notes
{
const int note = voice->getCurrentlyPlayingNote();
if (bottom == nullptr || note < bottom->getCurrentlyPlayingNote())
bottom = voice;
if (low == nullptr || note < low->getCurrentlyPlayingNote())
low = voice;
if (top == nullptr || note > top->getCurrentlyPlayingNote())
top = voice;
if (top == nullptr || note > top->getCurrentlyPlayingNote())
top = voice;
}
}
}
// Eliminate pathological cases (ie: only 1 note playing): we always give precedence to the lowest note(s)
if (top == low)
top = nullptr;
const int numUsableVoices = usableVoices.size();
// The oldest note that's playing with the target pitch playing is ideal..
// The oldest note that's playing with the target pitch is ideal..
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
@@ -547,7 +578,7 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
if (voice != bottom && voice != top && ! voice->isKeyDown() && ! voice->isSostenutoPedalDown())
if (voice != low && voice != top && voice->isPlayingButReleased())
return voice;
}
@@ -556,21 +587,25 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
if (voice != bottom && voice != top && ! voice->isKeyDown())
if (voice != low && voice != top && ! voice->isKeyDown())
return voice;
}
// At this point, all notes have fingers on them, so look for the oldest note
// that isn't the top or bottom note..
// Oldest voice that isn't protected
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
if (voice != bottom && voice != top)
if (voice != low && voice != top)
return voice;
}
// ..otherwise, there's only one or two voices to choose from - prefer to steal the highest one:
jassert (top != nullptr || bottom != nullptr);
return (top == nullptr ? bottom : top);
// We've only got "protected" voices now: lowest note takes priority
jassert (low != nullptr);
// Duophonic synth: give priority to the bass note:
if (top != nullptr)
return top;
return low;
}

+ 10
- 1
libs/juce/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -214,9 +214,18 @@ public:
*/
bool isKeyDown() const noexcept { return keyIsDown; }
/** Returns true if the sustain pedal is currently active for this voice. */
bool isSustainPedalDown() const noexcept { return sustainPedalDown; }
/** Returns true if the sostenuto pedal is currently active for this voice. */
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; }
/** Returns true if a voice is sounding in its release phase **/
bool isPlayingButReleased() const noexcept
{
return isVoiceActive() && ! (isKeyDown() || isSostenutoPedalDown() || isSustainPedalDown());
}
/** Returns true if this voice started playing its current note before the other voice did. */
bool wasStartedBefore (const SynthesiserVoice& other) const noexcept;
@@ -244,7 +253,7 @@ private:
int currentlyPlayingNote, currentPlayingMidiChannel;
uint32 noteOnTime;
SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sostenutoPedalDown;
bool keyIsDown, sustainPedalDown, sostenutoPedalDown;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for this method.


+ 37
- 33
libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -45,6 +45,14 @@ namespace CoreMidiHelpers
#define CHECK_ERROR(a) CoreMidiHelpers::checkError (a, __LINE__)
//==============================================================================
struct ScopedCFString
{
ScopedCFString() noexcept : cfString (nullptr) {}
~ScopedCFString() noexcept { if (cfString != nullptr) CFRelease (cfString); }
CFStringRef cfString;
};
static String getMidiObjectName (MIDIObjectRef entity)
{
String result;
@@ -116,7 +124,7 @@ namespace CoreMidiHelpers
if (numConnections > 0)
{
const SInt32* pid = reinterpret_cast <const SInt32*> (CFDataGetBytePtr (connections));
const SInt32* pid = reinterpret_cast<const SInt32*> (CFDataGetBytePtr (connections));
for (int i = 0; i < numConnections; ++i, ++pid)
{
@@ -133,7 +141,7 @@ namespace CoreMidiHelpers
|| connObjectType == kMIDIObjectType_ExternalDestination)
{
// Connected to an external device's endpoint (10.3 and later).
s = getEndpointName (static_cast <MIDIEndpointRef> (connObject), true);
s = getEndpointName (static_cast<MIDIEndpointRef> (connObject), true);
}
else
{
@@ -208,9 +216,9 @@ namespace CoreMidiHelpers
// correctly when called from the message thread!
jassert (MessageManager::getInstance()->isThisTheMessageThread());
CFStringRef name = getGlobalMidiClientName().toCFString();
CHECK_ERROR (MIDIClientCreate (name, &globalSystemChangeCallback, nullptr, &globalMidiClient));
CFRelease (name);
CoreMidiHelpers::ScopedCFString name;
name.cfString = getGlobalMidiClientName().toCFString();
CHECK_ERROR (MIDIClientCreate (name.cfString, &globalSystemChangeCallback, nullptr, &globalMidiClient));
}
return globalMidiClient;
@@ -220,12 +228,12 @@ namespace CoreMidiHelpers
class MidiPortAndEndpoint
{
public:
MidiPortAndEndpoint (MIDIPortRef p, MIDIEndpointRef ep)
MidiPortAndEndpoint (MIDIPortRef p, MIDIEndpointRef ep) noexcept
: port (p), endPoint (ep)
{
}
~MidiPortAndEndpoint()
~MidiPortAndEndpoint() noexcept
{
if (port != 0)
MIDIPortDispose (port);
@@ -234,7 +242,7 @@ namespace CoreMidiHelpers
MIDIEndpointDispose (endPoint);
}
void send (const MIDIPacketList* const packets)
void send (const MIDIPacketList* const packets) noexcept
{
if (port != 0)
MIDISend (port, endPoint, packets);
@@ -302,7 +310,7 @@ namespace CoreMidiHelpers
static void midiInputProc (const MIDIPacketList* pktlist, void* readProcRefCon, void* /*srcConnRefCon*/)
{
static_cast <MidiPortAndCallback*> (readProcRefCon)->handlePackets (pktlist);
static_cast<MidiPortAndCallback*> (readProcRefCon)->handlePackets (pktlist);
}
}
@@ -318,19 +326,18 @@ MidiOutput* MidiOutput::openDevice (int index)
{
MIDIEndpointRef endPoint = MIDIGetDestination ((ItemCount) index);
CFStringRef pname;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname)))
CoreMidiHelpers::ScopedCFString pname;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname.cfString)))
{
MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient();
MIDIPortRef port;
if (client != 0 && CHECK_ERROR (MIDIOutputPortCreate (client, pname, &port)))
if (client != 0 && CHECK_ERROR (MIDIOutputPortCreate (client, pname.cfString, &port)))
{
mo = new MidiOutput();
mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (port, endPoint);
}
CFRelease (pname);
}
}
@@ -339,20 +346,20 @@ MidiOutput* MidiOutput::openDevice (int index)
MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
{
MidiOutput* mo = nullptr;
MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient();
MIDIEndpointRef endPoint;
CFStringRef name = deviceName.toCFString();
if (client != 0 && CHECK_ERROR (MIDISourceCreate (client, name, &endPoint)))
CoreMidiHelpers::ScopedCFString name;
name.cfString = deviceName.toCFString();
if (client != 0 && CHECK_ERROR (MIDISourceCreate (client, name.cfString, &endPoint)))
{
mo = new MidiOutput();
MidiOutput* mo = new MidiOutput();
mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (0, endPoint);
return mo;
}
CFRelease (name);
return mo;
return nullptr;
}
MidiOutput::~MidiOutput()
@@ -370,7 +377,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
const MIDITimeStamp timeStamp = AudioGetCurrentHostTime();
#endif
HeapBlock <MIDIPacketList> allocatedPackets;
HeapBlock<MIDIPacketList> allocatedPackets;
MIDIPacketList stackPacket;
MIDIPacketList* packetToSend = &stackPacket;
const size_t dataSize = (size_t) message.getRawDataSize();
@@ -436,16 +443,16 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
if (MIDIEndpointRef endPoint = MIDIGetSource ((ItemCount) index))
{
CFStringRef name;
ScopedCFString name;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &name)))
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &name.cfString)))
{
if (MIDIClientRef client = getGlobalMidiClient())
{
MIDIPortRef port;
ScopedPointer <MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
ScopedPointer<MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
if (CHECK_ERROR (MIDIInputPortCreate (client, name, midiInputProc, mpc, &port)))
if (CHECK_ERROR (MIDIInputPortCreate (client, name.cfString, midiInputProc, mpc, &port)))
{
if (CHECK_ERROR (MIDIPortConnectSource (port, endPoint, nullptr)))
{
@@ -465,8 +472,6 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
}
}
}
CFRelease (name);
}
}
@@ -482,13 +487,14 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba
if (MIDIClientRef client = getGlobalMidiClient())
{
ScopedPointer <MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
ScopedPointer<MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
mpc->active = false;
MIDIEndpointRef endPoint;
CFStringRef name = deviceName.toCFString();
ScopedCFString name;
name.cfString = deviceName.toCFString();
if (CHECK_ERROR (MIDIDestinationCreate (client, name, midiInputProc, mpc, &endPoint)))
if (CHECK_ERROR (MIDIDestinationCreate (client, name.cfString, midiInputProc, mpc, &endPoint)))
{
mpc->portAndEndpoint = new MidiPortAndEndpoint (0, endPoint);
@@ -499,8 +505,6 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba
const ScopedLock sl (callbackLock);
activeCallbacks.add (mpc.release());
}
CFRelease (name);
}
return mi;


+ 5
- 0
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h View File

@@ -22,6 +22,9 @@
==============================================================================
*/
#ifndef JUCE_INCLUDEMODULEHEADERS_H_INCLUDED
#define JUCE_INCLUDEMODULEHEADERS_H_INCLUDED
#include "../juce_audio_plugin_client.h"
using namespace juce;
@@ -44,3 +47,5 @@ namespace juce
}
extern AudioProcessor* JUCE_CALLTYPE createPluginFilterOfType (AudioProcessor::WrapperType);
#endif // JUCE_INCLUDEMODULEHEADERS_H_INCLUDED

+ 1
- 0
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp View File

@@ -31,6 +31,7 @@
#include "AppConfig.h"
#include "../utility/juce_CheckSettingMacros.h"
#include "juce_IncludeModuleHeaders.h"
#if _MSC_VER || JUCE_MINGW


+ 5
- 0
libs/juce/source/modules/juce_core/files/juce_File.cpp View File

@@ -916,6 +916,11 @@ public:
const File temp (File::getSpecialLocation (File::tempDirectory));
expect (! File::nonexistent.exists());
expect (! File::nonexistent.existsAsFile());
expect (! File::nonexistent.isDirectory());
#if ! JUCE_WINDOWS
expect (File("/").isDirectory());
#endif
expect (home.isDirectory());
expect (home.exists());
expect (! home.existsAsFile());


+ 2
- 2
libs/juce/source/modules/juce_core/memory/juce_Memory.h View File

@@ -50,7 +50,7 @@ inline void deleteAndZero (Type& pointer) { delete poi
a specific number of bytes,
*/
template <typename Type, typename IntegerType>
inline Type* addBytesToPointer (Type* pointer, IntegerType bytes) noexcept { return (Type*) (((char*) pointer) + bytes); }
inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept { return (Type*) (((char*) basePointer) + bytes); }
/** A handy function which returns the difference between any two pointers, in bytes.
The address of the second pointer is subtracted from the first, and the difference in bytes is returned.
@@ -62,7 +62,7 @@ inline int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept { r
nullptr if the pointer is null.
*/
template <class Type>
inline Type* createCopyIfNotNull (const Type* pointer) { return pointer != nullptr ? new Type (*pointer) : nullptr; }
inline Type* createCopyIfNotNull (const Type* objectToCopy) { return objectToCopy != nullptr ? new Type (*objectToCopy) : nullptr; }
//==============================================================================
#if JUCE_MAC || JUCE_IOS || DOXYGEN


+ 2
- 2
libs/juce/source/modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -265,8 +265,8 @@ bool File::isDirectory() const
{
juce_statStruct info;
return fullPath.isEmpty()
|| (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
return fullPath.isNotEmpty()
&& (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
}
bool File::exists() const


+ 2
- 2
libs/juce/source/modules/juce_core/text/juce_String.h View File

@@ -89,12 +89,12 @@ public:
*/
String (const char* text, size_t maxChars);
/** Creates a string from a whcar_t character string.
/** Creates a string from a wchar_t character string.
Depending on the platform, this may be treated as either UTF-32 or UTF-16.
*/
String (const wchar_t* text);
/** Creates a string from a whcar_t character string.
/** Creates a string from a wchar_t character string.
Depending on the platform, this may be treated as either UTF-32 or UTF-16.
*/
String (const wchar_t* text, size_t maxChars);


+ 4
- 2
libs/juce/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp View File

@@ -32,8 +32,8 @@ namespace
jassert ((int) x >= -maxVal && (int) x <= maxVal
&& (int) y >= -maxVal && (int) y <= maxVal
&& (int) w >= -maxVal && (int) w <= maxVal
&& (int) h >= -maxVal && (int) h <= maxVal);
&& (int) w >= 0 && (int) w <= maxVal
&& (int) h >= 0 && (int) h <= maxVal);
#endif
return Rectangle<Type> (x, y, w, h);
@@ -427,6 +427,8 @@ void Graphics::drawRect (const Rectangle<int>& r, int lineThickness) const
void Graphics::drawRect (Rectangle<float> r, const float lineThickness) const
{
jassert (r.getWidth() >= 0.0f && r.getHeight() >= 0.0f);
RectangleList<float> rects;
rects.addWithoutMerging (r.removeFromTop (lineThickness));
rects.addWithoutMerging (r.removeFromBottom (lineThickness));


+ 6
- 3
libs/juce/source/modules/juce_gui_basics/components/juce_Component.cpp View File

@@ -1153,12 +1153,15 @@ void Component::setBounds (const int x, const int y, int w, int h)
void Component::sendMovedResizedMessagesIfPending()
{
if (flags.isMoveCallbackPending || flags.isResizeCallbackPending)
{
sendMovedResizedMessages (flags.isMoveCallbackPending, flags.isResizeCallbackPending);
const bool wasMoved = flags.isMoveCallbackPending;
const bool wasResized = flags.isResizeCallbackPending;
if (wasMoved || wasResized)
{
flags.isMoveCallbackPending = false;
flags.isResizeCallbackPending = false;
sendMovedResizedMessages (wasMoved, wasResized);
}
}


+ 34
- 1
libs/juce/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -3723,12 +3723,45 @@ void Desktop::Displays::findDisplays (float masterScale)
{
DisplayGeometry& geometry = DisplayGeometry::getOrCreateInstance (display, masterScale);
// add the main display first
int mainDisplayIdx;
for (mainDisplayIdx = 0; mainDisplayIdx < geometry.infos.size(); ++mainDisplayIdx)
{
const DisplayGeometry::ExtendedInfo& info = geometry.infos.getReference (mainDisplayIdx);
if (info.isMain)
break;
}
// no main display found then use the first
if (mainDisplayIdx >= geometry.infos.size())
mainDisplayIdx = 0;
// add the main display
{
const DisplayGeometry::ExtendedInfo& info =
geometry.infos.getReference (mainDisplayIdx);
Desktop::Displays::Display d;
d.isMain = true;
d.scale = masterScale * info.scale;
d.dpi = info.dpi;
d.totalArea = DisplayGeometry::physicalToScaled (info.totalBounds);
d.userArea = (info.usableBounds / d.scale) + info.topLeftScaled;
displays.add (d);
}
for (int i = 0; i < geometry.infos.size(); ++i)
{
// don't add the main display a second time
if (i == mainDisplayIdx)
continue;
const DisplayGeometry::ExtendedInfo& info = geometry.infos.getReference (i);
Desktop::Displays::Display d;
d.isMain = info.isMain;
d.isMain = false;
d.scale = masterScale * info.scale;
d.dpi = info.dpi;


Loading…
Cancel
Save