int poly_compute(poly_data *cd) { poly_iterator *itr = &cd->itr; poly_event *evt; itr->root = cd->last; itr->nevents = 0; poly_itr_reset(cd); while(cd->end_of_events == 0){ evt = poly_itr_next(cd); cd->last = evt; if(evt->timer == 0) { itr->nevents++; if(evt->pos + 1 == cd->total_events) { cd->end_of_events = 1; } } else { evt->timer--; break; } } return 0; }
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; }