int sporth_gen_line(sporth_stack *stack, void *ud) { plumber_data *pd = ud; int size; sp_ftbl *ft; char *str; char *args; switch(pd->mode){ case PLUMBER_CREATE: #ifdef DEBUG_MODE fprintf(stderr, "gen_line: create mode\n"); #endif plumber_add_ugen(pd, SPORTH_GEN_LINE, NULL); if(sporth_check_args(stack, "sfs") != SPORTH_OK) { fprintf(stderr, "Init: not enough arguments for gen_line\n"); return PLUMBER_NOTOK; } args = sporth_stack_pop_string(stack); size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); #ifdef DEBUG_MODE fprintf(stderr, "Creating line table %s of size %d\n", str, size); #endif sp_ftbl_create(pd->sp, &ft, size); if(sp_gen_line(pd->sp, ft, args) == SP_NOT_OK) { fprintf(stderr, "There was an issue creating the line ftable \"%s\".\n", str); stack->error++; return PLUMBER_NOTOK; } plumber_ftmap_add(pd, str, ft); break; case PLUMBER_INIT: args = sporth_stack_pop_string(stack); size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: printf("Error: Unknown mode!"); break; } return PLUMBER_OK; }
int sporth_gen_file(sporth_stack *stack, void *ud) { #ifndef NO_LIBSNDFILE plumber_data *pd = ud; sp_ftbl *ft; char *str; char *filename; int size; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_GEN_FILE, NULL); if(sporth_check_args(stack, "sfs") != SPORTH_OK) { fprintf(stderr, "Init: not enough arguments for gen_file\n"); return PLUMBER_NOTOK; } filename = sporth_stack_pop_string(stack); size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); sp_ftbl_create(pd->sp, &ft, size); if(sp_gen_file(pd->sp, ft, filename) == SP_NOT_OK) { fprintf(stderr, "There was an issue creating the ftable \"%s\".\n", str); stack->error++; return PLUMBER_NOTOK; } plumber_ftmap_add(pd, str, ft); break; case PLUMBER_INIT: filename = sporth_stack_pop_string(stack); size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: printf("Error: Unknown mode!"); break; } return PLUMBER_OK; #else return PLUMBER_NOTOK; #endif }
int sporth_gen_composite(sporth_stack *stack, void *ud) { plumber_data *pd = ud; uint32_t size; sp_ftbl *ft; char *str, *args; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_GEN_COMPOSITE, NULL); if(sporth_check_args(stack, "sfs") != SPORTH_OK) { fprintf(stderr,"composite: not enough arguments for gen_vals\n"); return PLUMBER_NOTOK; } args = sporth_stack_pop_string(stack); size = (uint32_t)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); sp_ftbl_create(pd->sp, &ft, size); sp_gen_composite(pd->sp, ft, args); plumber_ftmap_add(pd, str, ft); free(args); free(str); break; case PLUMBER_INIT: args = sporth_stack_pop_string(stack); size = (uint32_t)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); free(str); free(args); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: fprintf(stderr,"Error: Unknown mode!"); break; } return PLUMBER_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 sporth_gen_sine(sporth_stack *stack, void *ud) { plumber_data *pd = ud; int size; sp_ftbl *ft; char *str; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_GEN_SINE, NULL); if(sporth_check_args(stack, "sf") != SPORTH_OK) { fprintf(stderr, "Init: not enough arguments for gen_sine\n"); return PLUMBER_NOTOK; } size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); #ifdef DEBUG_MODE fprintf(stderr, "Creating sine table %s of size %d\n", str, size); #endif sp_ftbl_create(pd->sp, &ft, size); sp_gen_sine(pd->sp, ft); plumber_ftmap_add(pd, str, ft); free(str); break; case PLUMBER_INIT: size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); free(str); break; case PLUMBER_COMPUTE: size = (int)sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: printf("Error: Unknown mode!"); break; } return PLUMBER_OK; }
int sporth_scrambler(sporth_stack *stack, void *ud) { plumber_data *pd = ud; sp_ftbl *ft_s, *ft_d; char *src, *dst; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_SCRAMBLER, NULL); if(sporth_check_args(stack, "ss") != SPORTH_OK) { fprintf(stderr, "Init: not enough arguments for gen_line\n"); return PLUMBER_NOTOK; } src = sporth_stack_pop_string(stack); dst = sporth_stack_pop_string(stack); if(plumber_ftmap_search(pd, src, &ft_s) != PLUMBER_OK) { fprintf(stderr, "scrambler: could not find ftable %s", src); } sp_gen_scrambler(pd->sp, ft_s, &ft_d); plumber_ftmap_add(pd, dst, ft_d); break; case PLUMBER_INIT: sporth_stack_pop_string(stack); sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: break; case PLUMBER_DESTROY: break; default: break; } return PLUMBER_OK; }
int sporth_zeros(sporth_stack *stack, void *ud) { plumber_data *pd = ud; int size; sp_ftbl *ft; const char *str; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_ZEROS, NULL); if(sporth_check_args(stack, "sf") != SPORTH_OK) { plumber_print(pd, "Init: not enough arguments for zeros\n"); return PLUMBER_NOTOK; } size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); #ifdef DEBUG_MODE plumber_print(pd, "Zeros: creating table %s of size %d\n", str, size); #endif sp_ftbl_create(pd->sp, &ft, size); plumber_ftmap_add(pd, str, ft); break; case PLUMBER_INIT: size = (int)sporth_stack_pop_float(stack); str = sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: size = (int)sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: plumber_print(pd, "Error: Unknown mode!\n"); break; } return PLUMBER_OK; }
static int sporth_huion(plumber_data *pd, sporth_stack *stack, void **ud) { huion_d *hd; char *str; switch(pd->mode) { case PLUMBER_CREATE: fprintf(stderr, "Creating our custom gain plugin!\n"); if(sporth_check_args(stack, "s") != SPORTH_OK) { fprintf(stderr,"Incorrect arguments for huion\n"); stack->error++; return PLUMBER_NOTOK; } /* malloc and assign address to user data */ str = sporth_stack_pop_string(stack); hd = malloc(sizeof(huion_d)); *ud = hd; sp_ftbl_create(pd->sp, &hd->data, P_MAX); plumber_ftmap_add(pd, str, hd->data); huion_start(hd); break; case PLUMBER_INIT: str = sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: break; case PLUMBER_DESTROY: hd = *ud; huion_stop(hd); free(hd); break; default: fprintf(stderr, "Huion: unknown mode %d\n", pd->mode); break; } return PLUMBER_OK; }
int sporth_gen_eval(sporth_stack *stack, void *ud) { plumber_data *pd = ud; plumber_data my_pd; uint32_t size; sp_data *sp; sp_ftbl *ft; char *ftname; char *str; uint32_t n; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_GEN_EVAL, NULL); if(sporth_check_args(stack, "sfs") != SPORTH_OK) { plumber_print(pd, "Init: not enough arguments for gen_sine\n"); return PLUMBER_NOTOK; } str = sporth_stack_pop_string(stack); size = (uint32_t) sporth_stack_pop_float(stack); ftname = sporth_stack_pop_string(stack); sp_ftbl_create(pd->sp, &ft, size); plumber_ftmap_add(pd, ftname, ft); #ifdef DEBUG_MODE plumber_print(pd, "gen_sporth: compiling file %s to table of size %d\n", filename, size); #endif plumber_register(&my_pd); plumber_init(&my_pd); sp_create(&sp); sp->sr = pd->sp->sr; sp_srand(sp, pd->seed); my_pd.sp = sp; my_pd.sp->len = size; if(plumber_parse_string(&my_pd, str) == PLUMBER_OK) { plumber_compute(&my_pd, PLUMBER_INIT); for(n = 0; n < ft->size; n++) { plumber_compute(&my_pd, PLUMBER_COMPUTE); ft->tbl[n] = sporth_stack_pop_float(&my_pd.sporth.stack); } } plumber_clean(&my_pd); sp_destroy(&sp); break; case PLUMBER_INIT: sporth_stack_pop_string(stack); sporth_stack_pop_float(stack); sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: printf("Error: Unknown mode!"); break; } return PLUMBER_OK; }
int sporth_gen_padsynth(sporth_stack *stack, void *ud) { plumber_data *pd = ud; sp_ftbl *ft, *amps; char *ftname, *ampname; uint32_t size; SPFLOAT freq, bw; switch(pd->mode){ case PLUMBER_CREATE: plumber_add_ugen(pd, SPORTH_GEN_PADSYNTH, NULL); if(sporth_check_args(stack, "sfffs") != SPORTH_OK) { fprintf(stderr,"Padsynth: not enough arguments for gen_padsynth\n"); return PLUMBER_NOTOK; } ampname = sporth_stack_pop_string(stack); bw = sporth_stack_pop_float(stack); freq = sporth_stack_pop_float(stack); size = (uint32_t)sporth_stack_pop_float(stack); ftname = sporth_stack_pop_string(stack); if(plumber_ftmap_search(pd, ampname, &s) == PLUMBER_NOTOK) { stack->error++; return PLUMBER_NOTOK; } sp_ftbl_create(pd->sp, &ft, size); #ifdef DEBUG_MODE fprintf(stderr,"Running padsynth function\n"); #endif sp_gen_padsynth(pd->sp, ft, amps, freq, bw); plumber_ftmap_add(pd, ftname, ft); break; case PLUMBER_INIT: ampname = sporth_stack_pop_string(stack); bw = sporth_stack_pop_float(stack); freq = sporth_stack_pop_float(stack); size = (uint32_t)sporth_stack_pop_float(stack); ftname = sporth_stack_pop_string(stack); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); sporth_stack_pop_float(stack); sporth_stack_pop_float(stack); break; case PLUMBER_DESTROY: break; default: fprintf(stderr,"Error: Unknown mode!"); break; } return PLUMBER_OK; }
int sporth_poly(sporth_stack *stack, void *ud) { plumber_data *pd = ud; sporth_poly_d *poly; poly_voice *voice; poly_event *evt; uint32_t nvoices; char *ftname; char *file; uint32_t n, p; int id; switch(pd->mode) { case PLUMBER_CREATE: #ifdef DEBUG_MODE fprintf(stderr, "poly: Creating\n"); #endif poly = malloc(sizeof(sporth_poly_d)); plumber_add_ugen(pd, SPORTH_POLY, poly); if(sporth_check_args(stack, "ffss") != SPORTH_OK) { fprintf(stderr,"Invalid arguments for poly\n"); stack->error++; return PLUMBER_NOTOK; } ftname = sporth_stack_pop_string(stack); file = sporth_stack_pop_string(stack); poly->max_params = (uint32_t)sporth_stack_pop_float(stack); poly->max_voices = (uint32_t)sporth_stack_pop_float(stack); poly->dur = malloc(sizeof(uint32_t) * poly->max_voices); poly_init(&poly->poly); if(poly_binary_parse(&poly->poly, file, pd->sp->sr) != 0) { fprintf(stderr, "Could not read file %s\n", file); stack->error++; return PLUMBER_NOTOK; } poly_end(&poly->poly); poly_cluster_init(&poly->clust, poly->max_voices); sp_ftbl_create(pd->sp, &poly->ft, 1 + poly->max_voices * (2 + poly->max_params)); memset(poly->ft->tbl, 0, poly->ft->size * sizeof(SPFLOAT)); poly->ft->tbl[0] = poly->max_params; plumber_ftmap_add(pd, ftname, poly->ft); free(ftname); free(file); break; case PLUMBER_INIT: #ifdef DEBUG_MODE fprintf(stderr, "poly: Initialising\n"); #endif ftname = sporth_stack_pop_string(stack); file = sporth_stack_pop_string(stack); poly->max_params = (uint32_t)sporth_stack_pop_float(stack); poly->max_voices = (uint32_t)sporth_stack_pop_float(stack); free(ftname); free(file); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); sporth_stack_pop_float(stack); poly = pd->last->ud; poly_compute(&poly->poly); for(n = 0; n < poly->max_voices; n++) { poly->ft->tbl[1 + n * (poly->max_params + 2)] = 0.0; } poly_itr_reset(&poly->poly); for(n = 0; n < poly_nevents(&poly->poly); n++) { evt = poly_itr_next(&poly->poly); if(!poly_cluster_add(&poly->clust, &id)) { poly->dur[id] = evt->p[0] * pd->sp->sr; poly->ft->tbl[1 + id * (poly->max_params + 2)] = 1.0; poly->ft->tbl[2 + id * (poly->max_params + 2)] = evt->p[0]; for(p = 1; p < evt->nvals; p++) { poly->ft->tbl[2 + id * (poly->max_params + 2) + p] = evt->p[p]; } } } poly_cluster_reset(&poly->clust); nvoices = poly_cluster_nvoices(&poly->clust); for(n = 0; n < nvoices; n++) { voice = poly_next_voice(&poly->clust); poly->dur[voice->val] -= 1; } poly_cluster_reset(&poly->clust); for(n = 0; n < nvoices; n++) { voice = poly_next_voice(&poly->clust); if(poly->dur[voice->val] <= 0) { poly_cluster_remove(&poly->clust, voice->val); } } break; case PLUMBER_DESTROY: poly = pd->last->ud; poly_cluster_destroy(&poly->clust); poly_destroy(&poly->poly); free(poly->dur); free(poly); break; default: fprintf(stderr, "poly: Uknown mode!\n"); break; } return PLUMBER_OK; }
int sporth_tpoly(sporth_stack *stack, void *ud) { plumber_data *pd = ud; sporth_poly_d *poly; poly_voice *voice; SPFLOAT trig = 0; uint32_t nvoices; char *poly_ft; char *arg_ft; uint32_t n, p; int id; switch(pd->mode) { case PLUMBER_CREATE: #ifdef DEBUG_MODE fprintf(stderr, "poly: Creating\n"); #endif poly = malloc(sizeof(sporth_poly_d)); plumber_add_ugen(pd, SPORTH_TPOLY, poly); if(sporth_check_args(stack, "fffss") != SPORTH_OK) { fprintf(stderr,"Invalid arguments for tpoly\n"); stack->error++; return PLUMBER_NOTOK; } poly_ft = sporth_stack_pop_string(stack); arg_ft = sporth_stack_pop_string(stack); poly->max_params = (uint32_t)sporth_stack_pop_float(stack); poly->max_voices = (uint32_t)sporth_stack_pop_float(stack); trig = sporth_stack_pop_float(stack); if(plumber_ftmap_search(pd, arg_ft, &poly->arg_ft) == PLUMBER_NOTOK) { fprintf(stderr, "Could not find table %s\n", arg_ft); free(poly_ft); free(arg_ft); stack->error++; return PLUMBER_NOTOK; } poly->dur = malloc(sizeof(uint32_t) * poly->max_voices); poly_cluster_init(&poly->clust, poly->max_voices); sp_ftbl_create(pd->sp, &poly->ft, 1 + poly->max_voices * (2 + poly->max_params)); memset(poly->ft->tbl, 0, poly->ft->size * sizeof(SPFLOAT)); poly->ft->tbl[0] = poly->max_params; plumber_ftmap_add(pd, poly_ft, poly->ft); free(poly_ft); free(arg_ft); break; case PLUMBER_INIT: #ifdef DEBUG_MODE fprintf(stderr, "poly: Initialising\n"); #endif poly = pd->last->ud; poly_ft = sporth_stack_pop_string(stack); arg_ft = sporth_stack_pop_string(stack); poly->max_params = (uint32_t)sporth_stack_pop_float(stack); poly->max_voices = (uint32_t)sporth_stack_pop_float(stack); trig = sporth_stack_pop_float(stack); free(poly_ft); free(arg_ft); break; case PLUMBER_COMPUTE: sporth_stack_pop_float(stack); sporth_stack_pop_float(stack); trig = sporth_stack_pop_float(stack); poly = pd->last->ud; for(n = 0; n < poly->max_voices; n++) { poly->ft->tbl[1 + n * (poly->max_params + 2)] = 0.0; } if(trig != 0) { if(poly_cluster_add(&poly->clust, &id) == 0) { poly->dur[id] = poly->arg_ft->tbl[0] * pd->sp->sr; poly->ft->tbl[1 + id * (poly->max_params + 2)] = 1.0; poly->ft->tbl[2 + id * (poly->max_params + 2)] = poly->arg_ft->tbl[0]; for(p = 1; p < poly->arg_ft->size; p++) { poly->ft->tbl[2 + id * (poly->max_params + 2) + p] = poly->arg_ft->tbl[p]; } } for(n = 0; n < poly->ft->size; n++) { fprintf(stderr, "%g ", poly->ft->tbl[n]); } fprintf(stderr, "\n"); } poly_cluster_reset(&poly->clust); nvoices = poly_cluster_nvoices(&poly->clust); for(n = 0; n < nvoices; n++) { voice = poly_next_voice(&poly->clust); poly->dur[voice->val] -= 1; } poly_cluster_reset(&poly->clust); nvoices = poly_cluster_nvoices(&poly->clust); for(n = 0; n < nvoices; n++) { voice = poly_next_voice(&poly->clust); if(poly->dur[voice->val] <= 0) { poly_cluster_remove(&poly->clust, voice->val); } } break; case PLUMBER_DESTROY: poly = pd->last->ud; poly_cluster_destroy(&poly->clust); free(poly->dur); free(poly); break; default: fprintf(stderr, "tpoly: Uknown mode!\n"); break; } return PLUMBER_OK; }