feat: detect and slice audio attacks atomically and qualify sample editor workflows
This commit is contained in:
parent
edeeb8e8bb
commit
9e380d4dd0
20 changed files with 257 additions and 22 deletions
|
|
@ -199,17 +199,20 @@ static int sample_editor_tests()
|
|||
CHECK(e->process(XTC_SAMPLE_FADE_IN_POWER)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);
|
||||
CHECK(e->process(XTC_SAMPLE_REMOVE_DC)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);
|
||||
CHECK(e->process(XTC_SAMPLE_INVERT)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);
|
||||
CHECK(e->process(XTC_SAMPLE_REVERSE)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);CHECK(xtc_sample_read(e->sample(),10,&after)==XTC_OK && before==after);CHECK(e->undo_sample()==XTC_OK);CHECK(e->select(100,10)==XTC_ERR_INVALID_ARGUMENT);CHECK(e->view(10,8)==XTC_OK);size_t b=e->begin(),z=e->end();CHECK(e->select_audible(1,0)==XTC_ERR_NOT_FOUND && e->begin()==b && e->end()==z);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->select_audible(.01,2)==XTC_OK);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->snap_zero_crossings(65536)==XTC_OK);CHECK(e->view(e->frames(),1)==XTC_ERR_INVALID_ARGUMENT);e->hide();}},nullptr);
|
||||
CHECK(e->process(XTC_SAMPLE_REVERSE)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);CHECK(xtc_sample_read(e->sample(),10,&after)==XTC_OK && before==after);CHECK(e->undo_sample()==XTC_OK);CHECK(e->select(100,10)==XTC_ERR_INVALID_ARGUMENT);CHECK(e->view(10,8)==XTC_OK);size_t b=e->begin(),z=e->end();CHECK(e->select_audible(1,0)==XTC_ERR_NOT_FOUND && e->begin()==b && e->end()==z);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->select_audible(.01,2)==XTC_OK);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->snap_zero_crossings(65536)==XTC_OK);CHECK(e->detect_attacks(.1,2400)==XTC_OK && !e->attacks().empty());CHECK(e->view(e->frames(),1)==XTC_ERR_INVALID_ARGUMENT);unsigned int rate=0;size_t frames=0;CHECK(xtc_sample_info(e->sample(),&rate,&frames)==XTC_OK);CHECK(e->select(rate/10,rate*4/10)==XTC_OK);CHECK(e->trim_clip()==XTC_OK);e->hide();}},nullptr);
|
||||
CHECK(window.open_sample_editor()==XTC_OK);CHECK(s->selected_clip()!=UINT64_MAX);
|
||||
uint64_t id=s->selected_clip();CHECK(window.trim_sample_clip(id,48000,2400,12000)==XTC_OK);
|
||||
xtc_clip_info clip{};CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && clip.offset_tick==96 && clip.length_tick==384);
|
||||
uint64_t id=s->selected_clip();
|
||||
xtc_clip_info clip{};CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && clip.offset_tick==192 && clip.length_tick==576);
|
||||
CHECK(window.undo()==XTC_OK);CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && clip.offset_tick==0);
|
||||
{xtc_sample *data=nullptr;CHECK(xtc_sample_load(path,&data)==XTC_OK);std::string copy="/tmp/xtc-sample-gui-"+std::to_string(getpid())+".wav";
|
||||
submit_result=XTC_ERR_OUT_OF_MEMORY;CHECK(window.adopt_sample_copy(id,data,copy.c_str())==XTC_ERR_OUT_OF_MEMORY && access(copy.c_str(),F_OK)!=0);submit_result=XTC_OK;
|
||||
CHECK(window.adopt_sample_copy(id,data,copy.c_str())==XTC_OK);CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && !strcmp(clip.asset_path,copy.c_str()));
|
||||
CHECK(window.undo()==XTC_OK);CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && !strcmp(clip.asset_path,path));
|
||||
xtc_sample_destroy(data);CHECK(unlink(copy.c_str())==0);}
|
||||
window.do_callback();return failures ? 1 : 0;
|
||||
CHECK(window.slice_sample_clip(id,22050,{2400,4800,7200})==XTC_OK);
|
||||
size_t tracks=0,clips=0;CHECK(xtc_project_get_counts(s->project(),&tracks,&clips)==XTC_OK && clips==4);
|
||||
CHECK(window.undo()==XTC_OK);CHECK(xtc_project_get_counts(s->project(),&tracks,&clips)==XTC_OK && clips==1);
|
||||
window.do_callback();std::puts("Sample editor GUI selection/processing/adoption/slicing/undo passed.");return failures ? 1 : 0;
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include "xtc/xtc_plugin.h"
|
||||
#include "xtc/xtc_editing.h"
|
||||
#include "xtc/xtc_audio.h"
|
||||
#include "xtc/xtc_sample.h"
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -268,8 +270,33 @@ static void composition_failures(void)
|
|||
}
|
||||
xtc_project_destroy(p);assert(rmdir(root)==0);
|
||||
}
|
||||
static void sample_failures(void)
|
||||
{
|
||||
xtc_sample *source=NULL;xtc_project *p=NULL;char path[4096],root[]="/tmp/xtc-sample-fail-XXXXXX",dest[256];uint64_t t,id;int op,failure;
|
||||
assert(getcwd(path,sizeof(path)));assert(strlen(path)+40<sizeof(path));strcat(path,"/examples/projects/original-pluck.wav");assert(mkdtemp(root));
|
||||
snprintf(dest,sizeof(dest),"%s/copy.wav",root);
|
||||
assert(xtc_sample_load(path,&source)==XTC_OK && xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Audio",&t)==XTC_OK && xtc_project_import_audio(p,t,path,0,&id)==XTC_OK);
|
||||
for(op=0;op<12;++op){int succeeded=0;
|
||||
for(failure=0;failure<128;++failure){xtc_sample *output=NULL;xtc_project *copy=NULL;xtc_result r;size_t made=999,cuts[]={2400,4800};
|
||||
assert(xtc_project_clone(p,©)==XTC_OK);fail_after=failure;
|
||||
if(op<9)r=xtc_sample_process(source,100,1000,(xtc_sample_operation)op,op==XTC_SAMPLE_GAIN ? 2 : .5,&output);
|
||||
else if(op==9)r=xtc_sample_load(path,&output);
|
||||
else if(op==10)r=xtc_sample_write(source,100,1000,dest);
|
||||
else r=xtc_project_slice_source_frames(copy,id,48000,cuts,2,&made);
|
||||
fail_after=-1;
|
||||
if(r==XTC_OK)succeeded=1;
|
||||
else {assert(r==XTC_ERR_OUT_OF_MEMORY||r==XTC_ERR_IO);assert(output==NULL && made==999 && access(dest,F_OK)!=0);
|
||||
{size_t tracks,clips;uint64_t probe;assert(xtc_project_get_counts(copy,&tracks,&clips)==XTC_OK && clips==1);assert(xtc_project_duplicate_clip(copy,id,t,10000,&probe)==XTC_OK && probe==1);}}
|
||||
if(op==10&&succeeded)assert(unlink(dest)==0);
|
||||
{DIR *d=opendir(root);struct dirent *entry;assert(d);while((entry=readdir(d)))assert(!strcmp(entry->d_name,".")||!strcmp(entry->d_name,".."));assert(closedir(d)==0);}
|
||||
xtc_sample_destroy(output);xtc_project_destroy(copy);if(succeeded)break;
|
||||
}assert(succeeded);
|
||||
}
|
||||
xtc_sample_destroy(source);xtc_project_destroy(p);assert(rmdir(root)==0);
|
||||
}
|
||||
int main(void)
|
||||
{
|
||||
sample_failures();
|
||||
composition_failures();
|
||||
modern_edit_failures();
|
||||
builtin_failures();
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
#include "xtc/xtc_sample.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
int main(void)
|
||||
{
|
||||
char root[]="/tmp/xtc-sample-test-XXXXXX",path[256];float values[]={0,.25f,-.5f,.75f,0,0,.5f,-.25f};
|
||||
|
|
@ -64,5 +66,33 @@ int main(void)
|
|||
assert(xtc_sample_zero_crossing(s,6,1,&crossing)==XTC_OK && crossing==5);
|
||||
assert(xtc_sample_zero_crossing(s,8,1,&crossing)==XTC_OK && crossing==7);
|
||||
assert(xtc_sample_zero_crossing(s,0,65537,&crossing)==XTC_ERR_INVALID_ARGUMENT && crossing==7);}
|
||||
{size_t positions[128]={999},count=999;assert(xtc_sample_transients(s,0,8,.4,1,positions,128,&count)==XTC_OK && count==2 && positions[0]==2 && positions[1]==6);
|
||||
count=999;positions[0]=999;assert(xtc_sample_transients(s,0,8,.4,1,positions,1,&count)==XTC_ERR_CAPACITY && count==999 && positions[0]==999);
|
||||
assert(xtc_sample_transients(s,0,8,.4,5,positions,128,&count)==XTC_OK && count==1 && positions[0]==2);}
|
||||
{xtc_project *p=NULL,*q=NULL;xtc_audio_plan *a=NULL,*b=NULL;uint64_t t,c;float before[128],after[128];size_t cuts[]={0,4,8},made=999,tracks=0,clips=0;char song[256];
|
||||
assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Audio",&t)==XTC_OK && xtc_project_import_audio(p,t,path,10,&c)==XTC_OK);
|
||||
assert(xtc_audio_plan_create(p,8000,&a)==XTC_OK && xtc_audio_plan_render(a,0,before,128)==XTC_OK);
|
||||
assert(xtc_project_slice_source_frames(p,c,8000,cuts,3,&made)==XTC_OK && made==1);
|
||||
assert(xtc_audio_plan_create(p,8000,&b)==XTC_OK && xtc_audio_plan_render(b,0,after,128)==XTC_OK && !memcmp(before,after,sizeof(before)));
|
||||
snprintf(song,sizeof(song),"%s/slices.xtc",root);assert(xtc_project_save(p,song)==XTC_OK && xtc_project_create(&q)==XTC_OK && xtc_project_load(q,song)==XTC_OK);
|
||||
assert(xtc_project_get_counts(q,&tracks,&clips)==XTC_OK && clips==2);assert(unlink(song)==0);
|
||||
xtc_audio_plan_destroy(a);xtc_audio_plan_destroy(b);xtc_project_destroy(p);xtc_project_destroy(q);}
|
||||
{xtc_project *p=NULL;uint64_t t,c,extra;size_t cuts[]={1000,2000},made=999,tracks,clips;
|
||||
assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Full",&t)==XTC_OK && xtc_project_add_clip(p,t,"Source",0,960,&c)==XTC_OK && xtc_project_set_clip_asset(p,c,path)==XTC_OK);
|
||||
for(size_t j=1;j<XTC_PROJECT_MAX_CLIPS-1;++j)assert(xtc_project_add_clip(p,t,"Fill",10000,960,&extra)==XTC_OK);
|
||||
assert(xtc_project_slice_source_frames(p,c,48000,cuts,2,&made)==XTC_ERR_CAPACITY && made==999);
|
||||
assert(xtc_project_get_counts(p,&tracks,&clips)==XTC_OK && clips==XTC_PROJECT_MAX_CLIPS-1);
|
||||
assert(xtc_project_add_clip(p,t,"Probe",10000,960,&extra)==XTC_OK && extra==XTC_PROJECT_MAX_CLIPS-1);xtc_project_destroy(p);}
|
||||
{char big[256];unsigned char header[44];uint32_t count=(XTC_SAMPLE_MAX_FRAMES+1U)*4U;FILE *input=fopen(path,"rb"),*output;xtc_sample *q=NULL;
|
||||
assert(input && fread(header,1,44,input)==44 && fclose(input)==0);snprintf(big,sizeof(big),"%s/large.wav",root);
|
||||
for(unsigned int j=0;j<4;++j){header[4+j]=(unsigned char)((count+36U)>>(j*8));header[40+j]=(unsigned char)(count>>(j*8));}
|
||||
output=fopen(big,"wb");assert(output && fwrite(header,1,44,output)==44 && fflush(output)==0 && ftruncate(fileno(output),(off_t)count+44)==0 && fclose(output)==0);
|
||||
assert(xtc_sample_load(big,&q)==XTC_ERR_CAPACITY && q==NULL);assert(unlink(big)==0);}
|
||||
{char edge[256];float large=FLT_MAX;xtc_sample *q=NULL,*result=NULL;snprintf(edge,sizeof(edge),"%s/edge.wav",root);
|
||||
assert(xtc_recorder_create(edge,8000,1,&rec)==XTC_OK);xtc_recorder_push(rec,&large,1);assert(xtc_recorder_finish(rec)==XTC_OK);xtc_recorder_destroy(rec);
|
||||
assert(xtc_sample_load(edge,&q)==XTC_OK && xtc_sample_process(q,0,1,XTC_SAMPLE_GAIN,2,&result)==XTC_ERR_CAPACITY && result==NULL);
|
||||
assert(xtc_sample_read(q,0,&v)==XTC_OK && v==FLT_MAX);xtc_sample_destroy(q);assert(unlink(edge)==0);
|
||||
large=.001f;assert(xtc_recorder_create(edge,8000,1,&rec)==XTC_OK);xtc_recorder_push(rec,&large,1);assert(xtc_recorder_finish(rec)==XTC_OK);xtc_recorder_destroy(rec);
|
||||
assert(xtc_sample_load(edge,&q)==XTC_OK && xtc_sample_process(q,0,1,XTC_SAMPLE_NORMALIZE,1,&result)==XTC_ERR_CAPACITY && result==NULL);xtc_sample_destroy(q);assert(unlink(edge)==0);}
|
||||
xtc_sample_destroy(s);assert(unlink(path)==0 && rmdir(root)==0);puts("Sample editor core tests passed.");return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue