Signed-off-by: falkTX <falktx@falktx.com>fix-audiofile-buffering
| @@ -3255,29 +3255,31 @@ public: | |||
| if (fExt.worker != nullptr && fEventsIn.ctrl != nullptr) | |||
| { | |||
| fAtomBufferWorkerIn.createBuffer(eventBufferSize); | |||
| fAtomBufferWorkerResp.createBuffer(eventBufferSize); | |||
| fAtomBufferWorkerIn.createBuffer(eventBufferSize, true); | |||
| fAtomBufferWorkerResp.createBuffer(eventBufferSize, true); | |||
| fAtomBufferRealtimeSize = fAtomBufferWorkerIn.getSize(); // actual buffer size will be next power of 2 | |||
| fAtomBufferRealtime = static_cast<LV2_Atom*>(std::malloc(fAtomBufferRealtimeSize)); | |||
| fAtomBufferWorkerInTmpData = new uint8_t[fAtomBufferRealtimeSize]; | |||
| carla_mlock(fAtomBufferRealtime, fAtomBufferRealtimeSize); | |||
| } | |||
| if (fRdfDescriptor->ParameterCount > 0 || | |||
| (fUI.type != UI::TYPE_NULL && fEventsIn.count > 0 && (fEventsIn.data[0].type & CARLA_EVENT_DATA_ATOM) != 0)) | |||
| { | |||
| fAtomBufferEvIn.createBuffer(eventBufferSize); | |||
| fAtomBufferEvIn.createBuffer(eventBufferSize, true); | |||
| if (fAtomBufferRealtimeSize == 0) | |||
| { | |||
| fAtomBufferRealtimeSize = fAtomBufferEvIn.getSize(); // actual buffer size will be next power of 2 | |||
| fAtomBufferRealtime = static_cast<LV2_Atom*>(std::malloc(fAtomBufferRealtimeSize)); | |||
| carla_mlock(fAtomBufferRealtime, fAtomBufferRealtimeSize); | |||
| } | |||
| } | |||
| if (hasPatchParameterOutputs || | |||
| (fUI.type != UI::TYPE_NULL && fEventsOut.count > 0 && (fEventsOut.data[0].type & CARLA_EVENT_DATA_ATOM) != 0)) | |||
| { | |||
| fAtomBufferUiOut.createBuffer(std::min(eventBufferSize*32, 1638400U)); | |||
| fAtomBufferUiOut.createBuffer(std::min(eventBufferSize*32, 1638400U), true); | |||
| fAtomBufferUiOutTmpData = new uint8_t[fAtomBufferUiOut.getSize()]; | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| ../../includes/ | |||
| @@ -0,0 +1,3 @@ | |||
| ../includes/ | |||
| ../modules/ | |||
| ../utils/ | |||
| @@ -284,6 +284,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||
| |NATIVE_PLUGIN_HAS_UI | |||
| |NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE | |||
| |NATIVE_PLUGIN_REQUESTS_IDLE | |||
| |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE | |||
| |NATIVE_PLUGIN_USES_TIME), | |||
| /* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING, | |||
| /* audioIns */ 0, | |||
| @@ -296,7 +297,13 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||
| /* label */ "audiofile", | |||
| /* maker */ "falkTX", | |||
| /* copyright */ "GNU GPL v2+", | |||
| DESCFUNCS_WITHOUTCV | |||
| DESCFUNCS_WITHCV, | |||
| /* cvIns */ 0, | |||
| /* cvOuts */ 1, | |||
| /* bufnamefn */ nullptr, | |||
| /* bufrangefn */ nullptr, | |||
| /* ui_width */ 0, | |||
| /* ui_height */ 0 | |||
| }, | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -78,7 +78,7 @@ public: | |||
| // fNeedsFileRead(false), | |||
| // fEntireFileLoaded(false), | |||
| // fMaxFrame(0), | |||
| // fLastPoolFill(0.0f), | |||
| // fReadableBufferFill(0.0f), | |||
| // fPool(), | |||
| // fReader(), | |||
| // fFilename(), | |||
| @@ -253,8 +253,8 @@ protected: | |||
| return fVolume * 100.f; | |||
| case kParameterInfoPosition: | |||
| return fLastPosition; | |||
| // case kParameterInfoPoolFill: | |||
| // return fLastPoolFill; | |||
| case kParameterInfoPoolFill: | |||
| return fReadableBufferFill; | |||
| case kParameterInfoBitRate: | |||
| return static_cast<float>(fReader.getCurrentBitRate()); | |||
| } | |||
| @@ -290,10 +290,7 @@ protected: | |||
| { | |||
| case kParameterLooping: | |||
| if (fLoopMode != b) | |||
| { | |||
| fLoopMode = b; | |||
| // fReader.setLoopingMode(b); | |||
| } | |||
| break; | |||
| case kParameterHostSync: | |||
| if (fHostSync != b) | |||
| @@ -350,19 +347,17 @@ protected: | |||
| float* const out2 = outBuffer[1]; | |||
| float* const playCV = outBuffer[2]; | |||
| // const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex); | |||
| if (! fDoProcess) | |||
| { | |||
| // carla_stderr("P: no process"); | |||
| carla_zeroFloats(out1, frames); | |||
| carla_zeroFloats(out2, frames); | |||
| carla_zeroFloats(playCV, frames); | |||
| fLastPosition = 0.0f; | |||
| fLastPosition = 0.f; | |||
| fReadableBufferFill = 0.f; | |||
| return; | |||
| } | |||
| // const bool loopMode = fLoopMode; | |||
| bool needsIdleRequest = false; | |||
| bool playing; | |||
| uint64_t framePos; | |||
| @@ -385,152 +380,20 @@ protected: | |||
| // not playing | |||
| if (! playing) | |||
| { | |||
| // // carla_stderr("P: not playing"); | |||
| // if (framePos == 0 && fWasPlayingBefore) | |||
| // fReader.setNeedsRead(framePos); | |||
| carla_zeroFloats(out1, frames); | |||
| carla_zeroFloats(out2, frames); | |||
| carla_zeroFloats(playCV, frames); | |||
| // fWasPlayingBefore = false; | |||
| return; | |||
| } | |||
| // else | |||
| // { | |||
| // fWasPlayingBefore = true; | |||
| // } | |||
| fLastPosition = fReader.tickFrames(outBuffer, 0, frames, framePos, fLoopMode, isOffline()) * 100.f; | |||
| // // out of reach | |||
| // if ((frame < fPool.startFrame || frame >= fMaxFrame) && !loopMode) | |||
| // { | |||
| // if (frame < fPool.startFrame) | |||
| // { | |||
| // needsIdleRequest = true; | |||
| // fNeedsFileRead = true; | |||
| // fReader.setNeedsRead(frame); | |||
| // } | |||
| // | |||
| // carla_zeroFloats(out1, frames); | |||
| // carla_zeroFloats(out2, frames); | |||
| // carla_zeroFloats(playCV, frames); | |||
| // | |||
| // #ifndef __MOD_DEVICES__ | |||
| // if (fInlineDisplay.writtenValues < 32) | |||
| // { | |||
| // fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = 0.0f; | |||
| // fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = 0.0f; | |||
| // ++fInlineDisplay.writtenValues; | |||
| // } | |||
| // if (fInlineDisplay.pending == InlineDisplayNotPending) | |||
| // { | |||
| // needsIdleRequest = true; | |||
| // fInlineDisplay.pending = InlineDisplayNeedRequest; | |||
| // } | |||
| // #endif | |||
| // if (needsIdleRequest) | |||
| // hostRequestIdle(); | |||
| // | |||
| // if (frame == 0) | |||
| // fLastPosition = 0.0f; | |||
| // else if (frame >= fMaxFrame) | |||
| // fLastPosition = 100.0f; | |||
| // else | |||
| // fLastPosition = static_cast<float>(frame) / static_cast<float>(fMaxFrame) * 100.0f; | |||
| // return; | |||
| // } | |||
| // if (fEntireFileLoaded) | |||
| // { | |||
| // // NOTE: frame is always < fMaxFrame (or looping) | |||
| // uint32_t targetStartFrame = static_cast<uint32_t>(loopMode ? frame % fMaxFrame : frame); | |||
| // | |||
| // for (uint32_t framesDone=0, framesToDo=frames, remainingFrames; framesDone < frames;) | |||
| // { | |||
| // if (targetStartFrame + framesToDo <= fMaxFrame) | |||
| // { | |||
| // // everything fits together | |||
| // carla_copyFloats(out1+framesDone, fPool.buffer[0]+targetStartFrame, framesToDo); | |||
| // carla_copyFloats(out2+framesDone, fPool.buffer[1]+targetStartFrame, framesToDo); | |||
| // carla_fillFloatsWithSingleValue(playCV+framesDone, 10.f, framesToDo); | |||
| // break; | |||
| // } | |||
| // | |||
| // remainingFrames = std::min(fMaxFrame - targetStartFrame, framesToDo); | |||
| // carla_copyFloats(out1+framesDone, fPool.buffer[0]+targetStartFrame, remainingFrames); | |||
| // carla_copyFloats(out2+framesDone, fPool.buffer[1]+targetStartFrame, remainingFrames); | |||
| // carla_fillFloatsWithSingleValue(playCV+framesDone, 10.f, remainingFrames); | |||
| // framesDone += remainingFrames; | |||
| // framesToDo -= remainingFrames; | |||
| // | |||
| // if (! loopMode) | |||
| // { | |||
| // // not looping, stop here | |||
| // if (framesToDo != 0) | |||
| // { | |||
| // carla_zeroFloats(out1+framesDone, framesToDo); | |||
| // carla_zeroFloats(out2+framesDone, framesToDo); | |||
| // carla_zeroFloats(playCV+framesDone, framesToDo); | |||
| // } | |||
| // break; | |||
| // } | |||
| // | |||
| // // reset for next loop | |||
| // targetStartFrame = 0; | |||
| // } | |||
| // fLastPosition = static_cast<float>(targetStartFrame) / static_cast<float>(fMaxFrame) * 100.0f; | |||
| // } | |||
| // else | |||
| // { | |||
| // const bool offline = isOffline(); | |||
| // if (fReader.tryPutData(fPool, out1, out2, frame, frames, loopMode, offline, needsIdleRequest)) | |||
| // { | |||
| // carla_fillFloatsWithSingleValue(playCV, 10.f, frames); | |||
| // } | |||
| // else | |||
| // { | |||
| // carla_zeroFloats(out1, frames); | |||
| // carla_zeroFloats(out2, frames); | |||
| // carla_zeroFloats(playCV, frames); | |||
| // } | |||
| // | |||
| // if (needsIdleRequest) | |||
| // { | |||
| // fNeedsFileRead = true; | |||
| // | |||
| // if (isOffline()) | |||
| // { | |||
| // needsIdleRequest = false; | |||
| // fReader.readPoll(); | |||
| // | |||
| // if (fReader.tryPutData(fPool, out1, out2, frame, frames, loopMode, offline, needsIdleRequest)) | |||
| // { | |||
| // carla_fillFloatsWithSingleValue(playCV, 10.f, frames); | |||
| // } | |||
| // else | |||
| // { | |||
| // carla_zeroFloats(out1, frames); | |||
| // carla_zeroFloats(out2, frames); | |||
| // carla_zeroFloats(playCV, frames); | |||
| // } | |||
| // | |||
| // if (needsIdleRequest) | |||
| // fNeedsFileRead = true; | |||
| // } | |||
| // } | |||
| // | |||
| // const uint32_t modframe = static_cast<uint32_t>(frame % fMaxFrame); | |||
| // fLastPosition = static_cast<float>(modframe) / static_cast<float>(fMaxFrame) * 100.0f; | |||
| // | |||
| // if (modframe > fPool.startFrame) | |||
| // fLastPoolFill = static_cast<float>(modframe - fPool.startFrame) / static_cast<float>(fPool.numFrames) * 100.0f; | |||
| // else | |||
| // fLastPoolFill = 100.0f; | |||
| // } | |||
| if (fReader.tickFrames(outBuffer, 0, frames, framePos, fLoopMode, isOffline()) && ! fPendingFileRead) | |||
| { | |||
| fPendingFileRead = true; | |||
| needsIdleRequest = true; | |||
| } | |||
| fLastPosition = fReader.getLastPlayPosition() * 100.f; | |||
| fReadableBufferFill = fReader.getReadableBufferFill() * 100.f; | |||
| const float volume = fVolume; | |||
| if (carla_isNotEqual(volume, 1.0f)) | |||
| @@ -586,11 +449,11 @@ protected: | |||
| } | |||
| #endif | |||
| // if (fNeedsFileRead) | |||
| // { | |||
| // fReader.readPoll(); | |||
| // fNeedsFileRead = false; | |||
| // } | |||
| if (fPendingFileRead) | |||
| { | |||
| fPendingFileRead = false; | |||
| fReader.readPoll(); | |||
| } | |||
| } | |||
| void sampleRateChanged(double) override | |||
| @@ -725,17 +588,13 @@ private: | |||
| #endif | |||
| bool fEnabled = true; | |||
| bool fDoProcess = false; | |||
| // bool fWasPlayingBefore; | |||
| // volatile bool fNeedsFileRead; | |||
| // | |||
| // bool fEntireFileLoaded; | |||
| // uint32_t fMaxFrame; | |||
| bool fPendingFileRead = false; | |||
| uint32_t fInternalTransportFrame = 0; | |||
| float fLastPosition = 0.f; | |||
| // float fLastPoolFill; | |||
| float fReadableBufferFill = 0.f; | |||
| float fVolume = 1.f; | |||
| // AudioFilePool fPool; | |||
| AudioFileReader fReader; | |||
| CarlaString fFilename; | |||
| @@ -773,55 +632,41 @@ private: | |||
| carla_stdout("AudioFilePlugin::loadFilename(\"%s\")", filename); | |||
| fDoProcess = false; | |||
| // fLastPoolFill = 0.0f; | |||
| // fPool.destroy(); | |||
| fReader.destroy(); | |||
| fFilename.clear(); | |||
| if (filename == nullptr || *filename == '\0') | |||
| { | |||
| // fMaxFrame = 0; | |||
| return; | |||
| } | |||
| constexpr uint32_t kPreviewDataLen = sizeof(fPreviewData)/sizeof(float); | |||
| if (fReader.loadFilename(filename, static_cast<uint32_t>(getSampleRate()), kPreviewDataLen, fPreviewData)) | |||
| { | |||
| // fEntireFileLoaded = fReader.isEntireFileLoaded(); | |||
| // fMaxFrame = fReader.getMaxFrame(); | |||
| // | |||
| // if (fEntireFileLoaded) | |||
| // { | |||
| // fReader.putAndSwapAllData(fPool); | |||
| // fLastPoolFill = 100.0f; | |||
| // } | |||
| // else | |||
| // { | |||
| // fReader.createSwapablePool(fPool); | |||
| // fReader.readPoll(); | |||
| // } | |||
| fInternalTransportFrame = 0; | |||
| fDoProcess = true; | |||
| fFilename = filename; | |||
| hostSendPreviewBufferData('f', kPreviewDataLen, fPreviewData); | |||
| } | |||
| else | |||
| { | |||
| // fEntireFileLoaded = false; | |||
| // fMaxFrame = 0; | |||
| } | |||
| } | |||
| PluginClassEND(AudioFilePlugin) | |||
| static const char* _get_buffer_port_name(NativePluginHandle, const uint32_t index, const bool isOutput) | |||
| { | |||
| if (!isOutput || index != 2) | |||
| if (!isOutput) | |||
| return nullptr; | |||
| return "Play status"; | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| return "output_1"; | |||
| case 1: | |||
| return "output_2"; | |||
| case 2: | |||
| return "Play status"; | |||
| } | |||
| return nullptr; | |||
| } | |||
| static const NativePortRange* _get_buffer_port_range(NativePluginHandle, const uint32_t index, const bool isOutput) | |||
| @@ -0,0 +1 @@ | |||
| ../includes/ | |||
| @@ -0,0 +1,45 @@ | |||
| /* | |||
| * Carla shared memory utils | |||
| * Copyright (C) 2023 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 | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #ifndef CARLA_MEM_UTILS_HPP_INCLUDED | |||
| #define CARLA_MEM_UTILS_HPP_INCLUDED | |||
| #include "CarlaUtils.hpp" | |||
| #if !defined(CARLA_OS_WASM) && !defined(CARLA_OS_WIN) | |||
| # include <sys/mman.h> | |||
| #endif | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static inline | |||
| bool carla_mlock(void* const ptr, const size_t size) | |||
| { | |||
| #if defined(CARLA_OS_WASM) | |||
| // unsupported | |||
| return false; | |||
| (void)ptr; (void)size; | |||
| #elif defined(CARLA_OS_WIN) | |||
| return ::VirtualLock(ptr, size) != FALSE; | |||
| #else | |||
| return ::mlock(ptr, size) == 0; | |||
| #endif | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| #endif // CARLA_MEM_UTILS_HPP_INCLUDED | |||
| @@ -19,6 +19,7 @@ | |||
| #define CARLA_RING_BUFFER_HPP_INCLUDED | |||
| #include "CarlaMathUtils.hpp" | |||
| #include "CarlaMemUtils.hpp" | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| // Buffer structs | |||
| @@ -102,12 +103,22 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||
| fBuffer->head = 0; | |||
| fBuffer->tail = 0; | |||
| fBuffer->wrtn = 0; | |||
| fBuffer->head = fBuffer->tail = fBuffer->wrtn = 0; | |||
| fBuffer->invalidateCommit = false; | |||
| carla_zeroBytes(fBuffer->buf, fBuffer->size); | |||
| fErrorReading = fErrorWriting = false; | |||
| } | |||
| void flush() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); | |||
| fBuffer->head = fBuffer->tail = fBuffer->wrtn = 0; | |||
| fBuffer->invalidateCommit = false; | |||
| fErrorWriting = false; | |||
| } | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| @@ -141,6 +152,11 @@ public: | |||
| return fBuffer->buf == nullptr || fBuffer->head == fBuffer->tail; | |||
| } | |||
| uint32_t getSize() const noexcept | |||
| { | |||
| return fBuffer != nullptr ? fBuffer->size : 0; | |||
| } | |||
| uint32_t getReadableDataSize() const noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); | |||
| @@ -154,7 +170,7 @@ public: | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); | |||
| const uint32_t wrap = (fBuffer->tail >= fBuffer->wrtn) ? 0 : fBuffer->size; | |||
| const uint32_t wrap = fBuffer->tail > fBuffer->wrtn ? 0 : fBuffer->size; | |||
| return wrap + fBuffer->tail - fBuffer->wrtn; | |||
| } | |||
| @@ -502,10 +518,7 @@ class CarlaHeapRingBuffer : public CarlaRingBufferControl<HeapBuffer> | |||
| { | |||
| public: | |||
| CarlaHeapRingBuffer() noexcept | |||
| : fHeapBuffer{0, 0, 0, 0, false, nullptr} | |||
| { | |||
| carla_zeroStruct(fHeapBuffer); | |||
| } | |||
| : fHeapBuffer{0, 0, 0, 0, false, nullptr} {} | |||
| ~CarlaHeapRingBuffer() noexcept override | |||
| { | |||
| @@ -516,7 +529,7 @@ public: | |||
| fHeapBuffer.buf = nullptr; | |||
| } | |||
| void createBuffer(const uint32_t size) noexcept | |||
| void createBuffer(const uint32_t size, const bool mlock) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fHeapBuffer.buf == nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(size > 0,); | |||
| @@ -529,11 +542,18 @@ public: | |||
| fHeapBuffer.size = p2size; | |||
| setRingBuffer(&fHeapBuffer, true); | |||
| if (mlock) | |||
| { | |||
| carla_mlock(&fHeapBuffer, sizeof(fHeapBuffer)); | |||
| carla_mlock(fHeapBuffer.buf, p2size); | |||
| } | |||
| } | |||
| void deleteBuffer() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fHeapBuffer.buf != nullptr,); | |||
| if (fHeapBuffer.buf == nullptr) | |||
| return; | |||
| setRingBuffer(nullptr, false); | |||
| @@ -208,6 +208,8 @@ void* carla_shm_map(carla_shm_t& shm, const std::size_t size) noexcept | |||
| return nullptr; | |||
| } | |||
| ::VirtualLock(ptr, size); | |||
| shm.map = map; | |||
| return ptr; | |||
| #else | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * LV2 Atom Ring Buffer | |||
| * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2023 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 | |||
| @@ -23,26 +23,23 @@ | |||
| #include "lv2/atom.h" | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| class Lv2AtomRingBuffer : public CarlaRingBufferControl<HeapBuffer> | |||
| { | |||
| public: | |||
| Lv2AtomRingBuffer() noexcept | |||
| : fMutex(), | |||
| fHeapBuffer(HeapBuffer_INIT), | |||
| fHeapBuffer{0, 0, 0, 0, false, nullptr}, | |||
| fNeedsDataDelete(true) | |||
| { | |||
| carla_zeroStruct(fHeapBuffer); | |||
| } | |||
| Lv2AtomRingBuffer(Lv2AtomRingBuffer& ringBuf, uint8_t buf[]) noexcept | |||
| : fMutex(), | |||
| fHeapBuffer(HeapBuffer_INIT), | |||
| fHeapBuffer{0, 0, 0, 0, false, nullptr}, | |||
| fNeedsDataDelete(false) | |||
| { | |||
| carla_zeroStruct(fHeapBuffer); | |||
| fHeapBuffer.buf = buf; | |||
| fHeapBuffer.size = ringBuf.fHeapBuffer.size; | |||
| @@ -64,15 +61,15 @@ public: | |||
| fHeapBuffer.buf = nullptr; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| void createBuffer(const uint32_t size) noexcept | |||
| void createBuffer(const uint32_t size, const bool mlock) noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(fHeapBuffer.buf == nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(fNeedsDataDelete,); | |||
| CARLA_SAFE_ASSERT_RETURN(size > 0,); | |||
| const uint32_t p2size(carla_nextPowerOf2(size)); | |||
| const uint32_t p2size = carla_nextPowerOf2(size); | |||
| try { | |||
| fHeapBuffer.buf = new uint8_t[p2size]; | |||
| @@ -80,6 +77,12 @@ public: | |||
| fHeapBuffer.size = p2size; | |||
| setRingBuffer(&fHeapBuffer, true); | |||
| if (mlock) | |||
| { | |||
| carla_mlock(&fHeapBuffer, sizeof(fHeapBuffer)); | |||
| carla_mlock(fHeapBuffer.buf, p2size); | |||
| } | |||
| } | |||
| void deleteBuffer() noexcept | |||
| @@ -99,7 +102,7 @@ public: | |||
| return fHeapBuffer.size; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| bool tryLock() const noexcept | |||
| { | |||
| @@ -111,7 +114,7 @@ public: | |||
| fMutex.unlock(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| // NOTE: must have been locked before | |||
| bool get(uint32_t& portIndex, LV2_Atom* const retAtom) noexcept | |||
| @@ -145,7 +148,7 @@ public: | |||
| } | |||
| protected: | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| bool readAtom(uint32_t& portIndex, LV2_Atom* const retAtom) noexcept | |||
| { | |||
| @@ -175,7 +178,7 @@ protected: | |||
| return true; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| bool writeAtom(const LV2_Atom* const atom, const int32_t portIndex) noexcept | |||
| { | |||
| @@ -191,7 +194,7 @@ protected: | |||
| return commitWrite(); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // ---------------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| CarlaMutex fMutex; | |||
| @@ -204,6 +207,6 @@ private: | |||
| CARLA_DECLARE_NON_COPYABLE(Lv2AtomRingBuffer) | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| #endif // LV2_ATOM_RING_BUFFER_HPP_INCLUDED | |||