zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 7e46abf022c5aee0ed562d10c10a56d208f528c7
parent e29d503df7df55deb8d601db51a05d9249a5f9fa
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Wed,  8 May 2013 12:41:41 -0400

MiddleWare: Simple Deallocation

Now pointers can be returned to the middleware layer for deallocation purposes
To make these transitions smoother, some additional work may need to be done,
but this should prevent any major memory leaks for the time being.

Diffstat:
Msrc/Misc/Master.cpp | 21+++++++++++++--------
Msrc/Misc/MiddleWare.cpp | 19+++++++++++++++++--
Msrc/Misc/Part.cpp | 36++++++++++++++++++++++++++++++------
Msrc/Misc/Part.h | 5+++--
4 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp @@ -45,18 +45,22 @@ using rtosc::Ports; using rtosc::RtData; static Ports localports = { - {"echo", ":'hidden':Hidden port to echo messages", 0, [](const char *m, RtData) { + {"echo", ":'hidden':Hidden port to echo messages", 0, [](const char *m, RtData&) { bToU->raw_write(m-1);}}, - {"get-vu", "::", 0, [](const char *, RtData d) { + {"get-vu", "::", 0, [](const char *, RtData &d) { Master *m = (Master*)d.obj; bToU->write("/vu-meter", "bb", sizeof(m->vu), &m->vu, sizeof(float)*NUM_MIDI_PARTS, m->vuoutpeakpart);}}, - {"reset-vu", "::", 0, [](const char *, RtData d) { + {"reset-vu", "::", 0, [](const char *, RtData &d) { Master *m = (Master*)d.obj; m->vuresetpeaks();}}, - {"load-part:ib", "::", 0, [](const char *msg, RtData d) { - Master *m = (Master*)d.obj; - m->part[rtosc_argument(msg, 0).i] = *(Part**)rtosc_argument(msg, 1).b.data; - printf("part %d is now pointer %p\n", rtosc_argument(msg, 0).i, *(Part**)rtosc_argument(msg, 1).b.data);}}, + {"load-part:ib", "::", 0, [](const char *msg, RtData &d) { + Master *m = (Master*)d.obj; + Part *p = *(Part**)rtosc_argument(msg, 1).b.data; + int i = rtosc_argument(msg, 0).i; + m->part[i]->cloneTraits(*p); + d.reply("/free", "sb", "Part", sizeof(void*), &p); + m->part[i] = p; + printf("part %d is now pointer %p\n", i, p);}}, PARAMF(Master, volume, volume, log, 0.01, 4.42, "Master Volume"), RECURSP(Master, Part, part, part, 16, "Part"),//NUM_MIDI_PARTS @@ -336,7 +340,8 @@ class DataObj:public rtosc::RtData va_start(va,args); char *buffer = bToU->buffer(); rtosc_vmessage(buffer,bToU->buffer_size(),path,args,va); - bToU->raw_write(buffer); + printf("sending reply of '%s'\n", buffer); + reply(buffer); } virtual void reply(const char *msg) { diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp @@ -114,6 +114,17 @@ static int handler_function(const char *path, const char *types, lo_arg **argv, typedef void(*cb_t)(void*,const char*); + +void deallocate(const char *str, void *v) +{ + if(!strcmp(str, "Part")) + delete (Part*)v; + else + fprintf(stderr, "Unknown type '%s', leaking pointer %p!!\n", str, v); +} + + + /** * - Fetches liblo messages and forward them to the backend * - Grabs backend messages and distributes them to the frontends @@ -123,12 +134,16 @@ void osc_check(cb_t cb, void *ui) lo_server_recv_noblock(server, 0); while(bToU->hasNext()) { const char *rtmsg = bToU->read(); + puts(rtmsg); if(!strcmp(rtmsg, "/echo") && !strcmp(rtosc_argument_string(rtmsg),"ss") && !strcmp(rtosc_argument(rtmsg,0).s, "OSC_URL")) curr_url = rtosc_argument(rtmsg,1).s; - else if(curr_url == "GUI") { - cb(ui, bToU->read()); //GUI::raiseUi(gui, bToU->read()); + else if(!strcmp(rtmsg, "/free") + && !strcmp(rtosc_argument_string(rtmsg),"sb")) { + printf("got a '%s' pointer for deallocation...\n", rtosc_argument(rtmsg, 0).s); + } else if(curr_url == "GUI") { + cb(ui, rtmsg); //GUI::raiseUi(gui, bToU->read()); } else{ lo_message msg = lo_message_deserialise((void*)rtmsg, rtosc_message_length(rtmsg, bToU->buffer_size()), NULL); diff --git a/src/Misc/Part.cpp b/src/Misc/Part.cpp @@ -131,6 +131,30 @@ Part::Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_) defaults(); } + +void Part::cloneTraits(Part &p) const +{ +#define CLONE(x) p.x = this->x + CLONE(Penabled); + + p.setPvolume(this->Pvolume); + p.setPpanning(this->Ppanning); + + CLONE(Pminkey); + CLONE(Pmaxkey); + CLONE(Pkeyshift); + CLONE(Prcvchn); + + CLONE(Pvelsns); + CLONE(Pveloffs); + + CLONE(Pnoteon); + CLONE(Ppolymode); + CLONE(Plegatomode); + CLONE(Pkeylimit); + + CLONE(ctl); +} void Part::defaults() { @@ -605,10 +629,12 @@ void Part::NoteOn(unsigned char note, // Spawn another note (but silent) if legatomodevalid==true if(legatomodevalid) { + + //if this parameter is 127 for "unprocessed" partnote[posb].kititem[ci].sendtoparteffect = (kit[item].Psendtoparteffect < NUM_PART_EFX ? kit[item].Psendtoparteffect : - NUM_PART_EFX); //if this parameter is 127 for "unprocessed" + NUM_PART_EFX); if((kit[item].adpars != NULL) && ((kit[item].Padenabled) != 0)) @@ -619,7 +645,7 @@ void Part::NoteOn(unsigned char note, vel, portamento, note, - true); //true for silent. + true);//true for silent. if((kit[item].subpars != NULL) && ((kit[item].Psubenabled) != 0)) partnote[posb].kititem[ci].subnote = @@ -665,13 +691,11 @@ void Part::NoteOn(unsigned char note, */ void Part::NoteOff(unsigned char note) //relase the key { - int i; - // This note is released, so we remove it from the list. - if(not monomemnotes.empty()) + if(!monomemnotes.empty()) monomemnotes.remove(note); - for(i = POLIPHONY - 1; i >= 0; i--) //first note in, is first out if there are same note multiple times + for(int i = POLIPHONY - 1; i >= 0; i--) //first note in, is first out if there are same note multiple times if((partnote[i].status == KEY_PLAYING) && (partnote[i].note == note)) { if(ctl.sustain.sustain == 0) { //the sustain pedal is not pushed if((Ppolymode == 0) && (not monomemnotes.empty())) diff --git a/src/Misc/Part.h b/src/Misc/Part.h @@ -52,6 +52,9 @@ class Part /**Destructor*/ ~Part(); + // Copy misc parameters not stored in .xiz format + void cloneTraits(Part &part) const; + // Midi commands implemented void NoteOn(unsigned char note, unsigned char velocity, @@ -68,8 +71,6 @@ class Part /* The synthesizer part output */ void ComputePartSmps(); //Part output - //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) - //saves the instrument settings to a XML file //returns 0 for ok or <0 if there is an error