Browse Source

MIDI file/pattern: do not lose any RT events during save

Use a separate mutex for smaller operations,
so RT only has to depend on the big one which is locked less often.

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.3.0-RC1
falkTX 4 years ago
parent
commit
35feaa3c7f
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 34 additions and 22 deletions
  1. +26
    -17
      source/native-plugins/midi-base.hpp
  2. +2
    -1
      source/native-plugins/midi-file.cpp
  3. +6
    -4
      source/native-plugins/midi-pattern.cpp

+ 26
- 17
source/native-plugins/midi-base.hpp View File

@@ -57,7 +57,8 @@ public:
: kPlayer(player), : kPlayer(player),
fMidiPort(0), fMidiPort(0),
fStartTime(0), fStartTime(0),
fMutex(),
fReadMutex(),
fWriteMutex(),
fData() fData()
{ {
CARLA_SAFE_ASSERT(kPlayer != nullptr); CARLA_SAFE_ASSERT(kPlayer != nullptr);
@@ -187,7 +188,7 @@ public:


void removeRaw(const uint64_t time, const uint8_t* const data, const uint8_t size) void removeRaw(const uint64_t time, const uint8_t* const data, const uint8_t size)
{ {
const CarlaMutexLocker sl(fMutex);
const CarlaMutexLocker cmlw(fWriteMutex);


for (LinkedList<const RawMidiEvent*>::Itenerator it = fData.begin2(); it.valid(); it.next()) for (LinkedList<const RawMidiEvent*>::Itenerator it = fData.begin2(); it.valid(); it.next())
{ {
@@ -201,9 +202,12 @@ public:
if (std::memcmp(rawMidiEvent->data, data, size) != 0) if (std::memcmp(rawMidiEvent->data, data, size) != 0)
continue; continue;


delete rawMidiEvent;
fData.remove(it);
{
const CarlaMutexLocker cmlr(fReadMutex);
fData.remove(it);
}


delete rawMidiEvent;
return; return;
} }


@@ -215,7 +219,8 @@ public:


void clear() noexcept void clear() noexcept
{ {
const CarlaMutexLocker sl(fMutex);
const CarlaMutexLocker cmlr(fReadMutex);
const CarlaMutexLocker cmlw(fWriteMutex);


for (LinkedList<const RawMidiEvent*>::Itenerator it = fData.begin2(); it.valid(); it.next()) for (LinkedList<const RawMidiEvent*>::Itenerator it = fData.begin2(); it.valid(); it.next())
delete it.getValue(nullptr); delete it.getValue(nullptr);
@@ -226,17 +231,19 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// play on time // play on time


void play(const uint64_t timePosFrame, const uint32_t frames)
bool play(const uint64_t timePosFrame, const uint32_t frames)
{ {
play(static_cast<long double>(timePosFrame), static_cast<double>(frames));
return play(static_cast<long double>(timePosFrame), static_cast<double>(frames));
} }


void play(long double timePosFrame, const double frames, const double offset = 0.0)
bool play(long double timePosFrame, const double frames, const double offset = 0.0)
{ {
long double ldtime; long double ldtime;


if (! fMutex.tryLock())
return;
const CarlaMutexTryLocker cmtl(fReadMutex);

if (cmtl.wasNotLocked())
return false;


if (fStartTime != 0) if (fStartTime != 0)
timePosFrame += static_cast<long double>(fStartTime); timePosFrame += static_cast<long double>(fStartTime);
@@ -256,7 +263,7 @@ public:
kPlayer->writeMidiEvent(fMidiPort, ldtime + offset - timePosFrame, rawMidiEvent); kPlayer->writeMidiEvent(fMidiPort, ldtime + offset - timePosFrame, rawMidiEvent);
} }


fMutex.unlock();
return true;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -275,9 +282,9 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// special // special


const CarlaMutex& getLock() const noexcept
const CarlaMutex& getWriteMutex() const noexcept
{ {
return fMutex;
return fWriteMutex;
} }


LinkedList<const RawMidiEvent*>::Itenerator iteneratorBegin() const noexcept LinkedList<const RawMidiEvent*>::Itenerator iteneratorBegin() const noexcept
@@ -294,7 +301,7 @@ public:
static const std::size_t maxDataSize = 4 + 4*MAX_EVENT_DATA_SIZE; // std::strlen("0xFF:127:127:127"); static const std::size_t maxDataSize = 4 + 4*MAX_EVENT_DATA_SIZE; // std::strlen("0xFF:127:127:127");
static const std::size_t maxMsgSize = maxTimeSize + 3 /* sep + size + sep */ + maxDataSize + 1 /* newline */; static const std::size_t maxMsgSize = maxTimeSize + 3 /* sep + size + sep */ + maxDataSize + 1 /* newline */;


const CarlaMutexLocker sl(fMutex);
const CarlaMutexLocker cmlw(fWriteMutex);


if (fData.count() == 0) if (fData.count() == 0)
return nullptr; return nullptr;
@@ -346,7 +353,8 @@ public:


clear(); clear();


const CarlaMutexLocker sl(fMutex);
const CarlaMutexLocker cmlr(fReadMutex);
const CarlaMutexLocker cmlw(fWriteMutex);


for (size_t dataPos=0; dataPos < dataLen && *dataRead != '\0';) for (size_t dataPos=0; dataPos < dataLen && *dataRead != '\0';)
{ {
@@ -441,12 +449,13 @@ private:
uint8_t fMidiPort; uint8_t fMidiPort;
uint64_t fStartTime; uint64_t fStartTime;


CarlaMutex fMutex;
CarlaMutex fReadMutex;
CarlaMutex fWriteMutex;
LinkedList<const RawMidiEvent*> fData; LinkedList<const RawMidiEvent*> fData;


void appendSorted(const RawMidiEvent* const event) void appendSorted(const RawMidiEvent* const event)
{ {
const CarlaMutexLocker sl(fMutex);
const CarlaMutexLocker cmlw(fWriteMutex);


if (fData.isEmpty()) if (fData.isEmpty())
{ {


+ 2
- 1
source/native-plugins/midi-file.cpp View File

@@ -106,7 +106,8 @@ protected:
} }


if (fWasPlayingBefore) if (fWasPlayingBefore)
fMidiOut.play(timePos->frame, frames);
if (! fMidiOut.play(timePos->frame, frames))
fNeedsAllNotesOff = true;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------


+ 6
- 4
source/native-plugins/midi-pattern.cpp View File

@@ -266,13 +266,15 @@ protected:


if (loopedEndPos >= loopedPlayPos) if (loopedEndPos >= loopedPlayPos)
{ {
fMidiOut.play(loopedPlayPos, loopedEndPos-loopedPlayPos);
if (! fMidiOut.play(loopedPlayPos, loopedEndPos-loopedPlayPos))
fNeedsAllNotesOff = true;
} }
else else
{ {
const double diff = fMaxTicks - loopedPlayPos; const double diff = fMaxTicks - loopedPlayPos;
fMidiOut.play(loopedPlayPos, diff);
fMidiOut.play(0.0, loopedEndPos, diff);

if (! (fMidiOut.play(loopedPlayPos, diff) && fMidiOut.play(0.0, loopedEndPos, diff)))
fNeedsAllNotesOff = true;
} }
} }


@@ -458,7 +460,7 @@ private:
carla_zeroChars(strBuf, 0xff); carla_zeroChars(strBuf, 0xff);


const CarlaMutexLocker cml1(getPipeLock()); const CarlaMutexLocker cml1(getPipeLock());
const CarlaMutexLocker cml2(fMidiOut.getLock());
const CarlaMutexLocker cml2(fMidiOut.getWriteMutex());


writeMessage("midi-clear-all\n", 15); writeMessage("midi-clear-all\n", 15);




Loading…
Cancel
Save