feat(engine): render prepared per-track insert graphs (phase 82)

This commit is contained in:
Johannes Findeisen 2026-11-06 01:35:53 +01:00
commit 62cee7a7b0
10 changed files with 215 additions and 5 deletions

View file

@ -294,8 +294,37 @@ static void sample_failures(void)
}
xtc_sample_destroy(source);xtc_project_destroy(p);assert(rmdir(root)==0);
}
static void track_insert_failures(void)
{
xtc_project *p=NULL;xtc_track_chain c={0};uint64_t t,clip;int mode,failure;
assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Track",&t)==XTC_OK);
assert(xtc_plugin_probe_format(XTC_PLUGIN_BUILTIN,XTC_BUILTIN_PATH,2,48000,&c.slots[0].plugin)==XTC_OK);
c.count=1;c.output_gain=1;c.slots[0].wet=.5f;c.slots[0].enabled=1;
assert(xtc_project_set_chain(p,t,&c)==XTC_OK);
for(mode=0;mode<2;++mode) {
int succeeded=0;
if(mode)assert(xtc_project_add_midi_clip(p,t,0,960,&clip)==XTC_OK);
for(failure=0;failure<128;++failure) {
xtc_audio_plan *a=NULL;xtc_midi_plan *m=NULL;float out[512];xtc_result r;
fail_after=failure;
r=mode ? xtc_midi_plan_create(p,48000,&m) : xtc_audio_plan_create(p,48000,&a);
fail_after=-1;
if(r==XTC_OK) {
processing=1;
if(mode)assert(xtc_midi_plan_render(m,0,NULL,0,out,512)==XTC_OK);
else assert(xtc_audio_plan_render(a,0,out,512)==XTC_OK);
processing=0;succeeded=1;
}else assert(r==XTC_ERR_OUT_OF_MEMORY && !a && !m);
xtc_audio_plan_destroy(a);xtc_midi_plan_destroy(m);
if(succeeded)break;
}
assert(succeeded);
}
xtc_project_destroy(p);
}
int main(void)
{
track_insert_failures();
sample_failures();
composition_failures();
modern_edit_failures();

View file

@ -1,14 +1,49 @@
#define _POSIX_C_SOURCE 200809L
#include "xtc/xtc_plugin.h"
#include "xtc/xtc_editing.h"
#include "xtc/xtc_audio.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void rendering(void)
{
xtc_project *p=NULL;xtc_audio_plan *audio=NULL;xtc_midi_plan *midi=NULL;
xtc_track_chain c={0};xtc_recorder *rec=NULL;uint64_t track,clip,copy,note;
char wave[]="/tmp/xtc-fx-audio-XXXXXX";float impulse[32]={1},out[32],right[32];int fd=mkstemp(wave);assert(fd>=0);close(fd);unlink(wave);
assert(xtc_recorder_create(wave,8000,32,&rec)==XTC_OK);xtc_recorder_push(rec,impulse,32);assert(xtc_recorder_finish(rec)==XTC_OK);xtc_recorder_destroy(rec);
assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Audio",&track)==XTC_OK);
assert(xtc_project_import_audio(p,track,wave,0,&clip)==XTC_OK);
assert(xtc_project_duplicate_clip(p,clip,track,0,&copy)==XTC_OK);
assert(xtc_plugin_probe_format(XTC_PLUGIN_BUILTIN,XTC_BUILTIN_PATH,2,8000,&c.slots[0].plugin)==XTC_OK);
c.count=1;c.output_gain=.5f;c.slots[0].enabled=1;c.slots[0].wet=1;
c.slots[0].plugin.values[0]=1;c.slots[0].plugin.values[1]=0;c.slots[0].plugin.values[2]=1;
assert(xtc_project_set_chain(p,track,&c)==XTC_OK && xtc_audio_plan_create(p,8000,&audio)==XTC_OK);
assert(xtc_audio_plan_set_fade_frames(audio,0)==XTC_OK && xtc_audio_plan_render_stereo(audio,0,out,right,32)==XTC_OK);
for(size_t j=0;j<32;++j)assert(fabsf(out[j]-(j==8 ? 1.f : 0.f))<.00001f && right[j]==out[j]);
/* Discontinuity resets internal delay, and block boundaries preserve history. */
assert(xtc_audio_plan_render(audio,0,out,4)==XTC_OK && out[0]==0);
assert(xtc_audio_plan_render(audio,4,out,12)==XTC_OK && fabsf(out[4]-1)<.00001f);
xtc_audio_plan_destroy(audio);audio=NULL;
c.slots[0].enabled=0;assert(xtc_project_set_chain(p,track,&c)==XTC_OK && xtc_audio_plan_create(p,8000,&audio)==XTC_OK);
assert(xtc_audio_plan_set_fade_frames(audio,0)==XTC_OK && xtc_audio_plan_render(audio,0,out,32)==XTC_OK && out[0]==1 && out[8]==0);
xtc_audio_plan_destroy(audio);audio=NULL;
/* Reject split ownership of a nonlinear chain on a hybrid track. */
assert(xtc_project_add_midi_clip(p,track,0,960,&clip)==XTC_OK);
assert(xtc_audio_plan_create(p,8000,&audio)==XTC_ERR_UNSUPPORTED && audio==NULL);
xtc_project_destroy(p);p=NULL;
assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"MIDI",&track)==XTC_OK && xtc_project_add_midi_clip(p,track,0,960,&clip)==XTC_OK);
assert(xtc_project_add_note(p,clip,0,960,69,127,0,&note)==XTC_OK);
c.slots[0].enabled=1;assert(xtc_project_set_chain(p,track,&c)==XTC_OK && xtc_midi_plan_create(p,8000,&midi)==XTC_OK);
assert(xtc_midi_plan_set_fade_frames(midi,0)==XTC_OK && xtc_midi_plan_render(midi,0,NULL,0,out,32)==XTC_OK);
for(size_t j=0;j<32;++j)assert(fabsf(out[j]-(j<8 ? 0.f : .05f*sinf(6.28318530718f*440.f*(float)(j-8)/8000.f)))<.00001f);
xtc_midi_plan_destroy(midi);xtc_project_destroy(p);unlink(wave);
}
int main(void)
{
rendering();
xtc_project *p=NULL,*q=NULL;uint64_t a,b,duplicate;xtc_track_chain c={0},got={0};
char file[]="/tmp/xtc-chain-XXXXXX";int fd=mkstemp(file);assert(fd>=0);close(fd);
assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Audio",&a)==XTC_OK && xtc_project_add_track(p,"Other",&b)==XTC_OK);