/* port of GEN10 from Csound */ int sp_gen_sinesum(sp_data *sp, sp_ftbl *ft, const char *argstring) { sp_ftbl *args; sp_ftbl_create(sp, &args, 1); sp_gen_vals(sp, args, argstring); int32_t phs; SPFLOAT amp; int32_t flen = (int32_t)ft->size; SPFLOAT tpdlen = 2.0 * M_PI / (SPFLOAT) flen; int32_t i, n; for(i = (int32_t)args->size; i > 0; i--){ amp = args->tbl[args->size - i]; if(amp != 0) { for(phs = 0, n = 0; n < ft->size; n++){ ft->tbl[n] += sin(phs * tpdlen) * amp; phs += i; phs %= flen; } } } sp_ftbl_destroy(&args); return SP_OK; }
int main() { srand(time(NULL)); UserData ud; uint32_t bufsize; sp_data *sp; sp_create(&sp); sp_auxdata rvaux; sp_dtrig_create(&ud.dt); sp_tenv_create(&ud.tenv); sp_ftbl_create(sp, &ud.ft, 2048); sp_ftbl_create(sp, &ud.delta, 4); sp_ftbl_create(sp, &ud.nn, 1); sp_osc_create(&ud.osc); sp_gen_vals(sp, ud.delta, "0.2 0.2 0.2 0.1"); sp_gen_vals(sp, ud.nn, "60 62 64 67"); sp_tseq_create(&ud.seq); sp_tseq_init(sp, ud.seq, ud.nn); sp_dtrig_init(sp, ud.dt, ud.delta); ud.dt->loop = 1.0; sp_tenv_init(sp, ud.tenv); ud.tenv->atk = 0.01; ud.tenv->hold = 0.01; ud.tenv->rel = 0.05; sp_gen_sine(sp, ud.ft); sp_osc_init(sp, ud.osc, ud.ft, 0); ud.osc->freq = 1000; ud.osc->amp = 0.5; sp->len = 44100 * 5; sp_process(sp, &ud, write_osc); sp_dtrig_destroy(&ud.dt); sp_tseq_destroy(&ud.seq); sp_tenv_destroy(&ud.tenv); sp_ftbl_destroy(&ud.ft); sp_ftbl_destroy(&ud.nn); sp_ftbl_destroy(&ud.delta); sp_osc_destroy(&ud.osc); sp_destroy(&sp); return 0; }
int sp_gen_line(sp_data *sp, sp_ftbl *ft, const char *argstring) { uint16_t i, n = 0, seglen; SPFLOAT incr, amp = 0; SPFLOAT x1, x2, y1, y2; sp_ftbl *args; sp_ftbl_create(sp, &args, 1); sp_gen_vals(sp, args, argstring); if((args->size % 2) == 1 || args->size == 1) { fprintf(stderr, "Error: not enough arguments for gen_line.\n"); sp_ftbl_destroy(&args); return SP_NOT_OK; } else if(args->size == 2) { for(i = 0; i < ft->size; i++) { ft->tbl[i] = args->tbl[1]; } return SP_OK; } x1 = args->tbl[0]; y1 = args->tbl[1]; for(i = 2; i < args->size; i += 2) { x2 = args->tbl[i]; y2 = args->tbl[i + 1]; if(x2 < x1) { fprintf(stderr, "Error: x coordiates must be sequential!\n"); break; } seglen = (x2 - x1); incr = (SPFLOAT)(y2 - y1) / (seglen - 1); amp = y1; while(seglen != 0){ if(n < ft->size) { ft->tbl[n] = amp; amp += incr; seglen--; n++; } else { break; } } y1 = y2; x1 = x2; } sp_ftbl_destroy(&args); return SP_OK; }
int main() { UserData ud; /* allocate and initialize */ sp_create(&ud.sp); plumber_register(&ud.pd); plumber_init(&ud.pd); /* create an ftable with a size 1, which will be expanded with gen_vals */ sp_ftbl_create(ud.sp, &ud.seq, 1); /* Gen_vals will create a table from a string of numbers */ sp_gen_vals(ud.sp, ud.seq, "60 63 67 72"); /* Sporth code to be parsed, using a ftable generated in c called 'seq' */ char *str = "0.1 dmetro " "0 'seq' tseq " "0.01 port mtof " "0.5 1 1 1 fm"; /* Tell plumber that that we will take care of removing the following ftables */ /* This is needed for persistant ftables that don't get cleaned for * recompilation */ plumber_ftmap_delete(&ud.pd, 0); /* add ftable to plumber and call it "seq" */ plumber_ftmap_add(&ud.pd, "seq", ud.seq); /* Turn automatic deletion back "on" */ plumber_ftmap_delete(&ud.pd, 1); /* make plumber know about the soundpipe instance */ ud.pd.sp = ud.sp; /* parse string and allocate plumbing */ plumber_parse_string(&ud.pd, str); /* initialize the plumbing */ plumber_compute(&ud.pd, PLUMBER_INIT); /* run */ sp_process(ud.sp, &ud, process); /* Cleanup */ /* Plumber will handle freeing the memory of the ftable we added */ /* no need to call sp_ftbl_destroy */ plumber_clean(&ud.pd); sp_ftbl_destroy(&ud.seq); sp_destroy(&ud.sp); return 0; }
int chord_cloud_init(sp_data *sp, chord_cloud *cc, char *notes, SPFLOAT amp) { int i; sp_osc *tmposc; sp_dust *tmpdust; sp_tenv *tmpenv; sp_tevent *tmpretrig; sp_ftbl_create(sp, &cc->sine, 4096); sp_gen_sinesum(sp, cc->sine, "1 0.5 0.3 0.25, 0.1625"); sp_ftbl_create(sp, &cc->notes, 1); sp_gen_vals(sp, cc->notes, notes); cc->ampmax= amp; cc->grains= malloc(cc->notes->size * sizeof(chord_grain)); for(i = 0; i < cc->notes->size; i++) { chord_grain *grain = &cc->grains[i]; sp_osc_create(&grain->osc); sp_tenv_create(&grain->env); sp_dust_create(&grain->dust); sp_tevent_create(&grain->retrig); tmposc = grain->osc; tmpenv = grain->env; tmpdust = grain->dust; tmpretrig = grain->retrig; sp_dust_init(sp, tmpdust, 1, 8); sp_osc_init(sp, tmposc, cc->sine, 0); tmposc->freq = sp_midi2cps(cc->notes->tbl[i]); tmposc->amp = 1.0; grain->amp = 1.0; sp_tenv_init(sp, tmpenv); tmpenv->atk = 0.01; tmpenv->hold = 0; tmpenv->rel = 0.03; sp_tevent_init(sp, tmpretrig, cloud_reinit, cloud_compute, grain); } return SP_OK; }
int t_mode(sp_test *tst, sp_data *sp, const char *hash) { uint32_t n; int fail = 0; UserData ud; SPFLOAT met = 0, mod = 0, nn; modal_create(&ud.mod); modal_init(sp, ud.mod); sp_metro_create(&ud.met); sp_metro_init(sp, ud.met); ud.met->freq = 3.0; sp_ftbl_create(sp, &ud.notes, 1); sp_gen_vals(sp, ud.notes, "60 67 62 69 76"); sp_tseq_create(&ud.seq); sp_tseq_init(sp, ud.seq, ud.notes); for(n = 0; n < tst->size; n++) { met = 0; mod = 0; nn = 0; sp_metro_compute(sp, ud.met, NULL, &met); sp_tseq_compute(sp, ud.seq, &met, &nn); *ud.mod->freq = sp_midi2cps(nn); modal_compute(sp, ud.mod, &met, &mod); sp->out[0] = mod; sp_test_add_sample(tst, sp->out[0]); } fail = sp_test_verify(tst, hash); modal_destroy(&ud.mod); sp_metro_destroy(&ud.met); sp_ftbl_destroy(&ud.notes); sp_tseq_destroy(&ud.seq); if(fail) return SP_NOT_OK; else return SP_OK; }
void samp_create(sp_data *sp, samp_data *sd, size_t size, char *file, char *dtrig, SPFLOAT tempo, SPFLOAT delay) { int i; SPFLOAT tscale = 60.0 / tempo; sp_ftbl_create(sp, &sd->delta, 1); sp_gen_vals(sp, sd->delta, dtrig); sp_dtrig_create(&sd->dt); for(i = 0; i < sd->delta->size; i++) { sd->delta->tbl[i] *= tscale; } sp_dtrig_init(sp, sd->dt, sd->delta); sd->dt->delay = delay * tscale; sp_ftbl_create(sp, &sd->ft, 5574); sp_gen_file(sp, sd->ft, file); sp_tevent_create(&sd->te); sp_tevent_init(sp, sd->te, samp_reinit, samp_compute, sd); sd->pos = 0; }
int sp_gen_rand(sp_data *sp, sp_ftbl *ft, const char *argstring) { sp_ftbl *args; sp_ftbl_create(sp, &args, 1); sp_gen_vals(sp, args, argstring); int n, pos = 0, i, size = 0; for(n = 0; n < args->size; n += 2) { size = round(ft->size * args->tbl[n + 1]); for(i = 0; i < size; i++) { if(pos < ft->size) { ft->tbl[pos] = args->tbl[n]; pos++; } } } if(pos <= ft->size) { ft->size = pos; } sp_ftbl_destroy(&args); return SP_OK; }
/* based off of GEN 19 */ int sp_gen_composite(sp_data *sp, sp_ftbl *ft, const char *argstring) { SPFLOAT phs, inc, amp, dc, tpdlen = 2 * M_PI/ (SPFLOAT) ft->size; int i, n; sp_ftbl *args; sp_ftbl_create(sp, &args, 1); sp_gen_vals(sp, args, argstring); for(n = 0; n < args->size; n += 4) { inc = args->tbl[n] * tpdlen; amp = args->tbl[n + 1]; phs = args->tbl[n + 2] * tpd360; dc = args->tbl[n + 3]; for (i = 0; i <ft->size ; i++) { ft->tbl[i] += (SPFLOAT) (sin(phs) * amp + dc); if ((phs += inc) >= 2 * M_PI) phs -= 2 * M_PI; } } sp_ftbl_destroy(&args); return SP_OK; }
int t_tseq(sp_test *tst, sp_data *sp, const char *hash) { uint32_t n; int fail = 0; SPFLOAT env = 0; SPFLOAT osc = 0; SPFLOAT trig; SPFLOAT dtrig = 0; SPFLOAT note = 0; sp_srand(sp, 123456); UserData ud; sp_dtrig_create(&ud.dt); sp_tenv_create(&ud.tenv); sp_ftbl_create(sp, &ud.ft, 2048); sp_ftbl_create(sp, &ud.delta, 4); sp_ftbl_create(sp, &ud.nn, 1); sp_osc_create(&ud.osc); sp_gen_vals(sp, ud.delta, "0.2 0.2 0.2 0.1"); sp_gen_vals(sp, ud.nn, "60 62 64 67"); sp_tseq_create(&ud.seq); sp_tseq_init(sp, ud.seq, ud.nn); sp_dtrig_init(sp, ud.dt, ud.delta); ud.dt->loop = 1.0; sp_tenv_init(sp, ud.tenv); ud.tenv->atk = 0.01; ud.tenv->hold = 0.01; ud.tenv->rel = 0.05; sp_gen_sine(sp, ud.ft); sp_osc_init(sp, ud.osc, ud.ft, 0); ud.osc->freq = 1000; ud.osc->amp = 0.5; for(n = 0; n < tst->size; n++) { env = 0; osc = 0; dtrig = 0; note = 0; if(sp->pos == 0){ trig = 1.0; }else{ trig = 0.0; } sp_dtrig_compute(sp, ud.dt, &trig, &dtrig); sp_tseq_compute(sp, ud.seq, &dtrig, ¬e); ud.osc->freq = sp_midi2cps(note + 24); env = 1.0; sp_tenv_compute(sp, ud.tenv, &dtrig, &env); sp_osc_compute(sp, ud.osc, NULL, &osc); sp->out[0] = osc * env; sp_test_add_sample(tst, sp->out[0]); } fail = sp_test_verify(tst, hash); sp_dtrig_destroy(&ud.dt); sp_tseq_destroy(&ud.seq); sp_tenv_destroy(&ud.tenv); sp_ftbl_destroy(&ud.ft); sp_ftbl_destroy(&ud.nn); sp_ftbl_destroy(&ud.delta); sp_osc_destroy(&ud.osc); if(fail) return SP_NOT_OK; else return SP_OK; }
int main() { srand(time(NULL)); sp_data *sp; user_data ud; sp_create(&sp); SPFLOAT tempo = 144; ud.tempo = tempo; /* Create */ sp_count_create(&ud.cnt); sp_metro_create(&ud.clk); sp_metro_create(&ud.dblclk); samp_create(sp, &ud.snare, 5574, "snare.wav", "2 0.75 0.25", tempo, 1); samp_create(sp, &ud.kick, 7385, "kick.wav", "0.75 1.25 1 1", tempo, 0); samp_create(sp, &ud.hh, 4507, "hh.wav", "0.5 0.25 0.5 0.5 0.25 0.5 0.25 0.5 0.5 0.25", tempo, 0); sp_revsc_create(&ud.rev); sp_maygate_create(&ud.rthrow); sp_maygate_create(&ud.rgate); sp_rpt_create(&ud.rpt); sp_ftbl_create(sp, &ud.reps, 1); sp_tseq_create(&ud.rpick); sp_gen_vals(sp, ud.reps, "4 8 16 6"); sp_tseq_init(sp, ud.rpick, ud.reps); ud.rpick->shuf = 1.0; sp_reverse_create(&ud.rvs); sp_maygate_create(&ud.rvs_switch); /* Init */ sp->len = 44100 * (60.0 / tempo) * 32; sp_count_init(sp, ud.cnt); ud.cnt->count = 4; sp_metro_init(sp, ud.clk); ud.clk->freq = tempo / 60.0; sp_metro_init(sp, ud.dblclk); ud.dblclk->freq = tempo * 2 / 60.0; sp_revsc_init(sp, ud.rev); ud.rev->feedback = 0.9; ud.rev->lpfreq = 10000; sp_maygate_init(sp, ud.rthrow); ud.rthrow->prob = 0.5; sp_rpt_init(sp, ud.rpt, 1.0); //sp_rpt_set(ud.rpt, tempo, 8, 4); ud.rpt->bpm = tempo; ud.rpt->div = 8; ud.rpt->reps = 4; sp_maygate_init(sp, ud.rgate); ud.rgate->prob = 0.18; ud.rgate->mode = 1.0; sp_reverse_init(sp, ud.rvs, 60.0 / tempo); sp_maygate_init(sp, ud.rvs_switch); ud.rvs_switch->prob = 0.1; /* Process */ sp_process(sp, &ud, process); /* Destroy */ samp_destroy(&ud.snare); samp_destroy(&ud.kick); samp_destroy(&ud.hh); sp_revsc_destroy(&ud.rev); sp_maygate_destroy(&ud.rthrow); sp_maygate_destroy(&ud.rgate); sp_maygate_destroy(&ud.rvs_switch); sp_count_destroy(&ud.cnt); sp_metro_destroy(&ud.clk); sp_metro_destroy(&ud.dblclk); sp_rpt_destroy(&ud.rpt); sp_ftbl_destroy(&ud.reps); sp_tseq_destroy(&ud.rpick); sp_reverse_destroy(&ud.rvs); sp_destroy(&sp); return 0; }
int main() { srand(time(NULL)); int i; UserData ud; ud.pdel = 0; sp_data *sp; sp_create(&sp); sp->len = 44100 * 40; char *notes[] = { "62 69 78", "55 62 69 71", "43 50" }; for(i = 0; i < NUMLINE; i++) { sp_randi_create(&ud.line[i].randi); chord_cloud_create(&ud.line[i].cc); chord_cloud_init(sp, ud.line[i].cc, notes[i], 0.1); sp_randi_init(sp, ud.line[i].randi, rand()); ud.line[i].randi->cps = 0.1 + randf(1.5); } sp_revsc_create(&ud.rev); sp_revsc_init(sp, ud.rev); ud.rev->feedback = 0.95; sp_metro_create(&ud.clk); sp_metro_init(sp, ud.clk); ud.clk->freq = 86.0 / 60.0; sp_count_create(&ud.meter); sp_count_init(sp, ud.meter); ud.meter->count = 5; sp_drip_create(&ud.drip); sp_drip_init(sp, ud.drip, 0.01); sp_vdelay_create(&ud.del); /* give some headroom for the delay */ sp_vdelay_init(sp, ud.del, 0.4); ud.del->del = 0.3; sp_tenv_create(&ud.master); sp_tenv_init(sp, ud.master); ud.master->atk = 0; ud.master->hold = 30; ud.master->rel = 10; sp_progress_create(&ud.prog); sp_progress_init(sp, ud.prog); modal_create(&ud.mod); modal_init(sp, ud.mod); sp_ftbl_create(sp, &ud.notes, 1); sp_gen_vals(sp, ud.notes, "62 64 59 57"); sp_tseq_create(&ud.seq); sp_tseq_init(sp, ud.seq, ud.notes); sp_maygate_create(&ud.mg); sp_maygate_init(sp, ud.mg); ud.mg->prob = 0.3; ud.mg->mode = 1; sp_process(sp, &ud, process); for(i = 0; i < NUMLINE; i++) { sp_randi_destroy(&ud.line[i].randi); chord_cloud_destroy(&ud.line[i].cc); } sp_drip_destroy(&ud.drip); sp_revsc_destroy(&ud.rev); sp_metro_destroy(&ud.clk); sp_count_destroy(&ud.meter); sp_vdelay_destroy(&ud.del); sp_tenv_destroy(&ud.master); modal_destroy(&ud.mod); sp_ftbl_destroy(&ud.notes); sp_tseq_destroy(&ud.seq); sp_maygate_destroy(&ud.mg); sp_progress_destroy(&ud.prog); sp_destroy(&sp); return 0; }