@@ -232,9 +232,11 @@ protected: | |||||
carla_zeroFloats(audioIns[1], bufferSize); | carla_zeroFloats(audioIns[1], bufferSize); | ||||
carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount); | carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount); | ||||
int64_t oldTime, newTime; | |||||
while (! shouldThreadExit()) | while (! shouldThreadExit()) | ||||
{ | { | ||||
const int64_t oldTime = getTimeInMicroseconds(); | |||||
oldTime = getTimeInMicroseconds(); | |||||
const PendingRtEventsRunner prt(this, bufferSize, true); | const PendingRtEventsRunner prt(this, bufferSize, true); | ||||
@@ -244,7 +246,7 @@ protected: | |||||
pData->graph.process(pData, audioIns, audioOuts, bufferSize); | pData->graph.process(pData, audioIns, audioOuts, bufferSize); | ||||
const int64_t newTime = getTimeInMicroseconds(); | |||||
newTime = getTimeInMicroseconds(); | |||||
CARLA_SAFE_ASSERT_CONTINUE(newTime >= oldTime); | CARLA_SAFE_ASSERT_CONTINUE(newTime >= oldTime); | ||||
const int64_t remainingTime = cycleTime - (newTime - oldTime); | const int64_t remainingTime = cycleTime - (newTime - oldTime); | ||||
@@ -267,7 +269,7 @@ protected: | |||||
std::free(audioOuts[0]); | std::free(audioOuts[0]); | ||||
std::free(audioOuts[1]); | std::free(audioOuts[1]); | ||||
carla_stdout("CarlaEngineDummy audio thread finished"); | |||||
carla_stdout("CarlaEngineDummy audio thread finished with %u Xruns", pData->xruns); | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -68,6 +68,7 @@ | |||||
#include "jackbridge/JackBridge.hpp" | #include "jackbridge/JackBridge.hpp" | ||||
#include "water/files/File.h" | #include "water/files/File.h" | ||||
#include "water/misc/Time.h" | |||||
using CarlaBackend::CarlaEngine; | using CarlaBackend::CarlaEngine; | ||||
using CarlaBackend::EngineCallbackOpcode; | using CarlaBackend::EngineCallbackOpcode; | ||||
@@ -281,6 +282,15 @@ public: | |||||
gIsInitiated = true; | gIsInitiated = true; | ||||
const bool testing = std::getenv("CARLA_BRIDGE_TESTING") != nullptr; | |||||
int64_t timeToEnd; | |||||
if (testing) | |||||
{ | |||||
timeToEnd = water::Time::currentTimeMillis() + 10 * 1000; | |||||
fEngine->transportPlay(); | |||||
} | |||||
#if defined(USING_JUCE) && (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) | #if defined(USING_JUCE) && (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) | ||||
# ifndef CARLA_OS_WIN | # ifndef CARLA_OS_WIN | ||||
static const int argc = 0; | static const int argc = 0; | ||||
@@ -298,6 +308,8 @@ public: | |||||
# else | # else | ||||
carla_msleep(5); | carla_msleep(5); | ||||
# endif | # endif | ||||
if (testing && timeToEnd - water::Time::currentTimeMillis() < 0) | |||||
break; | |||||
} | } | ||||
#endif | #endif | ||||
@@ -332,7 +344,7 @@ protected: | |||||
} | } | ||||
private: | private: | ||||
const CarlaEngine* fEngine; | |||||
CarlaEngine* fEngine; | |||||
#ifdef USING_JUCE | #ifdef USING_JUCE | ||||
const juce::ScopedJuceInitialiser_GUI fJuceInitialiser; | const juce::ScopedJuceInitialiser_GUI fJuceInitialiser; | ||||
@@ -649,7 +661,14 @@ int main(int argc, char* argv[]) | |||||
if (const CarlaPluginInfo* const pluginInfo = carla_get_plugin_info(gHostHandle, 0)) | if (const CarlaPluginInfo* const pluginInfo = carla_get_plugin_info(gHostHandle, 0)) | ||||
{ | { | ||||
if (pluginInfo->hints & CarlaBackend::PLUGIN_HAS_CUSTOM_UI) | |||||
if (itype == CarlaBackend::PLUGIN_INTERNAL && (std::strcmp(label, "audiofile") == 0 || std::strcmp(label, "midifile") == 0)) | |||||
{ | |||||
if (file.exists()) | |||||
carla_set_custom_data(gHostHandle, 0, | |||||
CarlaBackend::CUSTOM_DATA_TYPE_STRING, | |||||
"file", file.getFullPathName().toRawUTF8()); | |||||
} | |||||
else if (pluginInfo->hints & CarlaBackend::PLUGIN_HAS_CUSTOM_UI) | |||||
{ | { | ||||
#ifdef HAVE_X11 | #ifdef HAVE_X11 | ||||
if (std::getenv("DISPLAY") != nullptr) | if (std::getenv("DISPLAY") != nullptr) | ||||
@@ -97,21 +97,14 @@ struct AudioFilePool { | |||||
CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool) | CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool) | ||||
}; | }; | ||||
class AbstractAudioPlayer | |||||
{ | |||||
public: | |||||
virtual ~AbstractAudioPlayer() {} | |||||
virtual uint64_t getLastFrame() const = 0; | |||||
}; | |||||
class AudioFileThread : public CarlaThread | class AudioFileThread : public CarlaThread | ||||
{ | { | ||||
public: | public: | ||||
AudioFileThread(AbstractAudioPlayer* const player) | |||||
AudioFileThread() | |||||
: CarlaThread("AudioFileThread"), | : CarlaThread("AudioFileThread"), | ||||
kPlayer(player), | |||||
fEntireFileLoaded(false), | fEntireFileLoaded(false), | ||||
fLoopingMode(true), | fLoopingMode(true), | ||||
fNeedsFrame(0), | |||||
fNeedsRead(false), | fNeedsRead(false), | ||||
fQuitNow(true), | fQuitNow(true), | ||||
fFilePtr(nullptr), | fFilePtr(nullptr), | ||||
@@ -120,10 +113,9 @@ public: | |||||
fPollTempData(nullptr), | fPollTempData(nullptr), | ||||
fPollTempSize(0), | fPollTempSize(0), | ||||
fPool(), | fPool(), | ||||
fMutex() | |||||
fMutex(), | |||||
fSignal() | |||||
{ | { | ||||
CARLA_ASSERT(kPlayer != nullptr); | |||||
static bool adInitiated = false; | static bool adInitiated = false; | ||||
if (! adInitiated) | if (! adInitiated) | ||||
@@ -168,16 +160,19 @@ public: | |||||
if (fPollTempData == nullptr) | if (fPollTempData == nullptr) | ||||
return; | return; | ||||
fNeedsRead = true; | |||||
fNeedsFrame = 0; | |||||
fNeedsRead = false; | |||||
fQuitNow = false; | fQuitNow = false; | ||||
startThread(); | startThread(); | ||||
} | } | ||||
void stopNow() | void stopNow() | ||||
{ | { | ||||
fNeedsFrame = 0; | |||||
fNeedsRead = false; | fNeedsRead = false; | ||||
fQuitNow = true; | fQuitNow = true; | ||||
fSignal.signal(); | |||||
stopThread(1000); | stopThread(1000); | ||||
const CarlaMutexLocker cml(fMutex); | const CarlaMutexLocker cml(fMutex); | ||||
@@ -209,9 +204,14 @@ public: | |||||
fLoopingMode = on; | fLoopingMode = on; | ||||
} | } | ||||
void setNeedsRead() noexcept | |||||
void setNeedsRead(const uint64_t frame) noexcept | |||||
{ | { | ||||
if (fEntireFileLoaded) | |||||
return; | |||||
fNeedsFrame = frame; | |||||
fNeedsRead = true; | fNeedsRead = true; | ||||
fSignal.signal(); | |||||
} | } | ||||
bool loadFilename(const char* const filename, const uint32_t sampleRate) | bool loadFilename(const char* const filename, const uint32_t sampleRate) | ||||
@@ -295,24 +295,73 @@ public: | |||||
carla_copyFloats(pool.buffer[1], fPool.buffer[1], fPool.numFrames); | carla_copyFloats(pool.buffer[1], fPool.buffer[1], fPool.numFrames); | ||||
} | } | ||||
bool tryPutData(AudioFilePool& pool, const uint64_t framePos, const uint32_t frames) | |||||
bool tryPutData(float* const out1, float* const out2, uint64_t framePos, const uint32_t frames) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(pool.numFrames == fPool.numFrames, false); | |||||
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0, false); | |||||
if (framePos >= fPool.numFrames) | |||||
return false; | |||||
if (framePos >= fNumFileFrames) | |||||
{ | |||||
if (fLoopingMode) | |||||
framePos %= fNumFileFrames; | |||||
else | |||||
return false; | |||||
} | |||||
uint64_t frameDiff; | |||||
const uint64_t numFramesNearEnd = fPool.numFrames*3/4; | |||||
#if 1 | |||||
const CarlaMutexLocker cml(fMutex); | const CarlaMutexLocker cml(fMutex); | ||||
/* | |||||
#else | |||||
const CarlaMutexTryLocker cmtl(fMutex); | const CarlaMutexTryLocker cmtl(fMutex); | ||||
if (! cmtl.wasLocked()) | if (! cmtl.wasLocked()) | ||||
return false; | |||||
*/ | |||||
{ | |||||
for (int i=0; i<5; ++i) | |||||
{ | |||||
pthread_yield(); | |||||
if (cmtl.tryAgain()) | |||||
break; | |||||
if (i == 4) | |||||
return false; | |||||
} | |||||
} | |||||
#endif | |||||
pool.startFrame = fPool.startFrame; | |||||
if (framePos < fPool.startFrame) | |||||
{ | |||||
if (fPool.startFrame + fPool.numFrames <= fNumFileFrames) | |||||
{ | |||||
setNeedsRead(framePos); | |||||
return false; | |||||
} | |||||
carla_copyFloats(pool.buffer[0] + framePos, fPool.buffer[0] + framePos, frames); | |||||
carla_copyFloats(pool.buffer[1] + framePos, fPool.buffer[1] + framePos, frames); | |||||
frameDiff = framePos + (fNumFileFrames - fPool.startFrame); | |||||
if (frameDiff + frames >= fPool.numFrames) | |||||
{ | |||||
setNeedsRead(framePos); | |||||
return false; | |||||
} | |||||
carla_copyFloats(out1, fPool.buffer[0] + frameDiff, frames); | |||||
carla_copyFloats(out2, fPool.buffer[1] + frameDiff, frames); | |||||
} | |||||
else | |||||
{ | |||||
frameDiff = framePos - fPool.startFrame; | |||||
if (frameDiff + frames >= fPool.numFrames) | |||||
{ | |||||
setNeedsRead(framePos); | |||||
return false; | |||||
} | |||||
carla_copyFloats(out1, fPool.buffer[0] + frameDiff, frames); | |||||
carla_copyFloats(out2, fPool.buffer[1] + frameDiff, frames); | |||||
} | |||||
if (frameDiff > numFramesNearEnd) | |||||
setNeedsRead(framePos + frames); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -372,17 +421,19 @@ public: | |||||
if (fNumFileFrames == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr) | if (fNumFileFrames == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr) | ||||
{ | { | ||||
carla_debug("R: no song loaded"); | carla_debug("R: no song loaded"); | ||||
fNeedsFrame = 0; | |||||
fNeedsRead = false; | fNeedsRead = false; | ||||
return; | return; | ||||
} | } | ||||
if (fPollTempData == nullptr) | if (fPollTempData == nullptr) | ||||
{ | { | ||||
carla_debug("R: nothing to poll"); | carla_debug("R: nothing to poll"); | ||||
fNeedsFrame = 0; | |||||
fNeedsRead = false; | fNeedsRead = false; | ||||
return; | return; | ||||
} | } | ||||
uint64_t lastFrame = kPlayer->getLastFrame(); | |||||
uint64_t lastFrame = fNeedsFrame; | |||||
int64_t readFrameCheck; | int64_t readFrameCheck; | ||||
if (lastFrame >= fNumFileFrames) | if (lastFrame >= fNumFileFrames) | ||||
@@ -398,6 +449,7 @@ public: | |||||
else | else | ||||
{ | { | ||||
carla_debug("R: transport out of bounds"); | carla_debug("R: transport out of bounds"); | ||||
fNeedsFrame = 0; | |||||
fNeedsRead = false; | fNeedsRead = false; | ||||
return; | return; | ||||
} | } | ||||
@@ -428,6 +480,7 @@ public: | |||||
if (rv < 0) | if (rv < 0) | ||||
{ | { | ||||
carla_stderr("R: ad_read failed"); | carla_stderr("R: ad_read failed"); | ||||
fNeedsFrame = 0; | |||||
fNeedsRead = false; | fNeedsRead = false; | ||||
return; | return; | ||||
} | } | ||||
@@ -442,36 +495,46 @@ public: | |||||
rv += ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv); | rv += ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv); | ||||
} | } | ||||
carla_debug("R: reading %li frames at frame %lu", rv, readFrameCheck); | |||||
// local copy | |||||
const uint32_t poolNumFrame = fPool.numFrames; | |||||
const int64_t fileFrames = fFileNfo.frames; | |||||
const bool isMonoFile = fFileNfo.channels == 1; | |||||
float* const pbuffer0 = fPool.buffer[0]; | |||||
float* const pbuffer1 = fPool.buffer[1]; | |||||
const float* const tmpbuf = fPollTempData; | |||||
// lock, and put data asap | // lock, and put data asap | ||||
const CarlaMutexLocker cml(fMutex); | const CarlaMutexLocker cml(fMutex); | ||||
do { | do { | ||||
for (; i < fPool.numFrames && j < rv; ++j) | |||||
for (; i < poolNumFrame && j < rv; ++j) | |||||
{ | { | ||||
if (fFileNfo.channels == 1) | |||||
if (isMonoFile) | |||||
{ | { | ||||
fPool.buffer[0][i] = fPollTempData[j]; | |||||
fPool.buffer[1][i] = fPollTempData[j]; | |||||
pbuffer0[i] = pbuffer1[i] = tmpbuf[j]; | |||||
i++; | i++; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (j % 2 == 0) | if (j % 2 == 0) | ||||
{ | { | ||||
fPool.buffer[0][i] = fPollTempData[j]; | |||||
pbuffer0[i] = tmpbuf[j]; | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
fPool.buffer[1][i] = fPollTempData[j]; | |||||
i++; | |||||
pbuffer1[i] = tmpbuf[j]; | |||||
++i; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (i >= fPool.numFrames) | |||||
if (i >= poolNumFrame) { | |||||
break; | break; | ||||
} | |||||
if (rv == fFileNfo.frames) | |||||
if (rv == fileFrames) | |||||
{ | { | ||||
// full file read | // full file read | ||||
j = 0; | j = 0; | ||||
@@ -481,14 +544,14 @@ public: | |||||
{ | { | ||||
carla_debug("read break, not enough space"); | carla_debug("read break, not enough space"); | ||||
carla_zeroFloats(fPool.buffer[0] + i, fPool.numFrames - i); | |||||
carla_zeroFloats(fPool.buffer[1] + i, fPool.numFrames - i); | |||||
carla_zeroFloats(pbuffer0, poolNumFrame - i); | |||||
carla_zeroFloats(pbuffer1, poolNumFrame - i); | |||||
break; | break; | ||||
} | } | ||||
} while (i < fPool.numFrames); | |||||
} while (i < poolNumFrame); | |||||
fPool.startFrame = lastFrame; | |||||
fPool.startFrame = readFrame; | |||||
} | } | ||||
fNeedsRead = false; | fNeedsRead = false; | ||||
@@ -497,25 +560,22 @@ public: | |||||
protected: | protected: | ||||
void run() override | void run() override | ||||
{ | { | ||||
const uint64_t numFramesNearEnd = fPool.numFrames*3/4; | |||||
uint64_t lastFrame; | |||||
while (! fQuitNow) | while (! fQuitNow) | ||||
{ | { | ||||
lastFrame = kPlayer->getLastFrame(); | |||||
if (fNeedsRead || lastFrame < fPool.startFrame || lastFrame - fPool.startFrame >= numFramesNearEnd) | |||||
if (fNeedsRead) | |||||
readPoll(); | readPoll(); | ||||
carla_msleep(50); | |||||
if (fQuitNow) | |||||
break; | |||||
fSignal.wait(); | |||||
} | } | ||||
} | } | ||||
private: | private: | ||||
AbstractAudioPlayer* const kPlayer; | |||||
bool fEntireFileLoaded; | bool fEntireFileLoaded; | ||||
bool fLoopingMode; | bool fLoopingMode; | ||||
volatile uint64_t fNeedsFrame; | |||||
volatile bool fNeedsRead; | volatile bool fNeedsRead; | ||||
volatile bool fQuitNow; | volatile bool fQuitNow; | ||||
@@ -529,6 +589,7 @@ private: | |||||
AudioFilePool fPool; | AudioFilePool fPool; | ||||
CarlaMutex fMutex; | CarlaMutex fMutex; | ||||
CarlaSignal fSignal; | |||||
CARLA_DECLARE_NON_COPY_STRUCT(AudioFileThread) | CARLA_DECLARE_NON_COPY_STRUCT(AudioFileThread) | ||||
}; | }; | ||||
@@ -46,11 +46,9 @@ static const char* const audiofilesWildcard = | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
#ifdef HAVE_PYQT | #ifdef HAVE_PYQT | ||||
class AudioFilePlugin : public NativePluginWithMidiPrograms<FileAudio>, | |||||
public AbstractAudioPlayer | |||||
class AudioFilePlugin : public NativePluginWithMidiPrograms<FileAudio> | |||||
#else | #else | ||||
class AudioFilePlugin : public NativePluginClass, | |||||
public AbstractAudioPlayer | |||||
class AudioFilePlugin : public NativePluginClass | |||||
#endif | #endif | ||||
{ | { | ||||
public: | public: | ||||
@@ -60,13 +58,12 @@ public: | |||||
#else | #else | ||||
: NativePluginClass(host), | : NativePluginClass(host), | ||||
#endif | #endif | ||||
AbstractAudioPlayer(), | |||||
fLoopMode(true), | fLoopMode(true), | ||||
fDoProcess(false), | fDoProcess(false), | ||||
fLastFrame(0), | |||||
fWasPlayingBefore(false), | |||||
fMaxFrame(0), | fMaxFrame(0), | ||||
fPool(), | fPool(), | ||||
fThread(this) | |||||
fThread() | |||||
#ifdef HAVE_PYQT | #ifdef HAVE_PYQT | ||||
, fPrograms(hostGetFilePath("audio"), audiofilesWildcard), | , fPrograms(hostGetFilePath("audio"), audiofilesWildcard), | ||||
fInlineDisplay() | fInlineDisplay() | ||||
@@ -80,11 +77,6 @@ public: | |||||
fPool.destroy(); | fPool.destroy(); | ||||
} | } | ||||
uint64_t getLastFrame() const override | |||||
{ | |||||
return fLastFrame; | |||||
} | |||||
protected: | protected: | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Plugin parameter calls | // Plugin parameter calls | ||||
@@ -139,7 +131,6 @@ protected: | |||||
fLoopMode = b; | fLoopMode = b; | ||||
fThread.setLoopingMode(b); | fThread.setLoopingMode(b); | ||||
fThread.setNeedsRead(); | |||||
} | } | ||||
void setCustomData(const char* const key, const char* const value) override | void setCustomData(const char* const key, const char* const value) override | ||||
@@ -166,8 +157,7 @@ protected: | |||||
if (! fDoProcess) | if (! fDoProcess) | ||||
{ | { | ||||
//carla_stderr("P: no process"); | |||||
fLastFrame = timePos->frame; | |||||
// carla_stderr("P: no process"); | |||||
carla_zeroFloats(out1, frames); | carla_zeroFloats(out1, frames); | ||||
carla_zeroFloats(out2, frames); | carla_zeroFloats(out2, frames); | ||||
return; | return; | ||||
@@ -176,23 +166,26 @@ protected: | |||||
// not playing | // not playing | ||||
if (! timePos->playing) | if (! timePos->playing) | ||||
{ | { | ||||
//carla_stderr("P: not playing"); | |||||
if (timePos->frame == 0 && fLastFrame > 0) | |||||
fThread.setNeedsRead(); | |||||
// carla_stderr("P: not playing"); | |||||
if (timePos->frame == 0 && fWasPlayingBefore) | |||||
fThread.setNeedsRead(timePos->frame); | |||||
fLastFrame = timePos->frame; | |||||
carla_zeroFloats(out1, frames); | carla_zeroFloats(out1, frames); | ||||
carla_zeroFloats(out2, frames); | carla_zeroFloats(out2, frames); | ||||
fWasPlayingBefore = false; | |||||
return; | return; | ||||
} | } | ||||
else | |||||
{ | |||||
fWasPlayingBefore = true; | |||||
} | |||||
// out of reach | // out of reach | ||||
if ((timePos->frame < fPool.startFrame || timePos->frame >= fMaxFrame) && !fLoopMode) | if ((timePos->frame < fPool.startFrame || timePos->frame >= fMaxFrame) && !fLoopMode) | ||||
{ | { | ||||
if (timePos->frame < fPool.startFrame) | if (timePos->frame < fPool.startFrame) | ||||
fThread.setNeedsRead(); | |||||
fThread.setNeedsRead(timePos->frame); | |||||
fLastFrame = timePos->frame; | |||||
carla_zeroFloats(out1, frames); | carla_zeroFloats(out1, frames); | ||||
carla_zeroFloats(out2, frames); | carla_zeroFloats(out2, frames); | ||||
@@ -251,15 +244,7 @@ protected: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
// NOTE: timePos->frame is always >= fPool.startFrame | |||||
const uint64_t poolStartFrame = timePos->frame - fThread.getPoolStartFrame(); | |||||
if (fThread.tryPutData(fPool, poolStartFrame, frames)) | |||||
{ | |||||
carla_copyFloats(out1, fPool.buffer[0]+poolStartFrame, frames); | |||||
carla_copyFloats(out2, fPool.buffer[1]+poolStartFrame, frames); | |||||
} | |||||
else | |||||
if (! fThread.tryPutData(out1, out2, timePos->frame, frames)) | |||||
{ | { | ||||
carla_zeroFloats(out1, frames); | carla_zeroFloats(out1, frames); | ||||
carla_zeroFloats(out2, frames); | carla_zeroFloats(out2, frames); | ||||
@@ -277,11 +262,10 @@ protected: | |||||
if (! fInlineDisplay.pending) | if (! fInlineDisplay.pending) | ||||
{ | { | ||||
fInlineDisplay.pending = true; | fInlineDisplay.pending = true; | ||||
// FIXME this is not supposed to be here, but in some idle callback | |||||
hostQueueDrawInlineDisplay(); | hostQueueDrawInlineDisplay(); | ||||
} | } | ||||
#endif | #endif | ||||
fLastFrame = timePos->frame; | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -428,8 +412,8 @@ protected: | |||||
private: | private: | ||||
bool fLoopMode; | bool fLoopMode; | ||||
bool fDoProcess; | bool fDoProcess; | ||||
bool fWasPlayingBefore; | |||||
volatile uint64_t fLastFrame; | |||||
uint32_t fMaxFrame; | uint32_t fMaxFrame; | ||||
AudioFilePool fPool; | AudioFilePool fPool; | ||||
@@ -205,35 +205,17 @@ private: | |||||
CARLA_SAFE_ASSERT_CONTINUE(midiEventHolder != nullptr); | CARLA_SAFE_ASSERT_CONTINUE(midiEventHolder != nullptr); | ||||
const MidiMessage& midiMessage(midiEventHolder->message); | const MidiMessage& midiMessage(midiEventHolder->message); | ||||
//const double time(track->getEventTime(i)*sampleRate); | |||||
const int dataSize(midiMessage.getRawDataSize()); | |||||
const int dataSize = midiMessage.getRawDataSize(); | |||||
if (dataSize <= 0 || dataSize > MAX_EVENT_DATA_SIZE) | if (dataSize <= 0 || dataSize > MAX_EVENT_DATA_SIZE) | ||||
continue; | continue; | ||||
if (midiMessage.isActiveSense()) | |||||
continue; | |||||
if (midiMessage.isMetaEvent()) | |||||
continue; | |||||
if (midiMessage.isMidiStart()) | |||||
continue; | |||||
if (midiMessage.isMidiContinue()) | |||||
continue; | |||||
if (midiMessage.isMidiStop()) | |||||
continue; | |||||
if (midiMessage.isMidiClock()) | |||||
continue; | |||||
if (midiMessage.isSongPositionPointer()) | |||||
continue; | |||||
if (midiMessage.isQuarterFrame()) | |||||
continue; | |||||
if (midiMessage.isFullFrame()) | |||||
continue; | |||||
if (midiMessage.isMidiMachineControlMessage()) | |||||
continue; | |||||
if (midiMessage.isSysEx()) | |||||
const uint8_t* const data = midiMessage.getRawData(); | |||||
if (! MIDI_IS_CHANNEL_MESSAGE(data[0])) | |||||
continue; | continue; | ||||
const double time(midiMessage.getTimeStamp()*sampleRate); | |||||
const double time = midiMessage.getTimeStamp() * sampleRate; | |||||
// const double time = track->getEventTime(i) * sampleRate; | |||||
CARLA_SAFE_ASSERT_CONTINUE(time >= 0.0); | CARLA_SAFE_ASSERT_CONTINUE(time >= 0.0); | ||||
fMidiOut.addRaw(static_cast<uint64_t>(time), midiMessage.getRawData(), static_cast<uint8_t>(dataSize)); | fMidiOut.addRaw(static_cast<uint64_t>(time), midiMessage.getRawData(), static_cast<uint8_t>(dataSize)); | ||||
@@ -325,6 +325,11 @@ public: | |||||
return !fLocked; | return !fLocked; | ||||
} | } | ||||
bool tryAgain() const noexcept | |||||
{ | |||||
return fMutex.tryLock(); | |||||
} | |||||
private: | private: | ||||
const Mutex& fMutex; | const Mutex& fMutex; | ||||
const bool fLocked; | const bool fLocked; | ||||