diff --git a/modules/juce_audio_devices/native/juce_linux_Midi.cpp b/modules/juce_audio_devices/native/juce_linux_Midi.cpp index dfed37d8df..8a7c4c55e0 100644 --- a/modules/juce_audio_devices/native/juce_linux_Midi.cpp +++ b/modules/juce_audio_devices/native/juce_linux_Midi.cpp @@ -25,9 +25,84 @@ #if JUCE_ALSA +// You can define these strings in your app if you want to override the default names: +#ifndef JUCE_ALSA_MIDI_INPUT_NAME + #define JUCE_ALSA_MIDI_INPUT_NAME "Juce Midi Input" +#endif + +#ifndef JUCE_ALSA_MIDI_OUTPUT_NAME + #define JUCE_ALSA_MIDI_OUTPUT_NAME "Juce Midi Output" +#endif + //============================================================================== namespace { + snd_seq_t* iterateMidiClient (snd_seq_t* seqHandle, + snd_seq_client_info_t* clientInfo, + const bool forInput, + StringArray& deviceNamesFound, + const int deviceIndexToOpen) + { + snd_seq_t* returnedHandle = nullptr; + + snd_seq_port_info_t* portInfo; + if (snd_seq_port_info_malloc (&portInfo) == 0) + { + int numPorts = snd_seq_client_info_get_num_ports (clientInfo); + const int client = snd_seq_client_info_get_client (clientInfo); + + snd_seq_port_info_set_client (portInfo, client); + snd_seq_port_info_set_port (portInfo, -1); + + while (--numPorts >= 0) + { + if (snd_seq_query_next_port (seqHandle, portInfo) == 0 + && (snd_seq_port_info_get_capability (portInfo) + & (forInput ? SND_SEQ_PORT_CAP_READ + : SND_SEQ_PORT_CAP_WRITE)) != 0) + { + deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo)); + + if (deviceNamesFound.size() == deviceIndexToOpen + 1) + { + const int sourcePort = snd_seq_port_info_get_port (portInfo); + const int sourceClient = snd_seq_client_info_get_client (clientInfo); + + if (sourcePort != -1) + { + if (forInput) + { + snd_seq_set_client_name (seqHandle, JUCE_ALSA_MIDI_INPUT_NAME); + + const int portId = snd_seq_create_simple_port (seqHandle, "Juce Midi In Port", + SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, + SND_SEQ_PORT_TYPE_MIDI_GENERIC); + + snd_seq_connect_from (seqHandle, portId, sourceClient, sourcePort); + } + else + { + snd_seq_set_client_name (seqHandle, JUCE_ALSA_MIDI_OUTPUT_NAME); + + const int portId = snd_seq_create_simple_port (seqHandle, "Juce Midi Out Port", + SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC); + + snd_seq_connect_to (seqHandle, portId, sourceClient, sourcePort); + } + + returnedHandle = seqHandle; + } + } + } + } + + snd_seq_port_info_free (portInfo); + } + + return returnedHandle; + } + snd_seq_t* iterateMidiDevices (const bool forInput, StringArray& deviceNamesFound, const int deviceIndexToOpen) @@ -49,65 +124,10 @@ namespace int numClients = snd_seq_system_info_get_cur_clients (systemInfo); while (--numClients >= 0 && returnedHandle == 0) - { if (snd_seq_query_next_client (seqHandle, clientInfo) == 0) - { - snd_seq_port_info_t* portInfo; - if (snd_seq_port_info_malloc (&portInfo) == 0) - { - int numPorts = snd_seq_client_info_get_num_ports (clientInfo); - const int client = snd_seq_client_info_get_client (clientInfo); - - snd_seq_port_info_set_client (portInfo, client); - snd_seq_port_info_set_port (portInfo, -1); - - while (--numPorts >= 0) - { - if (snd_seq_query_next_port (seqHandle, portInfo) == 0 - && (snd_seq_port_info_get_capability (portInfo) - & (forInput ? SND_SEQ_PORT_CAP_READ - : SND_SEQ_PORT_CAP_WRITE)) != 0) - { - deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo)); - - if (deviceNamesFound.size() == deviceIndexToOpen + 1) - { - const int sourcePort = snd_seq_port_info_get_port (portInfo); - const int sourceClient = snd_seq_client_info_get_client (clientInfo); - - if (sourcePort != -1) - { - if (forInput) - { - snd_seq_set_client_name (seqHandle, "Juce Midi Input"); - - const int portId = snd_seq_create_simple_port (seqHandle, "Juce Midi In Port", - SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, - SND_SEQ_PORT_TYPE_MIDI_GENERIC); - - snd_seq_connect_from (seqHandle, portId, sourceClient, sourcePort); - } - else - { - snd_seq_set_client_name (seqHandle, "Juce Midi Output"); - - const int portId = snd_seq_create_simple_port (seqHandle, "Juce Midi Out Port", - SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC); - - snd_seq_connect_to (seqHandle, portId, sourceClient, sourcePort); - } - - returnedHandle = seqHandle; - } - } - } - } - - snd_seq_port_info_free (portInfo); - } - } - } + returnedHandle = iterateMidiClient (seqHandle, clientInfo, + forInput, deviceNamesFound, + deviceIndexToOpen); snd_seq_client_info_free (clientInfo); } @@ -139,7 +159,7 @@ namespace forInput ? "in" : "out", forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE) - : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ), + : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ), forInput ? SND_SEQ_PORT_TYPE_APPLICATION : SND_SEQ_PORT_TYPE_MIDI_GENERIC); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index b7ac1b3b92..3fa39a4220 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -1141,26 +1141,26 @@ bool AudioProcessorGraph::disconnectNode (const uint32 nodeId) return doneAnything; } +bool AudioProcessorGraph::isConnectionLegal (Connection* const c) const +{ + const Node* const source = getNodeForId (c->sourceNodeId); + const Node* const dest = getNodeForId (c->destNodeId); + + return source != nullptr + && dest != nullptr + && (c->sourceChannelIndex != midiChannelIndex ? isPositiveAndBelow (c->sourceChannelIndex, source->processor->getNumOutputChannels()) + : source->processor->producesMidi()) + && (c->destChannelIndex != midiChannelIndex ? isPositiveAndBelow (c->destChannelIndex, dest->processor->getNumInputChannels()) + : dest->processor->acceptsMidi()); +} + bool AudioProcessorGraph::removeIllegalConnections() { bool doneAnything = false; for (int i = connections.size(); --i >= 0;) { - const Connection* const c = connections.getUnchecked(i); - - const Node* const source = getNodeForId (c->sourceNodeId); - const Node* const dest = getNodeForId (c->destNodeId); - - if (source == nullptr || dest == nullptr - || (c->sourceChannelIndex != midiChannelIndex - && ! isPositiveAndBelow (c->sourceChannelIndex, source->processor->getNumOutputChannels())) - || (c->sourceChannelIndex == midiChannelIndex - && ! source->processor->producesMidi()) - || (c->destChannelIndex != midiChannelIndex - && ! isPositiveAndBelow (c->destChannelIndex, dest->processor->getNumInputChannels())) - || (c->destChannelIndex == midiChannelIndex - && ! dest->processor->acceptsMidi())) + if (! isConnectionLegal (connections.getUnchecked(i))) { removeConnection (i); doneAnything = true; diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index 6a98ee38e6..0b2f88fa2f 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -245,6 +245,13 @@ public: */ bool disconnectNode (uint32 nodeId); + /** Returns true if the given connection's channel numbers map on to valid + channels at each end. + Even if a connection is valid when created, its status could change if + a node changes its channel config. + */ + bool isConnectionLegal (Connection* connection) const; + /** Performs a sanity checks of all the connections. This might be useful if some of the processors are doing things like changing diff --git a/modules/juce_core/native/juce_linux_Network.cpp b/modules/juce_core/native/juce_linux_Network.cpp index f6b2ea2b17..c603b4807c 100644 --- a/modules/juce_core/native/juce_linux_Network.cpp +++ b/modules/juce_core/native/juce_linux_Network.cpp @@ -340,7 +340,7 @@ private: static void writeHost (MemoryOutputStream& dest, const bool isPost, const String& path, const String& host, const int port) { - dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.1\r\nHost: " << host; + dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.0\r\nHost: " << host; if (port > 0) dest << ':' << port; diff --git a/modules/juce_core/network/juce_URL.cpp b/modules/juce_core/network/juce_URL.cpp index cb392e53b0..90de257ccd 100644 --- a/modules/juce_core/network/juce_URL.cpp +++ b/modules/juce_core/network/juce_URL.cpp @@ -84,6 +84,20 @@ URL& URL::operator= (const URL& other) return *this; } +bool URL::operator== (const URL& other) const +{ + return url == other.url + && postData == other.postData + && parameters == other.parameters + && filesToUpload == other.filesToUpload + && mimeTypes == other.mimeTypes; +} + +bool URL::operator!= (const URL& other) const +{ + return ! operator== (other); +} + URL::~URL() { } diff --git a/modules/juce_core/network/juce_URL.h b/modules/juce_core/network/juce_URL.h index 832d170122..c4fad9edd0 100644 --- a/modules/juce_core/network/juce_URL.h +++ b/modules/juce_core/network/juce_URL.h @@ -58,6 +58,13 @@ public: /** Copies this URL from another one. */ URL& operator= (const URL& other); + /** Compares two URLs. + All aspects of the URLs must be identical for them to match, including any parameters, + upload files, etc. + */ + bool operator== (const URL&) const; + bool operator!= (const URL&) const; + //============================================================================== /** Returns a string version of the URL. @@ -309,7 +316,6 @@ private: OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, const String& headers, const int timeOutMs, StringPairArray* responseHeaders); - JUCE_LEAK_DETECTOR (URL); }; diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 8233eaf524..78af6eaf6c 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -990,7 +990,7 @@ struct WildCardMatcher { for (;;) { - const juce_wchar wc = *wildcard; + const juce_wchar wc = wildcard.getAndAdvance(); const juce_wchar tc = *test; if (wc == tc @@ -1001,11 +1001,10 @@ struct WildCardMatcher return true; ++test; - ++wildcard; } else { - return wc == '*' && (wildcard[1] == 0 || matchesAnywhere (wildcard + 1, test, ignoreCase)); + return wc == '*' && (wildcard.isEmpty() || matchesAnywhere (wildcard, test, ignoreCase)); } } }