|
@@ -28,7 +28,6 @@ extern "C" { |
|
|
#include "water/threads/ScopedLock.h" |
|
|
#include "water/threads/ScopedLock.h" |
|
|
#include "water/threads/SpinLock.h" |
|
|
#include "water/threads/SpinLock.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) |
|
|
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) |
|
|
# pragma GCC diagnostic push |
|
|
# pragma GCC diagnostic push |
|
|
# pragma GCC diagnostic ignored "-Weffc++" |
|
|
# pragma GCC diagnostic ignored "-Weffc++" |
|
@@ -40,6 +39,14 @@ extern "C" { |
|
|
# pragma GCC diagnostic pop |
|
|
# pragma GCC diagnostic pop |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#ifdef CARLA_OS_WIN |
|
|
|
|
|
# include <windows.h> |
|
|
|
|
|
# define CARLA_MLOCK(ptr, size) VirtualLock((ptr), (size)) |
|
|
|
|
|
#else |
|
|
|
|
|
# include <sys/mman.h> |
|
|
|
|
|
# define CARLA_MLOCK(ptr, size) mlock((ptr), (size)) |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
typedef struct adinfo ADInfo; |
|
|
typedef struct adinfo ADInfo; |
|
|
|
|
|
|
|
|
struct AudioFilePool { |
|
|
struct AudioFilePool { |
|
@@ -81,11 +88,15 @@ struct AudioFilePool { |
|
|
numFrames = desiredNumFrames; |
|
|
numFrames = desiredNumFrames; |
|
|
buffer[0] = new float[numFrames]; |
|
|
buffer[0] = new float[numFrames]; |
|
|
buffer[1] = new float[numFrames]; |
|
|
buffer[1] = new float[numFrames]; |
|
|
|
|
|
CARLA_MLOCK(buffer[0], sizeof(float)*numFrames); |
|
|
|
|
|
CARLA_MLOCK(buffer[1], sizeof(float)*numFrames); |
|
|
|
|
|
|
|
|
if (withTempBuffers) |
|
|
if (withTempBuffers) |
|
|
{ |
|
|
{ |
|
|
tmpbuf[0] = new float[numFrames]; |
|
|
tmpbuf[0] = new float[numFrames]; |
|
|
tmpbuf[1] = new float[numFrames]; |
|
|
tmpbuf[1] = new float[numFrames]; |
|
|
|
|
|
CARLA_MLOCK(tmpbuf[0], sizeof(float)*numFrames); |
|
|
|
|
|
CARLA_MLOCK(tmpbuf[1], sizeof(float)*numFrames); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
reset(); |
|
|
reset(); |
|
@@ -282,10 +293,10 @@ public: |
|
|
{ |
|
|
{ |
|
|
// valid |
|
|
// valid |
|
|
const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames); |
|
|
const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames); |
|
|
const uint32_t poolNumFrames = sampleRate * 5; |
|
|
|
|
|
uint32_t resampleNumFrames; |
|
|
|
|
|
|
|
|
const uint32_t maxPoolNumFrames = sampleRate * 10; |
|
|
|
|
|
const bool needsResample = fFileNfo.sample_rate != sampleRate; |
|
|
|
|
|
|
|
|
if (fFileNfo.sample_rate != sampleRate) |
|
|
|
|
|
|
|
|
if (needsResample) |
|
|
{ |
|
|
{ |
|
|
if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32)) |
|
|
if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32)) |
|
|
{ |
|
|
{ |
|
@@ -297,31 +308,30 @@ public: |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate); |
|
|
fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate); |
|
|
resampleNumFrames = static_cast<uint32_t>( |
|
|
|
|
|
static_cast<double>(std::min(fileNumFrames, poolNumFrames)) * fResampleRatio + 0.5); |
|
|
|
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
fResampler.clear(); |
|
|
fResampler.clear(); |
|
|
fResampleRatio = 0.0; |
|
|
fResampleRatio = 0.0; |
|
|
resampleNumFrames = 0; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (fileNumFrames <= poolNumFrames) |
|
|
|
|
|
|
|
|
if (fileNumFrames <= maxPoolNumFrames) |
|
|
{ |
|
|
{ |
|
|
// entire file fits in a small pool, lets read it now |
|
|
// entire file fits in a small pool, lets read it now |
|
|
fPool.create(resampleNumFrames != 0 ? resampleNumFrames : fileNumFrames, false); |
|
|
|
|
|
readEntireFileIntoPool(resampleNumFrames != 0); |
|
|
|
|
|
|
|
|
fPool.create(needsResample ? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5) |
|
|
|
|
|
: fileNumFrames, false); |
|
|
|
|
|
readEntireFileIntoPool(needsResample); |
|
|
ad_close(fFilePtr); |
|
|
ad_close(fFilePtr); |
|
|
fFilePtr = nullptr; |
|
|
fFilePtr = nullptr; |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
// file is too big for our audio pool, we need an extra buffer |
|
|
// file is too big for our audio pool, we need an extra buffer |
|
|
fPool.create(poolNumFrames, true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t poolNumFrames = sampleRate * 1; |
|
|
const uint pollTempSize = poolNumFrames * fFileNfo.channels; |
|
|
const uint pollTempSize = poolNumFrames * fFileNfo.channels; |
|
|
const uint resampleTempSize = resampleNumFrames * fFileNfo.channels; |
|
|
|
|
|
|
|
|
uint resampleTempSize = 0; |
|
|
|
|
|
|
|
|
|
|
|
fPool.create(poolNumFrames, true); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
fPollTempData = new float[pollTempSize]; |
|
|
fPollTempData = new float[pollTempSize]; |
|
@@ -333,8 +343,13 @@ public: |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (resampleTempSize) |
|
|
|
|
|
|
|
|
CARLA_MLOCK(fPollTempData, sizeof(float)*pollTempSize); |
|
|
|
|
|
|
|
|
|
|
|
if (needsResample) |
|
|
{ |
|
|
{ |
|
|
|
|
|
resampleTempSize = static_cast<uint32_t>(static_cast<double>(poolNumFrames) * fResampleRatio + 0.5); |
|
|
|
|
|
resampleTempSize *= fFileNfo.channels; |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
fResampleTempData = new float[resampleTempSize]; |
|
|
fResampleTempData = new float[resampleTempSize]; |
|
|
} catch (...) { |
|
|
} catch (...) { |
|
@@ -346,6 +361,8 @@ public: |
|
|
carla_stderr2("loadFilename error, out of memory"); |
|
|
carla_stderr2("loadFilename error, out of memory"); |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CARLA_MLOCK(fResampleTempData, sizeof(float)*resampleTempSize); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
fPollTempSize = pollTempSize; |
|
|
fPollTempSize = pollTempSize; |
|
@@ -398,7 +415,7 @@ public: |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint64_t frameDiff; |
|
|
uint64_t frameDiff; |
|
|
const uint64_t numFramesNearEnd = fPool.numFrames*3/4; |
|
|
|
|
|
|
|
|
const uint64_t numFramesNearEnd = fPool.numFrames*3/5; |
|
|
|
|
|
|
|
|
const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex); |
|
|
const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex); |
|
|
|
|
|
|
|
@@ -684,8 +701,8 @@ public: |
|
|
// lock, and put data asap |
|
|
// lock, and put data asap |
|
|
const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex); |
|
|
const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex); |
|
|
|
|
|
|
|
|
carla_copyFloats(fPool.buffer[0], pbuffer0, poolNumFrames); |
|
|
|
|
|
carla_copyFloats(fPool.buffer[1], pbuffer1, poolNumFrames); |
|
|
|
|
|
|
|
|
std::memcpy(fPool.buffer[0], pbuffer0, sizeof(float)*poolNumFrames); |
|
|
|
|
|
std::memcpy(fPool.buffer[1], pbuffer1, sizeof(float)*poolNumFrames); |
|
|
fPool.startFrame = static_cast<uint64_t>(readFrame); |
|
|
fPool.startFrame = static_cast<uint64_t>(readFrame); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|