Skip to content

Commit

Permalink
audiofile plugin: add option to load quad channel files
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <[email protected]>
  • Loading branch information
falkTX committed Aug 15, 2023
1 parent c657fb0 commit a197fd7
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 22 deletions.
68 changes: 49 additions & 19 deletions source/native-plugins/audio-base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class AudioFileReader
return fFileNfo;
}

bool loadFilename(const char* const filename, const uint32_t sampleRate,
bool loadFilename(const char* const filename, const uint32_t sampleRate, const bool quad2ndChannels,
const uint32_t previewDataSize, float* previewData)
{
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
Expand All @@ -176,10 +176,10 @@ class AudioFileReader
ad_dump_nfo(99, &fFileNfo);

// invalid
if ((fFileNfo.channels != 1 && fFileNfo.channels != 2) || fFileNfo.frames <= 0)
if ((fFileNfo.channels != 1 && fFileNfo.channels != 2 && fFileNfo.channels != 4) || fFileNfo.frames <= 0)
{
if (fFileNfo.channels != 1 && fFileNfo.channels != 2)
carla_stderr("loadFilename(\"%s\", ...) has not 1 or 2 channels", filename);
if (fFileNfo.channels != 1 && fFileNfo.channels != 2 && fFileNfo.channels != 4)
carla_stderr("loadFilename(\"%s\", ...) has not 1, 2 or 4 channels", filename);

if (fFileNfo.frames <= 0)
carla_stderr("loadFilename(\"%s\", ...) has 0 frames", filename);
Expand Down Expand Up @@ -216,6 +216,8 @@ class AudioFileReader
numResampledFrames = numFileFrames;
}

fQuad2ndChannels = quad2ndChannels;

if (fFileNfo.can_seek == 0 || numResampledFrames <= sampleRate * kMinLengthSeconds)
{
// read and cache the first few seconds of the file if seekable
Expand Down Expand Up @@ -439,10 +441,12 @@ class AudioFileReader
const float previewDataSizeF = static_cast<float>(previewDataSize);
const uint samplesPerRun = fFileNfo.channels;
const uint maxSampleToRead = fileNumFrames - samplesPerRun;
CARLA_SAFE_ASSERT_INT_RETURN(samplesPerRun == 1 || samplesPerRun == 2, samplesPerRun,);
float tmp[2] = { 0.0f, 0.0f };
CARLA_SAFE_ASSERT_INT_RETURN(samplesPerRun == 1 || samplesPerRun == 2 || samplesPerRun == 4, samplesPerRun,);
float tmp[4];

if (samplesPerRun == 2)
if (samplesPerRun == 4)
previewDataSize -= 3;
else if (samplesPerRun == 2)
previewDataSize -= 1;

for (uint i=0; i<previewDataSize; ++i)
Expand Down Expand Up @@ -552,18 +556,26 @@ class AudioFileReader
if (r == 0)
break;

if (channels == 1)
switch (channels)
{
case 1:
fRingBufferL.writeCustomData(rbuffer, r * sizeof(float));
fRingBufferR.writeCustomData(rbuffer, r * sizeof(float));
}
else
{
break;
case 2:
for (ssize_t i=0; i < r;)
{
fRingBufferL.writeCustomData(&rbuffer[i++], sizeof(float));
fRingBufferR.writeCustomData(&rbuffer[i++], sizeof(float));
}
break;
case 4:
for (ssize_t i=fQuad2ndChannels?2:0; i < r; i += 4)
{
fRingBufferL.writeCustomData(&rbuffer[i], sizeof(float));
fRingBufferR.writeCustomData(&rbuffer[i+1], sizeof(float));
}
break;
}

fRingBufferL.commitWrite();
Expand Down Expand Up @@ -596,18 +608,26 @@ class AudioFileReader
if (r == 0)
break;

if (channels == 1)
switch (channels)
{
case 1:
fRingBufferL.writeCustomData(buffer, r * sizeof(float));
fRingBufferR.writeCustomData(buffer, r * sizeof(float));
}
else
{
break;
case 2:
for (ssize_t i=0; i < r;)
{
fRingBufferL.writeCustomData(&buffer[i++], sizeof(float));
fRingBufferR.writeCustomData(&buffer[i++], sizeof(float));
}
break;
case 4:
for (ssize_t i=fQuad2ndChannels?2:0; i < r; i += 4)
{
fRingBufferL.writeCustomData(&buffer[i], sizeof(float));
fRingBufferR.writeCustomData(&buffer[i+1], sizeof(float));
}
break;
}

fRingBufferL.commitWrite();
Expand All @@ -621,6 +641,7 @@ class AudioFileReader

private:
bool fEntireFileLoaded = false;
bool fQuad2ndChannels = false;
int fCurrentBitRate = 0;
float fLastPlayPosition = 0.f;
int64_t fNextFileReadPos = -1;
Expand Down Expand Up @@ -713,18 +734,27 @@ class AudioFileReader
// lock, and put data asap
const CarlaMutexLocker cml(fInitialMemoryPool.mutex);

if (channels == 1)
switch (channels)
{
case 1:
for (ssize_t i=0; i < rv; ++i)
fInitialMemoryPool.buffer[0][i] = fInitialMemoryPool.buffer[1][i] = resampledBuffer[i];
}
else
{
break;
case 2:
for (ssize_t i=0, j=0; i < rv; ++j)
{
fInitialMemoryPool.buffer[0][j] = resampledBuffer[i++];
fInitialMemoryPool.buffer[1][j] = resampledBuffer[i++];
}
break;
case 4:
for (ssize_t i=fQuad2ndChannels?2:0, j=0; i < rv; ++j)
{
fInitialMemoryPool.buffer[0][j] = resampledBuffer[i];
fInitialMemoryPool.buffer[1][j] = resampledBuffer[i+1];
i += 4;
}
break;
}
}

Expand Down
49 changes: 46 additions & 3 deletions source/native-plugins/audio-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class AudioFilePlugin : public NativePluginClass
kParameterHostSync,
kParameterVolume,
kParameterEnabled,
kParameterQuadChannels,
kParameterInfoChannels,
kParameterInfoBitRate,
kParameterInfoBitDepth,
Expand Down Expand Up @@ -192,6 +193,24 @@ class AudioFilePlugin : public NativePluginClass
param.ranges.max = 1.0f;
param.designation = NATIVE_PARAMETER_DESIGNATION_ENABLED;
break;
case kParameterQuadChannels:
param.name = "Quad Channels";
param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
NATIVE_PARAMETER_IS_ENABLED|
NATIVE_PARAMETER_IS_INTEGER|
NATIVE_PARAMETER_USES_SCALEPOINTS);
param.ranges.def = 0.0f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
{
static const NativeParameterScalePoint scalePoints[2] = {
{ "Channels 1 + 2", 0 },
{ "Channels 3 + 4", 1 }
};
param.scalePointCount = 2;
param.scalePoints = scalePoints;
}
break;
case kParameterInfoChannels:
param.name = "Num Channels";
param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
Expand Down Expand Up @@ -279,6 +298,8 @@ class AudioFilePlugin : public NativePluginClass
return fHostSync ? 1.f : 0.f;
case kParameterEnabled:
return fEnabled ? 1.f : 0.f;
case kParameterQuadChannels:
return fQuad2ndChannels ? 1.f : 0.f;
case kParameterVolume:
return fVolume * 100.f;
case kParameterInfoPosition:
Expand Down Expand Up @@ -336,6 +357,13 @@ class AudioFilePlugin : public NativePluginClass
fEnabled = b;
}
break;
case kParameterQuadChannels:
if (fQuad2ndChannels != b)
{
fQuad2ndChannels = b;
fPendingFileReload = true;
hostRequestIdle();
}
default:
break;
}
Expand Down Expand Up @@ -475,15 +503,27 @@ class AudioFilePlugin : public NativePluginClass
}
#endif

