feat: add a bounded WAV sampler with looping, relinking and saved presets
This commit is contained in:
parent
159fa939a1
commit
35bf6a00a1
24 changed files with 213 additions and 32 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "xtc/xtc_plugin.h"
|
||||
#include "../../src/audio/wave_internal.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "xtc/xtc_midi.h"
|
||||
|
|
@ -165,8 +166,8 @@ static void editable(void)
|
|||
assert(xtc_plugin_preset_save(&legacy,path)==XTC_OK);
|
||||
{FILE *f=fopen(path,"r");char lines[32768],line[2048];size_t used=0;assert(f);
|
||||
while(fgets(line,sizeof(line),f)) {
|
||||
if(!strncmp(line,"INSTRUMENT_CONTROLS",19) || !strncmp(line,"INSTRUMENT_AUTOMATION",21))continue;
|
||||
if(!strncmp(line,"XTC_PROJECT 14",14))strcpy(line,"XTC_PROJECT 13\n");
|
||||
if(!strncmp(line,"SAMPLE ",7) || !strncmp(line,"INSTRUMENT_CONTROLS",19) || !strncmp(line,"INSTRUMENT_AUTOMATION",21))continue;
|
||||
if(!strncmp(line,"XTC_PROJECT 15",14))strcpy(line,"XTC_PROJECT 13\n");
|
||||
assert(used+strlen(line)<sizeof(lines));strcpy(lines+used,line);used+=strlen(line);
|
||||
}fclose(f);f=fopen(path,"w");assert(f && fwrite(lines,1,used,f)==used);fclose(f);}
|
||||
assert(xtc_plugin_preset_load(path,&t)==XTC_OK && !t.control_count && t.index==0);
|
||||
|
|
@ -187,7 +188,40 @@ static void editable(void)
|
|||
assert(xtc_midi_decode(bend,3,7,&e)==XTC_OK && e.type==XTC_MIDI_BEND && e.channel==3 && e.velocity==64);}
|
||||
unlink(path);
|
||||
}
|
||||
static void sampler(void)
|
||||
{
|
||||
xtc_plugin_spec s,t;xtc_plugin *a=NULL,*b=NULL;float x[256],y[256],data[]={0,.25f,.5f,.75f};
|
||||
xtc_midi_event e={0,XTC_MIDI_NOTE_ON,0,60,127};size_t i;double envelope=0;
|
||||
char path[]="/tmp/xtc-sample-XXXXXX",preset[]="/tmp/xtc-sample-preset-XXXXXX";
|
||||
int fd=mkstemp(path),pd=mkstemp(preset);FILE *file;assert(fd>=0 && pd>=0);close(fd);close(pd);
|
||||
file=fopen(path,"wb");assert(file && xtc_wave_header(file,24000,4) && xtc_wave_write(file,data,4));fclose(file);
|
||||
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,4,48000,&s)==XTC_OK && s.instrument);
|
||||
strcpy(s.sample_path,path);s.values[2]=.1f;
|
||||
assert(xtc_plugin_create(&s,48000,256,&a)==XTC_OK && !xtc_plugin_asset_issues(a) && xtc_plugin_sample_frames(a)==4);
|
||||
assert(xtc_plugin_process_midi(a,&e,1,x,256)==XTC_OK);
|
||||
for(i=0;i<8;++i) {
|
||||
double expected=i<6 ? (double)i*.125 : .75;
|
||||
envelope+=(1-envelope)*(1-exp(-1/(.1*.001*48000)));
|
||||
assert(fabs(x[i]-expected*envelope)<1e-5);
|
||||
}
|
||||
for(i=8;i<256;++i)assert(x[i]==0);
|
||||
xtc_plugin_destroy(a);s.values[1]=1;
|
||||
assert(xtc_plugin_preset_save(&s,preset)==XTC_OK && xtc_plugin_preset_load(preset,&t)==XTC_OK);
|
||||
assert(!strcmp(t.sample_path,path) && t.values[1]==1);
|
||||
assert(xtc_plugin_create(&s,48000,256,&a)==XTC_OK && xtc_plugin_create(&t,48000,256,&b)==XTC_OK);
|
||||
assert(xtc_plugin_process_midi(a,&e,1,x,256)==XTC_OK && xtc_plugin_process_midi(b,&e,1,y,128)==XTC_OK);
|
||||
assert(xtc_plugin_process_midi(b,NULL,0,y+128,128)==XTC_OK && !memcmp(x,y,sizeof(x)));
|
||||
e.type=XTC_MIDI_NOTE_OFF;assert(xtc_plugin_process_midi(a,&e,1,x,256)==XTC_OK);
|
||||
for(i=0;i<200;++i)assert(xtc_plugin_process_midi(a,NULL,0,x,256)==XTC_OK);
|
||||
for(i=0;i<256;++i)assert(x[i]==0);
|
||||
xtc_plugin_destroy(a);xtc_plugin_destroy(b);unlink(path);
|
||||
assert(xtc_plugin_preset_load(preset,&t)==XTC_OK && !strcmp(t.sample_path,path));
|
||||
assert(xtc_plugin_create(&t,48000,256,&a)==XTC_OK && xtc_plugin_asset_issues(a)==1);
|
||||
e.type=XTC_MIDI_NOTE_ON;assert(xtc_plugin_process_midi(a,&e,1,x,256)==XTC_OK);
|
||||
for(i=0;i<256;++i)assert(x[i]==0);
|
||||
xtc_plugin_destroy(a);unlink(preset);
|
||||
}
|
||||
int main(void) {
|
||||
editable();transport(0);transport(1);automation();roundtrip(0,2);roundtrip(1,3);effects(2);effects(3);synth(0);synth(1);
|
||||
sampler();editable();transport(0);transport(1);automation();roundtrip(0,2);roundtrip(1,3);effects(2);effects(3);synth(0);synth(1);
|
||||
synth_partition(0);synth_partition(1);puts("Built-in devices passed.");return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ int main(void)
|
|||
}
|
||||
write_text(bad,"XTC_PROJECT 999\n");
|
||||
assert(xtc_project_load_diagnostic(loaded,bad,&diagnostic) == XTC_ERR_UNSUPPORTED && diagnostic.line == 1 &&
|
||||
diagnostic.format_version == 999 && !strcmp(diagnostic.record,"XTC_PROJECT") && strstr(diagnostic.message,"1..14"));
|
||||
diagnostic.format_version == 999 && !strcmp(diagnostic.record,"XTC_PROJECT") && strstr(diagnostic.message,"1..15"));
|
||||
write_text(bad,"XTC_PROJECT 10\nAPP 0 1 0\nTEMPO nope\n");
|
||||
assert(xtc_project_load_diagnostic(loaded,bad,&diagnostic) == XTC_ERR_FORMAT && diagnostic.line == 3 &&
|
||||
!strcmp(diagnostic.record,"TEMPO"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue