Skip to content

Commit

Permalink
Revert "lua NRT processing function (#1634)" (#1673)
Browse files Browse the repository at this point in the history
This reverts commit 0c06b09.
  • Loading branch information
tehn authored Apr 19, 2023
1 parent 4230035 commit 3bc8bda
Show file tree
Hide file tree
Showing 15 changed files with 8 additions and 357 deletions.
3 changes: 0 additions & 3 deletions crone/osc-methods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ osc methods:
/softcut/buffer/clear_channel [i]
/softcut/buffer/clear_region [ff]
/softcut/buffer/clear_region_channel [iff]
/softcut/buffer/render [iffi]
/softcut/buffer/process [iff]
/softcut/buffer/return [iff]
/softcut/reset []
/set/param/cut/phase_quant [if]
/set/param/cut/phase_offset [if]
Expand Down
93 changes: 2 additions & 91 deletions crone/src/BufDiskWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

//-----------------------
//-- debugging
#include <cstddef>
#include <iostream>
#include <iomanip>
#include <chrono>
Expand All @@ -14,15 +13,7 @@
#include <sndfile.hh>
#include <array>
#include <cmath>
#include <thread>
#include <utility>
// -------------------
// for shared memory
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
// -------------------

#include "BufDiskWorker.h"

Expand All @@ -37,14 +28,12 @@ std::array<BufDiskWorker::BufDesc, BufDiskWorker::maxBufs> BufDiskWorker::bufs;
int BufDiskWorker::numBufs = 0;
bool BufDiskWorker::shouldQuit = false;
int BufDiskWorker::sampleRate = 48000;
int BufDiskWorker::fd = -1;

// clamp unsigned int to upper bound, inclusive
static inline void clamp(size_t &x, const size_t a) {
if (x > a) { x = a; }
}


int BufDiskWorker::registerBuffer(float *data, size_t frames) {
int n = numBufs++;
bufs[n].data = data;
Expand Down Expand Up @@ -108,16 +97,6 @@ void BufDiskWorker::requestRender(size_t idx, float start, float dur, int sample
requestJob(job);
}

void BufDiskWorker::requestProcess(size_t idx, float start, float dur, ProcessCallback processCallback) {
BufDiskWorker::Job job{BufDiskWorker::JobType::Process, {idx, 0}, "", start, start, dur, 0, 0, 0, 1, false, 0, nullptr, processCallback };
requestJob(job);
}

void BufDiskWorker::requestPoke(size_t idx, float start, float dur, DoneCallback doneCallback) {
BufDiskWorker::Job job{BufDiskWorker::JobType::Poke, {idx, 0}, "", start, start, dur, 0, 0, 0, 1, false, 0, nullptr, nullptr, doneCallback};
requestJob(job);
}

void BufDiskWorker::workLoop() {
while (!shouldQuit) {
Job job;
Expand Down Expand Up @@ -156,34 +135,25 @@ void BufDiskWorker::workLoop() {
case JobType::Render:
render(bufs[job.bufIdx[0]], job.startSrc, job.dur, (size_t)job.samples, job.renderCallback);
break;
case JobType::Process:
process(bufs[job.bufIdx[0]], job.startSrc, job.dur, job.processCallback);
break;
case JobType::Poke:
poke(bufs[job.bufIdx[0]], job.startSrc, job.dur, job.doneCallback);
}
#if 0 // debug, timing
auto ms_now = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
auto ms_dur = ms_now - ms_start;
std::cout << "job finished; elapsed time = " << ms_dur << " ms" << std::endl;
#endif
}
shm_unlink("BufDiskWorker_shm");
}

void BufDiskWorker::init(int sr) {
sampleRate = sr;
// don't really love using this as a magic word,
// but I also don't love passing it around.
fd = shm_open("BufDiskWorker_shm", O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
if (worker == nullptr) {
worker = std::make_unique<std::thread>(std::thread(BufDiskWorker::workLoop));
worker->detach();
}
}

size_t BufDiskWorker::secToFrame(float seconds) {
return static_cast<size_t>(seconds * (float) sampleRate);
int BufDiskWorker::secToFrame(float seconds) {
return static_cast<int>(seconds * (float) sampleRate);
}

float BufDiskWorker::raisedCosFade(float unitphase) {
Expand Down Expand Up @@ -634,62 +604,3 @@ void BufDiskWorker::render(BufDesc &buf, float start, float dur, size_t samples,
callback(window, start, samples, sampleBuf);
delete[] sampleBuf;
}

void BufDiskWorker::process(BufDesc &buf, float start, float dur, ProcessCallback processCallback) {
size_t frStart = secToFrame(start);
if (frStart > buf.frames - 1) { return; }

size_t frDur;
if (dur < 0) {
frDur = buf.frames - frStart;
} else {
frDur = secToFrame(dur);
}
clamp(frDur, buf.frames - frStart);

if (fd == -1) {
std::cerr << "BufDiskWorker::process(): opening shared memory failed" << std::endl;
return;
}
size_t size = sizeof(float) * frDur;
if (ftruncate(fd, size) == -1) {
// can't process the whole buffer, so let's just give up
std::cerr << "BufDiskWorker::process(): resizing shared memory failed" << std::endl;
return;
}
float *BufDiskWorker_shm = (float *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (BufDiskWorker_shm == MAP_FAILED) {
// again, just give up
std::cerr << "BufDiskWorker::process(): mapping shared memory failed" << std::endl;
return;
}
for (size_t i = 0; i < frDur; ++i) {
BufDiskWorker_shm[i] = buf.data[frStart];
frStart++;
}
processCallback(frDur);
}

void BufDiskWorker::poke(BufDesc &buf, float start, float dur, DoneCallback doneCallback) {
size_t frDur = secToFrame(dur);
size_t frStart = secToFrame(start);
clamp(frDur, buf.frames - frStart);
if (fd == -1) {
// just give up
std::cerr << "BufDiskWorker::poke(): opening shared memory failed" << std::endl;
return;
}
size_t size = sizeof(float) * frDur;
float *BufDiskWorker_shm = (float *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (BufDiskWorker_shm == MAP_FAILED) {
// just give up
std::cerr << "BufDiskWorker::poke(): mapping shared memory failed" << std::endl;
return;
}
for (size_t i = 0; i < frDur; ++i) {
buf.data[frStart] = BufDiskWorker_shm[i];
frStart++;
}
std::cerr << "calling doneCallback" << std::endl;
doneCallback(0);
}
20 changes: 2 additions & 18 deletions crone/src/BufDiskWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,13 @@ namespace crone {
class BufDiskWorker {
public:
typedef std::function<void(float secPerSample, float start, size_t count, float* samples)> RenderCallback;
typedef std::function<void(size_t size)> ProcessCallback;
typedef std::function<void(int jobType)> DoneCallback;

private:
enum class JobType {
Clear, ClearWithFade, Copy,
ReadMono, ReadStereo,
WriteMono, WriteStereo,
Render, Process, Poke
Render,
};
struct Job {
JobType type;
Expand All @@ -52,8 +50,6 @@ namespace crone {
bool reverse;
int samples;
RenderCallback renderCallback;
ProcessCallback processCallback;
DoneCallback doneCallback;
};
struct BufDesc {
float *data;
Expand All @@ -69,10 +65,9 @@ namespace crone {
static bool shouldQuit;
static constexpr int sleepPeriodMs = 100;
static int sampleRate;
static int fd;
static constexpr int ioBufFrames = 1024;

static size_t secToFrame(float seconds);
static int secToFrame(float seconds);
static float raisedCosFade(float unitphase);
static float mixFade(float x, float y, float a, float b);

Expand All @@ -85,7 +80,6 @@ namespace crone {
static void requestJob(Job &job);

public:

// initialize with sample rate
static void init(int sr);

Expand Down Expand Up @@ -121,12 +115,6 @@ namespace crone {

static void requestRender(size_t idx, float start, float dur, int count, RenderCallback callback);

// process portion of buffer using custom function
static void requestProcess(size_t idx, float start, float dur, ProcessCallback processCallback);

// return contents of buffer produced by custon function
static void requestPoke(size_t idx, float start, float dur, DoneCallback doneCallback);

private:
static void workLoop();

Expand All @@ -153,10 +141,6 @@ namespace crone {
float start = 0, float dur = -1) noexcept;

static void render(BufDesc &buf, float start, float dur, size_t samples, RenderCallback callback);

static void process(BufDesc &buf, float start, float dur, ProcessCallback processCallback);

static void poke(BufDesc &buf, float start, float dur, DoneCallback doneCallback);
};

}
Expand Down
18 changes: 0 additions & 18 deletions crone/src/OscInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// Created by ezra on 11/4/18.
//

#include <iostream>
#include <utility>
#include <thread>

Expand Down Expand Up @@ -799,23 +798,6 @@ void OscInterface::addServerMethods() {
});
});

addServerMethod("/softcut/buffer/process", "iff", [](lo_arg **argv, int argc) {
if (argc < 2) return;
softCutClient->processBuffer(argv[0]->i, argv[1]->f, argv[2]->f,
[=](size_t size) {
lo_send(matronAddress, "/softcut/buffer/do_process", "i", size);
});
});

addServerMethod("/softcut/buffer/return", "iff", [](lo_arg **argv, int argc) {
if (argc < 3) return;
int ch = argv[0]->i;
softCutClient->pokeBuffer(ch, argv[1]->f, argv[2]->f,
[=](int jobType){
lo_send(matronAddress, "/softcut/buffer/done_callback", "ii", ch, jobType);
});
});

addServerMethod("/softcut/query/position", "i", [](lo_arg **argv, int argc) {
if(argc < 1) return;
int idx = argv[0]->i;
Expand Down
10 changes: 0 additions & 10 deletions crone/src/SoftcutClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,6 @@ namespace crone {
if (chan < 0 || chan > 1 || count < 1) { return; }
BufDiskWorker::requestRender(bufIdx[chan], start, dur, count, callback);
}

void processBuffer(int chan, float start, float dur, BufDiskWorker::ProcessCallback callback) {
if (chan < 0 || chan > 1) { return; }
BufDiskWorker::requestProcess(chan, start, dur, callback);
}

void pokeBuffer(int chan, float start, float dur, BufDiskWorker::DoneCallback doneCallback) {
if (chan < 0 || chan > 1) { return; }
BufDiskWorker::requestPoke(chan, start, dur, doneCallback);
}

// check if quantized phase has changed for a given voice
bool checkVoiceQuantPhase(int i) {
Expand Down
3 changes: 1 addition & 2 deletions crone/wscript
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,5 @@ def build(bld):
'm',
'sndfile'
],
cxxflags=crone_flags,
ldflags=['-lrt']
cxxflags=crone_flags
)
3 changes: 0 additions & 3 deletions lua/core/norns.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@ _norns.vu = function(in1, in2, out1, out2) end
_norns.softcut_phase = function(id, value) end

_norns.softcut_render = function(ch, start, sec_per_sample, samples) end
_norns.softcut_process = function(sample_index, current_value) return 0 end
_norns.softcut_do_process = function() end
_norns.softcut_done = function(ch, job_type) end
_norns.softcut_position = function(i,pos) end

-- default readings for battery
Expand Down
50 changes: 1 addition & 49 deletions lua/core/softcut.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
local SC = {}

local controlspec = require 'core/controlspec'
local clock = require 'clock'

-------------------------------
-- @section constants
Expand Down Expand Up @@ -381,51 +380,12 @@ SC.render_buffer = function(ch, start, dur, samples)
_norns.cut_buffer_render(ch, start, dur, samples)
end

--- request that softcut process buffer with user-defined process function
-- usage: clock.run(softcut.process_buffer(ch, start, dur, sleep_time, block_size))
-- @tparam integer ch : buffer channel index (1-based)
-- @tparam number start : beginning of region in seconds
-- @tparam number dur : length of region in seconds
-- @tparam number sleep_time : amount of time to wait between blocks in seconds; default 0.2
-- @tparam integer block_size : number of samples per block; default 1024
SC.process_buffer = function(ch, start, dur, sleep_time, block_size)
if not sleep_time or sleep_time < 0 then sleep_time = 0.2 end
if not block_size or block_size <= 0 then block_size = 1024 end
start = start or 0
dur = dur or -1
return function()
_norns.softcut_do_process = function() end
_norns.cut_buffer_process(ch, start, dur)
while true do
for i = 1, block_size do
if _norns.softcut_do_process() then goto done end
end
clock.sleep(sleep_time)
end
::done::
_norns.cut_buffer_return(ch, start, dur)
_norns.softcut_do_process = function() end
end
end

--- set function for render callback. use render_buffer to request contents.
-- @tparam function func : called when buffer content is ready. args: (ch, start, sec_per_sample, samples)
SC.event_render = function(func)
_norns.softcut_render = func
end

--- set function for processing of buffer. use process_buffer to apply.
-- @tparam function func : called when buffer content is processed. args: (sample_index, current_value)
SC.process_func = function(func)
_norns.softcut_process = func
end

--- set function for job callback. called when process_buffer is complete.
-- @tparam function func : called when buffer job is complete. args: (ch, job_type, num_to_expect)
SC.event_done = function(func)
_norns.softcut_done = func
end

--- query playback position
-- @tparam integer i : which softcut voice
SC.query_position = function(i) _norns.cut_query_position(i) end
Expand All @@ -445,14 +405,6 @@ end
function SC.reset()
_norns.cut_reset()
SC.event_phase(norns.none)
SC.event_render(norns.none)
SC.event_done(norns.none)
SC.process_func(function(_,_) return 0 end)
if _norns.cut_process_clock then
clock.cancel(_norns.cut_process_clock)
_norns.cut_process_clock = nil
end
_norns.softcut_do_process = function() end
end

--- get the default state of the softcut system
Expand All @@ -463,7 +415,7 @@ end
-- NB: these values are synchronized by hand with those specified in the softcut cpp sources
-- @treturn table table of parameter states for each voice
function SC.defaults()
local zeros = {}
zeros = {}

for i=1,SC.VOICE_COUNT do
zeros[i] = 0
Expand Down
Loading

0 comments on commit 3bc8bda

Please sign in to comment.