| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Plugin Host | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * 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. | * Patchbay port is input. | ||||
| * When this hint is not set, port is assumed to be output. | * 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. | * 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). | * 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. | * 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 | // Engine initializers | ||||
| // JACK | // JACK | ||||
| static CarlaEngine* newJack(); | |||||
| static CarlaEngine* newJack(); | |||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| // 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 | #else | ||||
| // RtAudio | // RtAudio | ||||
| static CarlaEngine* newRtAudio(const AudioApi api); | static CarlaEngine* newRtAudio(const AudioApi api); | ||||
| @@ -610,6 +610,9 @@ void carla_nsm_ready(int action) | |||||
| { | { | ||||
| #ifdef HAVE_LIBLO | #ifdef HAVE_LIBLO | ||||
| CarlaNSM::getInstance().ready(action); | CarlaNSM::getInstance().ready(action); | ||||
| #else | |||||
| // unused | |||||
| return; (void)action; | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Plugin Host | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * 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) | if (index < count) | ||||
| return getRtAudioApiName(index); | return getRtAudioApiName(index); | ||||
| index -= count; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -125,7 +124,6 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index2) | |||||
| { | { | ||||
| if (index < count) | if (index < count) | ||||
| return getRtAudioApiDeviceNames(index); | return getRtAudioApiDeviceNames(index); | ||||
| index -= count; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -154,7 +152,6 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2 | |||||
| { | { | ||||
| if (index < count) | if (index < count) | ||||
| return getRtAudioDeviceInfo(index, deviceName); | return getRtAudioDeviceInfo(index, deviceName); | ||||
| index -= count; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Plugin Host | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -1179,6 +1179,8 @@ public: | |||||
| if (const int numChan = audio.getNumChannels()) | if (const int numChan = audio.getNumChannels()) | ||||
| { | { | ||||
| const uint numChanu = static_cast<uint>(jmin(numChan, 2)); | |||||
| if (fPlugin->getAudioInCount() == 0) | if (fPlugin->getAudioInCount() == 0) | ||||
| audio.clear(); | audio.clear(); | ||||
| @@ -1190,12 +1192,12 @@ public: | |||||
| float inPeaks[2] = { 0.0f }; | float inPeaks[2] = { 0.0f }; | ||||
| float outPeaks[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); | inPeaks[i] = carla_findMaxNormalizedFloat(audioBuffers[i], numSamples); | ||||
| fPlugin->process(const_cast<const float**>(audioBuffers), audioBuffers, nullptr, nullptr, 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); | outPeaks[i] = carla_findMaxNormalizedFloat(audioBuffers[i], numSamples); | ||||
| kEngine->setPluginPeaks(fPlugin->getId(), inPeaks, outPeaks); | kEngine->setPluginPeaks(fPlugin->getId(), inPeaks, outPeaks); | ||||
| @@ -1724,10 +1724,10 @@ protected: | |||||
| { | { | ||||
| jackbridge_midi_clear_buffer(eventOut); | 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) | for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) | ||||
| { | { | ||||
| @@ -1749,6 +1749,7 @@ protected: | |||||
| const EngineMidiEvent& midiEvent(engineEvent.midi); | const EngineMidiEvent& midiEvent(engineEvent.midi); | ||||
| size = midiEvent.size; | size = midiEvent.size; | ||||
| CARLA_SAFE_ASSERT_CONTINUE(size > 0); | |||||
| if (size > EngineMidiEvent::kDataSize) | if (size > EngineMidiEvent::kDataSize) | ||||
| { | { | ||||
| @@ -1757,10 +1758,12 @@ protected: | |||||
| } | } | ||||
| else | 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 | // done | ||||
| mdataPtr = mdataTmp; | mdataPtr = mdataTmp; | ||||
| } | } | ||||
| @@ -2236,7 +2239,10 @@ private: | |||||
| char* value = nullptr; | char* value = nullptr; | ||||
| char* type = 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); | portIsCV = (std::strcmp(value, "CV") == 0); | ||||
| portIsOSC = (std::strcmp(value, "OSC") == 0); | portIsOSC = (std::strcmp(value, "OSC") == 0); | ||||
| @@ -2246,8 +2252,10 @@ private: | |||||
| uint canvasPortFlags = 0x0; | uint canvasPortFlags = 0x0; | ||||
| canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0; | canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0; | ||||
| if (portIsCV) | |||||
| /**/ if (portIsCV) | |||||
| canvasPortFlags |= PATCHBAY_PORT_TYPE_CV; | canvasPortFlags |= PATCHBAY_PORT_TYPE_CV; | ||||
| else if (portIsOSC) | |||||
| canvasPortFlags |= PATCHBAY_PORT_TYPE_OSC; | |||||
| else if (portIsAudio) | else if (portIsAudio) | ||||
| canvasPortFlags |= PATCHBAY_PORT_TYPE_AUDIO; | canvasPortFlags |= PATCHBAY_PORT_TYPE_AUDIO; | ||||
| else if (portIsMIDI) | 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); | 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); | fUsedPorts.list.append(portNameToId); | ||||
| return; // unused | |||||
| (void)portIsOSC; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -674,10 +674,10 @@ protected: | |||||
| if (fMidiOuts.count() > 0) | 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) | for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) | ||||
| { | { | ||||
| @@ -699,6 +699,7 @@ protected: | |||||
| const EngineMidiEvent& midiEvent(engineEvent.midi); | const EngineMidiEvent& midiEvent(engineEvent.midi); | ||||
| size = midiEvent.size; | size = midiEvent.size; | ||||
| CARLA_SAFE_ASSERT_CONTINUE(size > 0); | |||||
| if (size > EngineMidiEvent::kDataSize) | if (size > EngineMidiEvent::kDataSize) | ||||
| { | { | ||||
| @@ -707,10 +708,12 @@ protected: | |||||
| } | } | ||||
| else | 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 | // done | ||||
| mdataPtr = mdataTmp; | mdataPtr = mdataTmp; | ||||
| } | } | ||||
| @@ -2027,7 +2027,7 @@ public: | |||||
| const std::size_t instanceCount(fHandles.count()); | 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()) | for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin2(); it.valid(); it.next()) | ||||
| { | { | ||||
| @@ -1150,12 +1150,14 @@ public: | |||||
| case kPluginBridgeNonRtServerSetCustomData: | case kPluginBridgeNonRtServerSetCustomData: | ||||
| break; | break; | ||||
| case kPluginBridgeNonRtServerSetChunkDataFile: { | |||||
| case kPluginBridgeNonRtServerSetChunkDataFile: | |||||
| // uint/size, str[] (filename) | // 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 kPluginBridgeNonRtServerSetLatency: | ||||
| case kPluginBridgeNonRtServerSetParameterText: | case kPluginBridgeNonRtServerSetParameterText: | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Plugin, LADSPA implementation | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -1363,7 +1363,7 @@ public: | |||||
| const std::size_t instanceCount(fHandles.count()); | 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()) | for (LinkedList<LADSPA_Handle>::Itenerator it = fHandles.begin2(); it.valid(); it.next()) | ||||
| { | { | ||||
| @@ -5252,8 +5252,8 @@ public: | |||||
| // --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
| // find the most appropriate ui | // 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) | #if defined(BUILD_BRIDGE) || defined(LV2_UIS_ONLY_BRIDGES) | ||||
| const bool preferUiBridges(true); | const bool preferUiBridges(true); | ||||
| @@ -5286,16 +5286,20 @@ public: | |||||
| if (isUiBridgeable(i)) | if (isUiBridgeable(i)) | ||||
| eGtk3 = ii; | eGtk3 = ii; | ||||
| break; | break; | ||||
| #ifdef CARLA_OS_MAC | |||||
| case LV2_UI_COCOA: | case LV2_UI_COCOA: | ||||
| if (isUiBridgeable(i) && preferUiBridges) | if (isUiBridgeable(i) && preferUiBridges) | ||||
| eCocoa = ii; | eCocoa = ii; | ||||
| iCocoa = ii; | iCocoa = ii; | ||||
| break; | break; | ||||
| #endif | |||||
| #ifdef CARLA_OS_WIN | |||||
| case LV2_UI_WINDOWS: | case LV2_UI_WINDOWS: | ||||
| if (isUiBridgeable(i) && preferUiBridges) | if (isUiBridgeable(i) && preferUiBridges) | ||||
| eWindows = ii; | eWindows = ii; | ||||
| iWindows = ii; | iWindows = ii; | ||||
| break; | break; | ||||
| #endif | |||||
| case LV2_UI_X11: | case LV2_UI_X11: | ||||
| if (isUiBridgeable(i) && preferUiBridges) | if (isUiBridgeable(i) && preferUiBridges) | ||||
| eX11 = ii; | eX11 = ii; | ||||
| @@ -5303,8 +5307,6 @@ public: | |||||
| break; | break; | ||||
| case LV2_UI_EXTERNAL: | case LV2_UI_EXTERNAL: | ||||
| case LV2_UI_OLD_EXTERNAL: | case LV2_UI_OLD_EXTERNAL: | ||||
| if (isUiBridgeable(i)) | |||||
| eExt = ii; | |||||
| iExt = ii; | iExt = ii; | ||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -5332,8 +5334,6 @@ public: | |||||
| else if (eX11 >= 0) | else if (eX11 >= 0) | ||||
| iFinal = eX11; | iFinal = eX11; | ||||
| #endif | #endif | ||||
| //else if (eExt >= 0) // TODO | |||||
| // iFinal = eExt; | |||||
| #ifndef LV2_UIS_ONLY_BRIDGES | #ifndef LV2_UIS_ONLY_BRIDGES | ||||
| # ifdef CARLA_OS_MAC | # ifdef CARLA_OS_MAC | ||||
| else if (iCocoa >= 0) | else if (iCocoa >= 0) | ||||
| @@ -5421,7 +5421,7 @@ public: | |||||
| if ( | if ( | ||||
| (iFinal == eQt4 || iFinal == eQt5 || iFinal == eGtk2 || iFinal == eGtk3 || | (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 | #ifdef BUILD_BRIDGE | ||||
| && preferUiBridges && ! hasShowInterface | && preferUiBridges && ! hasShowInterface | ||||
| #endif | #endif | ||||
| @@ -197,11 +197,11 @@ public: | |||||
| if (fPorts.numMidiOuts > 0) | 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) | for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) | ||||
| { | { | ||||
| @@ -224,6 +224,7 @@ public: | |||||
| port = midiEvent.port; | port = midiEvent.port; | ||||
| size = midiEvent.size; | size = midiEvent.size; | ||||
| CARLA_SAFE_ASSERT_CONTINUE(size > 0); | |||||
| if (size > EngineMidiEvent::kDataSize) | if (size > EngineMidiEvent::kDataSize) | ||||
| { | { | ||||
| @@ -232,14 +233,20 @@ public: | |||||
| } | } | ||||
| else | 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 | // done | ||||
| mdataPtr = mdataTmp; | mdataPtr = mdataTmp; | ||||
| } | } | ||||
| } | } | ||||
| else | |||||
| { | |||||
| continue; | |||||
| } | |||||
| if (size > 0 && ! writeMidiEvent(port, engineEvent.time, size, mdataPtr)) | if (size > 0 && ! writeMidiEvent(port, engineEvent.time, size, mdataPtr)) | ||||
| break; | break; | ||||
| @@ -2,7 +2,7 @@ | |||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
| # Carla Backend code | # 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 | # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License as | # 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. | # Patchbay port is input. | ||||
| # When this hint is not set, port is assumed to be output. | # 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 is of Audio type. | ||||
| PATCHBAY_PORT_TYPE_AUDIO = 0x2 | |||||
| PATCHBAY_PORT_TYPE_AUDIO = 0x02 | |||||
| # Patchbay port is of CV type (Control Voltage). | # 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 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 | # Custom Data Types | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla JACK API for external applications | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -672,7 +672,7 @@ bool CarlaJackAppClient::handleRtData() | |||||
| if (i < fServer.numAudioIns) | if (i < fServer.numAudioIns) | ||||
| { | { | ||||
| const std::size_t remainingBufferSize = fServer.bufferSize * (fServer.numAudioIns - i); | const std::size_t remainingBufferSize = fServer.bufferSize * (fServer.numAudioIns - i); | ||||
| fdataReal += remainingBufferSize; | |||||
| //fdataReal += remainingBufferSize; | |||||
| fdataCopy += remainingBufferSize; | fdataCopy += remainingBufferSize; | ||||
| } | } | ||||
| @@ -701,7 +701,7 @@ bool CarlaJackAppClient::handleRtData() | |||||
| { | { | ||||
| const std::size_t remainingBufferSize = fServer.bufferSize * (fServer.numAudioOuts - i); | const std::size_t remainingBufferSize = fServer.bufferSize * (fServer.numAudioOuts - i); | ||||
| carla_zeroFloats(fdataCopy, remainingBufferSize); | carla_zeroFloats(fdataCopy, remainingBufferSize); | ||||
| fdataCopy += remainingBufferSize; | |||||
| //fdataCopy += remainingBufferSize; | |||||
| } | } | ||||
| // set midi inputs | // set midi inputs | ||||
| @@ -219,7 +219,7 @@ public: | |||||
| */ | */ | ||||
| const float* getReadPointer (int channelNumber) const noexcept | const float* getReadPointer (int channelNumber) const noexcept | ||||
| { | { | ||||
| jassert (isPositiveAndBelow (channelNumber, numChannels)); | |||||
| CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (channelNumber, numChannels), nullptr); | |||||
| return channels [channelNumber]; | return channels [channelNumber]; | ||||
| } | } | ||||
| @@ -232,8 +232,8 @@ public: | |||||
| */ | */ | ||||
| const float* getReadPointer (int channelNumber, int sampleIndex) const noexcept | 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; | return channels [channelNumber] + sampleIndex; | ||||
| } | } | ||||
| @@ -245,7 +245,7 @@ public: | |||||
| */ | */ | ||||
| float* getWritePointer (int channelNumber) noexcept | float* getWritePointer (int channelNumber) noexcept | ||||
| { | { | ||||
| jassert (isPositiveAndBelow (channelNumber, numChannels)); | |||||
| CARLA_SAFE_ASSERT_RETURN (isPositiveAndBelow (channelNumber, numChannels), nullptr); | |||||
| isClear = false; | isClear = false; | ||||
| return channels [channelNumber]; | return channels [channelNumber]; | ||||
| } | } | ||||
| @@ -258,8 +258,8 @@ public: | |||||
| */ | */ | ||||
| float* getWritePointer (int channelNumber, int sampleIndex) noexcept | 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; | isClear = false; | ||||
| return channels [channelNumber] + sampleIndex; | return channels [channelNumber] + sampleIndex; | ||||
| } | } | ||||
| @@ -449,143 +449,6 @@ public: | |||||
| bool hasBeenCleared() const noexcept { return isClear; } | 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. | /** Adds samples from another buffer to this one. | ||||
| @param destChannel the channel within this buffer to add the samples to | @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. | /** Copies samples from another buffer to this one. | ||||
| @param destChannel the channel within this buffer to copy the samples to | @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: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| int numChannels, size; | int numChannels, size; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Native Plugins | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * 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 { | typedef struct { | ||||
| const NativeHostDescriptor* host; | const NativeHostDescriptor* host; | ||||
| int octaves; | int octaves; | ||||
| @@ -52,7 +58,7 @@ static void miditranspose_cleanup(NativePluginHandle handle) | |||||
| static uint32_t miditranspose_get_parameter_count(NativePluginHandle handle) | static uint32_t miditranspose_get_parameter_count(NativePluginHandle handle) | ||||
| { | { | ||||
| return 2; | |||||
| return PARAM_COUNT; | |||||
| // unused | // unused | ||||
| (void)handle; | (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) | static const NativeParameter* miditranspose_get_parameter_info(NativePluginHandle handle, uint32_t index) | ||||
| { | { | ||||
| if (index >= 2) | |||||
| if (index > PARAM_COUNT) | |||||
| return NULL; | 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) | static float miditranspose_get_parameter_value(NativePluginHandle handle, uint32_t index) | ||||
| { | { | ||||
| switch (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) | 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) | 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 | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * 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) | 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) | if (event == nullptr) | ||||
| continue; | continue; | ||||
| @@ -410,20 +413,24 @@ public: | |||||
| for (int i=0; features[i] != nullptr; ++i) | 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; | ||||
| } | } | ||||
| break; | |||||
| } | } | ||||
| if (fHost.uiName == nullptr) | if (fHost.uiName == nullptr) | ||||
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * Carla Style, based on Qt5 fusion style | * Carla Style, based on Qt5 fusion style | ||||
| * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies) | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU Lesser General Public | * 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); | int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget); | ||||
| rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0); | rect = option->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0); | ||||
| #if 0 | |||||
| QRect r2(rect); | QRect r2(rect); | ||||
| int x1 = r2.left(); | int x1 = r2.left(); | ||||
| int x2 = r2.right(); | int x2 = r2.right(); | ||||
| int y1 = r2.top(); | int y1 = r2.top(); | ||||
| int y2 = r2.bottom(); | int y2 = r2.bottom(); | ||||
| #endif | |||||
| painter->setPen(d->innerContrastLine()); | painter->setPen(d->innerContrastLine()); | ||||
| @@ -2155,6 +2157,7 @@ void CarlaStyle::drawControl(ControlElement element, const QStyleOption *option, | |||||
| } | } | ||||
| if (flip) { | if (flip) { | ||||
| #if 0 | |||||
| QRect tmp = rect; | QRect tmp = rect; | ||||
| rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width()); | rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width()); | ||||
| int temp = x1; | int temp = x1; | ||||
| @@ -2163,6 +2166,7 @@ void CarlaStyle::drawControl(ControlElement element, const QStyleOption *option, | |||||
| temp = x2; | temp = x2; | ||||
| x2 = y2; | x2 = y2; | ||||
| y2 = temp; | y2 = temp; | ||||
| #endif | |||||
| } | } | ||||
| painter->setRenderHint(QPainter::Antialiasing, true); | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
| @@ -151,10 +151,10 @@ void fillEngineEventsFromWaterMidiBuffer(EngineEvent engineEvents[kMaxEngineEven | |||||
| static inline | static inline | ||||
| void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const EngineEvent engineEvents[kMaxEngineEventInternalCount]) | 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) | for (ushort i=0; i < kMaxEngineEventInternalCount; ++i) | ||||
| { | { | ||||
| @@ -176,6 +176,7 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En | |||||
| const EngineMidiEvent& midiEvent(engineEvent.midi); | const EngineMidiEvent& midiEvent(engineEvent.midi); | ||||
| size = midiEvent.size; | size = midiEvent.size; | ||||
| CARLA_SAFE_ASSERT_CONTINUE(size > 0); | |||||
| if (size > EngineMidiEvent::kDataSize) | if (size > EngineMidiEvent::kDataSize) | ||||
| { | { | ||||
| @@ -184,10 +185,12 @@ void fillWaterMidiBufferFromEngineEvents(water::MidiBuffer& midiBuffer, const En | |||||
| } | } | ||||
| else | 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 | // done | ||||
| mdataPtr = mdataTmp; | mdataPtr = mdataTmp; | ||||
| } | } | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Pipe Utilities | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -1123,7 +1123,7 @@ uintptr_t CarlaPipeServer::getPID() const noexcept | |||||
| #endif | #endif | ||||
| } | } | ||||
| // ----------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| bool CarlaPipeServer::startPipeServer(const char* const filename, | bool CarlaPipeServer::startPipeServer(const char* const filename, | ||||
| const char* const arg1, | const char* const arg1, | ||||
| @@ -1155,7 +1155,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| const CarlaMutexLocker cml(pData->writeLock); | const CarlaMutexLocker cml(pData->writeLock); | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // create pipes | // create pipes | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| @@ -1220,7 +1220,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| std::snprintf(pipeRecvClientStr, 100, "%i", pipeRecvClient); | std::snprintf(pipeRecvClientStr, 100, "%i", pipeRecvClient); | ||||
| std::snprintf(pipeSendClientStr, 100, "%i", pipeSendClient); | std::snprintf(pipeSendClientStr, 100, "%i", pipeSendClient); | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // set size, non-fatal | // set size, non-fatal | ||||
| #ifdef CARLA_OS_LINUX | #ifdef CARLA_OS_LINUX | ||||
| @@ -1233,7 +1233,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| } CARLA_SAFE_EXCEPTION("Set pipe size"); | } CARLA_SAFE_EXCEPTION("Set pipe size"); | ||||
| #endif | #endif | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // set non-block | // set non-block | ||||
| int ret; | int ret; | ||||
| @@ -1265,23 +1265,23 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| } | } | ||||
| #endif | #endif | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // set arguments | // set arguments | ||||
| const char* argv[8]; | const char* argv[8]; | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // argv[0] => filename | // argv[0] => filename | ||||
| argv[0] = filename; | argv[0] = filename; | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // argv[1-2] => args | // argv[1-2] => args | ||||
| argv[1] = arg1; | argv[1] = arg1; | ||||
| argv[2] = arg2; | argv[2] = arg2; | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // argv[3-6] => pipes | // argv[3-6] => pipes | ||||
| argv[3] = pipeRecvServerStr; | argv[3] = pipeRecvServerStr; | ||||
| @@ -1289,12 +1289,12 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| argv[5] = pipeRecvClientStr; | argv[5] = pipeRecvClientStr; | ||||
| argv[6] = pipeSendClientStr; | argv[6] = pipeSendClientStr; | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // argv[7] => null | // argv[7] => null | ||||
| argv[7] = nullptr; | argv[7] = nullptr; | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // start process | // start process | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| @@ -1324,15 +1324,14 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| return false; | return false; | ||||
| } | } | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // close duplicated handles used by the client | // close duplicated handles used by the client | ||||
| try { ::close(pipeRecvServer); } CARLA_SAFE_EXCEPTION("close(pipeRecvServer)"); | try { ::close(pipeRecvServer); } CARLA_SAFE_EXCEPTION("close(pipeRecvServer)"); | ||||
| try { ::close(pipeSendServer); } CARLA_SAFE_EXCEPTION("close(pipeSendServer)"); | try { ::close(pipeSendServer); } CARLA_SAFE_EXCEPTION("close(pipeSendServer)"); | ||||
| pipeRecvServer = pipeSendServer = INVALID_PIPE_VALUE; | |||||
| #endif | #endif | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // wait for client to say something | // wait for client to say something | ||||
| if (waitForClientFirstMessage(pipeRecvClient, 10*1000 /* 10 secs */)) | if (waitForClientFirstMessage(pipeRecvClient, 10*1000 /* 10 secs */)) | ||||
| @@ -1347,7 +1346,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| return true; | return true; | ||||
| } | } | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // failed to set non-block or get first child message, cannot continue | // failed to set non-block or get first child message, cannot continue | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| @@ -1372,7 +1371,7 @@ bool CarlaPipeServer::startPipeServer(const char* const filename, | |||||
| pData->pid = -1; | pData->pid = -1; | ||||
| #endif | #endif | ||||
| //---------------------------------------------------------------- | |||||
| //----------------------------------------------------------------------------------------------------------------- | |||||
| // close pipes | // close pipes | ||||
| #ifdef CARLA_OS_WIN | #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(pipeRecvClient); } CARLA_SAFE_EXCEPTION("close(pipeRecvClient)"); | ||||
| try { ::close(pipeSendClient); } CARLA_SAFE_EXCEPTION("close(pipeSendClient)"); | try { ::close(pipeSendClient); } CARLA_SAFE_EXCEPTION("close(pipeSendClient)"); | ||||
| pipeRecvClient = pipeSendClient = INVALID_PIPE_VALUE; | |||||
| //---------------------------------------------------------------- | //---------------------------------------------------------------- | ||||
| // kill ourselves if parent dies | // kill ourselves if parent dies | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Ring Buffer | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * 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 | bool tryRead(void* const buf, const uint32_t size) noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | 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(buf != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0, false); | CARLA_SAFE_ASSERT_RETURN(size > 0, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size, false); | CARLA_SAFE_ASSERT_RETURN(size < fBuffer->size, false); | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla String | * 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 | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
| @@ -37,14 +37,16 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString() noexcept | explicit CarlaString() noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) {} | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) {} | |||||
| /* | /* | ||||
| * Simple character. | * Simple character. | ||||
| */ | */ | ||||
| explicit CarlaString(const char c) noexcept | explicit CarlaString(const char c) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char ch[2]; | char ch[2]; | ||||
| ch[0] = c; | ch[0] = c; | ||||
| @@ -58,7 +60,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(char* const strBuf) noexcept | explicit CarlaString(char* const strBuf) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| _dup(strBuf); | _dup(strBuf); | ||||
| } | } | ||||
| @@ -68,7 +71,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const char* const strBuf) noexcept | explicit CarlaString(const char* const strBuf) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| _dup(strBuf); | _dup(strBuf); | ||||
| } | } | ||||
| @@ -78,7 +82,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const int value) noexcept | explicit CarlaString(const int value) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, "%d", value); | std::snprintf(strBuf, 0xff, "%d", value); | ||||
| @@ -92,7 +97,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const unsigned int value, const bool hexadecimal = false) noexcept | explicit CarlaString(const unsigned int value, const bool hexadecimal = false) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value); | std::snprintf(strBuf, 0xff, hexadecimal ? "0x%x" : "%u", value); | ||||
| @@ -106,7 +112,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const long value) noexcept | explicit CarlaString(const long value) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, "%ld", value); | std::snprintf(strBuf, 0xff, "%ld", value); | ||||
| @@ -120,7 +127,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const unsigned long value, const bool hexadecimal = false) noexcept | explicit CarlaString(const unsigned long value, const bool hexadecimal = false) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value); | std::snprintf(strBuf, 0xff, hexadecimal ? "0x%lx" : "%lu", value); | ||||
| @@ -134,7 +142,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const long long value) noexcept | explicit CarlaString(const long long value) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, "%lld", value); | std::snprintf(strBuf, 0xff, "%lld", value); | ||||
| @@ -148,7 +157,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const unsigned long long value, const bool hexadecimal = false) noexcept | explicit CarlaString(const unsigned long long value, const bool hexadecimal = false) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, hexadecimal ? "0x%llx" : "%llu", value); | std::snprintf(strBuf, 0xff, hexadecimal ? "0x%llx" : "%llu", value); | ||||
| @@ -162,7 +172,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const float value) noexcept | explicit CarlaString(const float value) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, "%f", value); | std::snprintf(strBuf, 0xff, "%f", value); | ||||
| @@ -176,7 +187,8 @@ public: | |||||
| */ | */ | ||||
| explicit CarlaString(const double value) noexcept | explicit CarlaString(const double value) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
| std::snprintf(strBuf, 0xff, "%g", value); | std::snprintf(strBuf, 0xff, "%g", value); | ||||
| @@ -193,7 +205,8 @@ public: | |||||
| */ | */ | ||||
| CarlaString(const CarlaString& str) noexcept | CarlaString(const CarlaString& str) noexcept | ||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | |||||
| fBufferLen(0), | |||||
| fBufferAlloc(false) | |||||
| { | { | ||||
| _dup(str.fBuffer); | _dup(str.fBuffer); | ||||
| } | } | ||||
| @@ -208,13 +221,12 @@ public: | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | 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: | 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. | * Static null string. | ||||
| @@ -786,7 +799,7 @@ private: | |||||
| if (std::strcmp(fBuffer, strBuf) == 0) | if (std::strcmp(fBuffer, strBuf) == 0) | ||||
| return; | return; | ||||
| if (fBuffer != _null()) | |||||
| if (fBufferAlloc) | |||||
| std::free(fBuffer); | std::free(fBuffer); | ||||
| fBufferLen = (size > 0) ? size : std::strlen(strBuf); | fBufferLen = (size > 0) ? size : std::strlen(strBuf); | ||||
| @@ -794,28 +807,31 @@ private: | |||||
| if (fBuffer == nullptr) | if (fBuffer == nullptr) | ||||
| { | { | ||||
| fBuffer = _null(); | |||||
| fBufferLen = 0; | |||||
| fBuffer = _null(); | |||||
| fBufferLen = 0; | |||||
| fBufferAlloc = false; | |||||
| return; | return; | ||||
| } | } | ||||
| std::strcpy(fBuffer, strBuf); | |||||
| fBufferAlloc = true; | |||||
| std::strcpy(fBuffer, strBuf); | |||||
| fBuffer[fBufferLen] = '\0'; | fBuffer[fBufferLen] = '\0'; | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT(size == 0); | |||||
| CARLA_SAFE_ASSERT_UINT(size == 0, static_cast<uint>(size)); | |||||
| // don't recreate null string | // don't recreate null string | ||||
| if (fBuffer == _null()) | |||||
| if (! fBufferAlloc) | |||||
| return; | return; | ||||
| CARLA_SAFE_ASSERT(fBuffer != nullptr); | CARLA_SAFE_ASSERT(fBuffer != nullptr); | ||||
| std::free(fBuffer); | std::free(fBuffer); | ||||
| fBuffer = _null(); | |||||
| fBufferLen = 0; | |||||
| fBuffer = _null(); | |||||
| fBufferLen = 0; | |||||
| fBufferAlloc = false; | |||||
| } | } | ||||
| } | } | ||||