feat: add a bounded WAV sampler with looping, relinking and saved presets

This commit is contained in:
Johannes Findeisen 2026-11-05 23:50:14 +01:00
commit 35bf6a00a1
24 changed files with 213 additions and 32 deletions

View file

@ -748,6 +748,14 @@ int main(int argc, char **argv)
CHECK(window.new_project()==XTC_OK && window.open_project("/tmp/xtc-internal-gui.xtc")==XTC_OK);
CHECK(xtc_project_get_instrument(sequence->project(),track,&spec)==XTC_OK && spec.index==instrument);
CHECK(xtc_graph_get_plugin(xtc_project_graph(sequence->project()),id,&spec)==XTC_OK && spec.index==effect && spec.point_count==1);
char sample[1024];CHECK(getcwd(sample,sizeof(sample))!=nullptr);std::strcat(sample,"/examples/projects/original-pluck.wav");
CHECK(window.load_sampler(track,sample)==XTC_OK);
CHECK(xtc_project_get_instrument(sequence->project(),track,&spec)==XTC_OK && spec.index==4 && !std::strcmp(spec.sample_path,sample));
CHECK(window.save_project("/tmp/xtc-sampler-gui.xtc")==XTC_OK);
CHECK(window.new_project()==XTC_OK && window.open_project("/tmp/xtc-sampler-gui.xtc")==XTC_OK);
CHECK(window.load_sampler(track,"/absent/sample.wav")==XTC_OK);
CHECK(window.load_sampler(track,sample)==XTC_OK); // Relink is one prepared history edit.
CHECK(window.undo()==XTC_OK && window.undo(true)==XTC_OK);unlink("/tmp/xtc-sampler-gui.xtc");
size_t added=SIZE_MAX;CHECK(window.add_plugin(XTC_BUILTIN_PATH,effect,&added)==XTC_OK);
CHECK(added!=id);CHECK(window.undo()==XTC_OK);
const xtc_project *before=sequence->project();reserve_result=XTC_ERR_OUT_OF_MEMORY;

View file

@ -56,7 +56,7 @@ def main():
run([str(binaries / 'xtc-check'), '--inspect', str(resources / 'xtc/examples/modern-session.xtc')])
assert (docs / 'WORKSPACE.md').is_file()
diagnose = subprocess.check_output([str(binaries / 'xtc-check'), '--diagnose'], text=True)
assert 'Project formats: 1..14' in diagnose and 'JACK compiled:' in diagnose
assert 'Project formats: 1..15' in diagnose and 'JACK compiled:' in diagnose
# Replacing a file symlink must not overwrite an unrelated target.
protected = stage / 'unrelated-target'
protected.write_text('keep unrelated target\n')

View file

@ -84,7 +84,7 @@ with tempfile.TemporaryDirectory(prefix="xtc-inspect-") as directory:
project.write_text(malformed)
check("--validate", project, 1)
for text, messages in [
(base.replace("XTC_PROJECT 10", "XTC_PROJECT 999"), ("line 1", "999", "1..14")),
(base.replace("XTC_PROJECT 10", "XTC_PROJECT 999"), ("line 1", "999", "1..15")),
("XTC_PROJECT 10\n", ("line 2", "APP")),
(base.replace("TEMPO 120000", "TEMPO 0"), ("line 3", "TEMPO")),
(base + "OPTIONAL_FUTURE 1\n", ("Unknown fields",)),

View file

@ -9,6 +9,7 @@
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
void *__real_malloc(size_t size);
void *__real_calloc(size_t count, size_t size);
@ -156,15 +157,16 @@ static void history_reservations(void)
static void builtin_failures(void)
{
unsigned int id;
for(id=0;id<4;++id) {
for(id=0;id<5;++id) {
int failure, succeeded=0; xtc_plugin_spec spec;
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,id,48000,&spec)==XTC_OK);
if(id==4) {assert(getcwd(spec.sample_path,sizeof(spec.sample_path)));strcat(spec.sample_path,"/examples/projects/original-pluck.wav");}
for(failure=0;failure<16;++failure) {
xtc_plugin *plugin=NULL; xtc_result result; float in[256]={0},out[256];
fail_after=failure;result=xtc_plugin_create(&spec,48000,256,&plugin);fail_after=-1;
if(result!=XTC_OK) {assert(result==XTC_ERR_OUT_OF_MEMORY && !plugin);continue;}
processing=1;
if(id<2) {xtc_midi_event event={0,XTC_MIDI_NOTE_ON,0,60,100};
if(spec.instrument) {xtc_midi_event event={0,XTC_MIDI_NOTE_ON,0,60,100};
assert(xtc_plugin_process_midi(plugin,&event,1,out,256)==XTC_OK);
} else assert(xtc_plugin_process(plugin,in,out,256)==XTC_OK);
processing=0;xtc_plugin_destroy(plugin);succeeded=1;break;