| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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; | |||
| /** @} */ | |||
| @@ -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); | |||
| @@ -610,6 +610,9 @@ void carla_nsm_ready(int action) | |||
| { | |||
| #ifdef HAVE_LIBLO | |||
| CarlaNSM::getInstance().ready(action); | |||
| #else | |||
| // unused | |||
| return; (void)action; | |||
| #endif | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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<uint>(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); i<count; ++i) | |||
| for (uint32_t i=0, count=jmin(fPlugin->getAudioInCount(), numChanu); i<count; ++i) | |||
| inPeaks[i] = carla_findMaxNormalizedFloat(audioBuffers[i], numSamples); | |||
| fPlugin->process(const_cast<const float**>(audioBuffers), audioBuffers, nullptr, nullptr, numSamples); | |||
| for (uint32_t i=0, count=jmin(fPlugin->getAudioOutCount(), 2U); i<count; ++i) | |||
| for (uint32_t i=0, count=jmin(fPlugin->getAudioOutCount(), numChanu); i<count; ++i) | |||
| outPeaks[i] = carla_findMaxNormalizedFloat(audioBuffers[i], numSamples); | |||
| kEngine->setPluginPeaks(fPlugin->getId(), inPeaks, outPeaks); | |||
| @@ -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<uint8_t>(mdataTmp, midiEvent.data, size); | |||
| // add channel | |||
| mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // set first byte | |||
| mdataTmp[0] = static_cast<uint8_t>(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // copy rest | |||
| carla_copy<uint8_t>(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<int>(portNameToId.port), static_cast<int>(canvasPortFlags), 0.0f, portNameToId.name); | |||
| fUsedPorts.list.append(portNameToId); | |||
| return; // unused | |||
| (void)portIsOSC; | |||
| } | |||
| #endif | |||
| @@ -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<uint8_t>(mdataTmp, midiEvent.data, size); | |||
| // add channel | |||
| mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // set first byte | |||
| mdataTmp[0] = static_cast<uint8_t>(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // copy rest | |||
| carla_copy<uint8_t>(mdataTmp+1, midiEvent.data+1, size-1); | |||
| // done | |||
| mdataPtr = mdataTmp; | |||
| } | |||
| @@ -2027,7 +2027,7 @@ public: | |||
| const std::size_t instanceCount(fHandles.count()); | |||
| if (fDescriptor->cleanup == nullptr) | |||
| if (fDescriptor->cleanup != nullptr) | |||
| { | |||
| for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin2(); it.valid(); it.next()) | |||
| { | |||
| @@ -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: | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin, LADSPA implementation | |||
| * Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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<LADSPA_Handle>::Itenerator it = fHandles.begin2(); it.valid(); it.next()) | |||
| { | |||
| @@ -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 | |||
| @@ -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<uint8_t>(mdataTmp, midiEvent.data, size); | |||
| // add channel | |||
| mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // set first byte | |||
| mdataTmp[0] = static_cast<uint8_t>(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // copy rest | |||
| carla_copy<uint8_t>(mdataTmp+1, midiEvent.data+1, size-1); | |||
| // done | |||
| mdataPtr = mdataTmp; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| continue; | |||
| } | |||
| if (size > 0 && ! writeMidiEvent(port, engineEvent.time, size, mdataPtr)) | |||
| break; | |||
| @@ -2,7 +2,7 @@ | |||
| # -*- coding: utf-8 -*- | |||
| # Carla Backend code | |||
| # Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com> | |||
| # Copyright (C) 2011-2018 Filipe Coelho <falktx@falktx.com> | |||
| # | |||
| # 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 | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla JACK API for external applications | |||
| * Copyright (C) 2016-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2016-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| @@ -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; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Native Plugins | |||
| * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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) | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Native Plugins | |||
| * Copyright (C) 2013-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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) | |||
| @@ -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 <falktx@falktx.com> | |||
| * Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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); | |||
| @@ -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<uint8_t>(mdataTmp, midiEvent.data, size); | |||
| // add channel | |||
| mdataTmp[0] = static_cast<uint8_t>(mdataTmp[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // set first byte | |||
| mdataTmp[0] = static_cast<uint8_t>(midiEvent.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT)); | |||
| // copy rest | |||
| carla_copy<uint8_t>(mdataTmp+1, midiEvent.data+1, size-1); | |||
| // done | |||
| mdataPtr = mdataTmp; | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Pipe Utilities | |||
| * Copyright (C) 2013-2017 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Ring Buffer | |||
| * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla String | |||
| * Copyright (C) 2013-2016 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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<uint>(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; | |||
| } | |||
| } | |||