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),
fMidiPort(0),
fStartTime(0),
fMutex(),
fReadMutex(),
fWriteMutex(),
fData()
{
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)
{
const CarlaMutexLocker sl(fMutex);
const CarlaMutexLocker cmlw(fWriteMutex);

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)
continue;

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

delete rawMidiEvent;
return;
}

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

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())
delete it.getValue(nullptr);
@@ -226,17 +231,19 @@ public:
// -------------------------------------------------------------------
// 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;

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

if (cmtl.wasNotLocked())
return false;

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

fMutex.unlock();
return true;
}

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

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

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 maxMsgSize = maxTimeSize + 3 /* sep + size + sep */ + maxDataSize + 1 /* newline */;

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

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

clear();

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

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

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

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

if (fData.isEmpty())
{


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

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

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)
{
fMidiOut.play(loopedPlayPos, loopedEndPos-loopedPlayPos);
if (! fMidiOut.play(loopedPlayPos, loopedEndPos-loopedPlayPos))
fNeedsAllNotesOff = true;
}
else
{
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);

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

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



Loading…
Cancel
Save