Update.
This commit is contained in:
parent
320addd5c9
commit
02e27a33a2
47 changed files with 882 additions and 62 deletions
|
|
@ -5,6 +5,8 @@
|
|||
#include "../../src/gui/mixer_widget.hpp"
|
||||
#include "../../src/gui/plugin_dialog.hpp"
|
||||
#include "../../src/gui/preferences_dialog.hpp"
|
||||
#include "../../src/gui/command_palette.hpp"
|
||||
#include <FL/Fl_Value_Input.H>
|
||||
#include "../../src/gui/plugin_library.hpp"
|
||||
#include <FL/Fl_Hold_Browser.H>
|
||||
#include <FL/Fl_Choice.H>
|
||||
|
|
@ -856,7 +858,7 @@ int main(int argc, char **argv)
|
|||
CHECK(window.create_track(true) == XTC_OK);
|
||||
uint64_t second = sequence->selected_track();
|
||||
auto *selector = sequence->instrument_choice(second); CHECK(selector && selector->value() == 0);
|
||||
CHECK(selector->size() == 4); // Sine, current project instrument, load, terminator.
|
||||
CHECK(selector->size() == 6); // Sine, two internal presets, project instrument, load, terminator.
|
||||
selector->value(1); selector->do_callback();
|
||||
CHECK(xtc_project_get_instrument(sequence->project(),second,&spec) == XTC_OK && spec.instrument);
|
||||
CHECK(sequence->selected_track() == second);
|
||||
|
|
@ -1080,6 +1082,58 @@ int main(int argc, char **argv)
|
|||
}
|
||||
xtc_project_destroy(project);
|
||||
}
|
||||
{
|
||||
reset();MainWindow window(false,"");window.show();CHECK(window.create_track(true)==XTC_OK);
|
||||
auto *seq=timeline(&window);auto clip=seq->selected_clip(),track=seq->selected_track();
|
||||
CHECK(window.set_tempo(135500)==XTC_OK && xtc_project_tempo(seq->project())==135500);
|
||||
CHECK(seq->selected_clip()==clip && seq->selected_track()==track);
|
||||
CHECK(window.undo()==XTC_OK && xtc_project_tempo(seq->project())==120000);
|
||||
CHECK(window.undo(true)==XTC_OK && xtc_project_tempo(seq->project())==135500);
|
||||
const auto *before=seq->project();reserve_result=XTC_ERR_OUT_OF_MEMORY;
|
||||
CHECK(window.set_tempo(100000)==XTC_ERR_OUT_OF_MEMORY && seq->project()==before);
|
||||
reserve_result=XTC_OK;CHECK(window.set_tempo(0)==XTC_ERR_INVALID_ARGUMENT);
|
||||
submit_result=XTC_ERR_CAPACITY;CHECK(window.set_tempo(100000)==XTC_ERR_CAPACITY && seq->project()==before);submit_result=XTC_OK;
|
||||
CHECK(window.set_tempo(135500)==XTC_OK);
|
||||
auto *bpm=dynamic_cast<Fl_Value_Input *>(find(&window,"BPM"));CHECK(bpm);
|
||||
if(bpm){bpm->value(140);bpm->do_callback();CHECK(xtc_project_tempo(seq->project())==140000);
|
||||
bpm->value(900);bpm->do_callback();CHECK(xtc_project_tempo(seq->project())==140000 && bpm->value()==140);}
|
||||
|
||||
auto *gain=dynamic_cast<Fl_Value_Input *>(find(&window,"Gain"));CHECK(gain);pump();
|
||||
if(gain){gain->value(.6);gain->do_callback();}xtc_track_info info{};xtc_project_get_track(seq->project(),0,&info);CHECK(info.gain==.6f);
|
||||
if(gain){Fl::focus(&gain->input);gain->input.value("0.123");pump();CHECK(std::strcmp(gain->input.value(),"0.123")==0);Fl::focus(nullptr);}
|
||||
CHECK(window.undo()==XTC_OK);xtc_project_get_track(seq->project(),0,&info);CHECK(info.gain==1);
|
||||
CHECK(seq->set_zoom(384)==XTC_OK);window.fit_song();CHECK(seq->zoom_level()<384);
|
||||
CHECK(contains(&window,"1 tracks / 1 clips"));
|
||||
Fl::add_timeout(.05,[](void *){auto *dialog=Fl::first_window();auto *search=dynamic_cast<Fl_Input *>(find(dialog,"Search commands"));CHECK(search);
|
||||
if(search){search->value("view/mixer");search->do_callback();}press(find(dialog,"Run command"));if(dialog->shown()){CHECK(false);dialog->hide();}});
|
||||
window.show_commands();CHECK(window.mixer()->visible_r());
|
||||
auto *bar=dynamic_cast<Fl_Menu_Bar *>(window.child(0));CHECK(bar);if(bar)bar->picked(bar->find_item("View/Sequencer"));
|
||||
auto *follow=dynamic_cast<Fl_Check_Button *>(find(&window,"Follow playhead"));CHECK(follow);
|
||||
if(follow){follow->value(1);follow->do_callback();CHECK(window.settings().follow_playhead==1);}
|
||||
press(find(&window,"Play"));engine_status.sample_position=960000;pump();
|
||||
auto *scroll=dynamic_cast<Fl_Scroll *>(seq->parent());CHECK(scroll && scroll->xposition()>0);
|
||||
press(find(&window,"Stop"));window.fit_song();CHECK(scroll && scroll->xposition()==0);
|
||||
|
||||
Fl::add_timeout(.05,[](void *){auto *dialog=Fl::first_window();auto *search=dynamic_cast<Fl_Input *>(find(dialog,"Search commands"));
|
||||
CHECK(search);if(search){search->value("does not exist");search->do_callback();}press(find(dialog,"Run command"));CHECK(dialog->shown());press(find(dialog,"Cancel"));});
|
||||
window.show_commands();
|
||||
CHECK(window.create_track(true)==XTC_OK);uint64_t second=seq->selected_track();
|
||||
window.mixer()->select_track(track);if(bar)bar->picked(bar->find_item("View/Mixer"));pump();
|
||||
if(gain){gain->value(.4);gain->do_callback();}xtc_project_get_track(seq->project(),0,&info);CHECK(info.id==track && info.gain==.4f);
|
||||
xtc_project_get_track(seq->project(),1,&info);CHECK(info.id==second && info.gain==1);
|
||||
window.do_callback();
|
||||
}
|
||||
{
|
||||
CommandPalette palette({"View/Mixer","File/Open"});
|
||||
Fl::add_timeout(.05,[](void *context){auto *p=static_cast<CommandPalette *>(context);auto *search=dynamic_cast<Fl_Input *>(find(p,"Search commands"));CHECK(search);
|
||||
if(search){search->value("FILE");search->do_callback();}int old=Fl::e_keysym;Fl::e_keysym=FL_Enter;CHECK(p->handle(FL_KEYDOWN)==1);Fl::e_keysym=old;},&palette);
|
||||
CHECK(palette.run()=="File/Open");
|
||||
}
|
||||
{
|
||||
CommandPalette palette({"View/Mixer"});
|
||||
Fl::add_timeout(.05,[](void *context){int old=Fl::e_keysym;Fl::e_keysym=FL_Escape;static_cast<CommandPalette *>(context)->handle(FL_KEYDOWN);Fl::e_keysym=old;},&palette);
|
||||
CHECK(palette.run().empty());
|
||||
}
|
||||
if (failures != 0) return 1;
|
||||
std::printf("GUI controls/errors/views/timers/cleanup passed: %u opens, %u closes.\n", opens, closes);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -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..12' in diagnose and 'JACK compiled:' in diagnose
|
||||
assert 'Project formats: 1..13' 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')
|
||||
|
|
|
|||
|
|
@ -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..12")),
|
||||
(base.replace("XTC_PROJECT 10", "XTC_PROJECT 999"), ("line 1", "999", "1..13")),
|
||||
("XTC_PROJECT 10\n", ("line 2", "APP")),
|
||||
(base.replace("TEMPO 120000", "TEMPO 0"), ("line 3", "TEMPO")),
|
||||
(base + "OPTIONAL_FUTURE 1\n", ("Unknown fields",)),
|
||||
|
|
|
|||
73
tests/unit/test_builtin.c
Normal file
73
tests/unit/test_builtin.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "xtc/xtc_plugin.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "xtc/xtc_midi.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
static void effects(unsigned int id)
|
||||
{
|
||||
xtc_plugin_spec s; xtc_plugin *a=NULL,*b=NULL; float in[256]={0},x[256],y[256]; size_t k,i; double energy=0;
|
||||
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,id,48000,&s)==XTC_OK);
|
||||
assert(xtc_plugin_create(&s,48000,256,&a)==XTC_OK);
|
||||
assert(xtc_plugin_create(&s,48000,256,&b)==XTC_OK);
|
||||
for(k=0;k<600;++k) {
|
||||
in[0]=k==0 ? 1 : 0;
|
||||
assert(xtc_plugin_process(a,in,x,256)==XTC_OK);
|
||||
assert(xtc_plugin_process(b,in,y,128)==XTC_OK);
|
||||
assert(xtc_plugin_process(b,in+128,y+128,128)==XTC_OK);
|
||||
for(i=0;i<256;++i) {assert(isfinite(x[i]));assert(fabsf(x[i]-y[i])<1e-6f);if(k>0)energy+=fabs(x[i]);}
|
||||
}
|
||||
assert(energy>.01);xtc_plugin_destroy(a);xtc_plugin_destroy(b);
|
||||
s.values[2]=0; assert(xtc_plugin_create(&s,48000,256,&a)==XTC_OK);
|
||||
in[0]=1;assert(xtc_plugin_process(a,in,x,256)==XTC_OK);assert(!memcmp(in,x,sizeof(in)));xtc_plugin_destroy(a);
|
||||
s.values[1]=2;assert(xtc_plugin_spec_validate(&s)!=XTC_OK);
|
||||
}
|
||||
static void synth(unsigned int id)
|
||||
{
|
||||
xtc_plugin_spec s; xtc_plugin *p=NULL; float out[256]; size_t i,k; double energy=0;
|
||||
xtc_midi_event e={0,XTC_MIDI_NOTE_ON,0,60,100};
|
||||
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,id,48000,&s)==XTC_OK);
|
||||
assert(xtc_plugin_create(&s,48000,256,&p)==XTC_OK);
|
||||
assert(xtc_plugin_process_midi(p,&e,1,out,256)==XTC_OK);
|
||||
for(i=0;i<256;++i)energy+=fabs(out[i]);
|
||||
assert(energy>0);
|
||||
e.type=XTC_MIDI_NOTE_OFF;assert(xtc_plugin_process_midi(p,&e,1,out,256)==XTC_OK);
|
||||
for(k=0;k<200;++k)assert(xtc_plugin_process_midi(p,NULL,0,out,256)==XTC_OK);
|
||||
for(i=0;i<256;++i)assert(fabsf(out[i])<1e-5f);
|
||||
e.type=XTC_MIDI_ALL_OFF;assert(xtc_plugin_process_midi(p,&e,1,out,256)==XTC_OK);
|
||||
for(i=0;i<256;++i)assert(out[i]==0);
|
||||
xtc_plugin_destroy(p);
|
||||
}
|
||||
static void automation(void)
|
||||
{
|
||||
xtc_plugin_spec s; xtc_plugin *p=NULL; float in[128],out[128]; size_t i;
|
||||
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,2,960,&s)==XTC_OK);
|
||||
s.tempo=60000; s.values[0]=2000; s.point_count=2;
|
||||
s.points[0]=(xtc_plugin_point){0,2,0,0}; s.points[1]=(xtc_plugin_point){100,2,0,1};
|
||||
assert(xtc_plugin_create(&s,960,128,&p)==XTC_OK);
|
||||
for(i=0;i<128;++i)in[i]=1;
|
||||
assert(xtc_plugin_process_at(p,in,out,128,0)==XTC_OK);
|
||||
for(i=0;i<128;++i) assert(fabsf(out[i]-(i<100 ? 1-(float)i/100 : 0))<1e-6f);
|
||||
xtc_plugin_destroy(p);
|
||||
}
|
||||
static void roundtrip(void)
|
||||
{
|
||||
xtc_project *p=NULL,*q=NULL; xtc_plugin_spec s,t; uint64_t track; size_t id; xtc_graph *g=NULL;
|
||||
char path[]="/tmp/xtc-builtin-XXXXXX"; int fd=mkstemp(path); assert(fd>=0); close(fd);
|
||||
assert(xtc_project_create(&p)==XTC_OK); assert(xtc_project_create(&q)==XTC_OK);
|
||||
assert(xtc_project_add_track(p,"Keys",&track)==XTC_OK);
|
||||
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,0,48000,&s)==XTC_OK);
|
||||
assert(xtc_project_set_instrument(p,track,&s)==XTC_OK);
|
||||
assert(xtc_plugin_probe(XTC_BUILTIN_PATH,2,48000,&s)==XTC_OK); s.values[0]=250;
|
||||
s.point_count=2; s.points[0]=(xtc_plugin_point){0,2,0,.1f}; s.points[1]=(xtc_plugin_point){960,2,0,.6f};
|
||||
assert(xtc_graph_clone(xtc_project_graph(p),&g)==XTC_OK);
|
||||
assert(xtc_graph_add_plugin(g,&s,&id)==XTC_OK); assert(xtc_project_set_graph(p,g)==XTC_OK);xtc_graph_destroy(g);
|
||||
assert(xtc_project_save(p,path)==XTC_OK); assert(xtc_project_load(q,path)==XTC_OK);
|
||||
assert(xtc_graph_get_plugin(xtc_project_graph(q),id,&t)==XTC_OK); assert(t.values[0]==250 && t.point_count==2);
|
||||
assert(xtc_project_get_instrument(q,track,&t)==XTC_OK && t.index==0 && t.format==XTC_PLUGIN_BUILTIN);
|
||||
xtc_project_destroy(p);xtc_project_destroy(q);unlink(path);
|
||||
}
|
||||
int main(void) {automation();roundtrip();effects(2);effects(3);synth(0);synth(1);puts("Built-in devices passed.");return 0;}
|
||||
|
|
@ -68,7 +68,7 @@ int main(void)
|
|||
assert(xtc_project_add_track(old,"Old",&id) == XTC_OK && xtc_project_add_track(next,"New",&id) == XTC_OK);
|
||||
assert(xtc_project_save(old,song) == XTC_OK); size = bytes(song,before);
|
||||
assert(xtc_project_load_diagnostic(loaded,song,&diagnostic) == XTC_OK && diagnostic.result == XTC_OK &&
|
||||
diagnostic.format_version == 12 && !diagnostic.line);
|
||||
diagnostic.format_version == 13 && !diagnostic.line);
|
||||
for (mode = 1; mode <= 5; ++mode) {
|
||||
fault = mode;
|
||||
assert(xtc_project_save(next,song) == XTC_ERR_IO);
|
||||
|
|
@ -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..12"));
|
||||
diagnostic.format_version == 999 && !strcmp(diagnostic.record,"XTC_PROJECT") && strstr(diagnostic.message,"1..13"));
|
||||
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"));
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ int main(void)
|
|||
CHECK(fd>=0);close(fd);unlink(path);
|
||||
xtc_settings_defaults(&a);CHECK(xtc_settings_validate(&a)==XTC_OK);
|
||||
b=a;CHECK(xtc_settings_load(&b,path)==XTC_ERR_NOT_FOUND);
|
||||
strcpy(a.clap_paths,"~/space folder:/tmp/quoted\"name\\path");a.loop_enabled=1;a.note_velocity=87;
|
||||
strcpy(a.clap_paths,"~/space folder:/tmp/quoted\"name\\path");a.loop_enabled=1;a.follow_playhead=1;a.note_velocity=87;
|
||||
CHECK(xtc_settings_save(&a,path)==XTC_OK);CHECK(stat(path,&st)==0 && (st.st_mode&0777)==0600);
|
||||
CHECK(xtc_settings_load(&b,path)==XTC_OK);CHECK(memcmp(&a,&b,sizeof(a))==0);
|
||||
xtc_settings_schema(&n);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue