Phase 12: Improve audio transitions and verify sample-accurate timing
This commit is contained in:
parent
461689dd44
commit
05140c2e93
29 changed files with 795 additions and 33 deletions
|
|
@ -202,3 +202,13 @@ window, reopens in another window, compares stereo rendering exactly, verifies
|
|||
playhead/meters and pause/resume/seek/home, and continues editing/saving.
|
||||
Mock GUI tests inject failed stop/seek/project preparation and recording guards.
|
||||
See [WORKFLOW.md](../../docs/WORKFLOW.md) for acceptance details and limitations.
|
||||
|
||||
## Phase 12 transitions
|
||||
|
||||
Backend fault tests verify start/stop ramp samples, repeated requests, callback
|
||||
completion, silent/held blocks before collection and deactivation error/retry.
|
||||
GUI tests keep immediate mocked stop semantics; real workflow/live GUI tests
|
||||
wait for asynchronous fade acknowledgement. `test_quality` in the unit suite
|
||||
checks exact source envelopes/timing and variable blocks, including tempo
|
||||
snapshot changes. See [AUDIO_QUALITY.md](../../docs/AUDIO_QUALITY.md) for commands,
|
||||
latency limitations and the pending listening checklist.
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ 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_transition_frames(xtc_backend *, size_t frames)
|
||||
{ CHECK(frames == 240); return XTC_OK; }
|
||||
xtc_result xtc_backend_request_stop(xtc_backend *backend)
|
||||
{ return xtc_backend_stop(backend); }
|
||||
xtc_result xtc_backend_stop(xtc_backend *backend)
|
||||
{ CHECK(backend == &handle); ++stops; if (stop_result == XTC_OK) handle.running = 0; return stop_result; }
|
||||
xtc_result xtc_backend_get_status(const xtc_backend *backend, xtc_backend_status *status)
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ int main(int argc, char **argv)
|
|||
unsigned int rate = 0U, frames = 0U, blocks = 0U;
|
||||
CHECK(std::sscanf(status->label(), "JACK | %u Hz | %u frames | stereo | %u blocks", &rate, &frames, &blocks) == 3);
|
||||
CHECK(rate > 0U && frames > 0U && blocks > 0U);
|
||||
stop->do_callback();
|
||||
stop->do_callback(); pump();
|
||||
CHECK(find(window, "ready / stopped") != nullptr);
|
||||
uint64_t paused = timeline->position(); pump();
|
||||
CHECK(timeline->position() == paused);
|
||||
|
|
@ -93,7 +93,7 @@ int main(int argc, char **argv)
|
|||
play->do_callback();
|
||||
pump();
|
||||
CHECK(find(window, "running — modular graph") != nullptr);
|
||||
stop->do_callback();
|
||||
stop->do_callback(); pump();
|
||||
char directory[] = "/tmp/xtc-live-record-XXXXXX"; CHECK(mkdtemp(directory) != nullptr);
|
||||
std::string take = std::string(directory) + "/take.wav";
|
||||
std::string song = std::string(directory) + "/song.xtc";
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ static std::vector<float> render(const xtc_project *project)
|
|||
CHECK(xtc_graph_compile(xtc_project_graph(project), 48000, 256, &graph) == XTC_OK);
|
||||
CHECK(xtc_audio_plan_create(project, 48000, &audio) == XTC_OK);
|
||||
CHECK(xtc_midi_plan_create(project, 48000, &midi) == XTC_OK);
|
||||
CHECK(xtc_audio_plan_set_fade_frames(audio, 240) == XTC_OK);
|
||||
CHECK(xtc_midi_plan_set_fade_frames(midi, 240) == XTC_OK);
|
||||
std::vector<float> result;
|
||||
for (uint64_t pos = 0; pos < 96000; pos += 256) {
|
||||
float al[256], ar[256], ml[256], mr[256], left[256], right[256];
|
||||
|
|
@ -113,7 +115,7 @@ int main(int argc, char **argv)
|
|||
CHECK(arranged.start_tick == 1920 && arranged.length_tick == 3840);
|
||||
CHECK(window.import_audio(wave.c_str()) == XTC_OK);
|
||||
expected = render(timeline->project());
|
||||
CHECK(expected[0] > 0); // Imported audio is routed without graph-file edits.
|
||||
CHECK(expected[0] == 0 && expected[2] > 0); // Imported audio is routed without graph-file edits.
|
||||
CHECK(expected[2 * 48001] != 0); // Arranged notes also reach the output.
|
||||
CHECK(xtc_graph_get_counts(xtc_project_graph(timeline->project()), &nodes, &edges) == XTC_OK);
|
||||
CHECK(nodes == 3 && edges == 2); // Audio and instrument -> output.
|
||||
|
|
@ -144,12 +146,13 @@ int main(int argc, char **argv)
|
|||
auto *right_meter = dynamic_cast<Fl_Progress *>(button(window, "Output R"));
|
||||
CHECK(left_meter && right_meter && left_meter->value() > 0 && right_meter->value() > 0);
|
||||
CHECK(window.pause_playback() == XTC_OK);
|
||||
pump(); // Fade completion is acknowledged by the GUI timer.
|
||||
CHECK(left_meter->value() == 0 && right_meter->value() == 0);
|
||||
uint64_t paused = timeline->position(); pump();
|
||||
CHECK(timeline->position() == paused);
|
||||
press(window, "Play"); pump();
|
||||
CHECK(timeline->position() > paused);
|
||||
press(window, "Stop");
|
||||
press(window, "Stop"); pump();
|
||||
paused = timeline->position(); pump(); CHECK(timeline->position() == paused);
|
||||
press(window, "To start"); CHECK(timeline->position() == 0);
|
||||
press(window, "Add MIDI clip");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue