1
0
Fork 0
forked from hanez/xtc

Phase 26: add common parameter targets, step automation and MIDI control mapping

This commit is contained in:
Johannes Findeisen 2026-10-27 16:37:59 +01:00
commit 901a536f10
38 changed files with 740 additions and 67 deletions

View file

@ -5,6 +5,7 @@
#include "../../src/gui/mixer_widget.hpp"
#include "../../src/gui/plugin_dialog.hpp"
#include <FL/Fl_Hold_Browser.H>
#include <FL/Fl_Choice.H>
#include <unistd.h>
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
@ -630,6 +631,31 @@ int main(int argc, char **argv)
mixer->reset_meters(); CHECK(!mixer->master_clipped());
window.do_callback();
}
{
reset(); MainWindow window(false);
auto *sequence = timeline(&window);
unsigned int bindings[3] = {1,74,11}, actual[3];
CHECK(window.set_control_map(2,bindings) == XTC_OK);
CHECK(xtc_project_get_control_map(sequence->project(),2,actual) == XTC_OK && actual[0] == 1);
CHECK(window.undo(false) == XTC_OK);
CHECK(xtc_project_get_control_map(sequence->project(),2,actual) == XTC_OK && actual[0] == 7);
CHECK(window.undo(true) == XTC_OK);
const xtc_project *before = sequence->project();
bindings[1] = 1;
CHECK(window.set_control_map(2,bindings) == XTC_ERR_INVALID_ARGUMENT && sequence->project() == before);
auto *mixer_ui = window.mixer();
CHECK(sequence->add_track() == XTC_OK);
auto *mode = dynamic_cast<Fl_Choice *>(find(&window,"Interpolation")); CHECK(mode);
if (mode) mode->value(1);
CHECK(mixer_ui->point(0,.25f) == XTC_OK);
xtc_automation_point point{};
CHECK(xtc_project_get_automation(sequence->project(),0,&point) == XTC_OK && point.step == 1);
CHECK(window.save_project("/tmp/xtc-gui-controls-test.xtc") == XTC_OK);
CHECK(window.new_project() == XTC_OK && window.open_project("/tmp/xtc-gui-controls-test.xtc") == XTC_OK);
CHECK(xtc_project_get_control_map(sequence->project(),2,actual) == XTC_OK && actual[0] == 1 && actual[1] == 74);
CHECK(xtc_project_get_automation(sequence->project(),0,&point) == XTC_OK && point.step == 1);
unlink("/tmp/xtc-gui-controls-test.xtc"); window.do_callback();
}
if (const char *module = std::getenv("XTC_TEST_PLUGIN")) {
reset();
MainWindow window(false);

View file

@ -37,7 +37,7 @@ def main():
assert os.access(root / 'bin/xtc-check', os.X_OK)
run([str(root / 'bin/xtc-check')])
diagnose = subprocess.check_output([str(root / 'bin/xtc-check'), '--diagnose'], text=True)
assert 'Project formats: 1..9' in diagnose and 'JACK compiled:' in diagnose
assert 'Project formats: 1..10' in diagnose and 'JACK compiled:' in diagnose
# Upgrade/repair repeats the same owned-file install and keeps unrelated data.
(root / 'include/xtc/xtc.h').write_text('old installation marker\n')
run(make + ['install'] + variables, env=env)

View file

@ -56,7 +56,7 @@ int main(int argc, char **argv)
for (j = 0; j < 2; ++j)
REQUIRE(xtc_project_add_note(project, clip, 0, 384000, 48 + (unsigned int)i, 100, 0,
&note) == XTC_OK);
point = (xtc_automation_point){track, 0, XTC_AUTOMATION_GAIN, 0.1f};
point = (xtc_automation_point){track, 0, XTC_AUTOMATION_GAIN, 0.1f,0};
REQUIRE(xtc_project_set_automation(project, &point) == XTC_OK);
point.tick = 384000;
point.value = 0.2f;

View file

@ -1,5 +1,6 @@
#define _POSIX_C_SOURCE 200809L
#include "xtc/xtc_plugin.h"
#include "xtc/xtc_control.h"
#include "xtc/xtc_project.h"
#include "xtc/xtc_realtime.h"
#include <assert.h>
@ -79,6 +80,12 @@ static void graph_roundtrip(const xtc_plugin_spec *spec)
assert(xtc_project_create(&loaded) == XTC_OK);
assert(xtc_project_load(loaded,path) == XTC_OK);
assert(xtc_graph_compile(xtc_project_graph(loaded),48000,31,&again) == XTC_ERR_NOT_FOUND && !again);
{
xtc_parameter_key key = {XTC_PARAMETER_PLUGIN,plugin,copy.control_count ? copy.ports[0] : 0};
xtc_parameter_state state = {0}; state.value = .75f;
assert(xtc_project_parameter(loaded,key,48000,&state) == XTC_ERR_NOT_FOUND && state.value == .75f);
assert(xtc_project_automate(loaded,key,48000,0,1,1,0) == XTC_ERR_NOT_FOUND);
}
assert(xtc_project_save(loaded,path) == XTC_OK);
xtc_graph_destroy(g); xtc_project_destroy(project); xtc_project_destroy(loaded);
xtc_plan_destroy(p); unlink(path);
@ -167,6 +174,25 @@ int main(int argc, char **argv)
assert(xtc_plugin_process_at(other,in,split,1,25) == XTC_OK && split[0] == 2);
xtc_plugin_destroy(p); xtc_plugin_destroy(other); p = NULL;
}
{
xtc_project *project = NULL; xtc_graph *g = NULL;
xtc_parameter_key key;
xtc_parameter_state state;
xtc_plugin_spec copy;
size_t id;
assert(xtc_project_create(&project) == XTC_OK && xtc_graph_create(8,&g) == XTC_OK);
assert(xtc_graph_add_plugin(g,&s,&id) == XTC_OK && xtc_project_set_graph(project,g) == XTC_OK);
key = (xtc_parameter_key){XTC_PARAMETER_PLUGIN,id,s.ports[0]};
assert(xtc_project_parameter(project,key,48000,&state) == XTC_OK && state.automated && state.info.id == s.ports[0]);
assert(xtc_project_set_parameter(project,key,48000,.75f) == XTC_OK);
assert(xtc_project_automate(project,key,48000,3,1,1,0) == XTC_OK);
assert(xtc_project_automate(project,key,48000,3,99,NAN,1) == XTC_OK); // Removal ignores mode/value.
assert(xtc_project_set_parameter(project,key,48000,3) == XTC_ERR_INVALID_ARGUMENT);
assert(xtc_graph_get_plugin(xtc_project_graph(project),id,&copy) == XTC_OK && copy.values[0] == .75f && copy.point_count == 2);
key.parameter = 63;
assert(xtc_project_automate(project,key,48000,0,1,0,0) == XTC_ERR_NOT_FOUND);
xtc_graph_destroy(g); xtc_project_destroy(project);
}
s.point_count = 0;
s.values[0] = 3; assert(xtc_plugin_create(&s,48000,17,&p) == XTC_ERR_UNSUPPORTED && !p);
assert(xtc_plugin_probe(argv[1],1,48000,&s) == XTC_OK && !s.inputs);

