Skip to content

Commit

Permalink
Get Watchpoints Practically Working
Browse files Browse the repository at this point in the history
  • Loading branch information
fundamental committed May 20, 2016
1 parent 51591b3 commit 229a227
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 46 deletions.
29 changes: 22 additions & 7 deletions src/Misc/Master.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static const Ports sysefxPort =

static const Ports sysefsendto =
{
{"to#" STRINGIFY(NUM_SYS_EFX) "::i",
{"to#" STRINGIFY(NUM_SYS_EFX) "::i",
rProp(parameter) rDoc("sysefx to sysefx routing gain"), 0, [](const char *m, RtData&d)
{
//same ugly workaround as before
Expand All @@ -98,6 +98,16 @@ static const Ports sysefsendto =
}}
};

#define rBegin [](const char *msg, RtData &d) { Master *m = (Master*)d.obj
#define rEnd }

static const Ports watchPorts = {
{"add:s", rDoc("Add synthesis state to watch"), 0,
rBegin;
m->watcher.add_watch(rtosc_argument(msg,0).s);
rEnd},
};

static const Ports master_ports = {
rString(last_xmz, XMZ_PATH_MAX, "File name for last name loaded if any."),
rRecursp(part, 16, "Part"),//NUM_MIDI_PARTS
Expand Down Expand Up @@ -241,11 +251,16 @@ static const Ports master_ports = {
{"HDDRecorder/pause:", rDoc("Pause recording"), 0, [](const char *, RtData &d) {
Master *m = (Master*)d.obj;
m->HDDRecorder.pause();}},
{"watch/add:s", rDoc("Add synthesis state to watch"), 0, [](const char *msg, RtData &d) {
Master *m = (Master*)d.obj;
m->watcher.add_watch(rtosc_argument(msg,0).s);}},

{"watch/", rDoc("Interface to grab out live synthesis state"), &watchPorts,
rBOIL_BEGIN;
SNIP;
watchPorts.dispatch(msg, data);
rBOIL_END},
};

#undef rBegin
#undef rEnd

const Ports &Master::ports = master_ports;

class DataObj:public rtosc::RtData
Expand Down Expand Up @@ -364,7 +379,7 @@ void Master::applyOscEvent(const char *msg)
DataObj d{loc_buf, 1024, this, bToU};
memset(loc_buf, 0, sizeof(loc_buf));
d.matches = 0;

if(strcmp(msg, "/get-vu") && false) {
fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 5 + 30, 0 + 40);
fprintf(stdout, "backend[*]: '%s'<%s>\n", msg,
Expand Down Expand Up @@ -690,7 +705,7 @@ bool Master::AudioOut(float *outr, float *outl)
}
if(events>1 && false)
fprintf(stderr, "backend: %d events per cycle\n",events);


//Swaps the Left channel with Right Channel
if(swaplr)
Expand Down
4 changes: 2 additions & 2 deletions src/Misc/Part.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,14 +502,14 @@ bool Part::NoteOn(unsigned char note,
if(item.Padenabled)
notePool.insertNote(note, sendto,
{memory.alloc<ADnote>(kit[i].adpars, pars,
wm, (pre+"kit"+i+"/add/").c_str), 0, i});
wm, (pre+"kit"+i+"/adpars/").c_str), 0, i});
if(item.Psubenabled)
notePool.insertNote(note, sendto,
{memory.alloc<SUBnote>(kit[i].subpars, pars), 1, i});
if(item.Ppadenabled)
notePool.insertNote(note, sendto,
{memory.alloc<PADnote>(kit[i].padpars, pars, interpolation, wm,
(pre+"kit"+i+"/pad/").c_str), 2, i});
(pre+"kit"+i+"/padpars/").c_str), 2, i});
} catch (std::bad_alloc & ba) {
std::cerr << "dropped new note: " << ba.what() << std::endl;
}
Expand Down
15 changes: 15 additions & 0 deletions src/Params/LFOParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ using namespace rtosc;
#define rObject LFOParams
#undef rChangeCb
#define rChangeCb if (obj->time) { obj->last_update_timestamp = obj->time->time(); }
#define rBegin [](const char *msg, rtosc::RtData &d) {
#define rEnd }
static const rtosc::Ports _ports = {
rSelf(LFOParams),
rPaste,
Expand All @@ -45,7 +47,20 @@ static const rtosc::Ports _ports = {
"0..4 second delay"),
rToggle(Pcontinous, rShort("c"), "Enable for global operation"),
rParamZyn(Pstretch, rShort("str"), rCentered, "Note frequency stretch"),

//Float valued aliases
{"delay::f", rProp(parameter) rMap(units, ms) rLog(0,4000), 0,
rBegin;

rEnd},
#define rPseudoLog(a,b) rLog(a,b)
{"period::f", rProp(parameter) rMap(units, ms) rPseudoLog(0.10, 1500.0), 0,
rBegin;
rEnd},
};
#undef rPseudoLog
#undef rBegin
#undef rEnd
#undef rChangeCb

