Phase 35: add persistent preferences and sequencer loop playback
This commit is contained in:
parent
4873b70672
commit
47b7d38a66
21 changed files with 852 additions and 108 deletions
|
|
@ -4,6 +4,8 @@
|
|||
#include "../../src/gui/piano_roll.hpp"
|
||||
#include "../../src/gui/mixer_widget.hpp"
|
||||
#include "../../src/gui/plugin_dialog.hpp"
|
||||
#include "../../src/gui/preferences_dialog.hpp"
|
||||
#include "../../src/gui/plugin_library.hpp"
|
||||
#include <FL/Fl_Hold_Browser.H>
|
||||
#include <FL/Fl_Choice.H>
|
||||
#include <FL/Fl_Value_Slider.H>
|
||||
|
|
@ -126,6 +128,8 @@ xtc_result xtc_backend_close(xtc_backend *backend)
|
|||
}
|
||||
xtc_result xtc_backend_start(xtc_backend *backend)
|
||||
{ CHECK(backend == &handle); ++starts; if (start_result == XTC_OK) { handle.running = 1; engine_status.active_revision = engine_status.submitted_revision; } return start_result; }
|
||||
xtc_result xtc_backend_set_loop(xtc_backend *,uint64_t start,uint64_t end,int enabled)
|
||||
{ return enabled && (end<=start || end-start<64) ? XTC_ERR_INVALID_ARGUMENT : XTC_OK; }
|
||||
xtc_result xtc_backend_set_transition_frames(xtc_backend *, size_t frames)
|
||||
{ CHECK(frames == 240); return XTC_OK; }
|
||||
xtc_result xtc_backend_request_stop(xtc_backend *backend)
|
||||
|
|
@ -183,7 +187,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false);
|
||||
MainWindow window(false,"");
|
||||
window.show(argc, argv);
|
||||
auto *play = find(&window, "Play");
|
||||
auto *stop = find(&window, "Stop");
|
||||
|
|
@ -535,7 +539,7 @@ int main(int argc, char **argv)
|
|||
for (xtc_result failure : {XTC_ERR_IO, XTC_ERR_UNSUPPORTED}) {
|
||||
reset();
|
||||
open_result = failure;
|
||||
MainWindow window(false);
|
||||
MainWindow window(false,"");
|
||||
window.show(argc, argv);
|
||||
CHECK(contains(&window, "Open JACK failed") && !find(&window, "Play")->active());
|
||||
open_result = XTC_OK;
|
||||
|
|
@ -549,21 +553,21 @@ int main(int argc, char **argv)
|
|||
partial_open = true;
|
||||
open_result = XTC_ERR_IO;
|
||||
{
|
||||
MainWindow window(false);
|
||||
MainWindow window(false,"");
|
||||
CHECK(alive == 1U && !find(&window, "Play")->active());
|
||||
window.do_callback(); // Partially initialized handles are closed only.
|
||||
CHECK(alive == 0U);
|
||||
}
|
||||
reset();
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
MainWindow window(false);
|
||||
MainWindow window(false,"");
|
||||
press(find(&window, "Play"));
|
||||
window.do_callback();
|
||||
}
|
||||
CHECK(alive == 0U);
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false); auto *s = timeline(&window);
|
||||
MainWindow window(false,""); auto *s = timeline(&window);
|
||||
CHECK(s->add_track() == XTC_OK && s->rename_selection("Keys") == XTC_OK);
|
||||
CHECK(s->add_region() == XTC_OK && s->rename_selection("Verse") == XTC_OK);
|
||||
CHECK(s->grid(120) == XTC_OK && s->grid() == 120 && s->grid(0) == XTC_ERR_INVALID_ARGUMENT);
|
||||
|
|
@ -585,7 +589,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
{
|
||||
reset();
|
||||
MainWindow window(false);
|
||||
MainWindow window(false,"");
|
||||
auto *canvas = graph_canvas(&window);
|
||||
CHECK(canvas != nullptr);
|
||||
CHECK(canvas->add_node(XTC_NODE_OSCILLATOR) == XTC_OK);
|
||||
|
|
@ -628,7 +632,7 @@ int main(int argc, char **argv)
|
|||
window.do_callback();
|
||||
}
|
||||
{
|
||||
reset(); MainWindow window(false);
|
||||
reset(); MainWindow window(false,"");
|
||||
auto *sequence = timeline(&window); auto *mixer = window.mixer();
|
||||
CHECK(sequence->add_track() == XTC_OK);
|
||||
CHECK(mixer->add_bus() == XTC_OK);
|
||||
|
|
@ -649,7 +653,7 @@ int main(int argc, char **argv)
|
|||
window.do_callback();
|
||||
}
|
||||
{
|
||||
reset(); MainWindow window(false);
|
||||
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);
|
||||
|
|
@ -674,7 +678,7 @@ int main(int argc, char **argv)
|
|||
unlink("/tmp/xtc-gui-controls-test.xtc"); window.do_callback();
|
||||
}
|
||||
{
|
||||
reset(); MainWindow window(false);
|
||||
reset(); MainWindow window(false,"");
|
||||
auto *sequence = timeline(&window); auto *canvas = graph_canvas(&window);
|
||||
CHECK(sequence->add_track() == XTC_OK && sequence->add_midi_clip() == XTC_OK);
|
||||
const uint64_t track = sequence->selected_track(), clip = sequence->selected_clip();
|
||||
|
|
@ -705,7 +709,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
if (const char *module = std::getenv("XTC_TEST_PLUGIN")) {
|
||||
reset();
|
||||
MainWindow window(false);
|
||||
MainWindow window(false,"");
|
||||
auto *sequence = timeline(&window);
|
||||
size_t id = SIZE_MAX;
|
||||
CHECK(window.add_plugin(module,0,&id) == XTC_OK);
|
||||
|
|
@ -807,7 +811,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
for (const char *variable : {"XTC_TEST_CLAP","XTC_TEST_VST2","XTC_TEST_VST3"}) {
|
||||
if (const char *module = std::getenv(variable)) {
|
||||
reset(); MainWindow window(false); auto *sequence = timeline(&window);
|
||||
reset(); MainWindow window(false,""); auto *sequence = timeline(&window);
|
||||
size_t id = SIZE_MAX; xtc_plugin_spec spec{};
|
||||
CHECK(window.add_plugin(module,0,&id) == XTC_OK);
|
||||
CHECK(xtc_graph_get_plugin(xtc_project_graph(sequence->project()),id,&spec) == XTC_OK);
|
||||
|
|
@ -831,7 +835,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
for (const char *variable : {"XTC_TEST_SYNTH_CLAP","XTC_TEST_SYNTH_VST2","XTC_TEST_SYNTH_VST3"}) {
|
||||
if (const char *module = std::getenv(variable)) {
|
||||
reset(); MainWindow window(false); auto *sequence = timeline(&window);
|
||||
reset(); MainWindow window(false,""); auto *sequence = timeline(&window);
|
||||
CHECK(sequence->add_track() == XTC_OK && sequence->add_midi_clip() == XTC_OK);
|
||||
uint64_t track = sequence->selected_track(); xtc_plugin_spec spec{};
|
||||
CHECK(window.assign_instrument(track,module,0) == XTC_OK);
|
||||
|
|
@ -867,7 +871,7 @@ int main(int argc, char **argv)
|
|||
// the current model. Exercise real sidebar buttons rather than mock actions.
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false); window.show();
|
||||
MainWindow window(false,""); window.show();
|
||||
auto *sequence = timeline(&window);
|
||||
CHECK(sequence != nullptr);
|
||||
auto *midi = find(&window,"New MIDI track");
|
||||
|
|
@ -908,7 +912,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false); window.show(); auto *sequence = timeline(&window);
|
||||
MainWindow window(false,""); window.show(); auto *sequence = timeline(&window);
|
||||
CHECK(window.create_track(true) == XTC_OK);
|
||||
uint64_t clip = sequence->selected_clip(), track = sequence->selected_track();
|
||||
auto *snap = dynamic_cast<Fl_Choice *>(find(&window,"Snap")); CHECK(snap && snap->value() == 3);
|
||||
|
|
@ -964,6 +968,44 @@ int main(int argc, char **argv)
|
|||
xtc_project_get_note(sequence->project(),0,¬e); CHECK(note.velocity > 29 && note.pitch == 60 && note.channel == 2);
|
||||
unlink("/tmp/xtc-grid-velocity.xtc"); window.do_callback();
|
||||
}
|
||||
{
|
||||
char dir[]="/tmp/xtc-preferences-XXXXXX"; CHECK(mkdtemp(dir));
|
||||
std::string path=std::string(dir)+"/.xtc.conf";
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false,path.c_str());window.show();
|
||||
xtc_settings settings=window.settings();settings.note_velocity=73;settings.sequencer_snap=480;
|
||||
CHECK(window.apply_preferences(settings)==XTC_OK);
|
||||
CHECK(timeline(&window)->grid()==480);
|
||||
int old_state=Fl::e_state;Fl::e_state=FL_SHIFT;
|
||||
gesture(timeline(&window),228,12,96,0);Fl::e_state=old_state;
|
||||
CHECK(window.settings().loop_start==960 && window.settings().loop_end==2880);
|
||||
CHECK(window.set_loop(960,3840,true)==XTC_OK);
|
||||
CHECK(window.settings().loop_enabled==1 && window.settings().loop_start==960);
|
||||
CHECK(window.set_loop(4000,2000,true)==XTC_ERR_INVALID_ARGUMENT);
|
||||
settings=window.settings();CHECK(window.apply_preferences(settings)==XTC_OK);
|
||||
settings.note_velocity=128;CHECK(window.apply_preferences(settings)==XTC_ERR_INVALID_ARGUMENT);
|
||||
PreferencesDialog dialog(window.settings(),path,[&](const xtc_settings &v){return window.apply_preferences(v);});
|
||||
auto *input=dynamic_cast<Fl_Input *>(find(&dialog,"New note velocity"));CHECK(input);
|
||||
if(input)input->value("81");
|
||||
press(find(&dialog,"Apply"));CHECK(window.settings().note_velocity==81);
|
||||
if(input)input->value("82");
|
||||
press(find(&dialog,"Close"));CHECK(window.settings().note_velocity==81);
|
||||
window.do_callback();
|
||||
}
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false,path.c_str());CHECK(window.settings().note_velocity==81);
|
||||
CHECK(window.settings().loop_start==960 && window.settings().loop_enabled==1);
|
||||
xtc_settings paths=window.settings();
|
||||
std::string binary=std::string(dir)+"/test.clap";FILE *f=fopen(binary.c_str(),"wb");CHECK(f);if(f)fclose(f);
|
||||
std::snprintf(paths.clap_paths,sizeof(paths.clap_paths),"%s:%s",dir,dir);
|
||||
paths.vst2_paths[0]=paths.vst3_paths[0]=paths.ladspa_paths[0]=0;
|
||||
auto files=xtc_plugin_files(paths);CHECK(files.size()==1 && files[0]==binary);
|
||||
unlink(binary.c_str());window.do_callback();
|
||||
}
|
||||
unlink(path.c_str());rmdir(dir);
|
||||
}
|
||||
if (failures != 0) return 1;
|
||||
std::printf("GUI controls/errors/views/timers/cleanup passed: %u opens, %u closes.\n", opens, closes);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue