Skip to content
Permalink
main
Go to file
 
 
Cannot retrieve contributors at this time
146 lines (123 sloc) 5.25 KB
//
// Created by emb on 11/28/18.
//
#ifndef CRONE_CUTCLIENT_H
#define CRONE_CUTCLIENT_H
#include <iostream>
#include "BufDiskWorker.h"
#include "Bus.h"
#include "Client.h"
#include "Utilities.h"
#include "softcut/Softcut.h"
#include "softcut/Types.h"
namespace crone {
class SoftcutClient: public Client<2, 2> {
public:
static constexpr float MaxRate = static_cast<float>(softcut::Resampler::OUT_BUF_FRAMES);
static constexpr float MinRate = static_cast<float>(softcut::Resampler::OUT_BUF_FRAMES * -1);
enum { MaxBlockFrames = 2048};
enum { BufFrames = 16777216 };
enum { NumVoices = 6 };
enum { NumBuffers = 2 };
typedef enum { SourceAdc=0 } SourceId;
typedef Bus<2, MaxBlockFrames> StereoBus;
typedef Bus<1, MaxBlockFrames> MonoBus;
public:
SoftcutClient();
private:
// processors
softcut::Softcut<NumVoices> cut;
// main buffer
float buf[NumBuffers][BufFrames];
// buffer index for use with BufDiskWorker
int bufIdx[NumBuffers];
// busses
StereoBus mix;
MonoBus input[NumVoices];
MonoBus output[NumVoices];
// levels
LogRamp inLevel[2][NumVoices];
LogRamp outLevel[NumVoices];
LogRamp outPan[NumVoices];
LogRamp fbLevel[NumVoices][NumVoices];
// enabled flags
bool enabled[NumVoices];
softcut::phase_t quantPhase[NumVoices];
float bufDur;
private:
void process(jack_nframes_t numFrames) override;
void setSampleRate(jack_nframes_t) override;
inline size_t secToFrame(float sec) {
return static_cast<size_t >(sec * jack_get_sample_rate(Client::client));
}
public:
/// FIXME: the "commands" structure shouldn't really be necessary.
/// should be able to refactor most/all parameters for atomic access.
// called from audio thread
void handleCommand(Commands::CommandPacket *p) override;
// these accessors can be called from other threads, so don't need to go through the commands queue
//-- buffer manipulation
//-- time parameters are in seconds
//-- negative 'dur' parameter reads/clears/writes as much as possible.
void readBufferMono(const std::string &path, float startTimeSrc = 0.f, float startTimeDst = 0.f,
float dur = -1.f, int chanSrc = 0, int chanDst = 0) {
BufDiskWorker::requestReadMono(bufIdx[chanDst], path, startTimeSrc, startTimeDst, dur, chanSrc);
}
void readBufferStereo(const std::string &path, float startTimeSrc = 0.f, float startTimeDst = 0.f,
float dur = -1.f) {
BufDiskWorker::requestReadStereo(bufIdx[0], bufIdx[1], path, startTimeSrc, startTimeDst, dur);
}
void writeBufferMono(const std::string &path, float start, float dur, int chan) {
BufDiskWorker::requestWriteMono(bufIdx[chan], path, start, dur);
}
void writeBufferStereo(const std::string &path, float start, float dur) {
BufDiskWorker::requestWriteStereo(bufIdx[0], bufIdx[1], path, start, dur);
}
void clearBuffer(int chan, float start=0.f, float dur=-1) {
if (chan < 0 || chan > 1) { return; }
BufDiskWorker::requestClear(bufIdx[chan], start, dur);
}
void clearBufferWithFade(int chan, float start=0.f, float dur=-1, float fadeTime=0.f, float preserve=0.f) {
if (chan < 0 || chan > 1) { return; }
BufDiskWorker::requestClearWithFade(bufIdx[chan], start, dur, fadeTime, preserve);
}
void copyBuffer(int srcChan, int dstChan,
float srcStart=0.f, float dstStart=0.f, float dur=-1,
float fadeTime=0.f, float preserve=0.f, bool reverse=false) {
if (srcChan < 0 || srcChan > 1 || dstChan < 0 || dstChan > 1) { return; }
BufDiskWorker::requestCopy(bufIdx[srcChan], bufIdx[dstChan],
srcStart, dstStart, dur,
fadeTime, preserve, reverse);
}
void renderSamples(int chan, float start, float dur, int count, BufDiskWorker::RenderCallback callback) {
if (chan < 0 || chan > 1 || count < 1) { return; }
BufDiskWorker::requestRender(bufIdx[chan], start, dur, count, callback);
}
// check if quantized phase has changed for a given voice
// returns true
bool checkVoiceQuantPhase(int i) {
if (quantPhase[i] != cut.getQuantPhase(i)) {
quantPhase[i] = cut.getQuantPhase(i);
return true;
} else {
return false;
}
}
softcut::phase_t getQuantPhase(int i) {
return cut.getQuantPhase(i);
}
void setPhaseQuant(int i, softcut::phase_t q) {
cut.setPhaseQuant(i, q);
}
void setPhaseOffset(int i, float sec) {
cut.setPhaseOffset(i, sec);
}
int getNumVoices() const { return NumVoices; }
void reset();
private:
void clearBusses(size_t numFrames);
void mixInput(size_t numFrames);
void mixOutput(size_t numFrames);
};
}
#endif //CRONE_CUTCLIENT_H