const rtosc::Ports &LFOParams::ports = _ports;
Expand Down
6 changes: 3 additions & 3 deletions src/Synth/ADnote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1886,11 +1886,11 @@ void ADnote::Global::initparameters(const ADnoteGlobalParam &param,
ScratchString pre = prefix;
FreqEnvelope = memory.alloc<Envelope>(*param.FreqEnvelope, basefreq, synth.dt());
FreqLfo = memory.alloc<LFO>(*param.FreqLfo, basefreq, time, wm,
(pre+"FreqLfo/").c_str);
(pre+"GlobalPar/FreqLfo/").c_str);

AmpEnvelope = memory.alloc<Envelope>(*param.AmpEnvelope, basefreq, synth.dt());
AmpLfo = memory.alloc<LFO>(*param.AmpLfo, basefreq, time, wm,
(pre+"AmpLfo/").c_str);
(pre+"GlobalPar/AmpLfo/").c_str);

Volume = 4.0f * powf(0.1f, 3.0f * (1.0f - param.PVolume / 96.0f)) //-60 dB .. 0 dB
* VelF(velocity, param.PAmpVelocityScaleFunction); //sensing
Expand All @@ -1900,7 +1900,7 @@ void ADnote::Global::initparameters(const ADnoteGlobalParam &param,

FilterEnvelope = memory.alloc<Envelope>(*param.FilterEnvelope, basefreq, synth.dt());
FilterLfo = memory.alloc<LFO>(*param.FilterLfo, basefreq, time, wm,
(pre+"FilterLfo/").c_str);
(pre+"GlobalPar/FilterLfo/").c_str);

Filter->addMod(*FilterEnvelope);
Filter->addMod(*FilterLfo);
Expand Down
7 changes: 3 additions & 4 deletions src/Synth/LFO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ LFO::LFO(const LFOParams &lfopars, float basefreq, const AbsTime &t, WatchManage
deterministic(!lfopars.Pfreqrand),
dt_(t.dt()),
lfopars_(lfopars), basefreq_(basefreq),
watchPhase(m, watch_prefix, "phase"),
watchMag(m, watch_prefix, "magnitude")
watchOut(m, watch_prefix, "out")
{
int stretch = lfopars.Pstretch;
if(stretch == 0)
Expand Down Expand Up @@ -170,8 +169,8 @@ float LFO::lfoout()
computeNextFreqRnd();
}

watchPhase(phase);
watchMag(out);
float watch_data[2] = {phase, out};
watchOut(watch_data, 2);

return out;
}
Expand Down
3 changes: 1 addition & 2 deletions src/Synth/LFO.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ class LFO
const LFOParams &lfopars_;
const float basefreq_;

FloatWatchPoint watchPhase;
FloatWatchPoint watchMag;
VecWatchPoint watchOut;

void computeNextFreqRnd(void);
};
Expand Down
49 changes: 44 additions & 5 deletions src/Synth/WatchPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ WatchPoint::WatchPoint(WatchManager *ref, const char *prefix, const char *id)
strncpy(identity, prefix, 128);
if(id)
strncat(identity, id, 128);
//printf("new watchpoint ={%s:%s} <%s>\n", prefix, id, identity);
}

bool WatchPoint::is_active(void)
Expand All @@ -44,7 +43,7 @@ bool WatchPoint::is_active(void)

if(reference && reference->active(identity)) {
active = true;
samples_left = reference->samples(identity);
samples_left = 1;
return true;
}

Expand All @@ -54,12 +53,17 @@ bool WatchPoint::is_active(void)
FloatWatchPoint::FloatWatchPoint(WatchManager *ref, const char *prefix, const char *id)
:WatchPoint(ref, prefix, id)
{}

VecWatchPoint::VecWatchPoint(WatchManager *ref, const char *prefix, const char *id)
:WatchPoint(ref, prefix, id)
{}

