#define _POSIX_C_SOURCE 200809L #include "xtc/xtc_plugin.h" #include #include #include "xtc/xtc_midi.h" #include #include #include #include static void effects(unsigned int id) { xtc_plugin_spec s; xtc_plugin *a=NULL,*b=NULL; float in[256]={0},x[256],y[256]; size_t k,i; double energy=0; assert(xtc_plugin_probe(XTC_BUILTIN_PATH,id,48000,&s)==XTC_OK); assert(xtc_plugin_create(&s,48000,256,&a)==XTC_OK); assert(xtc_plugin_create(&s,48000,256,&b)==XTC_OK); for(k=0;k<600;++k) { in[0]=k==0 ? 1 : 0; assert(xtc_plugin_process(a,in,x,256)==XTC_OK); assert(xtc_plugin_process(b,in,y,128)==XTC_OK); assert(xtc_plugin_process(b,in+128,y+128,128)==XTC_OK); for(i=0;i<256;++i) {assert(isfinite(x[i]));assert(fabsf(x[i]-y[i])<1e-6f);if(k>0)energy+=fabs(x[i]);} } assert(energy>.01);xtc_plugin_destroy(a);xtc_plugin_destroy(b); s.values[2]=0; assert(xtc_plugin_create(&s,48000,256,&a)==XTC_OK); in[0]=1;assert(xtc_plugin_process(a,in,x,256)==XTC_OK);assert(!memcmp(in,x,sizeof(in)));xtc_plugin_destroy(a); s.values[1]=2;assert(xtc_plugin_spec_validate(&s)!=XTC_OK); } static void synth(unsigned int id) { xtc_plugin_spec s; xtc_plugin *p=NULL; float out[256]; size_t i,k; double energy=0; xtc_midi_event e={0,XTC_MIDI_NOTE_ON,0,60,100}; assert(xtc_plugin_probe(XTC_BUILTIN_PATH,id,48000,&s)==XTC_OK); assert(xtc_plugin_create(&s,48000,256,&p)==XTC_OK); assert(xtc_plugin_process_midi(p,&e,1,out,256)==XTC_OK); for(i=0;i<256;++i)energy+=fabs(out[i]); assert(energy>0); e.type=XTC_MIDI_NOTE_OFF;assert(xtc_plugin_process_midi(p,&e,1,out,256)==XTC_OK); for(k=0;k<200;++k)assert(xtc_plugin_process_midi(p,NULL,0,out,256)==XTC_OK); for(i=0;i<256;++i)assert(fabsf(out[i])<1e-5f); e.type=XTC_MIDI_ALL_OFF;assert(xtc_plugin_process_midi(p,&e,1,out,256)==XTC_OK); for(i=0;i<256;++i)assert(out[i]==0); xtc_plugin_destroy(p); } static void automation(void) { xtc_plugin_spec s; xtc_plugin *p=NULL; float in[128],out[128]; size_t i; assert(xtc_plugin_probe(XTC_BUILTIN_PATH,2,960,&s)==XTC_OK); s.tempo=60000; s.values[0]=2000; s.point_count=2; s.points[0]=(xtc_plugin_point){0,2,0,0}; s.points[1]=(xtc_plugin_point){100,2,0,1}; assert(xtc_plugin_create(&s,960,128,&p)==XTC_OK); for(i=0;i<128;++i)in[i]=1; assert(xtc_plugin_process_at(p,in,out,128,0)==XTC_OK); for(i=0;i<128;++i) assert(fabsf(out[i]-(i<100 ? 1-(float)i/100 : 0))<1e-6f); xtc_plugin_destroy(p); } static void roundtrip(void) { xtc_project *p=NULL,*q=NULL; xtc_plugin_spec s,t; uint64_t track; size_t id; xtc_graph *g=NULL; char path[]="/tmp/xtc-builtin-XXXXXX"; int fd=mkstemp(path); assert(fd>=0); close(fd); assert(xtc_project_create(&p)==XTC_OK); assert(xtc_project_create(&q)==XTC_OK); assert(xtc_project_add_track(p,"Keys",&track)==XTC_OK); assert(xtc_plugin_probe(XTC_BUILTIN_PATH,0,48000,&s)==XTC_OK); assert(xtc_project_set_instrument(p,track,&s)==XTC_OK); assert(xtc_plugin_probe(XTC_BUILTIN_PATH,2,48000,&s)==XTC_OK); s.values[0]=250; s.point_count=2; s.points[0]=(xtc_plugin_point){0,2,0,.1f}; s.points[1]=(xtc_plugin_point){960,2,0,.6f}; assert(xtc_graph_clone(xtc_project_graph(p),&g)==XTC_OK); assert(xtc_graph_add_plugin(g,&s,&id)==XTC_OK); assert(xtc_project_set_graph(p,g)==XTC_OK);xtc_graph_destroy(g); assert(xtc_project_save(p,path)==XTC_OK); assert(xtc_project_load(q,path)==XTC_OK); assert(xtc_graph_get_plugin(xtc_project_graph(q),id,&t)==XTC_OK); assert(t.values[0]==250 && t.point_count==2); assert(xtc_project_get_instrument(q,track,&t)==XTC_OK && t.index==0 && t.format==XTC_PLUGIN_BUILTIN); xtc_project_destroy(p);xtc_project_destroy(q);unlink(path); } int main(void) {automation();roundtrip();effects(2);effects(3);synth(0);synth(1);puts("Built-in devices passed.");return 0;}