bool UndoHistoryImpl::mergeEvent(time_t now, const char *msg, char *buf, size_t N) { if(history_pos == 0) return false; for(int i=history_pos-1; i>=0; --i) { if(difftime(now, history[i].first) > 2) break; if(!strcmp(getUndoAddress(msg), getUndoAddress(history[i].second))) { //We can splice events together, merging them into one event rtosc_arg_t args[3]; args[0] = rtosc_argument(msg, 0); args[1] = rtosc_argument(history[i].second,1); args[2] = rtosc_argument(msg, 2); rtosc_amessage(buf, N, msg, rtosc_argument_string(msg), args); delete [] history[i].second; history[i].second = buf; history[i].first = now; return true; } } return false; }
//verifies a message with all types included serializes and deserializes int main() { unsigned message_len; int32_t i = 42; //integer float f = 0.25; //float const char *s = "string"; //string rtosc_blob_t b = {3,(uint8_t*)s};//blob int64_t h = -125; //long integer uint64_t t = 22412; //timetag double d = 0.125; //double const char *S = "Symbol"; //symbol char c = 25; //character int32_t r = 0x12345678; //RGBA midi_t m = {0x12,0x23, //midi 0x34,0x45 }; //true //false //nil //inf message_len = rtosc_message(buffer, 1024, "/dest", "[ifsbhtdScrmTFNI]", i,f,s,b.len,b.data,h,t,d,S,c,r,m); assert_int_eq(96, message_len, "Generating A Message With All Arg Types", __LINE__); rtosc_arg_t arg; assert_int_eq(i, rtosc_argument(buffer, 0).i, "Checking 'i' Argument", __LINE__); CHECK(f,f,1); assert_str_eq(s, rtosc_argument(buffer, 2).s, "Checking 's' Argument", __LINE__); CHECK(b.len,b.len,3); assert_hex_eq((char*)b.data, (char*)arg.b.data, 3, b.len, "Checking 'b.data' Argument", __LINE__); CHECK(h,h,4); CHECK(t,t,5); CHECK(d,d,6); assert_str_eq(S,rtosc_argument(buffer, 7).s, "Checking 'S' Argument", __LINE__); assert_char_eq(c,rtosc_argument(buffer, 8).i, "Checking 'c' Argument", __LINE__); CHECK(r,i,9); CHECK(m,m,10); assert_char_eq('T', rtosc_type(buffer,11), "Checking 'T' Argument", __LINE__); assert_char_eq('F', rtosc_type(buffer,12), "Checking 'F' Argument", __LINE__); assert_char_eq('N', rtosc_type(buffer,13), "Checking 'N' Argument", __LINE__); assert_char_eq('I', rtosc_type(buffer,14), "Checking 'I' Argument", __LINE__); assert_true(rtosc_valid_message_p(buffer, message_len), "Verifying Message Is Valid", __LINE__); return test_summary(); }
//verify that empty strings can be retreived int main() { size_t length = rtosc_message(buffer, 1024, "/path", "sss", "", "", ""); // /pat h000 ,sss 0000 0000 0000 0000 assert_int_eq(28, length, "Build Empty String Based Message", __LINE__); assert_non_null(rtosc_argument(buffer, 0).s, "Check Arg 1", __LINE__); assert_non_null(rtosc_argument(buffer, 1).s, "Check Arg 2", __LINE__); assert_non_null(rtosc_argument(buffer, 2).s, "Check Arg 3", __LINE__); return test_summary(); }
void UndoHistoryImpl::rewind(const char *msg) { memset(tmp, 0, sizeof(tmp)); printf("rewind('%s')\n", msg); rtosc_arg_t arg = rtosc_argument(msg,1); rtosc_amessage(tmp, 256, rtosc_argument(msg,0).s, rtosc_argument_string(msg)+2, &arg); cb(tmp); }
void BankView::OSC_raw(const char *msg) { if(strcmp(rtosc_argument_string(msg), "iss")) return; int nslot = rtosc_argument(msg,0).i; const char *name = rtosc_argument(msg,1).s; const char *fname = rtosc_argument(msg,2).s; if(0 <= nslot && nslot < 160) slots[nslot]->update(name, fname); }
void UndoHistoryImpl::replay(const char *msg) { printf("replay...'%s'\n", msg); rtosc_arg_t arg = rtosc_argument(msg,2); printf("replay address: '%s'\n", rtosc_argument(msg, 0).s); int len = rtosc_amessage(tmp, 256, rtosc_argument(msg,0).s, rtosc_argument_string(msg)+2, &arg); if(len) cb(tmp); }
void plot_data_cb(const char *msg, void*) { const int samples = rtosc_argument(msg, 0).i; //Construct blob piecewise if(rtosc_message(dsp_osc_buf, 2048, "/ui/plot", "b", samples, NULL)) { //Fill reserved space float *data = (float*) rtosc_argument(dsp_osc_buf,0).b.data; for(int i=0; i < samples; ++i) data[i] = get_sample((float)i/samples); } gui_message(dsp_osc_buf); }
void UndoHistory::showHistory(void) const { int i = 0; for(auto s : impl->history) printf("#%d type: %s dest: %s arguments: %s\n", i++, s.second, rtosc_argument(s.second, 0).s, rtosc_argument_string(s.second)); }
void port_checker::server::on_recv(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg) { (void)argv; // std::cout << "on_recv: " << path << ", " << waiting << std::endl; // for(const char** exp_path = exp_paths; *exp_path; // ++exp_path, ++_replied_path) // std::cout << " - exp: " << *exp_path << std::endl; if(waiting && exp_paths && exp_paths[0]) { _replied_path = 0; for(const char** exp_path = exp_paths; *exp_path; ++exp_path, ++_replied_path) if(!strcmp(*exp_path, path)) { size_t len = lo_message_length(msg, path); *last_buffer = std::vector<char>(len); size_t written; lo_message_serialise(msg, path, last_buffer->data(), &written); if(written > last_buffer->size()) // ouch... throw std::runtime_error("can not happen, " "lo_message_length has been used"); last_args->resize(argc); for(int i = 0; i < argc; ++i) { (*last_args)[i].val = rtosc_argument(last_buffer->data(), i); (*last_args)[i].type = types[i]; } waiting = false; break; } } }
void BankList::OSC_raw(const char *msg) { if(!strcmp(msg, "/bank-list")) { const int pos = rtosc_argument(msg, 0).i; const char *path = rtosc_argument(msg, 1).s; value(0); if(pos == 0) this->clear(); this->add(path); osc->write("/loadbank"); } if(!strcmp(msg, "/loadbank")) { value(rtosc_argument(msg, 0).i); } }
void EnvelopeFreeEdit::OSC_raw(const char *msg) { const char *args = rtosc_argument_string(msg); if(strstr(msg,"Penvpoints") && !strcmp(args, "i")) { Penvpoints = rtosc_argument(msg, 0).i; } else if(strstr(msg,"Penvdt") && !strcmp(args, "b")) { rtosc_blob_t b = rtosc_argument(msg, 0).b; assert(b.len == MAX_ENVELOPE_POINTS); memcpy(Penvdt, b.data, MAX_ENVELOPE_POINTS); } else if(strstr(msg,"Penvval") && !strcmp(args, "b")) { rtosc_blob_t b = rtosc_argument(msg, 0).b; assert(b.len == MAX_ENVELOPE_POINTS); memcpy(Penvval, b.data, MAX_ENVELOPE_POINTS); } else if(strstr(msg, "Penvval") && !strcmp(args, "c")) { const char *str = strstr(msg, "Penvval"); int id = atoi(str+7); assert(0 <= id && id < MAX_ENVELOPE_POINTS); Penvval[id] = rtosc_argument(msg, 0).i; } else if(strstr(msg, "Penvdt") && !strcmp(args, "c")) { const char *str = strstr(msg, "Penvdt"); int id = atoi(str+6); assert(0 <= id && id < MAX_ENVELOPE_POINTS); Penvdt[id] = rtosc_argument(msg, 0).i; } else if(strstr(msg,"Penvsustain") && !strcmp(args, "i")) { Penvsustain = rtosc_argument(msg, 0).i; } redraw(); do_callback(); }
int main() { //clean buffer memset(buffer1, 0xc3, sizeof(buffer1)); //generate liblo message 1 size_t len = 128; lo_message message = lo_message_new(); assert_non_null(message, "Generating A Liblo Message 1 (int/float)", __LINE__); lo_message_add_float(message, 24.0); lo_message_add_int32(message, 42); lo_message_serialise(message, "/path", buffer1, &len); assert_str_eq("/path", buffer1, "Verifying Path From Message 1", __LINE__); assert_f32_eq(24.0f, rtosc_argument(buffer1, 0).f, "Verifying Float From Message 1", __LINE__); assert_int_eq(42, rtosc_argument(buffer1, 1).i, "Verifying Int From Message 1", __LINE__); assert_int_eq(20, rtosc_message_length(buffer1, 128), "Verifying Length From Message 1", __LINE__); //Message 2 size_t len2 = rtosc_message(buffer2, 1024, "/li", "bb", 4, buffer1, 4, buffer1); assert_int_eq(24, len2, "Generate A Rtosc Message 2 (bb)", __LINE__); lo_message msg2 = lo_message_deserialise((void*)buffer2, len2, &result_var); if(assert_non_null(msg2, "Deserialize Message 2 To Liblo", __LINE__)) printf("# Liblo Did Not Accept the Rtosc Message [error '%d']\n", result_var); //Message 3 size_t len3 = rtosc_message(buffer3+4, 2048, "/close-ui", ""); assert_int_eq(16, len3, "Generate A Rtosc Message 3 ()", __LINE__); lo_message msg3 = lo_message_deserialise((void*)(buffer3+4), len3, &result_var); if(assert_non_null(msg2, "Deserialize Message 3 To Liblo", __LINE__)) printf("#Liblo Did Not Accept the Rtosc Message [error '%d']\n", result_var); //Bundle 4 size_t len4 = rtosc_bundle(buffer4, 2048, 0xdeadbeefcafebaad, 3, buffer1, buffer2, buffer3+4); assert_int_eq(88, len4, "Generate A Bundle 4", __LINE__); //Bundle 5 lo_timetag time; time.sec = 0xdeadbeef; time.frac = 0xcafebaad; lo_bundle ms4 = lo_bundle_new(time); lo_bundle_add_message(ms4, "/path", message); lo_bundle_add_message(ms4, "/li", msg2); lo_bundle_add_message(ms4, "/close-ui", msg3); size_t len5 = 2048; lo_bundle_serialise(ms4,(void*)buffer5, &len5); //Verify 4 == 5 assert_non_null(ms4, "Generate A Liblo Bundle 5", __LINE__); assert_hex_eq(buffer5, buffer4, len5, len4, "Verify Liblo Style Bundles", __LINE__); //Cleanup lo_message_free(message); lo_message_free(msg2); lo_message_free(msg3); lo_bundle_free(ms4); return test_summary(); }
"Frequency Modulation To Combined Spectra"), rParamZyn(Pmodulationpar1, "modulation parameter"), rParamZyn(Pmodulationpar2, "modulation parameter"), rParamZyn(Pmodulationpar3, "modulation parameter"), //TODO update to rArray and test {"phase#128::c:i", rProp(parameter) rLinear(0,127) rDoc("Sets harmonic phase"), NULL, [](const char *m, rtosc::RtData &d) { const char *mm = m; while(*mm && !isdigit(*mm)) ++mm; unsigned char &phase = ((OscilGen*)d.obj)->Phphase[atoi(mm)]; if(!rtosc_narguments(m)) d.reply(d.loc, "c", phase); else phase = rtosc_argument(m,0).i; }}, //TODO update to rArray and test {"magnitude#128::c:i", rProp(parameter) rLinear(0,127) rDoc("Sets harmonic magnitude"), NULL, [](const char *m, rtosc::RtData &d) { //printf("I'm at '%s'\n", d.loc); const char *mm = m; while(*mm && !isdigit(*mm)) ++mm; unsigned char &mag = ((OscilGen*)d.obj)->Phmag[atoi(mm)]; if(!rtosc_narguments(m)) d.reply(d.loc, "c", mag); else { mag = rtosc_argument(m,0).i; //printf("setting magnitude\n\n"); //XXX hack hack char *repath = strdup(d.loc);
int main() { int32_t i = 42; //integer float f = 0.25; //float const char *s = "string"; //string size_t message_size = 32; CHECK(rtosc_message(buffer, 1024, "/dest", "ifs", i,f,s) == message_size); CHECK(rtosc_argument(buffer, 0).i == i); CHECK(rtosc_argument(buffer, 1).f == f); CHECK(!strcmp(rtosc_argument(buffer, 2).s, s)); CHECK(rtosc_message_length(buffer,1024) == 32); memmove(buffer+1, buffer, message_size); CHECK(!strcmp(buffer+1, "/dest")); CHECK(rtosc_argument(buffer+1, 0).i == i); CHECK(rtosc_argument(buffer+1, 1).f == f); CHECK(!strcmp(rtosc_argument(buffer+1, 2).s, s)); CHECK(rtosc_message_length(buffer+1,1024-1) == 32); memmove(buffer+2, buffer+1, message_size); CHECK(!strcmp(buffer+2, "/dest")); CHECK(rtosc_argument(buffer+2, 0).i == i); CHECK(rtosc_argument(buffer+2, 1).f == f); CHECK(!strcmp(rtosc_argument(buffer+2, 2).s, s)); CHECK(rtosc_message_length(buffer+2,1024-2) == 32); memmove(buffer+3, buffer+2, message_size); CHECK(!strcmp(buffer+3, "/dest")); CHECK(rtosc_argument(buffer+3, 0).i == i); CHECK(rtosc_argument(buffer+3, 1).f == f); CHECK(!strcmp(rtosc_argument(buffer+3, 2).s, s)); CHECK(rtosc_message_length(buffer+3,1024-3) == 32); memmove(buffer+4, buffer+3, message_size); CHECK(!strcmp(buffer+4, "/dest")); CHECK(rtosc_argument(buffer+4, 0).i == i); CHECK(rtosc_argument(buffer+4, 1).f == f); CHECK(!strcmp(rtosc_argument(buffer+4, 2).s, s)); CHECK(rtosc_message_length(buffer+4,1024-4) == 32); for(int j=0; j<4; ++j) { fprintf(stderr, "offset %d\n", j); CHECK(rtosc_argument(buffer+4+j, 0).i == i); CHECK(rtosc_argument(buffer+4+j, 1).f == f); CHECK(!strcmp(rtosc_argument(buffer+4+j, 2).s, s)); CHECK(rtosc_message_length(buffer+4+j,1024-4-j) == (unsigned)(32-j)); } return err; }
const char *getUndoAddress(const char *msg) { return rtosc_argument(msg,0).s; }
rToggle(cfg.SwapStereo, "Swap Left And Right Channels"), rToggle(cfg.BankUIAutoClose, "Automatic Closing of BackUI After Patch Selection"), rParamI(cfg.GzipCompression, "Level of Gzip Compression For Save Files"), rParamI(cfg.Interpolation, "Level of Interpolation, Linear/Cubic"), {"cfg.presetsDirList", rProp(parameter) rDoc("list of preset search directories"), 0, [](const char *msg, rtosc::RtData &d) { Config &c = *(Config*)d.obj; if(rtosc_narguments(msg) != 0) { std::string args = rtosc_argument_string(msg); //clear everything c.clearpresetsdirlist(); for(int i=0; i<(int)args.size(); ++i) if(args[i] == 's') c.cfg.presetsDirList[i] = rtosc_argument(msg, i).s; } char types[MAX_BANK_ROOT_DIRS+1]; rtosc_arg_t args[MAX_BANK_ROOT_DIRS]; size_t pos = 0; //zero out data memset(types, 0, sizeof(types)); memset(args, 0, sizeof(args)); for(int i=0; i<MAX_BANK_ROOT_DIRS; ++i) { if(!c.cfg.presetsDirList[i].empty()) { types[pos] = 's'; args[pos].s = c.cfg.presetsDirList[i].c_str(); pos++;
#define rObject EffectMgr static const rtosc::Ports local_ports = { rSelf(EffectMgr), rPaste, rRecurp(filterpars, "Filter Parameter for Dynamic Filter"), {"parameter#128::i", rProp(alias) rDoc("Parameter Accessor"), NULL, [](const char *msg, rtosc::RtData &d) { EffectMgr *eff = (EffectMgr*)d.obj; const char *mm = msg; while(!isdigit(*mm))++mm; if(!rtosc_narguments(msg)) d.reply(d.loc, "i", eff->geteffectparrt(atoi(mm))); else { eff->seteffectparrt(atoi(mm), rtosc_argument(msg, 0).i); d.broadcast(d.loc, "i", eff->geteffectparrt(atoi(mm))); } }}, {"preset::i", rProp(alias) rDoc("Effect Preset Selector"), NULL, [](const char *msg, rtosc::RtData &d) { EffectMgr *eff = (EffectMgr*)d.obj; if(!rtosc_narguments(msg)) d.reply(d.loc, "i", eff->getpreset()); else { eff->changepresetrt(rtosc_argument(msg, 0).i); d.broadcast(d.loc, "i", eff->getpreset()); } }}, {"eq-coeffs:", rProp(internal) rDoc("Get equalizer Coefficients"), NULL,