frac32buffer audio in left
frac32buffer audio in right
bool32.risingfalling record
bool32.risingfalling play
bool32.risingfalling overdub
frac32.positive loop feedback
frac32buffer audio out L
frac32buffer audio out R
objref tableL
objref tableR
bool rec;
bool play;
int recpos;
int length;
uint32_t inputL;
uint32_t inputR;
uint32_t dataL;
uint32_t dataR;
int playpos;
int shift;
playpos = 0;
recpos = 0;
rec = 0;
play = 0;
// record
if ((inlet_rec) && !rec) {
rec = 1;
recpos = 0;
playpos = 0;
} else if (!(inlet_rec)) {
rec = 0;
length = recpos;
}
// play
play = (!rec);
// set 'shift factor' for storing the recording length/the sync output
if (attr_tableL.LENGTH == 8192) {
shift = 14;
}
if (attr_tableL.LENGTH == 16384) {
shift = 13;
}
if (attr_tableL.LENGTH == 32768) {
shift = 12;
}
if (attr_tableL.LENGTH == 65536) {
shift = 11;
}
if (attr_tableL.LENGTH == 131072) {
shift = 10;
}
if (attr_tableL.LENGTH == 262144) {
shift = 9;
}
if (attr_tableL.LENGTH == 524288) {
shift = 8;
}
if (attr_tableL.LENGTH == 1048576) {
shift = 7;
}
// input
inputL = (__SSAT((inlet_waveL), 28));
inputR = (__SSAT((inlet_waveR), 28));
// record
if (rec) {
if (recpos < (attr_tableL.LENGTH - 1))
attr_tableL.array[recpos++] = inputL;
attr_tableR.array[recpos] = inputR;
attr_tableL.array[attr_tableL.LENGTH - 1] = (recpos << shift);
}
// play
if (inlet_play) {
if (!(playpos == ((attr_tableL.array[attr_tableL.LENGTH - 1]) >> shift)))
playpos == playpos++;
else
playpos = 0;
} else
playpos = 0;
// feedback
dataL = ___SMMUL((attr_tableL.array[playpos]) << 3, inlet_feedback << 2);
dataR = ___SMMUL((attr_tableR.array[playpos]) << 3, inlet_feedback << 2);
attr_tableL.array[playpos] = dataL;
attr_tableR.array[playpos] = dataR;
outlet_waveL = (dataL * play);
outlet_waveR = (dataR * play);
// overdub
if (inlet_dub && play) {
attr_tableL.array[playpos] = (dataL + inputL);
attr_tableR.array[playpos] = (dataR + inputR);
}