| @@ -2,8 +2,8 @@ | |||||
| set -e | set -e | ||||
| JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/distrho/DISTRHO/libs/juce/source/modules/" | |||||
| CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/falktx/Carla/source/modules/" | |||||
| JUCE_MODULES_DIR="/home/falktx/FOSS/GIT-mine/DISTRHO/libs/juce/source/modules/" | |||||
| CARLA_MODULES_DIR="/home/falktx/FOSS/GIT-mine/Carla/source/modules/" | |||||
| MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics juce_gui_extra") | MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics juce_gui_extra") | ||||
| @@ -41,6 +41,7 @@ MidiOutput* MidiOutput::openDevice (int index) | |||||
| MidiOutput::~MidiOutput() | MidiOutput::~MidiOutput() | ||||
| { | { | ||||
| stopBackgroundThread(); | |||||
| } | } | ||||
| void MidiOutput::sendMessageNow (const MidiMessage&) | void MidiOutput::sendMessageNow (const MidiMessage&) | ||||
| @@ -512,12 +512,14 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName) | |||||
| MidiOutput::~MidiOutput() | MidiOutput::~MidiOutput() | ||||
| { | { | ||||
| delete static_cast <MidiOutputDevice*> (internal); | |||||
| stopBackgroundThread(); | |||||
| delete static_cast<MidiOutputDevice*> (internal); | |||||
| } | } | ||||
| void MidiOutput::sendMessageNow (const MidiMessage& message) | void MidiOutput::sendMessageNow (const MidiMessage& message) | ||||
| { | { | ||||
| static_cast <MidiOutputDevice*> (internal)->sendMessageNow (message); | |||||
| static_cast<MidiOutputDevice*> (internal)->sendMessageNow (message); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -529,7 +531,7 @@ MidiInput::MidiInput (const String& nm) | |||||
| MidiInput::~MidiInput() | MidiInput::~MidiInput() | ||||
| { | { | ||||
| stop(); | stop(); | ||||
| delete static_cast <AlsaPortAndCallback*> (internal); | |||||
| delete static_cast<AlsaPortAndCallback*> (internal); | |||||
| } | } | ||||
| void MidiInput::start() | void MidiInput::start() | ||||
| @@ -357,6 +357,8 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName) | |||||
| MidiOutput::~MidiOutput() | MidiOutput::~MidiOutput() | ||||
| { | { | ||||
| stopBackgroundThread(); | |||||
| delete static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal); | delete static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal); | ||||
| } | } | ||||
| @@ -297,11 +297,11 @@ MidiInput::MidiInput (const String& name_) | |||||
| MidiInput::~MidiInput() | MidiInput::~MidiInput() | ||||
| { | { | ||||
| delete static_cast <MidiInCollector*> (internal); | |||||
| delete static_cast<MidiInCollector*> (internal); | |||||
| } | } | ||||
| void MidiInput::start() { static_cast <MidiInCollector*> (internal)->start(); } | |||||
| void MidiInput::stop() { static_cast <MidiInCollector*> (internal)->stop(); } | |||||
| void MidiInput::start() { static_cast<MidiInCollector*> (internal)->start(); } | |||||
| void MidiInput::stop() { static_cast<MidiInCollector*> (internal)->stop(); } | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -432,7 +432,7 @@ MidiOutput::~MidiOutput() | |||||
| { | { | ||||
| stopBackgroundThread(); | stopBackgroundThread(); | ||||
| MidiOutHandle* const h = static_cast <MidiOutHandle*> (internal); | |||||
| MidiOutHandle* const h = static_cast<MidiOutHandle*> (internal); | |||||
| if (MidiOutHandle::activeHandles.contains (h) && --(h->refCount) == 0) | if (MidiOutHandle::activeHandles.contains (h) && --(h->refCount) == 0) | ||||
| { | { | ||||
| @@ -444,7 +444,7 @@ MidiOutput::~MidiOutput() | |||||
| void MidiOutput::sendMessageNow (const MidiMessage& message) | void MidiOutput::sendMessageNow (const MidiMessage& message) | ||||
| { | { | ||||
| const MidiOutHandle* const handle = static_cast <const MidiOutHandle*> (internal); | |||||
| const MidiOutHandle* const handle = static_cast<const MidiOutHandle*> (internal); | |||||
| if (message.getRawDataSize() > 3 || message.isSysEx()) | if (message.getRawDataSize() > 3 || message.isSysEx()) | ||||
| { | { | ||||
| @@ -127,9 +127,7 @@ class WMAudioReader : public AudioFormatReader | |||||
| public: | public: | ||||
| WMAudioReader (InputStream* const input_) | WMAudioReader (InputStream* const input_) | ||||
| : AudioFormatReader (input_, TRANS (wmFormatName)), | : AudioFormatReader (input_, TRANS (wmFormatName)), | ||||
| wmvCoreLib ("Wmvcore.dll"), | |||||
| currentPosition (0), | |||||
| bufferStart (0), bufferEnd (0) | |||||
| wmvCoreLib ("Wmvcore.dll") | |||||
| { | { | ||||
| JUCE_LOAD_WINAPI_FUNCTION (wmvCoreLib, WMCreateSyncReader, wmCreateSyncReader, | JUCE_LOAD_WINAPI_FUNCTION (wmvCoreLib, WMCreateSyncReader, wmCreateSyncReader, | ||||
| HRESULT, (IUnknown*, DWORD, IWMSyncReader**)) | HRESULT, (IUnknown*, DWORD, IWMSyncReader**)) | ||||
| @@ -168,30 +166,24 @@ public: | |||||
| checkCoInitialiseCalled(); | checkCoInitialiseCalled(); | ||||
| if (startSampleInFile != currentPosition) | |||||
| { | |||||
| currentPosition = startSampleInFile; | |||||
| wmSyncReader->SetRange (((QWORD) startSampleInFile * 10000000) / (int) sampleRate, 0); | |||||
| bufferStart = bufferEnd = 0; | |||||
| } | |||||
| const int stride = numChannels * sizeof (int16); | const int stride = numChannels * sizeof (int16); | ||||
| bool firstLoop = true; | |||||
| while (numSamples > 0) | while (numSamples > 0) | ||||
| { | { | ||||
| if (bufferEnd <= bufferStart) | |||||
| if (! bufferedRange.contains (startSampleInFile)) | |||||
| { | { | ||||
| const bool hasJumped = (startSampleInFile != bufferedRange.getEnd()); | |||||
| if (hasJumped) | |||||
| wmSyncReader->SetRange ((QWORD) (startSampleInFile * 10000000 / (int64) sampleRate), 0); | |||||
| ComSmartPtr<INSSBuffer> sampleBuffer; | ComSmartPtr<INSSBuffer> sampleBuffer; | ||||
| QWORD sampleTime, duration; | QWORD sampleTime, duration; | ||||
| DWORD flags, outputNum; | DWORD flags, outputNum; | ||||
| WORD streamNum; | WORD streamNum; | ||||
| int64 readBufferStart; | |||||
| HRESULT hr = wmSyncReader->GetNextSample (1, sampleBuffer.resetAndGetPointerAddress(), &sampleTime, | |||||
| &duration, &flags, &outputNum, &streamNum); | |||||
| readBufferStart = (int64)floor((sampleTime * sampleRate) * 0.0000001); | |||||
| HRESULT hr = wmSyncReader->GetNextSample (1, sampleBuffer.resetAndGetPointerAddress(), | |||||
| &sampleTime, &duration, &flags, &outputNum, &streamNum); | |||||
| if (sampleBuffer != nullptr) | if (sampleBuffer != nullptr) | ||||
| { | { | ||||
| @@ -199,41 +191,35 @@ public: | |||||
| DWORD dataLength = 0; | DWORD dataLength = 0; | ||||
| hr = sampleBuffer->GetBufferAndLength (&rawData, &dataLength); | hr = sampleBuffer->GetBufferAndLength (&rawData, &dataLength); | ||||
| bufferStart = 0; | |||||
| bufferEnd = (int) dataLength; | |||||
| if (bufferEnd <= 0) | |||||
| { | |||||
| sampleBuffer->Release(); | |||||
| if (dataLength == 0) | |||||
| return false; | return false; | ||||
| } | |||||
| buffer.ensureSize (bufferEnd); | |||||
| memcpy (buffer.getData(), rawData, bufferEnd); | |||||
| if (hasJumped) | |||||
| bufferedRange.setStart ((int64) ((sampleTime * (int64) sampleRate) / 10000000)); | |||||
| else | |||||
| bufferedRange.setStart (bufferedRange.getEnd()); // (because the positions returned often aren't continguous) | |||||
| if (firstLoop && readBufferStart < startSampleInFile) | |||||
| { | |||||
| bufferStart += stride * (int) (startSampleInFile - readBufferStart); | |||||
| if (bufferStart > bufferEnd) | |||||
| bufferStart = bufferEnd; | |||||
| } | |||||
| bufferedRange.setLength ((int64) (dataLength / stride)); | |||||
| buffer.ensureSize ((int) dataLength); | |||||
| memcpy (buffer.getData(), rawData, (size_t) dataLength); | |||||
| } | } | ||||
| else | |||||
| else if (hr == NS_E_NO_MORE_SAMPLES) | |||||
| { | { | ||||
| bufferStart = 0; | |||||
| bufferEnd = 512; | |||||
| buffer.ensureSize (bufferEnd); | |||||
| bufferedRange.setStart (startSampleInFile); | |||||
| bufferedRange.setLength (256); | |||||
| buffer.ensureSize (256 * stride); | |||||
| buffer.fillWith (0); | buffer.fillWith (0); | ||||
| } | } | ||||
| firstLoop = false; | |||||
| else | |||||
| { | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| const int16* const rawData = static_cast <const int16*> (addBytesToPointer (buffer.getData(), bufferStart)); | |||||
| const int numToDo = jmin (numSamples, (bufferEnd - bufferStart) / stride); | |||||
| const int offsetInBuffer = (int) (startSampleInFile - bufferedRange.getStart()); | |||||
| const int16* const rawData = static_cast<const int16*> (addBytesToPointer (buffer.getData(), offsetInBuffer * stride)); | |||||
| const int numToDo = jmin (numSamples, (int) (bufferedRange.getLength() - offsetInBuffer)); | |||||
| for (int i = 0; i < numDestChannels; ++i) | for (int i = 0; i < numDestChannels; ++i) | ||||
| { | { | ||||
| @@ -250,13 +236,9 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| bufferStart += numToDo * stride; | |||||
| if (bufferEnd - bufferStart < stride) | |||||
| bufferStart = bufferEnd; | |||||
| startSampleInFile += numToDo; | |||||
| startOffsetInDestBuffer += numToDo; | startOffsetInDestBuffer += numToDo; | ||||
| numSamples -= numToDo; | numSamples -= numToDo; | ||||
| currentPosition += numToDo; | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -265,9 +247,8 @@ public: | |||||
| private: | private: | ||||
| DynamicLibrary wmvCoreLib; | DynamicLibrary wmvCoreLib; | ||||
| ComSmartPtr<IWMSyncReader> wmSyncReader; | ComSmartPtr<IWMSyncReader> wmSyncReader; | ||||
| int64 currentPosition; | |||||
| MemoryBlock buffer; | MemoryBlock buffer; | ||||
| int bufferStart, bufferEnd; | |||||
| Range<int64> bufferedRange; | |||||
| void checkCoInitialiseCalled() | void checkCoInitialiseCalled() | ||||
| { | { | ||||
| @@ -44,7 +44,6 @@ FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse) | |||||
| FileOutputStream::~FileOutputStream() | FileOutputStream::~FileOutputStream() | ||||
| { | { | ||||
| flushBuffer(); | flushBuffer(); | ||||
| flushInternal(); | |||||
| closeHandle(); | closeHandle(); | ||||
| } | } | ||||
| @@ -29,7 +29,7 @@ | |||||
| #ifndef JUCE_WIN32_COMSMARTPTR_H_INCLUDED | #ifndef JUCE_WIN32_COMSMARTPTR_H_INCLUDED | ||||
| #define JUCE_WIN32_COMSMARTPTR_H_INCLUDED | #define JUCE_WIN32_COMSMARTPTR_H_INCLUDED | ||||
| #ifndef _MSC_VER | |||||
| #if ! (defined (_MSC_VER) || defined (__uuidof)) | |||||
| template<typename Type> struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } }; | template<typename Type> struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } }; | ||||
| #define __uuidof(x) UUIDGetter<x>::get() | #define __uuidof(x) UUIDGetter<x>::get() | ||||
| #endif | #endif | ||||
| @@ -558,8 +558,16 @@ bool ChildProcess::start (const StringArray& args, int streamFlags) | |||||
| String escaped; | String escaped; | ||||
| for (int i = 0; i < args.size(); ++i) | for (int i = 0; i < args.size(); ++i) | ||||
| escaped << args[i].replace ("\"", "\\\"") | |||||
| .replace (" ", "\\ ") << ' '; | |||||
| { | |||||
| String arg (args[i]); | |||||
| // If there are spaces, surround it with quotes. If there are quotes, | |||||
| // replace them with \" so that CommandLineToArgv will correctly parse them. | |||||
| if (arg.containsAnyOf ("\" ")) | |||||
| arg = arg.replace ("\"", "\\\"").quoted(); | |||||
| escaped << arg << ' '; | |||||
| } | |||||
| return start (escaped.trim(), streamFlags); | return start (escaped.trim(), streamFlags); | ||||
| } | } | ||||
| @@ -29,19 +29,6 @@ namespace ColourHelpers | |||||
| return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : static_cast<uint8> (n * 255.996f)); | return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : static_cast<uint8> (n * 255.996f)); | ||||
| } | } | ||||
| // This is an adjusted brightness value, based on the way the human | |||||
| // eye responds to different colour channels.. | |||||
| static float getPerceivedBrightness (Colour c) noexcept | |||||
| { | |||||
| const float r = c.getFloatRed(); | |||||
| const float g = c.getFloatGreen(); | |||||
| const float b = c.getFloatBlue(); | |||||
| return std::sqrt (r * r * 0.241f | |||||
| + g * g * 0.691f | |||||
| + b * b * 0.068f); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| struct HSB | struct HSB | ||||
| { | { | ||||
| @@ -333,6 +320,13 @@ Colour Colour::withHue (float h) const noexcept { ColourHelpers::HSB hs | |||||
| Colour Colour::withSaturation (float s) const noexcept { ColourHelpers::HSB hsb (*this); hsb.saturation = s; return hsb.toColour (*this); } | Colour Colour::withSaturation (float s) const noexcept { ColourHelpers::HSB hsb (*this); hsb.saturation = s; return hsb.toColour (*this); } | ||||
| Colour Colour::withBrightness (float v) const noexcept { ColourHelpers::HSB hsb (*this); hsb.brightness = v; return hsb.toColour (*this); } | Colour Colour::withBrightness (float v) const noexcept { ColourHelpers::HSB hsb (*this); hsb.brightness = v; return hsb.toColour (*this); } | ||||
| float Colour::getPerceivedBrightness() const noexcept | |||||
| { | |||||
| return std::sqrt (0.241f * square (getFloatRed()) | |||||
| + 0.691f * square (getFloatGreen()) | |||||
| + 0.068f * square (getFloatBlue())); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| Colour Colour::withRotatedHue (const float amountToRotate) const noexcept | Colour Colour::withRotatedHue (const float amountToRotate) const noexcept | ||||
| { | { | ||||
| @@ -386,9 +380,9 @@ Colour Colour::greyLevel (const float brightness) noexcept | |||||
| //============================================================================== | //============================================================================== | ||||
| Colour Colour::contrasting (const float amount) const noexcept | Colour Colour::contrasting (const float amount) const noexcept | ||||
| { | { | ||||
| return overlaidWith ((ColourHelpers::getPerceivedBrightness (*this) >= 0.5f | |||||
| ? Colours::black | |||||
| : Colours::white).withAlpha (amount)); | |||||
| return overlaidWith ((getPerceivedBrightness() >= 0.5f | |||||
| ? Colours::black | |||||
| : Colours::white).withAlpha (amount)); | |||||
| } | } | ||||
| Colour Colour::contrasting (Colour target, float minContrast) const noexcept | Colour Colour::contrasting (Colour target, float minContrast) const noexcept | ||||
| @@ -409,8 +403,8 @@ Colour Colour::contrasting (Colour target, float minContrast) const noexcept | |||||
| Colour Colour::contrasting (Colour colour1, | Colour Colour::contrasting (Colour colour1, | ||||
| Colour colour2) noexcept | Colour colour2) noexcept | ||||
| { | { | ||||
| const float b1 = ColourHelpers::getPerceivedBrightness (colour1); | |||||
| const float b2 = ColourHelpers::getPerceivedBrightness (colour2); | |||||
| const float b1 = colour1.getPerceivedBrightness(); | |||||
| const float b2 = colour2.getPerceivedBrightness(); | |||||
| float best = 0.0f; | float best = 0.0f; | ||||
| float bestDist = 0.0f; | float bestDist = 0.0f; | ||||
| @@ -243,6 +243,12 @@ public: | |||||
| */ | */ | ||||
| float getBrightness() const noexcept; | float getBrightness() const noexcept; | ||||
| /** Returns a skewed brightness value, adjusted to better reflect the way the human | |||||
| eye responds to different colour channels. This makes it better than getBrightness() | |||||
| for comparing differences in brightness. | |||||
| */ | |||||
| float getPerceivedBrightness() const noexcept; | |||||
| /** Returns the colour's hue, saturation and brightness components all at once. | /** Returns the colour's hue, saturation and brightness components all at once. | ||||
| The values returned are in the range 0.0 to 1.0 | The values returned are in the range 0.0 to 1.0 | ||||
| */ | */ | ||||
| @@ -225,10 +225,13 @@ void LookAndFeel_V3::drawTabButton (TabBarButton& button, Graphics& g, bool isMo | |||||
| if (TabbedButtonBar* bar = button.findParentComponentOfClass<TabbedButtonBar>()) | if (TabbedButtonBar* bar = button.findParentComponentOfClass<TabbedButtonBar>()) | ||||
| { | { | ||||
| if (button.isFrontTab() && bar->isColourSpecified (TabbedButtonBar::frontTextColourId)) | |||||
| col = bar->findColour (TabbedButtonBar::frontTextColourId); | |||||
| else if (bar->isColourSpecified (TabbedButtonBar::tabTextColourId)) | |||||
| col = bar->findColour (TabbedButtonBar::tabTextColourId); | |||||
| TabbedButtonBar::ColourIds colID = button.isFrontTab() ? TabbedButtonBar::frontTextColourId | |||||
| : TabbedButtonBar::tabTextColourId; | |||||
| if (bar->isColourSpecified (colID)) | |||||
| col = bar->findColour (colID); | |||||
| else if (isColourSpecified (colID)) | |||||
| col = findColour (colID); | |||||
| } | } | ||||
| const Rectangle<float> area (button.getTextArea().toFloat()); | const Rectangle<float> area (button.getTextArea().toFloat()); | ||||
| @@ -102,7 +102,6 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||||
| args.add (startPath); | args.add (startPath); | ||||
| args.add (filters.replaceCharacter (';', ' ')); | args.add (filters.replaceCharacter (';', ' ')); | ||||
| args.add ("2>/dev/null"); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -136,6 +135,8 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||||
| args.add ("--filename=" + file.getFileName()); | args.add ("--filename=" + file.getFileName()); | ||||
| } | } | ||||
| args.add ("2>/dev/null"); // (to avoid logging info ending up in the results) | |||||
| ChildProcess child; | ChildProcess child; | ||||
| if (child.start (args, ChildProcess::wantStdOut)) | if (child.start (args, ChildProcess::wantStdOut)) | ||||
| @@ -165,18 +165,20 @@ juce_wchar CodeDocument::Iterator::nextChar() noexcept | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| const juce_wchar result = charPointer.getAndAdvance(); | |||||
| if (result == 0) | |||||
| { | |||||
| ++line; | |||||
| charPointer = nullptr; | |||||
| } | |||||
| else | |||||
| if (const juce_wchar result = charPointer.getAndAdvance()) | |||||
| { | { | ||||
| if (charPointer.isEmpty()) | |||||
| { | |||||
| ++line; | |||||
| charPointer = nullptr; | |||||
| } | |||||
| ++position; | ++position; | ||||
| return result; | return result; | ||||
| } | } | ||||
| ++line; | |||||
| charPointer = nullptr; | |||||
| } | } | ||||
| } | } | ||||
| @@ -212,9 +214,7 @@ juce_wchar CodeDocument::Iterator::peekNextChar() const noexcept | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| const juce_wchar c = *charPointer; | |||||
| if (c != 0) | |||||
| if (const juce_wchar c = *charPointer) | |||||
| return c; | return c; | ||||
| if (const CodeDocumentLine* const l = document->lines [line + 1]) | if (const CodeDocumentLine* const l = document->lines [line + 1]) | ||||
| @@ -116,7 +116,7 @@ public: | |||||
| if (previousCommand != 0) | if (previousCommand != 0) | ||||
| message << "\n\n(" | message << "\n\n(" | ||||
| << TRANS("Currently assigned to \"CMDN\"") | << TRANS("Currently assigned to \"CMDN\"") | ||||
| .replace ("CMDN", owner.getCommandManager().getNameOfCommand (previousCommand)) | |||||
| .replace ("CMDN", TRANS (owner.getCommandManager().getNameOfCommand (previousCommand))) | |||||
| << ')'; | << ')'; | ||||
| setMessage (message); | setMessage (message); | ||||