WatchManager::WatchManager(thrlnk *link)
:write_back(link), new_active(false)
{
memset(active_list, 0, sizeof(active_list));
memset(sample_list, 0, sizeof(sample_list));
memset(data_list, 0, sizeof(data_list));
memset(deactivate, 0, sizeof(deactivate));
}

Expand All @@ -70,6 +74,7 @@ void WatchManager::add_watch(const char *id)
if(!active_list[i][0]) {
strncpy(active_list[i], id, 128);
new_active = true;
sample_list[i] = 0;
break;
}
}
Expand All @@ -85,19 +90,39 @@ void WatchManager::del_watch(const char *id)

void WatchManager::tick(void)
{
//Try to send out any vector stuff
for(int i=0; i<MAX_WATCH; ++i) {
if(sample_list[i]) {
char arg_types[MAX_SAMPLE+1] = {0};
rtosc_arg_t arg_val[MAX_SAMPLE];
for(int j=0; j<sample_list[i]; ++j) {
arg_types[j] = 'f';
arg_val[j].f = data_list[i][j];
}

write_back->writeArray(active_list[i], arg_types, arg_val);
deactivate[i] = true;
}
}

//Cleanup internal data
new_active = false;

//Clear deleted slots
for(int i=0; i<MAX_WATCH; ++i)
if(deactivate[i])
for(int i=0; i<MAX_WATCH; ++i) {
if(deactivate[i]) {
memset(active_list[i], 0, 128);
sample_list[i] = 0;
}
}

}

bool WatchManager::active(const char *id) const
{
assert(this);
assert(id);
if(new_active)
if(new_active || true)
for(int i=0; i<MAX_WATCH; ++i)
if(!strcmp(active_list[i], id))
return true;
Expand All @@ -121,3 +146,17 @@ void WatchManager::satisfy(const char *id, float f)
del_watch(id);
}

void WatchManager::satisfy(const char *id, float *f, int n)
{
int selected = -1;
for(int i=0; i<MAX_WATCH; ++i)
if(!strcmp(active_list[i], id))
selected = i;

if(selected == -1)
return;

//FIXME buffer overflow
for(int i=0; i<n; ++i)
data_list[selected][sample_list[selected]++] = f[i];
}
44 changes: 22 additions & 22 deletions src/Synth/WatchPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,12 @@
WatchPoint.h - Synthesis State Watcher
Copyright (C) 2015-2015 Mark McCurry
Author: Mark McCurry
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License (version 2 or later) for more details.
You should have received a copy of the GNU General Public License (version 2)
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
*/

#pragma once
Expand All @@ -36,12 +28,15 @@ struct WatchPoint
};

#define MAX_WATCH 16
#define MAX_WATCH_PATH 128
#define MAX_SAMPLE 128
struct WatchManager
{
typedef rtosc::ThreadLink thrlnk;
thrlnk *write_back;
bool new_active;
char active_list[128][MAX_WATCH];
char active_list[MAX_WATCH][MAX_WATCH_PATH];
float data_list[MAX_SAMPLE][MAX_WATCH];
int sample_list[MAX_WATCH];
bool deactivate[MAX_WATCH];

Expand All @@ -57,6 +52,7 @@ struct WatchManager

//Watch Point Response API
void satisfy(const char *, float);
void satisfy(const char *, float*, int);
};

struct FloatWatchPoint:public WatchPoint
Expand All @@ -71,11 +67,15 @@ struct FloatWatchPoint:public WatchPoint
}
};

//struct VecWatchPoint:public WatchPoint
//{
// inline void operator()(float *f, int n)
// {
// if(!is_active()) {
// }
// }
//};
//basically the same as the float watch point, only it consumes tuples
struct VecWatchPoint : public WatchPoint
{
VecWatchPoint(WatchManager *ref, const char *prefix, const char *id);
inline void operator()(float *f, int n)
{
if(is_active() && reference) {
reference->satisfy(identity, f, n);
active = false;
}
}
};
2 changes: 1 addition & 1 deletion src/UI/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ class UI_Interface:public Fl_Osc_Interface
virtual void damage(const char *path) override
{
#ifndef NO_UI
printf("\n\nDamage(\"%s\")\n", path);
//printf("\n\nDamage(\"%s\")\n", path);
std::set<Fl_Osc_Widget*> to_update;
for(auto pair:map) {
if(strstr(pair.first.c_str(), path)) {
Expand Down

0 comments on commit 229a227

Please sign in to comment.