From 9e380d4dd06347fa9b3f3249ec0684dcbea22e22 Mon Sep 17 00:00:00 2001 From: hanez Date: Fri, 6 Nov 2026 01:16:39 +0100 Subject: [PATCH] feat: detect and slice audio attacks atomically and qualify sample editor workflows --- README.md | 3 ++- docs/AUDIO_EDITOR.md | 22 ++++++++++++++++ docs/AUDIO_FILES.md | 4 +++ docs/RELEASE_NOTES.md | 12 +++++++++ docs/ROADMAP.md | 36 ++++++++++++++++++++++++--- docs/USER_MANUAL.md | 6 +++++ docs/WORKSPACE.md | 4 +++ include/xtc/xtc_sample.h | 21 +++++++++++++--- screenshots/README.md | 15 ++++++++++- screenshots/sample-editor.png | Bin 0 -> 59508 bytes screenshots/sample-transients.png | Bin 0 -> 58453 bytes src/audio/sample.c | 32 ++++++++++++++++++++++++ src/gui/main_window.cpp | 14 ++++++++++- src/gui/main_window.hpp | 1 + src/gui/sample_editor.cpp | 19 ++++++++++---- src/gui/sample_editor.hpp | 9 ++++++- tests/integration/test_gui.cpp | 11 +++++--- tests/integration/test_reliability.c | 27 ++++++++++++++++++++ tests/unit/test_sample.c | 30 ++++++++++++++++++++++ tools/capture_screenshots.cpp | 13 ++++++++-- 20 files changed, 257 insertions(+), 22 deletions(-) create mode 100644 screenshots/sample-editor.png create mode 100644 screenshots/sample-transients.png diff --git a/README.md b/README.md index 1e193d7..0b6b46f 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,8 @@ select a missing clip and use File/Relink selected audio to repair it. Add MIDI clip on an existing track, then open Piano roll (Ctrl+4) to draw notes. Connect a MIDI source to the JACK `midi_in` port for live playing; Panic/F9 silences held notes. See [MIDI workflow and limits](docs/MIDI.md). -See [audio workflow and limits](docs/AUDIO_FILES.md). +See [audio workflow and limits](docs/AUDIO_FILES.md) and the +[sample editor workflows](docs/AUDIO_EDITOR.md). Mixer (Ctrl+2) selects a track for gain/pan/mute/solo and automation editing. Ctrl+Z undoes; Ctrl+Shift+Z or Ctrl+Y redoes up to 32 edits. The GUI now exposes left `output` and `output_right` JACK ports; route both diff --git a/docs/AUDIO_EDITOR.md b/docs/AUDIO_EDITOR.md index ef220cc..96cc21d 100644 --- a/docs/AUDIO_EDITOR.md +++ b/docs/AUDIO_EDITOR.md @@ -49,3 +49,25 @@ Select audible bounds finds the first and last sample strictly above the chosen ## Phase 78 Snap to zero crossings searches each selected boundary within a source-frame radius up to 65,536. It uses the mono source, chooses earlier positions on equal distance and changes both endpoints only if both searches yield a nonempty range. Source edges qualify only when their adjacent sample is zero. This can reduce boundary discontinuities but does not guarantee click-free output; musical-tick trimming/slicing can move a boundary away from the exact crossing. + +## Phase 79 + +Detect attacks uses absolute sample amplitude, an initial armed state, rearming below one quarter of the threshold and a minimum frame gap between retained attacks. It marks up to 128 source positions in orange; hovering the statistics shows exact frame indices. This is a threshold detector, not spectral onset detection, beat detection or tempo estimation. Selection/processing changes invalidate the markers. Slice clip at attacks splits the current clip reference at those positions in one project undo step and closes the editor. Edits in the local buffer must be saved/relinked first if the slices should use processed audio. Source positions round to nearest musical ticks; out-of-trim, edge and coalesced cuts are skipped. No usable cuts rejects. Left ID, source references and outside fades remain; inner explicit fades clear. Long explicit fades and existing automatic region fades can sound different after splitting. Timeline/source rounding may differ by one sample, so this is not sample-accurate timeline slicing. The no-explicit-fade aligned regression fixture remains bit-identical across slicing. No media files are written by slicing. + +## Validation and timing limits + +Every phase passed focused model and GUI checks before its implementation commit. +The integrated checks add allocation failure/cleanup, oversized sources, overflow, +clip ID rollback, exact selected samples, persistence, no-fade render comparison, +plugin fixtures, software JACK, Clang analysis, ASan/UBSan and install layouts. +The actual source editor and attack markers are shown in the +[screenshot gallery](../screenshots/README.md). + +Trim placement preserves alignment in musical ticks; independent source/timeline +conversion can differ by one sample. No sample-accurate timeline cuts or +click-free transitions are promised. Clip source data outside a local processing +selection remains intact; exported selections contain only their chosen frames. +Closing the editor discards unsaved local processing. Successful project Undo +keeps generated files for redo/history; only failed adoption removes its owned +new output. Rejecting sources above the editor's frame limit may temporarily +use the existing WAV reader's larger decode bound before rejecting them. diff --git a/docs/AUDIO_FILES.md b/docs/AUDIO_FILES.md index 605b7d8..1281258 100644 --- a/docs/AUDIO_FILES.md +++ b/docs/AUDIO_FILES.md @@ -216,3 +216,7 @@ seeks, shortened media tails, one-frame files, source/project limits, capacity rollback, duplication/fade inheritance, persistence/invalid metadata, undo, peak bins after source removal and byte-identical source preservation. GUI tests cover short-clip selection, shared previews, split/duplicate/delete and undo. + +Phases 69–79 add a modal audio source editor with frame selection, reversible +processing, selection export, copy adoption and transient slicing. See +[AUDIO_EDITOR.md](AUDIO_EDITOR.md) for commands, undo behavior and mono/size limits. diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index f5ddd7d..ff56455 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -95,3 +95,15 @@ Screenshots are refreshed, including the command palette. See WORKSPACE.md. Phase 38 adds dependency-free Soft Keys/Sub Bass instruments and Delay/Reverb effects with saved controls and automation. Choose instruments in track headers; insert effects on selected graph wires from Edit. See [BUILTIN_DEVICES.md](BUILTIN_DEVICES.md). + +## Phases 69–79: audio source editing + +Audio clips now open a modal waveform editor with native frame selection, +zoom, source statistics, nondestructive timeline trims, selection export and +save-copy adoption. Local one-step undo supports reverse, polarity inversion, +DC removal, linear/equal-power fades and gain/normalization. Silence boundaries, +zero-crossing snapping and amplitude attack markers support transactional clip +slicing. Originals are never overwritten; exported media remains available to +project undo/redo. Source editing uses the existing mono downmix and bounded +snapshots; timeline cuts round to musical ticks. See +[AUDIO_EDITOR.md](AUDIO_EDITOR.md) for exact behavior and remaining limits. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index b34ea52..988fde5 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1837,12 +1837,40 @@ Implemented: deterministic nearest zero-sample/sign-crossing boundary search wit Detect threshold attacks with a refractory gap, inspect their source positions, and split the original clip at representable interior source transients in one undoable transactional operation. Qualify integrated rollback, persistence, rendering and GUI behavior. ### Tasks and acceptance criteria -- [ ] Implement bounded C99 analysis/processing and accessible FLTK controls. -- [ ] Preserve source files, atomic error handling, history and callback safety. -- [ ] Pass meaningful core and GUI checks; document exact behavior and limits. +- [x] Implement bounded C99 analysis/processing and accessible FLTK controls. +- [x] Preserve source files, atomic error handling, history and callback safety. +- [x] Pass meaningful core and GUI checks; document exact behavior and limits. ### Implementation status -Planned. +Implemented: hysteretic amplitude attack detection with refractory gaps, source-frame markers and transactional nearest-tick slicing with one project undo step. Capacity failures preserve clips/IDs; core render comparison and persistence reload, GUI slicing/undo, allocation rollback, sanitizer, static-analysis, plugin/JACK and installation checks pass. See integrated validation and AUDIO_EDITOR.md for explicit mono, timing and detector limits. + + +### Integrated validation for Phases 69–79 + +Each of the eleven phases has its own tested implementation commit. The final +warning-enabled core/offline suite and focused sample-editor GUI checks cover +native frame selection, trim rounding, local processing/undo, selection export, +failed/successful copy adoption, project undo and slicing. The native-rate GUI +case trims through the actual editor callback using the fixture's 22.05 kHz rate. +Core regressions verify exact range samples, curve endpoints, residual DC, +silence/zero-crossing ties, threshold hysteresis, attack capacity, partial-slice +capacity rollback/ID preservation, an aligned no-fade render comparison and +saved-slice reload. Oversized source, overflow and gain-cap failures are explicit. + +Allocation-failure injection covers every processing operation, source loading, +WAV save cleanup and slicing preparation. Full GUI and LADSPA/CLAP/VST2/VST3 +effect/instrument fixtures, software JACK lifecycle, ASan/UBSan core and focused/ +full GUI, Clang analysis and both staged install layouts passed. Sanitizer GUI +runs retain only the existing system Fontconfig leak suppression. The public +sample API, docs and two real editor captures are included in the repository. + +No dependency or project-format migration was added (writer 16, reads 1–16). +All sample I/O, allocation and processing run on the control thread. The editor +uses the existing mono downmix, bounded snapshots and one local undo/redo step; +project trims/slices remain musical-tick based. Long-file streaming, stereo +source editing, audition/scrubbing, time stretching, spectral processing, +physical listening/hardware and arbitrary third-party plugins remain unqualified. +See [AUDIO_EDITOR.md](AUDIO_EDITOR.md) for precise workflows and limits. --- diff --git a/docs/USER_MANUAL.md b/docs/USER_MANUAL.md index 0ce457d..99f3f74 100644 --- a/docs/USER_MANUAL.md +++ b/docs/USER_MANUAL.md @@ -218,3 +218,9 @@ batch audio fades and static mixer A/B recall. See [MODERN_EDITING.md](MODERN_EDITING.md) for commands, scope and limitations. See [arrangement and composition workflows](COMPOSITION_WORKFLOWS.md) for markers, MIDI composition, normalization and portable media collection. + +Select an audio clip and open View / Sample editor (or double-click it) to inspect +source samples, choose native frame ranges, trim the clip or export a new WAV. +Processing and one-level local undo remain in the editor until Save full copy and +relink. See [AUDIO_EDITOR.md](AUDIO_EDITOR.md) for all sample tools, transient +slicing, musical-tick rounding and source preservation limits. diff --git a/docs/WORKSPACE.md b/docs/WORKSPACE.md index 4436111..c88fa90 100644 --- a/docs/WORKSPACE.md +++ b/docs/WORKSPACE.md @@ -239,3 +239,7 @@ batch audio fades and static mixer A/B recall. See Phases 58–68 add arrangement markers and sections, ripple edits, complete track duplication, MIDI splitting/consolidation and composition tools, peak normalization and portable media collection. See [COMPOSITION_WORKFLOWS.md](COMPOSITION_WORKFLOWS.md). + +Phases 69–79 add a modal audio source editor with frame selection, reversible +processing, selection export, copy adoption and transient slicing. See +[AUDIO_EDITOR.md](AUDIO_EDITOR.md) for commands, undo behavior and mono/size limits. diff --git a/include/xtc/xtc_sample.h b/include/xtc/xtc_sample.h index 5b6ec09..d484183 100644 --- a/include/xtc/xtc_sample.h +++ b/include/xtc/xtc_sample.h @@ -5,7 +5,8 @@ extern "C" { #endif /* Control-thread sample editor snapshots. Same WAV mono downmix as playback. - * <=4194304 source frames. No file writes or realtime use. Ranges are half-open, + * <=4194304 source frames. Only explicit save writes files; never use in realtime. + * Ranges are half-open, * nonempty native source frames; failures preserve outputs. */ #define XTC_SAMPLE_MAX_FRAMES 4194304U typedef struct xtc_sample xtc_sample; @@ -18,7 +19,8 @@ xtc_result xtc_sample_analyze(const xtc_sample *sample,size_t begin,size_t end,x typedef enum { XTC_SAMPLE_REVERSE, XTC_SAMPLE_INVERT, XTC_SAMPLE_REMOVE_DC, XTC_SAMPLE_FADE_IN, XTC_SAMPLE_FADE_OUT, XTC_SAMPLE_FADE_IN_POWER, XTC_SAMPLE_FADE_OUT_POWER, XTC_SAMPLE_GAIN, XTC_SAMPLE_NORMALIZE } xtc_sample_operation; /* Independent full-source result; only [begin,end) changes. Never mutates input. * amount: GAIN 0..16, NORMALIZE target 0threshold, minimum gap since last retained attack. threshold >0..1, + * gap 1..MAX_FRAMES; includes a loud range start. No spectral/beat inference. + * All outputs unchanged on NOT_FOUND/capacity/errors. positions capacity 1..128. */ +xtc_result xtc_sample_transients(const xtc_sample *sample,size_t begin,size_t end, + double threshold,size_t gap,size_t *positions,size_t capacity,size_t *count); +/* Sorted unique native source positions round to nearest timeline tick. Skip + * boundaries/out-of-trim and coalesced ticks. Split entire clip atomically, + * retaining left ID and outer explicit fades; no render auto-fades synthesized. + * Source/routing/mix unchanged, count unchanged on failure/no usable cuts. */ +xtc_result xtc_project_slice_source_frames(xtc_project *project,uint64_t clip,unsigned int rate, + const size_t *positions,size_t count,size_t *out_slices); /* Control-thread bounded mono float32 WAV save. Absolute path <512 bytes, - * NEW destination only. Failure/cancel publishes nothing and removes temporary. */ + * NEW destination only. Failure publishes nothing and removes temporary. */ xtc_result xtc_sample_write(const xtc_sample *sample,size_t begin,size_t end,const char *path); /* Select native source frame bounds inside the clip's current audible trim. * Start rounds up to a tick; end rounds down. Sub-tick empty ranges reject. diff --git a/screenshots/README.md b/screenshots/README.md index c1d0041..6555ab6 100644 --- a/screenshots/README.md +++ b/screenshots/README.md @@ -1,6 +1,7 @@ # xtc screenshots -All captures refreshed from the Phase 68 FLTK application on 2026-11-06. +The main gallery was refreshed after Phase 68 on 2026-11-06. Two additional +Phase 79 captures show the new sample editor and transient markers. These are actual rendered application windows and menus on a 1440 × 960 virtual X11 screen, without mockups, compositing or image edits. @@ -35,6 +36,15 @@ See [COMPOSITION_WORKFLOWS.md](../docs/COMPOSITION_WORKFLOWS.md) for precise behavior, limits and commands. The screenshots illustrate implemented workflows; they do not establish feature parity with other DAWs. +## Audio source editor (Phases 69–79) + +- [Frame selection, waveform, statistics and processing controls](sample-editor.png) +- [Detected source attacks and clip slicing controls](sample-transients.png) + +These captures show the actual modal editor with the repository pluck WAV. +Processing is staged locally; Save full copy and relink applies it to the project. +See [AUDIO_EDITOR.md](../docs/AUDIO_EDITOR.md) for limits and frame/tick rounding. + ## Refreshed application views All pre-existing images below were recaptured. Mixer playback meters come from @@ -102,3 +112,6 @@ prerequisites, a running JACK server, Xvfb (`xvfb-run`), ImageMagick (`import`) PNGs. All demonstration edits and collection outputs use an automatically removed temporary directory; no preferences are saved. It neither installs dependencies nor starts/reconfigures the audio server. + +Set `XTC_CAPTURE_SAMPLE_ONLY=1` for the capture tool (or the make target) to write +only the two sample-editor images while retaining the existing gallery. diff --git a/screenshots/sample-editor.png b/screenshots/sample-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..e4eebeebe15e0e38c1701b1336260a1a7f5b2ae6 GIT binary patch literal 59508 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 literal 0 HcmV?d00001 diff --git a/screenshots/sample-transients.png b/screenshots/sample-transients.png new file mode 100644 index 0000000000000000000000000000000000000000..13be3f812a20a7a4bd7be0f3d17a183cfbc68cb8 GIT binary patch literal 58453 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 literal 0 HcmV?d00001 diff --git a/src/audio/sample.c b/src/audio/sample.c index bd492ee..09b150e 100644 --- a/src/audio/sample.c +++ b/src/audio/sample.c @@ -1,5 +1,6 @@ #include "xtc/xtc_sample.h" #include "wave_internal.h" +#include "../project/project_internal.h" #include #include #include @@ -102,3 +103,34 @@ xtc_result xtc_sample_zero_crossing(const xtc_sample *s,size_t center,size_t rad if(best==SIZE_MAX)return XTC_ERR_NOT_FOUND; *out=best;return XTC_OK; } + +xtc_result xtc_sample_transients(const xtc_sample *s,size_t begin,size_t end, + double threshold,size_t gap,size_t *positions,size_t capacity,size_t *count) +{ + size_t i,n=0,found[XTC_SAMPLE_MAX_TRANSIENTS];int armed=1; + if(!range(s,begin,end)||!positions||!count||!capacity||capacity>XTC_SAMPLE_MAX_TRANSIENTS||!gap||gap>XTC_SAMPLE_MAX_FRAMES||!isfinite(threshold)||threshold<=0||threshold>1)return XTC_ERR_INVALID_ARGUMENT; + for(i=begin;iwave.samples[i]);if(value<=threshold*.25)armed=1; + if(armed && value>threshold){armed=0;if(!n||i-found[n-1]>=gap){if(n==capacity)return XTC_ERR_CAPACITY;found[n++]=i;}} + } + if(!n)return XTC_ERR_NOT_FOUND; + memcpy(positions,found,n*sizeof(*positions));*count=n;return XTC_OK; +} +xtc_result xtc_project_slice_source_frames(xtc_project *p,uint64_t id,unsigned int rate, + const size_t *positions,size_t count,size_t *out_slices) +{ + xtc_clip_info c;xtc_project *copy=NULL;size_t i,n=0;uint64_t current=id,last,factor,denom;xtc_result r; + if(!p||!positions||!out_slices||!rate||rate>768000||!count||count>XTC_SAMPLE_MAX_TRANSIENTS)return XTC_ERR_INVALID_ARGUMENT; + for(i=0;iXTC_SAMPLE_MAX_FRAMES||(i&&positions[i]<=positions[i-1]))return XTC_ERR_INVALID_ARGUMENT; + r=xtc_project_find_clip(p,id,&c);if(r!=XTC_OK)return r; + if(c.midi||!c.asset_path[0])return XTC_ERR_INVALID_STATE; + factor=(uint64_t)xtc_project_tempo(p)*XTC_TICKS_PER_QUARTER;denom=(uint64_t)rate*60000U;last=c.offset_tick; + r=xtc_project_clone(p,©);if(r!=XTC_OK)return r; + for(i=0;r==XTC_OK&&i=c.offset_tick+c.length_tick)continue; + r=xtc_project_split_audio(copy,current,c.start_tick+source-c.offset_tick,&next); + if(r==XTC_OK){current=next;last=source;++n;} + } + if(r==XTC_OK&&!n)r=XTC_ERR_NOT_FOUND; + if(r==XTC_OK){xtc_project old=*p;*p=*copy;*copy=old;*out_slices=n;} + xtc_project_destroy(copy);return r; +} diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp index b70b485..79fd00d 100644 --- a/src/gui/main_window.cpp +++ b/src/gui/main_window.cpp @@ -2615,6 +2615,15 @@ xtc_result MainWindow::adopt_sample_copy(uint64_t id,const xtc_sample *sample,co if(r!=XTC_OK){if(written)std::remove(path);xtc_project_destroy(candidate);return r;} sequencer_->select(clip.track_id,id);mark_dirty();return XTC_OK; } +xtc_result MainWindow::slice_sample_clip(uint64_t id,unsigned int rate,const std::vector &positions) +{ + auto r=before_arrangement_edit(this);if(r!=XTC_OK)return r; + xtc_project *candidate=nullptr;size_t count=0;r=xtc_project_clone(project_.get(),&candidate); + if(r==XTC_OK)r=xtc_project_slice_source_frames(candidate,id,rate,positions.data(),positions.size(),&count); + if(r==XTC_OK)r=install_project(candidate,false); + if(r!=XTC_OK){xtc_project_destroy(candidate);return r;} + xtc_clip_info clip{};xtc_project_find_clip(project_.get(),id,&clip);sequencer_->select(clip.track_id,id);mark_dirty();return XTC_OK; +} xtc_result MainWindow::trim_sample_clip(uint64_t id,unsigned int rate,size_t begin,size_t end) { auto r=before_arrangement_edit(this);if(r!=XTC_OK)return r; @@ -2631,13 +2640,16 @@ xtc_result MainWindow::open_sample_editor() if(r!=XTC_OK)return r; if(clip.midi||!clip.asset_path[0])return XTC_ERR_INVALID_STATE; xtc_sample *sample=nullptr;r=xtc_sample_load(clip.asset_path,&sample);if(r!=XTC_OK)return r; - SampleEditor editor(sample); + try { + SampleEditor editor(SampleEditor::Data(sample,xtc_sample_destroy)); uint64_t first=0,last=0;unsigned int rate;size_t frames;xtc_sample_info(sample,&rate,&frames); if(xtc_project_tick_to_sample(project_.get(),clip.offset_tick,rate,&first)==XTC_OK && xtc_project_tick_to_sample(project_.get(),clip.offset_tick+clip.length_tick,rate,&last)==XTC_OK) editor.select(static_cast(std::min(first,static_cast(frames))),static_cast(std::min(last,static_cast(frames)))); + editor.slice=[this,id=clip.id](unsigned int sr,const std::vector &positions){return slice_sample_clip(id,sr,positions);}; editor.adopt=[this,id=clip.id](const xtc_sample *data,const char *path){return adopt_sample_copy(id,data,path);}; editor.trim=[this,id=clip.id](unsigned int sr,size_t b,size_t e){return trim_sample_clip(id,sr,b,e);}; editor.run();return XTC_OK; + } catch(const std::bad_alloc &){return XTC_ERR_OUT_OF_MEMORY;} } void MainWindow::show_commands() { diff --git a/src/gui/main_window.hpp b/src/gui/main_window.hpp index 8f232be..52b2ae3 100644 --- a/src/gui/main_window.hpp +++ b/src/gui/main_window.hpp @@ -63,6 +63,7 @@ class MainWindow : public Fl_Double_Window { /* Control-thread plugin commands, transactional model adoption. */ xtc_result assign_instrument(uint64_t track, const char *path, unsigned int index); xtc_result adopt_sample_copy(uint64_t clip,const xtc_sample *sample,const char *path); + xtc_result slice_sample_clip(uint64_t clip,unsigned int rate,const std::vector &positions); xtc_result trim_sample_clip(uint64_t clip,unsigned int rate,size_t begin,size_t end); xtc_result open_sample_editor(); void export_audio(); diff --git a/src/gui/sample_editor.cpp b/src/gui/sample_editor.cpp index 70c634f..0f6f8c3 100644 --- a/src/gui/sample_editor.cpp +++ b/src/gui/sample_editor.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include class SampleCanvas : public Fl_Widget { SampleEditor &editor_;size_t anchor_=0; size_t frame(int px) const {size_t width=std::max(size_t(1),editor_.frames()/editor_.zoom());return std::min(editor_.frames()-1,editor_.origin()+static_cast(std::max(0,std::min(w()-1,px-x())))*width/static_cast(w()));} @@ -26,11 +28,13 @@ public: if(beditor_.begin()){fl_color(fl_rgb_color(45,76,80));fl_rectf(x()+px,y(),1,h());} xtc_sample_stats stats{};if(xtc_sample_analyze(editor_.sample(),b,e,&stats)==XTC_OK){fl_color(fl_rgb_color(95,204,182));int a=static_cast(std::max(-1.f,std::min(1.f,stats.maximum))*(h()/2-8));int z=static_cast(std::max(-1.f,std::min(1.f,stats.minimum))*(h()/2-8));fl_line(x()+px,y()+h()/2-a,x()+px,y()+h()/2-z);} } + fl_color(fl_rgb_color(220,164,92));for(size_t frame:editor_.attacks()){if(frame=width)continue;int px=x()+static_cast((frame-editor_.origin())*static_cast(w())/width);fl_line(px,y(),px,y()+h());} fl_color(xtc_ui::border());fl_line(x(),y()+h()/2,x()+w(),y()+h()/2);fl_pop_clip(); } }; -SampleEditor::SampleEditor(xtc_sample *sample):Fl_Double_Window(1100,650,"xtc — Sample editor"),sample_(sample,xtc_sample_destroy) +SampleEditor::SampleEditor(Data sample):Fl_Double_Window(1100,650,"xtc — Sample editor"),sample_(std::move(sample)) { + if(!sample_)throw std::invalid_argument("Sample editor requires a loaded source"); xtc_sample_info(sample_.get(),&rate_,&frames_);end_=frames_;set_modal();Fl_Group::begin(); auto *hint=new Fl_Box(16,12,1068,34,"Source frames / mono downmix — drag a range; numeric endpoints are exclusive. Original file unchanged.");hint->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); begin_input_=new Fl_Value_Input(90,58,140,28,"Start frame");end_input_=new Fl_Value_Input(330,58,140,28,"End frame");origin_input_=new Fl_Value_Input(580,58,140,28,"View start"); @@ -48,13 +52,15 @@ SampleEditor::SampleEditor(xtc_sample *sample):Fl_Double_Window(1100,650,"xtc auto *gain=new Fl_Button(704,562,160,30,"Gain / normalize...");gain->callback([](Fl_Widget *,void *c){auto *e=static_cast(c);const char *text=fl_input("Mode (0 gain, 1 normalize), linear gain 0..16 or target peak >0..1","1 0.9");if(!text)return;unsigned int mode;double value;char extra;if(std::sscanf(text,"%u %lf %c",&mode,&value,&extra)!=2||mode>1){fl_alert("Enter mode and linear value.");return;}auto r=e->process(mode ? XTC_SAMPLE_NORMALIZE : XTC_SAMPLE_GAIN,value);if(r!=XTC_OK)fl_alert("Gain edit failed: %s",xtc_result_string(r));},this); auto *silence=new Fl_Button(876,562,200,30,"Select audible bounds...");silence->callback([](Fl_Widget *,void *c){auto *e=static_cast(c);const char *text=fl_input("Silence threshold dBFS (-120..0), padding ms (0..10000)","-60 2");if(!text)return;double db,ms;char extra;if(std::sscanf(text,"%lf %lf %c",&db,&ms,&extra)!=2||!std::isfinite(db)||!std::isfinite(ms)||db< -120||db>0||ms<0||ms>10000){fl_alert("Enter a threshold and padding within the shown bounds.");return;}auto r=e->select_audible(std::pow(10.,db/20),static_cast(std::min(static_cast(e->frames_),ms*e->rate_/1000)));if(r!=XTC_OK)fl_alert("Audible bounds not found: %s",xtc_result_string(r));},this); auto *zero=new Fl_Button(16,604,180,30,"Snap to zero crossings...");zero->callback([](Fl_Widget *,void *c){auto *e=static_cast(c);const char *text=fl_input("Search radius in source frames (0..65536)","256");if(!text)return;unsigned int radius;char extra;if(std::sscanf(text,"%u %c",&radius,&extra)!=1||radius>65536){fl_alert("Enter a radius 0..65536.");return;}auto r=e->snap_zero_crossings(radius);if(r!=XTC_OK)fl_alert("Selection unchanged: %s",xtc_result_string(r));},this); + auto *attacks=new Fl_Button(210,604,180,30,"Detect attacks...");attacks->callback([](Fl_Widget *,void *c){auto *e=static_cast(c);const char *text=fl_input("Attack threshold dBFS (-120..0), minimum gap ms (>0..10000)","-12 80");if(!text)return;double db,ms;char extra;if(std::sscanf(text,"%lf %lf %c",&db,&ms,&extra)!=2||!std::isfinite(db)||!std::isfinite(ms)||db< -120||db>0||ms<=0||ms>10000){fl_alert("Enter a threshold and positive minimum gap.");return;}auto r=e->detect_attacks(std::pow(10.,db/20),std::max(size_t(1),static_cast(std::min(static_cast(e->frames_),ms*e->rate_/1000))));if(r!=XTC_OK)fl_alert("Attack detection failed: %s",xtc_result_string(r));},this); + auto *slices=new Fl_Button(404,604,180,30,"Slice clip at attacks");slices->callback([](Fl_Widget *,void *c){auto r=static_cast(c)->slice_clip();if(r!=XTC_OK)fl_alert("Clip unchanged: %s",xtc_result_string(r));else static_cast(c)->hide();},this); auto *undo=new Fl_Button(850,604,110,30,"Undo / redo");undo->callback([](Fl_Widget *,void *c){auto r=static_cast(c)->undo_sample();if(r!=XTC_OK)fl_alert("No local sample edit to undo.");},this); auto *close=new Fl_Button(970,604,110,30,"Close");close->callback([](Fl_Widget *,void *c){static_cast(c)->hide();},this);callback([](Fl_Widget *,void *c){static_cast(c)->hide();},this); Fl_Group::end();xtc_ui::style(this);refresh(); } -xtc_result SampleEditor::select(size_t b,size_t e){if(b>=e||e>frames_)return XTC_ERR_INVALID_ARGUMENT;begin_=b;end_=e;refresh();return XTC_OK;} +xtc_result SampleEditor::select(size_t b,size_t e){if(b>=e||e>frames_)return XTC_ERR_INVALID_ARGUMENT;if(begin_!=b||end_!=e)attacks_.clear();begin_=b;end_=e;refresh();return XTC_OK;} xtc_result SampleEditor::view(size_t b,unsigned int zoom){if(b>=frames_||!zoom||zoom>64)return XTC_ERR_INVALID_ARGUMENT;origin_=b;zoom_=zoom;refresh();return XTC_OK;} -void SampleEditor::refresh(){begin_input_->value(static_cast(begin_));end_input_->value(static_cast(end_));origin_input_->value(static_cast(origin_));xtc_sample_stats s{};xtc_sample_analyze(sample_.get(),begin_,end_,&s);char text[256];std::snprintf(text,sizeof(text),"%u Hz / %zu source frames / selection %zu..%zu (%0.6f s) / zoom %ux\nMin %.6f Max %.6f RMS %.6f DC %.6f",rate_,frames_,begin_,end_,static_cast(end_-begin_)/rate_,zoom_,s.minimum,s.maximum,s.rms,s.mean);stats_->copy_label(text);canvas_->redraw();} +void SampleEditor::refresh(){begin_input_->value(static_cast(begin_));end_input_->value(static_cast(end_));origin_input_->value(static_cast(origin_));xtc_sample_stats s{};xtc_sample_analyze(sample_.get(),begin_,end_,&s);char text[256];std::snprintf(text,sizeof(text),"%u Hz / %zu source frames / selection %zu..%zu (%0.6f s) / zoom %ux\nMin %.6f Max %.6f RMS %.6f DC %.6f",rate_,frames_,begin_,end_,static_cast(end_-begin_)/rate_,zoom_,s.minimum,s.maximum,s.rms,s.mean);stats_->copy_label(text);std::string attacks="Detected source frames (nearest tick used for slicing):";for(size_t frame:attacks_)attacks+=" "+std::to_string(frame);stats_->copy_tooltip(attacks.c_str());canvas_->redraw();} void SampleEditor::run(){show();while(shown())Fl::wait();} xtc_result SampleEditor::trim_clip(){return trim ? trim(rate_,begin_,end_) : XTC_ERR_INVALID_STATE;} @@ -65,10 +71,13 @@ xtc_result SampleEditor::export_selection(const char *path){return xtc_sample_wr xtc_result SampleEditor::process(xtc_sample_operation operation,double amount) { xtc_sample *next=nullptr;auto r=xtc_sample_process(sample_.get(),begin_,end_,operation,amount,&next);if(r!=XTC_OK)return r; - previous_=std::move(sample_);sample_.reset(next);copy_label("xtc — Sample editor / local sample changes; save a copy to keep");refresh();return XTC_OK; + previous_=std::move(sample_);sample_.reset(next);attacks_.clear();copy_label("xtc — Sample editor / local sample changes; save a copy to keep");refresh();return XTC_OK; } -xtc_result SampleEditor::undo_sample(){if(!previous_)return XTC_ERR_NOT_FOUND;sample_.swap(previous_);refresh();return XTC_OK;} +xtc_result SampleEditor::undo_sample(){if(!previous_)return XTC_ERR_NOT_FOUND;sample_.swap(previous_);attacks_.clear();refresh();return XTC_OK;} xtc_result SampleEditor::select_audible(double threshold,size_t padding){size_t b=0,e=0;auto r=xtc_sample_audible_bounds(sample_.get(),begin_,end_,threshold,padding,&b,&e);return r==XTC_OK ? select(b,e) : r;} xtc_result SampleEditor::snap_zero_crossings(size_t radius){size_t b=0,e=0;auto r=xtc_sample_zero_crossing(sample_.get(),begin_,radius,&b);if(r==XTC_OK)r=xtc_sample_zero_crossing(sample_.get(),end_,radius,&e);return r==XTC_OK ? select(b,e) : r;} + +xtc_result SampleEditor::detect_attacks(double threshold,size_t gap){size_t positions[XTC_SAMPLE_MAX_TRANSIENTS],count=0;auto r=xtc_sample_transients(sample_.get(),begin_,end_,threshold,gap,positions,XTC_SAMPLE_MAX_TRANSIENTS,&count);if(r!=XTC_OK)return r;try{std::vector next(positions,positions+count);attacks_.swap(next);}catch(const std::bad_alloc &){return XTC_ERR_OUT_OF_MEMORY;}refresh();return XTC_OK;} +xtc_result SampleEditor::slice_clip(){return slice&&!attacks_.empty() ? slice(rate_,attacks_) : XTC_ERR_INVALID_STATE;} diff --git a/src/gui/sample_editor.hpp b/src/gui/sample_editor.hpp index c52dc3b..d8da483 100644 --- a/src/gui/sample_editor.hpp +++ b/src/gui/sample_editor.hpp @@ -4,13 +4,15 @@ #include #include #include +#include class Fl_Value_Input; class Fl_Box; class SampleCanvas; class SampleEditor : public Fl_Double_Window { public: /* Takes ownership of loaded snapshot. Modal edits never touch audio callbacks. */ - explicit SampleEditor(xtc_sample *sample); + using Data=std::unique_ptr; + explicit SampleEditor(Data sample); std::function trim; xtc_result trim_clip(); std::function adopt; @@ -20,6 +22,10 @@ public: xtc_result undo_sample(); xtc_result select_audible(double threshold,size_t padding); xtc_result snap_zero_crossings(size_t radius); + std::function &)> slice; + xtc_result detect_attacks(double threshold,size_t gap); + xtc_result slice_clip(); + const std::vector &attacks() const {return attacks_;} void run(); xtc_result select(size_t begin,size_t end); xtc_result view(size_t begin,unsigned int zoom); @@ -31,6 +37,7 @@ public: private: std::unique_ptr sample_{nullptr,xtc_sample_destroy}; std::unique_ptr previous_{nullptr,xtc_sample_destroy}; + std::vector attacks_; size_t frames_=0,begin_=0,end_=0,origin_=0;unsigned int rate_=0,zoom_=1; Fl_Value_Input *begin_input_,*end_input_,*origin_input_;Fl_Box *stats_;SampleCanvas *canvas_; }; diff --git a/tests/integration/test_gui.cpp b/tests/integration/test_gui.cpp index 5b0591b..5a76a80 100644 --- a/tests/integration/test_gui.cpp +++ b/tests/integration/test_gui.cpp @@ -199,17 +199,20 @@ static int sample_editor_tests() CHECK(e->process(XTC_SAMPLE_FADE_IN_POWER)==XTC_OK);CHECK(e->undo_sample()==XTC_OK); CHECK(e->process(XTC_SAMPLE_REMOVE_DC)==XTC_OK);CHECK(e->undo_sample()==XTC_OK); CHECK(e->process(XTC_SAMPLE_INVERT)==XTC_OK);CHECK(e->undo_sample()==XTC_OK); - CHECK(e->process(XTC_SAMPLE_REVERSE)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);CHECK(xtc_sample_read(e->sample(),10,&after)==XTC_OK && before==after);CHECK(e->undo_sample()==XTC_OK);CHECK(e->select(100,10)==XTC_ERR_INVALID_ARGUMENT);CHECK(e->view(10,8)==XTC_OK);size_t b=e->begin(),z=e->end();CHECK(e->select_audible(1,0)==XTC_ERR_NOT_FOUND && e->begin()==b && e->end()==z);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->select_audible(.01,2)==XTC_OK);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->snap_zero_crossings(65536)==XTC_OK);CHECK(e->view(e->frames(),1)==XTC_ERR_INVALID_ARGUMENT);e->hide();}},nullptr); + CHECK(e->process(XTC_SAMPLE_REVERSE)==XTC_OK);CHECK(e->undo_sample()==XTC_OK);CHECK(xtc_sample_read(e->sample(),10,&after)==XTC_OK && before==after);CHECK(e->undo_sample()==XTC_OK);CHECK(e->select(100,10)==XTC_ERR_INVALID_ARGUMENT);CHECK(e->view(10,8)==XTC_OK);size_t b=e->begin(),z=e->end();CHECK(e->select_audible(1,0)==XTC_ERR_NOT_FOUND && e->begin()==b && e->end()==z);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->select_audible(.01,2)==XTC_OK);CHECK(e->select(0,e->frames())==XTC_OK);CHECK(e->snap_zero_crossings(65536)==XTC_OK);CHECK(e->detect_attacks(.1,2400)==XTC_OK && !e->attacks().empty());CHECK(e->view(e->frames(),1)==XTC_ERR_INVALID_ARGUMENT);unsigned int rate=0;size_t frames=0;CHECK(xtc_sample_info(e->sample(),&rate,&frames)==XTC_OK);CHECK(e->select(rate/10,rate*4/10)==XTC_OK);CHECK(e->trim_clip()==XTC_OK);e->hide();}},nullptr); CHECK(window.open_sample_editor()==XTC_OK);CHECK(s->selected_clip()!=UINT64_MAX); - uint64_t id=s->selected_clip();CHECK(window.trim_sample_clip(id,48000,2400,12000)==XTC_OK); - xtc_clip_info clip{};CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && clip.offset_tick==96 && clip.length_tick==384); + uint64_t id=s->selected_clip(); + xtc_clip_info clip{};CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && clip.offset_tick==192 && clip.length_tick==576); CHECK(window.undo()==XTC_OK);CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && clip.offset_tick==0); {xtc_sample *data=nullptr;CHECK(xtc_sample_load(path,&data)==XTC_OK);std::string copy="/tmp/xtc-sample-gui-"+std::to_string(getpid())+".wav"; submit_result=XTC_ERR_OUT_OF_MEMORY;CHECK(window.adopt_sample_copy(id,data,copy.c_str())==XTC_ERR_OUT_OF_MEMORY && access(copy.c_str(),F_OK)!=0);submit_result=XTC_OK; CHECK(window.adopt_sample_copy(id,data,copy.c_str())==XTC_OK);CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && !strcmp(clip.asset_path,copy.c_str())); CHECK(window.undo()==XTC_OK);CHECK(xtc_project_find_clip(s->project(),id,&clip)==XTC_OK && !strcmp(clip.asset_path,path)); xtc_sample_destroy(data);CHECK(unlink(copy.c_str())==0);} - window.do_callback();return failures ? 1 : 0; + CHECK(window.slice_sample_clip(id,22050,{2400,4800,7200})==XTC_OK); + size_t tracks=0,clips=0;CHECK(xtc_project_get_counts(s->project(),&tracks,&clips)==XTC_OK && clips==4); + CHECK(window.undo()==XTC_OK);CHECK(xtc_project_get_counts(s->project(),&tracks,&clips)==XTC_OK && clips==1); + window.do_callback();std::puts("Sample editor GUI selection/processing/adoption/slicing/undo passed.");return failures ? 1 : 0; } int main(int argc, char **argv) { diff --git a/tests/integration/test_reliability.c b/tests/integration/test_reliability.c index ebc7c3d..3ff55b4 100644 --- a/tests/integration/test_reliability.c +++ b/tests/integration/test_reliability.c @@ -7,6 +7,8 @@ #include "xtc/xtc_plugin.h" #include "xtc/xtc_editing.h" #include "xtc/xtc_audio.h" +#include "xtc/xtc_sample.h" +#include #include #include #include @@ -268,8 +270,33 @@ static void composition_failures(void) } xtc_project_destroy(p);assert(rmdir(root)==0); } +static void sample_failures(void) +{ + xtc_sample *source=NULL;xtc_project *p=NULL;char path[4096],root[]="/tmp/xtc-sample-fail-XXXXXX",dest[256];uint64_t t,id;int op,failure; + assert(getcwd(path,sizeof(path)));assert(strlen(path)+40d_name,".")||!strcmp(entry->d_name,".."));assert(closedir(d)==0);} + xtc_sample_destroy(output);xtc_project_destroy(copy);if(succeeded)break; + }assert(succeeded); + } + xtc_sample_destroy(source);xtc_project_destroy(p);assert(rmdir(root)==0); +} int main(void) { + sample_failures(); composition_failures(); modern_edit_failures(); builtin_failures(); diff --git a/tests/unit/test_sample.c b/tests/unit/test_sample.c index af91b92..809fcab 100644 --- a/tests/unit/test_sample.c +++ b/tests/unit/test_sample.c @@ -2,9 +2,11 @@ #include "xtc/xtc_sample.h" #include #include +#include #include #include #include +#include int main(void) { char root[]="/tmp/xtc-sample-test-XXXXXX",path[256];float values[]={0,.25f,-.5f,.75f,0,0,.5f,-.25f}; @@ -64,5 +66,33 @@ int main(void) assert(xtc_sample_zero_crossing(s,6,1,&crossing)==XTC_OK && crossing==5); assert(xtc_sample_zero_crossing(s,8,1,&crossing)==XTC_OK && crossing==7); assert(xtc_sample_zero_crossing(s,0,65537,&crossing)==XTC_ERR_INVALID_ARGUMENT && crossing==7);} + {size_t positions[128]={999},count=999;assert(xtc_sample_transients(s,0,8,.4,1,positions,128,&count)==XTC_OK && count==2 && positions[0]==2 && positions[1]==6); + count=999;positions[0]=999;assert(xtc_sample_transients(s,0,8,.4,1,positions,1,&count)==XTC_ERR_CAPACITY && count==999 && positions[0]==999); + assert(xtc_sample_transients(s,0,8,.4,5,positions,128,&count)==XTC_OK && count==1 && positions[0]==2);} + {xtc_project *p=NULL,*q=NULL;xtc_audio_plan *a=NULL,*b=NULL;uint64_t t,c;float before[128],after[128];size_t cuts[]={0,4,8},made=999,tracks=0,clips=0;char song[256]; + assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Audio",&t)==XTC_OK && xtc_project_import_audio(p,t,path,10,&c)==XTC_OK); + assert(xtc_audio_plan_create(p,8000,&a)==XTC_OK && xtc_audio_plan_render(a,0,before,128)==XTC_OK); + assert(xtc_project_slice_source_frames(p,c,8000,cuts,3,&made)==XTC_OK && made==1); + assert(xtc_audio_plan_create(p,8000,&b)==XTC_OK && xtc_audio_plan_render(b,0,after,128)==XTC_OK && !memcmp(before,after,sizeof(before))); + snprintf(song,sizeof(song),"%s/slices.xtc",root);assert(xtc_project_save(p,song)==XTC_OK && xtc_project_create(&q)==XTC_OK && xtc_project_load(q,song)==XTC_OK); + assert(xtc_project_get_counts(q,&tracks,&clips)==XTC_OK && clips==2);assert(unlink(song)==0); + xtc_audio_plan_destroy(a);xtc_audio_plan_destroy(b);xtc_project_destroy(p);xtc_project_destroy(q);} + {xtc_project *p=NULL;uint64_t t,c,extra;size_t cuts[]={1000,2000},made=999,tracks,clips; + assert(xtc_project_create(&p)==XTC_OK && xtc_project_add_track(p,"Full",&t)==XTC_OK && xtc_project_add_clip(p,t,"Source",0,960,&c)==XTC_OK && xtc_project_set_clip_asset(p,c,path)==XTC_OK); + for(size_t j=1;j>(j*8));header[40+j]=(unsigned char)(count>>(j*8));} + output=fopen(big,"wb");assert(output && fwrite(header,1,44,output)==44 && fflush(output)==0 && ftruncate(fileno(output),(off_t)count+44)==0 && fclose(output)==0); + assert(xtc_sample_load(big,&q)==XTC_ERR_CAPACITY && q==NULL);assert(unlink(big)==0);} + {char edge[256];float large=FLT_MAX;xtc_sample *q=NULL,*result=NULL;snprintf(edge,sizeof(edge),"%s/edge.wav",root); + assert(xtc_recorder_create(edge,8000,1,&rec)==XTC_OK);xtc_recorder_push(rec,&large,1);assert(xtc_recorder_finish(rec)==XTC_OK);xtc_recorder_destroy(rec); + assert(xtc_sample_load(edge,&q)==XTC_OK && xtc_sample_process(q,0,1,XTC_SAMPLE_GAIN,2,&result)==XTC_ERR_CAPACITY && result==NULL); + assert(xtc_sample_read(q,0,&v)==XTC_OK && v==FLT_MAX);xtc_sample_destroy(q);assert(unlink(edge)==0); + large=.001f;assert(xtc_recorder_create(edge,8000,1,&rec)==XTC_OK);xtc_recorder_push(rec,&large,1);assert(xtc_recorder_finish(rec)==XTC_OK);xtc_recorder_destroy(rec); + assert(xtc_sample_load(edge,&q)==XTC_OK && xtc_sample_process(q,0,1,XTC_SAMPLE_NORMALIZE,1,&result)==XTC_ERR_CAPACITY && result==NULL);xtc_sample_destroy(q);assert(unlink(edge)==0);} xtc_sample_destroy(s);assert(unlink(path)==0 && rmdir(root)==0);puts("Sample editor core tests passed.");return 0; } diff --git a/tools/capture_screenshots.cpp b/tools/capture_screenshots.cpp index aad8544..0f1cc41 100644 --- a/tools/capture_screenshots.cpp +++ b/tools/capture_screenshots.cpp @@ -1,5 +1,6 @@ /* Optional documentation tool: real FLTK widgets and real backend, isolated data. */ #include "../src/gui/main_window.hpp" +#include "../src/gui/sample_editor.hpp" #include "../src/gui/sequencer_widget.hpp" #include "../src/gui/mixer_widget.hpp" #include "../src/gui/piano_roll.hpp" @@ -29,9 +30,10 @@ void pump() {auto end=std::chrono::steady_clock::now()+std::chrono::milliseconds template T *first(Fl_Group &g) {for(int i=0;i(c))return t;if(auto *n=dynamic_cast(c))if(auto *t=first(*n))return t;}return nullptr;} Fl_Widget *named(Fl_Group &g,const char *label) {for(int i=0;ilabel()&&!strcmp(c->label(),label))return c;if(auto *n=dynamic_cast(c))if(auto *w=named(*n,label))return w;}return nullptr;} void tab(const char *label) {auto *page=named(*main_window,label);if(!page)throw std::runtime_error(label);auto *tabs=dynamic_cast(page->parent());if(!tabs)throw std::runtime_error("Tab parent");tabs->value(page);tabs->redraw();pump();} -void capture(const char *name) {Fl::flush();pump();std::string command="import -window root '"+destination+"/"+name+".png'";if(system(command.c_str()))throw std::runtime_error("ImageMagick capture failed");std::printf("Captured %s\n",name);std::fflush(stdout);} +void capture(const char *name) {if(std::getenv("XTC_CAPTURE_SAMPLE_ONLY")&&std::strncmp(name,"sample-",7))return;Fl::flush();pump();std::string command="import -window root '"+destination+"/"+name+".png'";if(system(command.c_str()))throw std::runtime_error("ImageMagick capture failed");std::printf("Captured %s\n",name);std::fflush(stdout);} struct Modal {const char *name;const char *page;}; -void modal_capture(void *data) {auto *job=static_cast(data);auto *w=Fl::modal();if(!w||w==main_window)throw std::runtime_error("Expected a modal dialog");if(job->page){auto *tabs=first(*w);auto *page=named(*w,job->page);if(!tabs||!page)throw std::runtime_error(job->page);tabs->value(page);tabs->redraw();}capture(job->name);auto *cancel=named(*w,"Cancel");if(!cancel)cancel=named(*w,"Close");if(!cancel)cancel=named(*w,"OK");if(cancel)cancel->do_callback();else w->do_callback();} +void modal_capture(void *data) {auto *job=static_cast(data);auto *w=Fl::modal();if(!w||w==main_window)throw std::runtime_error("Expected a modal dialog");if(auto *editor=dynamic_cast(w)){editor->select(2400,std::min(size_t(12000),editor->frames()));if(!strcmp(job->name,"sample-transients")){editor->select(0,editor->frames());check(editor->detect_attacks(.05,2400));}} +if(job->page){auto *tabs=first(*w);auto *page=named(*w,job->page);if(!tabs||!page)throw std::runtime_error(job->page);tabs->value(page);tabs->redraw();}capture(job->name);auto *cancel=named(*w,"Cancel");if(!cancel)cancel=named(*w,"Close");if(!cancel)cancel=named(*w,"OK");if(cancel)cancel->do_callback();else w->do_callback();} void dialog(const char *name,std::function action,const char *page=nullptr) {Modal job{name,page};Fl::add_timeout(.3,modal_capture,&job);action();Fl::remove_timeout(modal_capture,&job);pump();} void menu(const char *path) {auto *bar=first(*main_window);const auto *item=bar->find_item(path);if(!item)throw std::runtime_error(path);bar->picked(item);} void piano_view() { @@ -59,6 +61,12 @@ int main(int argc,char **argv) { MainWindow window(false,"");main_window=&window;window.resize(0,0,1400,900);window.show();check(window.open_project(project.c_str()));pump(); auto *s=first(window);if(!s)throw std::runtime_error("Sequencer missing"); auto reset=[&](){window.reset_layout();check(window.open_project(project.c_str()));window.resize(0,20,1400,900);tab("Sequencer");s->select(0,0);s->position(0);check(window.set_loop(3840,7680,true));window.fit_song();pump();}; + if(std::getenv("XTC_CAPTURE_SAMPLE_ONLY")) { + reset();char source[4096];if(!realpath("examples/projects/original-pluck.wav",source))throw std::runtime_error("Missing sample WAV"); + check(window.create_track(false));check(window.import_audio(source)); + dialog("sample-editor",[&]{check(window.open_sample_editor());});dialog("sample-transients",[&]{check(window.open_sample_editor());}); + window.do_callback();std::puts("Sample-editor captures completed.");return 0; + } reset();capture("overview");capture("sequencer-loop");capture("arrangement-markers"); s->position(4800);check(window.loop_section());capture("section-navigation"); dialog("marker-edit",[&]{s->marker_dialog();}); @@ -82,6 +90,7 @@ int main(int argc,char **argv) { window.detach_transport(true);pump();capture("transport-detached");window.detach_mixer(true);pump();capture("workspace-detached");capture("mixer-detached");reset(); window.detach_editor(0,true);pump();capture("sequencer-detached");reset();tab("Modular Graph");window.detach_editor(1,true);pump();capture("graph-detached");reset(); char wave[4096];if(!realpath("examples/projects/original-pluck.wav",wave))throw std::runtime_error("Missing WAV");check(window.create_track(false));check(window.import_audio(wave));check(s->set_zoom(192));check(s->audio_properties(.8f,240,480));pump();capture("sequencer-audio-waveform"); + dialog("sample-editor",[&]{check(window.open_sample_editor());});dialog("sample-transients",[&]{check(window.open_sample_editor());}); dialog("audio-clip-properties",[&]{s->audio_properties_dialog();});dialog("audio-normalization",[&]{s->normalize_dialog();});check(s->normalize_audio(.25f));capture("audio-normalization-result"); dialog("project-collection",[&]{menu("File/Collect project media...");});check(window.collect_project((root+"/portable").c_str())); dialog("loop-range",[&]{button("Loop range...");});dialog("midi-controller-mapping",[&]{menu("Audio/MIDI controller mapping");});dialog("about",[&]{menu("Help/About");});