View file

@ -3,6 +3,7 @@
#include "xtc/xtc_mixer.h"
#include "xtc/xtc_midi.h"
#include "xtc/xtc_plugin.h"
#include "xtc/xtc_control.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@ -18,7 +19,7 @@ int main(void)
assert(mkdtemp(root));
assert(xtc_project_create(&p) == XTC_OK);
snprintf(file,sizeof(file),"%s/migration.xtc",root);
for (version = 1; version <= 8; ++version) {
for (version = 1; version <= 9; ++version) {
xtc_track_info t; xtc_clip_info c; size_t notes, points;
snprintf(old,sizeof(old),"tests/fixtures/project-v%u.xtc",version);
assert(xtc_project_load(p,old) == XTC_OK);
@ -28,6 +29,9 @@ int main(void)
assert(c.gain == 1 && c.fade_in_tick == 0 && c.fade_out_tick == 0);
assert(xtc_project_note_count(p,&notes) == XTC_OK && notes == (size_t)(version >= 3));
assert(xtc_project_automation_count(p,&points) == XTC_OK && points == (size_t)(version >= 4));
{ unsigned int map[3]; xtc_automation_point point;
assert(xtc_project_get_control_map(p,0,map) == XTC_OK && map[0] == 7 && map[1] == 10 && map[2] == 64);
if (points) assert(xtc_project_get_automation(p,0,&point) == XTC_OK && !point.step); }
assert(xtc_project_save(p,file) == XTC_OK && xtc_project_load(p,file) == XTC_OK);
}
for (version = 5; version <= 6; ++version) {
@ -85,6 +89,6 @@ int main(void)
assert(xtc_project_load(p,file) == XTC_ERR_FORMAT);
{ xtc_clip_info c; assert(xtc_project_find_clip(p,clip,&c) == XTC_OK && c.asset_path[0]); } }
xtc_project_destroy(p); unlink(file); rmdir(moved);
puts("v1-v8 migration, current folder relocation, cwd independence and missing-media preservation passed.");
puts("v1-v9 migration, current folder relocation, cwd independence and missing-media preservation passed.");
return 0;
}

View file

@ -18,10 +18,10 @@ int main(void)
for (i = 0; i < XTC_PROJECT_MAX_NOTES; ++i) assert(xtc_project_add_note(p,clips[i%1024],i/1024,1,60,100,0,&id) == XTC_OK);
assert(xtc_project_add_note(p,clips[0],0,1,60,100,0,&id) == XTC_ERR_CAPACITY);
for (i = 0; i < XTC_MAX_AUTOMATION_POINTS; ++i) {
xtc_automation_point a = {tracks[i%64],i/64,XTC_AUTOMATION_GAIN,.1f};
xtc_automation_point a = {tracks[i%64],i/64,XTC_AUTOMATION_GAIN,.1f,0};
assert(xtc_project_set_automation(p,&a) == XTC_OK);
}
{ xtc_automation_point a = {tracks[0],1000,XTC_AUTOMATION_GAIN,1}; assert(xtc_project_set_automation(p,&a) == XTC_ERR_CAPACITY); }
{ xtc_automation_point a = {tracks[0],1000,XTC_AUTOMATION_GAIN,1,0}; assert(xtc_project_set_automation(p,&a) == XTC_ERR_CAPACITY); }
assert(xtc_graph_create(256,&graph) == XTC_OK && xtc_graph_add_instrument(graph,&previous) == XTC_OK);
for (i = 1; i < 256; ++i) {
assert((i == 255 ? xtc_graph_add_output(graph,&node) : xtc_graph_add_meter(graph,&node)) == XTC_OK);