if (fPendingFileRead)
if (fPendingFileReload)
{
fPendingFileReload = fPendingFileRead = false;

if (char* const filename = fFilename.releaseBufferPointer())
{
loadFilename(filename);
std::free(filename);
}
}
else if (fPendingFileRead)
{
fPendingFileRead = false;
fReader.readPoll();
}
}

void sampleRateChanged(double) override
void sampleRateChanged(const double sampleRate) override
{
fVolumeFilter.setSampleRate(sampleRate);

if (char* const filename = fFilename.releaseBufferPointer())
{
loadFilename(filename);
Expand Down Expand Up @@ -615,6 +655,8 @@ class AudioFilePlugin : public NativePluginClass
bool fEnabled = true;
bool fDoProcess = false;
bool fPendingFileRead = false;
bool fPendingFileReload = false;
bool fQuad2ndChannels = false;

uint32_t fInternalTransportFrame = 0;
float fLastPosition = 0.f;
Expand Down Expand Up @@ -668,7 +710,8 @@ class AudioFilePlugin : public NativePluginClass

constexpr uint32_t kPreviewDataLen = sizeof(fPreviewData)/sizeof(float);

if (fReader.loadFilename(filename, static_cast<uint32_t>(getSampleRate()), kPreviewDataLen, fPreviewData))
if (fReader.loadFilename(filename, static_cast<uint32_t>(getSampleRate()), fQuad2ndChannels,
kPreviewDataLen, fPreviewData))
{
fInternalTransportFrame = 0;
fDoProcess = true;
Expand Down

0 comments on commit a197fd7

Please sign in to comment.