diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index ff8a67ab4..cfde1bcc7 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -329,22 +329,27 @@ static const uint PARAMETER_USES_CUSTOM_TEXT = 0x400; * Patchbay port is input. * When this hint is not set, port is assumed to be output. */ -static const uint PATCHBAY_PORT_IS_INPUT = 0x1; +static const uint PATCHBAY_PORT_IS_INPUT = 0x01; /*! * Patchbay port is of Audio type. */ -static const uint PATCHBAY_PORT_TYPE_AUDIO = 0x2; +static const uint PATCHBAY_PORT_TYPE_AUDIO = 0x02; /*! * Patchbay port is of CV type (Control Voltage). */ -static const uint PATCHBAY_PORT_TYPE_CV = 0x4; +static const uint PATCHBAY_PORT_TYPE_CV = 0x04; /*! * Patchbay port is of MIDI type. */ -static const uint PATCHBAY_PORT_TYPE_MIDI = 0x8; +static const uint PATCHBAY_PORT_TYPE_MIDI = 0x08; + +/*! + * Patchbay port is of OSC type. + */ +static const uint PATCHBAY_PORT_TYPE_OSC = 0x10; /** @} */ diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index e40c61658..db899aa8e 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -1181,11 +1181,14 @@ public: // Engine initializers // JACK - static CarlaEngine* newJack(); + static CarlaEngine* newJack(); #ifdef BUILD_BRIDGE // Bridge - static CarlaEngine* newBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName); + static CarlaEngine* newBridge(const char* const audioPoolBaseName, + const char* const rtClientBaseName, + const char* const nonRtClientBaseName, + const char* const nonRtServerBaseName); #else // RtAudio static CarlaEngine* newRtAudio(const AudioApi api); diff --git a/source/backend/CarlaStandaloneNSM.cpp b/source/backend/CarlaStandaloneNSM.cpp index 8e30654e0..064de5566 100644 --- a/source/backend/CarlaStandaloneNSM.cpp +++ b/source/backend/CarlaStandaloneNSM.cpp @@ -610,6 +610,9 @@ void carla_nsm_ready(int action) { #ifdef HAVE_LIBLO CarlaNSM::getInstance().ready(action); +#else + // unused + return; (void)action; #endif } diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 7753075bf..1e0a706e1 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -100,7 +100,6 @@ const char* CarlaEngine::getDriverName(const uint index2) { if (index < count) return getRtAudioApiName(index); - index -= count; } #endif @@ -125,7 +124,6 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index2) { if (index < count) return getRtAudioApiDeviceNames(index); - index -= count; } #endif @@ -154,7 +152,6 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2 { if (index < count) return getRtAudioDeviceInfo(index, deviceName); - index -= count; } #endif diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index 3ae596213..97ce586a9 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -1179,6 +1179,8 @@ public: if (const int numChan = audio.getNumChannels()) { + const uint numChanu = static_cast(jmin(numChan, 2)); + if (fPlugin->getAudioInCount() == 0) audio.clear(); @@ -1190,12 +1192,12 @@ public: float inPeaks[2] = { 0.0f }; float outPeaks[2] = { 0.0f }; - for (uint32_t i=0, count=jmin(fPlugin->getAudioInCount(), 2U); igetAudioInCount(), numChanu); iprocess(const_cast(audioBuffers), audioBuffers, nullptr, nullptr, numSamples); - for (uint32_t i=0, count=jmin(fPlugin->getAudioOutCount(), 2U); igetAudioOutCount(), numChanu); isetPluginPeaks(fPlugin->getId(), inPeaks, outPeaks); diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 05aa0627e..3dc793af1 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -1724,10 +1724,10 @@ protected: { jackbridge_midi_clear_buffer(eventOut); - uint8_t size = 0; - uint8_t mdata[3] = { 0, 0, 0 }; - const uint8_t* mdataPtr = mdata; - uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + uint8_t size = 0; + uint8_t mdata[3] = { 0, 0, 0 }; + uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + const uint8_t* mdataPtr; for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) { @@ -1749,6 +1749,7 @@ protected: const EngineMidiEvent& midiEvent(engineEvent.midi); size = midiEvent.size; + CARLA_SAFE_ASSERT_CONTINUE(size > 0); if (size > EngineMidiEvent::kDataSize) { @@ -1757,10 +1758,12 @@ protected: } else { - // copy - carla_copy(mdataTmp, midiEvent.data, size); - // add channel - mdataTmp[0] = static_cast(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + // set first byte + mdataTmp[0] = static_cast(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + + // copy rest + carla_copy(mdataTmp+1, midiEvent.data+1, size-1); + // done mdataPtr = mdataTmp; } @@ -2236,7 +2239,10 @@ private: char* value = nullptr; char* type = nullptr; - if (jackbridge_get_property(uuid, JACKEY_SIGNAL_TYPE, &value, &type) && value != nullptr && type != nullptr && std::strcmp(type, "text/plain") == 0) + if (jackbridge_get_property(uuid, JACKEY_SIGNAL_TYPE, &value, &type) + && value != nullptr + && type != nullptr + && std::strcmp(type, "text/plain") == 0) { portIsCV = (std::strcmp(value, "CV") == 0); portIsOSC = (std::strcmp(value, "OSC") == 0); @@ -2246,8 +2252,10 @@ private: uint canvasPortFlags = 0x0; canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0; - if (portIsCV) + /**/ if (portIsCV) canvasPortFlags |= PATCHBAY_PORT_TYPE_CV; + else if (portIsOSC) + canvasPortFlags |= PATCHBAY_PORT_TYPE_OSC; else if (portIsAudio) canvasPortFlags |= PATCHBAY_PORT_TYPE_AUDIO; else if (portIsMIDI) @@ -2258,9 +2266,6 @@ private: callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast(portNameToId.port), static_cast(canvasPortFlags), 0.0f, portNameToId.name); fUsedPorts.list.append(portNameToId); - - return; // unused - (void)portIsOSC; } #endif diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index 42bf8107b..89c3659fb 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -674,10 +674,10 @@ protected: if (fMidiOuts.count() > 0) { - uint8_t size = 0; - uint8_t mdata[3] = { 0, 0, 0 }; - const uint8_t* mdataPtr = mdata; - uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + uint8_t size = 0; + uint8_t mdata[3] = { 0, 0, 0 }; + uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + const uint8_t* mdataPtr; for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) { @@ -699,6 +699,7 @@ protected: const EngineMidiEvent& midiEvent(engineEvent.midi); size = midiEvent.size; + CARLA_SAFE_ASSERT_CONTINUE(size > 0); if (size > EngineMidiEvent::kDataSize) { @@ -707,10 +708,12 @@ protected: } else { - // copy - carla_copy(mdataTmp, midiEvent.data, size); - // add channel - mdataTmp[0] = static_cast(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + // set first byte + mdataTmp[0] = static_cast(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + + // copy rest + carla_copy(mdataTmp+1, midiEvent.data+1, size-1); + // done mdataPtr = mdataTmp; } diff --git a/source/backend/plugin/CarlaPluginDSSI.cpp b/source/backend/plugin/CarlaPluginDSSI.cpp index 73512d788..4d3cec257 100644 --- a/source/backend/plugin/CarlaPluginDSSI.cpp +++ b/source/backend/plugin/CarlaPluginDSSI.cpp @@ -2027,7 +2027,7 @@ public: const std::size_t instanceCount(fHandles.count()); - if (fDescriptor->cleanup == nullptr) + if (fDescriptor->cleanup != nullptr) { for (LinkedList::Itenerator it = fHandles.begin2(); it.valid(); it.next()) { diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp index e7727980b..60a5953ed 100644 --- a/source/backend/plugin/CarlaPluginJack.cpp +++ b/source/backend/plugin/CarlaPluginJack.cpp @@ -1150,12 +1150,14 @@ public: case kPluginBridgeNonRtServerSetCustomData: break; - case kPluginBridgeNonRtServerSetChunkDataFile: { + case kPluginBridgeNonRtServerSetChunkDataFile: // uint/size, str[] (filename) - const uint32_t chunkFilePathSize(fShmNonRtServerControl.readUInt()); - char chunkFilePath[chunkFilePathSize]; - fShmNonRtServerControl.readCustomData(chunkFilePath, chunkFilePathSize); - } break; + if (const uint32_t chunkFilePathSize = fShmNonRtServerControl.readUInt()) + { + char chunkFilePath[chunkFilePathSize]; + fShmNonRtServerControl.readCustomData(chunkFilePath, chunkFilePathSize); + } + break; case kPluginBridgeNonRtServerSetLatency: case kPluginBridgeNonRtServerSetParameterText: diff --git a/source/backend/plugin/CarlaPluginLADSPA.cpp b/source/backend/plugin/CarlaPluginLADSPA.cpp index eea5cb7f3..1f526bef4 100644 --- a/source/backend/plugin/CarlaPluginLADSPA.cpp +++ b/source/backend/plugin/CarlaPluginLADSPA.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin, LADSPA implementation - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -1363,7 +1363,7 @@ public: const std::size_t instanceCount(fHandles.count()); - if (fDescriptor->cleanup == nullptr) + if (fDescriptor->cleanup != nullptr) { for (LinkedList::Itenerator it = fHandles.begin2(); it.valid(); it.next()) { diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index a40b3e32a..23cb2534c 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -5252,8 +5252,8 @@ public: // --------------------------------------------------------------- // find the most appropriate ui - int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, eExt, iCocoa, iWindows, iX11, iExt, iFinal; - eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = eExt = iCocoa = iWindows = iX11 = iExt = iFinal = -1; + int eQt4, eQt5, eGtk2, eGtk3, eCocoa, eWindows, eX11, iCocoa, iWindows, iX11, iExt, iFinal; + eQt4 = eQt5 = eGtk2 = eGtk3 = eCocoa = eWindows = eX11 = iCocoa = iWindows = iX11 = iExt = iFinal = -1; #if defined(BUILD_BRIDGE) || defined(LV2_UIS_ONLY_BRIDGES) const bool preferUiBridges(true); @@ -5286,16 +5286,20 @@ public: if (isUiBridgeable(i)) eGtk3 = ii; break; +#ifdef CARLA_OS_MAC case LV2_UI_COCOA: if (isUiBridgeable(i) && preferUiBridges) eCocoa = ii; iCocoa = ii; break; +#endif +#ifdef CARLA_OS_WIN case LV2_UI_WINDOWS: if (isUiBridgeable(i) && preferUiBridges) eWindows = ii; iWindows = ii; break; +#endif case LV2_UI_X11: if (isUiBridgeable(i) && preferUiBridges) eX11 = ii; @@ -5303,8 +5307,6 @@ public: break; case LV2_UI_EXTERNAL: case LV2_UI_OLD_EXTERNAL: - if (isUiBridgeable(i)) - eExt = ii; iExt = ii; break; default: @@ -5332,8 +5334,6 @@ public: else if (eX11 >= 0) iFinal = eX11; #endif - //else if (eExt >= 0) // TODO - // iFinal = eExt; #ifndef LV2_UIS_ONLY_BRIDGES # ifdef CARLA_OS_MAC else if (iCocoa >= 0) @@ -5421,7 +5421,7 @@ public: if ( (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || - iFinal == eCocoa || iFinal == eWindows || iFinal == eX11 || iFinal == eExt) + iFinal == eCocoa || iFinal == eWindows || iFinal == eX11) #ifdef BUILD_BRIDGE && preferUiBridges && ! hasShowInterface #endif diff --git a/source/bridges-plugin/CarlaBridgeSingleLV2.cpp b/source/bridges-plugin/CarlaBridgeSingleLV2.cpp index b9f03c805..5cb6ad199 100644 --- a/source/bridges-plugin/CarlaBridgeSingleLV2.cpp +++ b/source/bridges-plugin/CarlaBridgeSingleLV2.cpp @@ -197,11 +197,11 @@ public: if (fPorts.numMidiOuts > 0) { - uint8_t port = 0; - uint8_t size = 0; - uint8_t mdata[3] = { 0, 0, 0 }; - const uint8_t* mdataPtr = mdata; - uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + uint8_t port = 0; + uint8_t size = 0; + uint8_t mdata[3] = { 0, 0, 0 }; + uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + const uint8_t* mdataPtr; for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) { @@ -224,6 +224,7 @@ public: port = midiEvent.port; size = midiEvent.size; + CARLA_SAFE_ASSERT_CONTINUE(size > 0); if (size > EngineMidiEvent::kDataSize) { @@ -232,14 +233,20 @@ public: } else { - // copy - carla_copy(mdataTmp, midiEvent.data, size); - // add channel - mdataTmp[0] = static_cast(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + // set first byte + mdataTmp[0] = static_cast(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + + // copy rest + carla_copy(mdataTmp+1, midiEvent.data+1, size-1); + // done mdataPtr = mdataTmp; } } + else + { + continue; + } if (size > 0 && ! writeMidiEvent(port, engineEvent.time, size, mdataPtr)) break; diff --git a/source/carla_backend.py b/source/carla_backend.py index 37372dc85..1d8955ee1 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # Carla Backend code -# Copyright (C) 2011-2017 Filipe Coelho +# Copyright (C) 2011-2018 Filipe Coelho # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -300,16 +300,19 @@ PARAMETER_USES_CUSTOM_TEXT = 0x400 # Patchbay port is input. # When this hint is not set, port is assumed to be output. -PATCHBAY_PORT_IS_INPUT = 0x1 +PATCHBAY_PORT_IS_INPUT = 0x01 # Patchbay port is of Audio type. -PATCHBAY_PORT_TYPE_AUDIO = 0x2 +PATCHBAY_PORT_TYPE_AUDIO = 0x02 # Patchbay port is of CV type (Control Voltage). -PATCHBAY_PORT_TYPE_CV = 0x4 +PATCHBAY_PORT_TYPE_CV = 0x04 # Patchbay port is of MIDI type. -PATCHBAY_PORT_TYPE_MIDI = 0x8 +PATCHBAY_PORT_TYPE_MIDI = 0x08 + +# Patchbay port is of OSC type. +PATCHBAY_PORT_TYPE_OSC = 0x10 # ------------------------------------------------------------------------------------------------------------ # Custom Data Types diff --git a/source/libjack/libjack.cpp b/source/libjack/libjack.cpp index dc3685e45..c22445be2 100644 --- a/source/libjack/libjack.cpp +++ b/source/libjack/libjack.cpp @@ -1,6 +1,6 @@ /* * Carla JACK API for external applications - * Copyright (C) 2016-2017 Filipe Coelho + * Copyright (C) 2016-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -672,7 +672,7 @@ bool CarlaJackAppClient::handleRtData() if (i < fServer.numAudioIns) { const std::size_t remainingBufferSize = fServer.bufferSize * (fServer.numAudioIns - i); - fdataReal += remainingBufferSize; + //fdataReal += remainingBufferSize; fdataCopy += remainingBufferSize; } @@ -701,7 +701,7 @@ bool CarlaJackAppClient::handleRtData() { const std::size_t remainingBufferSize = fServer.bufferSize * (fServer.numAudioOuts - i); carla_zeroFloats(fdataCopy, remainingBufferSize); - fdataCopy += remainingBufferSize; + //fdataCopy += remainingBufferSize; } // set midi inputs diff --git a/source/modules/water/buffers/AudioSampleBuffer.h b/source/modules/water/buffers/AudioSampleBuffer.h index 4f2511f89..c3b6c7b69 100644 --- a/source/modules/water/buffers/AudioSampleBuffer.h +++ b/source/modules/water/buffers/AudioSampleBuffer.h @@ -219,7 +219,7 @@ public: */ const float* getReadPointer (int channelNumber) const noexcept { - jassert (isPositiveAndBelow (channelNumber, numChannels)); + CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (channelNumber, numChannels), nullptr); return channels [channelNumber]; } @@ -232,8 +232,8 @@ public: */ const float* getReadPointer (int channelNumber, int sampleIndex) const noexcept { - jassert (isPositiveAndBelow (channelNumber, numChannels)); - jassert (isPositiveAndBelow (sampleIndex, size)); + CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (channelNumber, numChannels), nullptr); + CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (sampleIndex, size), nullptr); return channels [channelNumber] + sampleIndex; } @@ -245,7 +245,7 @@ public: */ float* getWritePointer (int channelNumber) noexcept { - jassert (isPositiveAndBelow (channelNumber, numChannels)); + CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (channelNumber, numChannels), nullptr); isClear = false; return channels [channelNumber]; } @@ -258,8 +258,8 @@ public: */ float* getWritePointer (int channelNumber, int sampleIndex) noexcept { - jassert (isPositiveAndBelow (channelNumber, numChannels)); - jassert (isPositiveAndBelow (sampleIndex, size)); + CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (channelNumber, numChannels), nullptr); + CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (sampleIndex, size), nullptr); isClear = false; return channels [channelNumber] + sampleIndex; } @@ -449,143 +449,6 @@ public: bool hasBeenCleared() const noexcept { return isClear; } //============================================================================== - /** Returns a sample from the buffer. - The channel and index are not checked - they are expected to be in-range. If not, - an assertion will be thrown, but in a release build, you're into 'undefined behaviour' - territory. - */ - float getSample (int channel, int sampleIndex) const noexcept - { - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (sampleIndex, size)); - return *(channels [channel] + sampleIndex); - } - - /** Sets a sample in the buffer. - The channel and index are not checked - they are expected to be in-range. If not, - an assertion will be thrown, but in a release build, you're into 'undefined behaviour' - territory. - */ - void setSample (int destChannel, int destSample, float newValue) noexcept - { - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (isPositiveAndBelow (destSample, size)); - *(channels [destChannel] + destSample) = newValue; - isClear = false; - } - - /** Adds a value to a sample in the buffer. - The channel and index are not checked - they are expected to be in-range. If not, - an assertion will be thrown, but in a release build, you're into 'undefined behaviour' - territory. - */ - void addSample (int destChannel, int destSample, float valueToAdd) noexcept - { - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (isPositiveAndBelow (destSample, size)); - *(channels [destChannel] + destSample) += valueToAdd; - isClear = false; - } - - /** Applies a gain multiple to a region of one channel. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! - */ - void applyGain (int channel, - int startSample, - int numSamples, - float gain) noexcept - { - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (gain != 1.0f && ! isClear) - { - float* const d = channels [channel] + startSample; - - if (carla_isZero (gain)) - carla_zeroFloats (d, numSamples); - else - carla_multiply (d, gain, numSamples); - } - } - - /** Applies a gain multiple to a region of all the channels. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGain (int startSample, - int numSamples, - float gain) noexcept - { - for (int i = 0; i < numChannels; ++i) - applyGain (i, startSample, numSamples, gain); - } - - /** Applies a gain multiple to all the audio data. */ - void applyGain (float gain) noexcept - { - applyGain (0, size, gain); - } - - /** Applies a range of gains to a region of a channel. - - The gain that is applied to each sample will vary from - startGain on the first sample to endGain on the last Sample, - so it can be used to do basic fades. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGainRamp (int channel, - int startSample, - int numSamples, - float startGain, - float endGain) noexcept - { - if (! isClear) - { - if (startGain == endGain) - { - applyGain (channel, startSample, numSamples, startGain); - } - else - { - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - const float increment = (endGain - startGain) / numSamples; - float* d = channels [channel] + startSample; - - while (--numSamples >= 0) - { - *d++ *= startGain; - startGain += increment; - } - } - } - } - - /** Applies a range of gains to a region of all channels. - - The gain that is applied to each sample will vary from - startGain on the first sample to endGain on the last Sample, - so it can be used to do basic fades. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGainRamp (int startSample, - int numSamples, - float startGain, - float endGain) noexcept - { - for (int i = 0; i < numChannels; ++i) - applyGainRamp (i, startSample, numSamples, startGain, endGain); - } - /** Adds samples from another buffer to this one. @param destChannel the channel within this buffer to add the samples to @@ -682,50 +545,6 @@ public: } } - - /** Adds samples from an array of floats, applying a gain ramp to them. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source data to use - @param numSamples the number of samples to process - @param startGain the gain to apply to the first sample (this is multiplied with - the source samples before they are added to this buffer) - @param endGain the gain to apply to the final sample. The gain is linearly - interpolated between the first and last samples. - */ - void addFromWithRamp (int destChannel, - int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) noexcept - { - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (startGain == endGain) - { - addFrom (destChannel, destStartSample, source, numSamples, startGain); - } - else - { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) - { - isClear = false; - const float increment = (endGain - startGain) / numSamples; - float* d = channels [destChannel] + destStartSample; - - while (--numSamples >= 0) - { - *d++ += startGain * *source++; - startGain += increment; - } - } - } - } - /** Copies samples from another buffer to this one. @param destChannel the channel within this buffer to copy the samples to @@ -837,51 +656,6 @@ public: } } - /** Copies samples from an array of floats into one of the channels, applying a gain ramp. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - @param startGain the gain to apply to the first sample (this is multiplied with - the source samples before they are copied to this buffer) - @param endGain the gain to apply to the final sample. The gain is linearly - interpolated between the first and last samples. - - @see addFrom - */ - void copyFromWithRamp (int destChannel, - int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) noexcept - { - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (startGain == endGain) - { - copyFrom (destChannel, destStartSample, source, numSamples, startGain); - } - else - { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) - { - isClear = false; - const float increment = (endGain - startGain) / numSamples; - float* d = channels [destChannel] + destStartSample; - - while (--numSamples >= 0) - { - *d++ = startGain * *source++; - startGain += increment; - } - } - } - } - private: //============================================================================== int numChannels, size; diff --git a/source/native-plugins/midi-transpose.c b/source/native-plugins/midi-transpose.c index 60a80eaad..bde0b96c2 100644 --- a/source/native-plugins/midi-transpose.c +++ b/source/native-plugins/midi-transpose.c @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2012-2014 Filipe Coelho + * Copyright (C) 2012-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,6 +22,12 @@ // ----------------------------------------------------------------------- +typedef enum { + PARAM_OCTAVES = 0, + PARAM_SEMITONES, + PARAM_COUNT +} MidiTransposeParams; + typedef struct { const NativeHostDescriptor* host; int octaves; @@ -52,7 +58,7 @@ static void miditranspose_cleanup(NativePluginHandle handle) static uint32_t miditranspose_get_parameter_count(NativePluginHandle handle) { - return 2; + return PARAM_COUNT; // unused (void)handle; @@ -60,51 +66,54 @@ static uint32_t miditranspose_get_parameter_count(NativePluginHandle handle) static const NativeParameter* miditranspose_get_parameter_info(NativePluginHandle handle, uint32_t index) { - if (index >= 2) + if (index > PARAM_COUNT) return NULL; - static NativeParameter param[] = + static NativeParameter param; + + param.hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE|NATIVE_PARAMETER_IS_INTEGER; + param.unit = NULL; + param.scalePointCount = 0; + param.scalePoints = NULL; + + switch (index) { - { - .name = "Octaves", - .unit = NULL, - .hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE|NATIVE_PARAMETER_IS_INTEGER, - .ranges.def = 0.0f, - .ranges.min = -8.0f, - .ranges.max = 8.0f, - .ranges.step = 1.0f, - .ranges.stepSmall = 1.0f, - .ranges.stepLarge = 1.0f, - .scalePointCount = 0, - .scalePoints = NULL, - }, - { - .name = "Semitones", - .unit = NULL, - .hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE|NATIVE_PARAMETER_IS_INTEGER, - .ranges.def = 0.0f, - .ranges.min = -12.0f, - .ranges.max = 12.0f, - .ranges.step = 1.0f, - .ranges.stepSmall = 1.0f, - .ranges.stepLarge = 1.0f, - .scalePointCount = 0, - .scalePoints = NULL, - }, - }; - return ¶m[index]; + case PARAM_OCTAVES: + param.name = "Octaves"; + param.ranges.def = 0.0f, + param.ranges.min = -8.0f, + param.ranges.max = 8.0f, + param.ranges.step = 1.0f; + param.ranges.stepSmall = 1.0f; + param.ranges.stepLarge = 4.0f; + break; + case PARAM_SEMITONES: + param.name = "Semitones"; + param.ranges.def = 0.0f, + param.ranges.min = -12.0f, + param.ranges.max = 12.0f, + param.ranges.step = 1.0f; + param.ranges.stepSmall = 1.0f; + param.ranges.stepLarge = 4.0f; + break; + } + + return ¶m; + + // unused + (void)handle; } static float miditranspose_get_parameter_value(NativePluginHandle handle, uint32_t index) { switch (index) { - case 0: - return (float)handlePtr->octaves; - case 1: - return (float)handlePtr->semitones; - default: - return 0.0f; + case PARAM_OCTAVES: + return (float)handlePtr->octaves; + case PARAM_SEMITONES: + return (float)handlePtr->semitones; + default: + return 0.0f; } } @@ -112,16 +121,13 @@ static void miditranspose_set_parameter_value(NativePluginHandle handle, uint32_ { switch (index) { - case 0: - handlePtr->octaves = (int)value; - break; - case 1: - handlePtr->semitones = (int)value; - break; - default: - return; + case PARAM_OCTAVES: + handlePtr->octaves = (int)value; + break; + case PARAM_SEMITONES: + handlePtr->semitones = (int)value; + break; } - } static void miditranspose_process(NativePluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount) diff --git a/source/plugin/carla-lv2.cpp b/source/plugin/carla-lv2.cpp index 6bbe17a05..a9c2f904a 100644 --- a/source/plugin/carla-lv2.cpp +++ b/source/plugin/carla-lv2.cpp @@ -1,6 +1,6 @@ /* * Carla Native Plugins - * Copyright (C) 2013-2017 Filipe Coelho + * Copyright (C) 2013-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -191,7 +191,10 @@ public: for (uint32_t i=0; i < fPorts.numMidiIns; ++i) { - LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], event) + const LV2_Atom_Sequence* const eventsIn(fPorts.eventsIn[i]); + CARLA_SAFE_ASSERT_CONTINUE(eventsIn != nullptr); + + LV2_ATOM_SEQUENCE_FOREACH(eventsIn, event) { if (event == nullptr) continue; @@ -410,20 +413,24 @@ public: for (int i=0; features[i] != nullptr; ++i) { - if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) == 0) + if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) != 0) + continue; + + const LV2_Options_Option* const options((const LV2_Options_Option*)features[i]->data); + CARLA_SAFE_ASSERT_BREAK(options != nullptr); + + for (int j=0; options[j].key != 0; ++j) { - const LV2_Options_Option* const options((const LV2_Options_Option*)features[i]->data); + if (options[j].key != fUridMap->map(fUridMap->handle, LV2_UI__windowTitle)) + continue; - for (int j=0; options[j].key != 0; ++j) - { - if (options[j].key == fUridMap->map(fUridMap->handle, LV2_UI__windowTitle)) - { - fHost.uiName = carla_strdup((const char*)options[j].value); - break; - } - } + const char* const title((const char*)options[j].value); + CARLA_SAFE_ASSERT_BREAK(title != nullptr && title[0] != '\0'); + + fHost.uiName = carla_strdup(title); break; } + break; } if (fHost.uiName == nullptr) diff --git a/source/theme/CarlaStyle.cpp b/source/theme/CarlaStyle.cpp index ac98dd4bc..a080f59fa 100644 --- a/source/theme/CarlaStyle.cpp +++ b/source/theme/CarlaStyle.cpp @@ -1,7 +1,7 @@ /* * Carla Style, based on Qt5 fusion style * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies) - * Copyright (C) 2013-2014 Filipe Coelho + * Copyright (C) 2013-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -2115,11 +2115,13 @@ void CarlaStyle::drawControl(ControlElement element, const QStyleOption *option, int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget); rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0); +#if 0 QRect r2(rect); int x1 = r2.left(); int x2 = r2.right(); int y1 = r2.top(); int y2 = r2.bottom(); +#endif painter->setPen(d->innerContrastLine()); @@ -2155,6 +2157,7 @@ void CarlaStyle::drawControl(ControlElement element, const QStyleOption *option, } if (flip) { +#if 0 QRect tmp = rect; rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width()); int temp = x1; @@ -2163,6 +2166,7 @@ void CarlaStyle::drawControl(ControlElement element, const QStyleOption *option, temp = x2; x2 = y2; y2 = temp; +#endif } painter->setRenderHint(QPainter::Antialiasing, true); diff --git a/source/utils/CarlaEngineUtils.hpp b/source/utils/CarlaEngineUtils.hpp index ab92bdca1..ca0a10181 100644 --- a/source/utils/CarlaEngineUtils.hpp +++ b/source/utils/CarlaEngineUtils.hpp @@ -151,10 +151,10 @@ void fillEngineEventsFromWaterMidiBuffer(EngineEvent engineEvents[kMaxEngineEven static inline void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const EngineEvent engineEvents[kMaxEngineEventInternalCount]) { - uint8_t size = 0; - uint8_t mdata[3] = { 0, 0, 0 }; - const uint8_t* mdataPtr = mdata; - uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + uint8_t size = 0; + uint8_t mdata[3] = { 0, 0, 0 }; + uint8_t mdataTmp[EngineMidiEvent::kDataSize]; + const uint8_t* mdataPtr; for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) { @@ -176,6 +176,7 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En const EngineMidiEvent& midiEvent(engineEvent.midi); size = midiEvent.size; + CARLA_SAFE_ASSERT_CONTINUE(size > 0); if (size > EngineMidiEvent::kDataSize) { @@ -184,10 +185,12 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En } else { - // copy - carla_copy(mdataTmp, midiEvent.data, size); - // add channel - mdataTmp[0] = static_cast(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + // set first byte + mdataTmp[0] = static_cast(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); + + // copy rest + carla_copy(mdataTmp+1, midiEvent.data+1, size-1); + // done mdataPtr = mdataTmp; } diff --git a/source/utils/CarlaPipeUtils.cpp b/source/utils/CarlaPipeUtils.cpp index c551a3bbd..14d143c86 100644 --- a/source/utils/CarlaPipeUtils.cpp +++ b/source/utils/CarlaPipeUtils.cpp @@ -1,6 +1,6 @@ /* * Carla Pipe Utilities - * Copyright (C) 2013-2017 Filipe Coelho + * Copyright (C) 2013-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -1123,7 +1123,7 @@ uintptr_t CarlaPipeServer::getPID() const noexcept #endif } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- bool CarlaPipeServer::startPipeServer(const char* const filename, const char* const arg1, @@ -1155,7 +1155,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, const CarlaMutexLocker cml(pData->writeLock); - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // create pipes #ifdef CARLA_OS_WIN @@ -1220,7 +1220,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, std::snprintf(pipeRecvClientStr, 100, "%i", pipeRecvClient); std::snprintf(pipeSendClientStr, 100, "%i", pipeSendClient); - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // set size, non-fatal #ifdef CARLA_OS_LINUX @@ -1233,7 +1233,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, } CARLA_SAFE_EXCEPTION("Set pipe size"); #endif - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // set non-block int ret; @@ -1265,23 +1265,23 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, } #endif - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // set arguments const char* argv[8]; - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // argv[0] => filename argv[0] = filename; - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // argv[1-2] => args argv[1] = arg1; argv[2] = arg2; - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // argv[3-6] => pipes argv[3] = pipeRecvServerStr; @@ -1289,12 +1289,12 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, argv[5] = pipeRecvClientStr; argv[6] = pipeSendClientStr; - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // argv[7] => null argv[7] = nullptr; - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // start process #ifdef CARLA_OS_WIN @@ -1324,15 +1324,14 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, return false; } - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // close duplicated handles used by the client try { ::close(pipeRecvServer); } CARLA_SAFE_EXCEPTION("close(pipeRecvServer)"); try { ::close(pipeSendServer); } CARLA_SAFE_EXCEPTION("close(pipeSendServer)"); - pipeRecvServer = pipeSendServer = INVALID_PIPE_VALUE; #endif - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // wait for client to say something if (waitForClientFirstMessage(pipeRecvClient, 10*1000 /* 10 secs */)) @@ -1347,7 +1346,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, return true; } - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // failed to set non-block or get first child message, cannot continue #ifdef CARLA_OS_WIN @@ -1372,7 +1371,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, pData->pid = -1; #endif - //---------------------------------------------------------------- + //----------------------------------------------------------------------------------------------------------------- // close pipes #ifdef CARLA_OS_WIN @@ -1544,7 +1543,6 @@ bool CarlaPipeClient::initPipeClient(const char* argv[]) noexcept try { ::close(pipeRecvClient); } CARLA_SAFE_EXCEPTION("close(pipeRecvClient)"); try { ::close(pipeSendClient); } CARLA_SAFE_EXCEPTION("close(pipeSendClient)"); - pipeRecvClient = pipeSendClient = INVALID_PIPE_VALUE; //---------------------------------------------------------------- // kill ourselves if parent dies diff --git a/source/utils/CarlaRingBuffer.hpp b/source/utils/CarlaRingBuffer.hpp index 40e40f7cc..e58cffa30 100644 --- a/source/utils/CarlaRingBuffer.hpp +++ b/source/utils/CarlaRingBuffer.hpp @@ -1,6 +1,6 @@ /* * Carla Ring Buffer - * Copyright (C) 2013-2014 Filipe Coelho + * Copyright (C) 2013-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -320,6 +320,7 @@ protected: bool tryRead(void* const buf, const uint32_t size) noexcept { CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fBuffer->buf != nullptr, false); CARLA_SAFE_ASSERT_RETURN(buf != nullptr, false); CARLA_SAFE_ASSERT_RETURN(size > 0, false); CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size, false); diff --git a/source/utils/CarlaString.hpp b/source/utils/CarlaString.hpp index 52f51182e..c11ac88b0 100644 --- a/source/utils/CarlaString.hpp +++ b/source/utils/CarlaString.hpp @@ -1,6 +1,6 @@ /* * Carla String - * Copyright (C) 2013-2016 Filipe Coelho + * Copyright (C) 2013-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -37,14 +37,16 @@ public: */ explicit CarlaString() noexcept : fBuffer(_null()), - fBufferLen(0) {} + fBufferLen(0), + fBufferAlloc(false) {} /* * Simple character. */ explicit CarlaString(const char c) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char ch[2]; ch[0] = c; @@ -58,7 +60,8 @@ public: */ explicit CarlaString(char* const strBuf) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { _dup(strBuf); } @@ -68,7 +71,8 @@ public: */ explicit CarlaString(const char* const strBuf) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { _dup(strBuf); } @@ -78,7 +82,8 @@ public: */ explicit CarlaString(const int value) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, "%d", value); @@ -92,7 +97,8 @@ public: */ explicit CarlaString(const unsigned int value, const bool hexadecimal = false) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value); @@ -106,7 +112,8 @@ public: */ explicit CarlaString(const long value) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, "%ld", value); @@ -120,7 +127,8 @@ public: */ explicit CarlaString(const unsigned long value, const bool hexadecimal = false) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value); @@ -134,7 +142,8 @@ public: */ explicit CarlaString(const long long value) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, "%lld", value); @@ -148,7 +157,8 @@ public: */ explicit CarlaString(const unsigned long long value, const bool hexadecimal = false) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, hexadecimal ? "0x%llx" : "%llu", value); @@ -162,7 +172,8 @@ public: */ explicit CarlaString(const float value) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, "%f", value); @@ -176,7 +187,8 @@ public: */ explicit CarlaString(const double value) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { char strBuf[0xff+1]; std::snprintf(strBuf, 0xff, "%g", value); @@ -193,7 +205,8 @@ public: */ CarlaString(const CarlaString& str) noexcept : fBuffer(_null()), - fBufferLen(0) + fBufferLen(0), + fBufferAlloc(false) { _dup(str.fBuffer); } @@ -208,13 +221,12 @@ public: { CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - if (fBuffer == _null()) - return; - - std::free(fBuffer); + if (fBufferAlloc) + std::free(fBuffer); - fBuffer = nullptr; - fBufferLen = 0; + fBuffer = nullptr; + fBufferLen = 0; + fBufferAlloc = false; } // ------------------------------------------------------------------- @@ -757,8 +769,9 @@ public: // ------------------------------------------------------------------- private: - char* fBuffer; // the actual string buffer - std::size_t fBufferLen; // string length + char* fBuffer; // the actual string buffer + std::size_t fBufferLen; // string length + bool fBufferAlloc; // wherever the buffer is allocated, not using _null() /* * Static null string. @@ -786,7 +799,7 @@ private: if (std::strcmp(fBuffer, strBuf) == 0) return; - if (fBuffer != _null()) + if (fBufferAlloc) std::free(fBuffer); fBufferLen = (size > 0) ? size : std::strlen(strBuf); @@ -794,28 +807,31 @@ private: if (fBuffer == nullptr) { - fBuffer = _null(); - fBufferLen = 0; + fBuffer = _null(); + fBufferLen = 0; + fBufferAlloc = false; return; } - std::strcpy(fBuffer, strBuf); + fBufferAlloc = true; + std::strcpy(fBuffer, strBuf); fBuffer[fBufferLen] = '\0'; } else { - CARLA_SAFE_ASSERT(size == 0); + CARLA_SAFE_ASSERT_UINT(size == 0, static_cast(size)); // don't recreate null string - if (fBuffer == _null()) + if (! fBufferAlloc) return; CARLA_SAFE_ASSERT(fBuffer != nullptr); std::free(fBuffer); - fBuffer = _null(); - fBufferLen = 0; + fBuffer = _null(); + fBufferLen = 0; + fBufferAlloc = false; } }