AUDIO
Source snapshot · 12 October 2026

Main-thread UI and device owner

examples/tutorials/src/ui/mod.rs · 914 source lines

Read the chapters in source order. Select a numbered source line to expand its explanation; the line numbers and code match this snapshot exactly.

cargo run -p ravet-examples --bin midi-synth --locked -- --ui-test target/examples-ui-guide
Chapters
  1. Import the native and control-thread services lines 1–15
  2. Build an explicit device-capability record lines 16–61
  3. Validate the requested output configuration lines 62–102
  4. Validate channel-pair selection lines 103–121
  5. Own output, duplex or test rendering lines 122–147
  6. Keep UI state outside the callback lines 148–165
  7. Initialize and explicitly refresh inventories lines 166–238
  8. Stop and release native ownership lines 239–251
  9. Report a full control queue lines 252–263
  10. Start from validated settings lines 264–346
  11. Choose output-only or clocked duplex ownership lines 347–385
  12. Send the prepared patch before playback lines 386–414
  13. Dispatch and validate page messages lines 415–462
  14. Validate short MIDI at the bridge lines 463–475
  15. Inspect exact MIDI 2.0 fields lines 476–527
  16. Handle explicit device and mode actions lines 528–552
  17. Render a hardware-free UI probe lines 553–558
  18. Convert coherent words into presentation JSON lines 559–577
  19. Clean up and implement the native bridge lines 578–602
  20. Open the window with the default I/O settings lines 603–637
  21. Exercise all modes without device I/O lines 638–783
  22. Check uniform design-canvas scaling lines 784–821
  23. Verify settings opt-out and default behavior lines 822–870
  24. Check keyboard and numeric control gestures lines 871–892
  25. Check pointer-held notes and cancellation lines 893–914

Import the native and control-thread services

This module owns JSON, device selection, stream lifetime and the native window on the main thread. audio is the separate prepared owner. Rc/RefCell are for main-thread shared UI state; Arc hands coherent telemetry to the audio owner.

1//! macOS example window, main-thread UI/device ownership and bounded audio handoff.

Source note: macOS example window, main-thread UI/device ownership and bounded audio handoff.

Link to line 1
2mod audio;

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 2
3use crate::synth::{DEFAULT_VALUES, RANGES, SynthPatch};

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 3
4use audio::{Audio, Command, MAX_FRAMES, QUEUE, Routing, Shared};

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 4
5use cpal::traits::DeviceTrait;

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 5
6use ravet_device::{

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 6
7 ClockedDuplexOptions, ClockedDuplexStream, OutputStream, PreparedOutput, cpal,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 7
8 open_clocked_duplex, open_output,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 8
9};

Close the surrounding scope, value or argument list in “Import the native and control-thread services”.

Link to line 9
10use ravet_foundation::{Midi2Kind, Midi2Message, MidiMessage};

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 10
11use ravet_webview::{Callbacks, StandaloneOptions, StandaloneWindow};

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 11
12use serde_json::{Value, json};

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 12
13use std::{cell::RefCell, rc::Rc, sync::Arc};

Bring these module/type names into scope for “Import the native and control-thread services”; the surrounding chapter explains their responsibilities.

Link to line 13
14type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

Define a type alias so the following functions can use this complete result/error type by its shorter name.

Link to line 14
15

Blank line separating the surrounding statements.

Link to line 15

Build an explicit device-capability record

Filter default-channel f32 ranges. Form common candidate rates plus the device default, sort/deduplicate and retain supported values in 8–192 kHz. Keep candidate buffers supported by a range, including unknown negotiation. Report channels capped at 64. These labels are capabilities, not latency measurements.

16fn device_info(

Define device_info. Filter default-channel f32 ranges. Form common candidate rates plus the device default, sort/deduplicate and retain supported values in 8–192 kHz. Keep candidate buffers supported by a range, including unknown negotiation. Report channels capped at 64. These labels are capabilities, not latency measurements.

Link to line 16
17 id: String,

Define or initialize id with the displayed type/value. Its ownership and use are described in “Build an explicit device-capability record”.

Link to line 17
18 name: String,

Define or initialize name with the displayed type/value. Its ownership and use are described in “Build an explicit device-capability record”.

Link to line 18
19 ranges: Vec<cpal::SupportedStreamConfigRange>,

Define or initialize ranges with the displayed type/value. Its ownership and use are described in “Build an explicit device-capability record”.

Link to line 19
20 default: cpal::SupportedStreamConfig,

Define or initialize default with the displayed type/value. Its ownership and use are described in “Build an explicit device-capability record”.

Link to line 20
21) -> Result<Value> {

Complete the function’s parameter list and specify the return type. A Result preserves the explicit success/error distinction.

Link to line 21
22 let channels = default.channels();

Bind channels to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 22
23 let ranges = ranges

Bind ranges to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 23
24 .into_iter()

Consume the collection into an owning iterator; its elements are moved into the following transformation.

Link to line 24
25 .filter(|r| r.sample_format() == cpal::SampleFormat::F32 && r.channels() == channels)

Keep only entries for which this predicate returns true.

Link to line 25
26 .collect::<Vec<_>>();

Collect the iterator into an owned Vec. This may allocate and belongs to setup, offline fixtures or the main-thread UI path.

Link to line 26
27 let mut rates = vec![

Bind mutable rates to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 27
28 8000,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 28
29 11025,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 29
30 16000,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 30
31 22050,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 31
32 32000,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 32
33 44100,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 33
34 48000,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 34
35 88200,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 35
36 96000,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 36
37 176400,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 37
38 192000,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 38
39 default.sample_rate(),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Build an explicit device-capability record” explanation above.

Link to line 39
40 ];

Close the surrounding scope, value or argument list in “Build an explicit device-capability record”.

Link to line 40
41 rates.sort_unstable();

Sort the candidate values in place; ordering of equal entries is irrelevant here.

Link to line 41
42 rates.dedup();

Remove adjacent duplicates after sorting so each candidate appears once.

Link to line 42
43 rates.retain(|rate| {

Filter this existing Vec in place by the supplied supported-value predicate.

Link to line 43
44 (8000..=192000).contains(rate)

Assign the computed value to (8000... The right-hand expression supplies the new value for this step.

Link to line 44
45 && ranges

Require this additional condition as well; the combined check succeeds only when all conditions are true.

Link to line 45
46 .iter()

Borrow collection entries for iteration without moving or copying the whole collection.

Link to line 46
47 .any(|r| r.min_sample_rate() <= *rate && *rate <= r.max_sample_rate())

Return true if any entry satisfies this predicate; stop at the first match.

Link to line 47
48 });

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 48
49 let buffers = [32, 64, 128, 256, 512, 1024, 2048, 4096]

Bind buffers to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 49
50 .into_iter()

Consume the collection into an owning iterator; its elements are moved into the following transformation.

Link to line 50
51 .filter(|frames| {

Keep only entries for which this predicate returns true.

Link to line 51
52 ranges.iter().any(|r| match r.buffer_size() {

Borrow collection entries for iteration without moving or copying the whole collection.

Link to line 52
53 cpal::SupportedBufferSize::Range { min, max } => min <= frames && frames <= max,

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 53
54 cpal::SupportedBufferSize::Unknown => true,

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 54
55 })

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 55
56 })

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 56
57 .collect::<Vec<_>>();

Collect the iterator into an owned Vec. This may allocate and belongs to setup, offline fixtures or the main-thread UI path.

Link to line 57
58 Ok(

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 58
59 json!({"id":id,"name":name,"channels":channels.min(64),"rates":rates,"default_rate":default.sample_rate(),"buffers":buffers}),

Build the main-thread presentation JSON from these named values; the audio owner publishes fixed words instead of serializing JSON.

Link to line 59
60 )

Close the surrounding scope, value or argument list in “Build an explicit device-capability record”.

Link to line 60
61}

Close the surrounding scope, value or argument list in “Build an explicit device-capability record”.

Link to line 61

Validate the requested output configuration

Read unsigned rate/buffer fields, check bounds and match an available f32 configuration with the device’s default channel count. Buffer zero means device default; a positive value requests a fixed buffer. A requested buffer does not guarantee every callback has that length.

62fn selected_output_config(device: &cpal::Device, message: &Value) -> Result<cpal::StreamConfig> {

Define selected_output_config. Read unsigned rate/buffer fields, check bounds and match an available f32 configuration with the device’s default channel count. Buffer zero means device default; a positive value requests a fixed buffer. A requested buffer does not guarantee every callback has that length.

Link to line 62
63 let default = device.default_output_config()?;

Bind default to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 63
64 let rate = u32::try_from(

Bind rate to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 64
65 message["sample_rate"]

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Validate the requested output configuration” explanation above.

Link to line 65
66 .as_u64()

Accept a JSON unsigned integer. Missing, negative or incompatible values produce None for the subsequent validation.

Link to line 66
67 .ok_or("Choose a sample rate")?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 67
68 )?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 68
69 let buffer = u32::try_from(

Bind buffer to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 69
70 message["buffer_size"]

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Validate the requested output configuration” explanation above.

Link to line 70
71 .as_u64()

Accept a JSON unsigned integer. Missing, negative or incompatible values produce None for the subsequent validation.

Link to line 71
72 .ok_or("Choose a buffer size")?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 72
73 )?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 73
74 if !(8000..=192000).contains(&rate) || buffer > 65536 || default.channels() > 64 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Validate the requested output configuration”.

Link to line 74
75 return Err("Unsupported output configuration".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 75
76 }

Close the surrounding scope, value or argument list in “Validate the requested output configuration”.

Link to line 76
77 let supported = device.supported_output_configs()?.any(|r| {

Bind supported to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 77
78 r.sample_format() == cpal::SampleFormat::F32

Assign the computed value to r.sample_format(). The right-hand expression supplies the new value for this step.

Link to line 78
79 && r.channels() == default.channels()

Require this additional condition as well; the combined check succeeds only when all conditions are true.

Link to line 79
80 && r.min_sample_rate() <= rate

Require this additional condition as well; the combined check succeeds only when all conditions are true.

Link to line 80
81 && rate <= r.max_sample_rate()

Require this additional condition as well; the combined check succeeds only when all conditions are true.

Link to line 81
82 && (buffer == 0

Require this additional condition as well; the combined check succeeds only when all conditions are true.

Link to line 82
83 || match r.buffer_size() {

Accept this alternative condition in the surrounding check; evaluation stops once the combined condition is true.

Link to line 83
84 cpal::SupportedBufferSize::Range { min, max } => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 84
85 *min <= buffer && buffer <= *max

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Validate the requested output configuration” explanation above.

Link to line 85
86 }

Close the surrounding scope, value or argument list in “Validate the requested output configuration”.

Link to line 86
87 cpal::SupportedBufferSize::Unknown => true,

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 87
88 })

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 88
89 });

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 89
90 if !supported {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Validate the requested output configuration”.

Link to line 90
91 return Err("Selected sample rate / buffer size is unavailable".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 91
92 }

Close the surrounding scope, value or argument list in “Validate the requested output configuration”.

Link to line 92
93 Ok(cpal::StreamConfig {

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 93
94 channels: default.channels(),

Define or initialize channels with the displayed type/value. Its ownership and use are described in “Validate the requested output configuration”.

Link to line 94
95 sample_rate: rate,

Define or initialize sample_rate with the displayed type/value. Its ownership and use are described in “Validate the requested output configuration”.

Link to line 95
96 buffer_size: if buffer == 0 {

Define or initialize buffer_size with the displayed type/value. Its ownership and use are described in “Validate the requested output configuration”.

Link to line 96
97 cpal::BufferSize::Default

Define or initialize cpal with the displayed type/value. Its ownership and use are described in “Validate the requested output configuration”.

Link to line 97
98 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Validate the requested output configuration” explanation above.

Link to line 98
99 cpal::BufferSize::Fixed(buffer)

Define or initialize cpal with the displayed type/value. Its ownership and use are described in “Validate the requested output configuration”.

Link to line 99
100 },

Close the surrounding scope, value or argument list in “Validate the requested output configuration”.

Link to line 100
101 })

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 101
102}

Close the surrounding scope, value or argument list in “Validate the requested output configuration”.

Link to line 102

Validate channel-pair selection

Require a nonempty list of at most 32 pairs. Pair starts must be even, unique, within the device and below 64. Mark the first and, if available, second channel. A final odd channel is allowed as a one-channel pair.

103fn channel_mask(pairs: &Value, channels: usize) -> Result<u64> {

Define channel_mask. Require a nonempty list of at most 32 pairs. Pair starts must be even, unique, within the device and below 64. Mark the first and, if available, second channel. A final odd channel is allowed as a one-channel pair.

Link to line 103
104 let pairs = pairs

Bind pairs to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 104
105 .as_array()

Require a JSON array and borrow its entries; incompatible JSON produces None.

Link to line 105
106 .filter(|p| !p.is_empty() && p.len() <= 32)

Keep only entries for which this predicate returns true.

Link to line 106
107 .ok_or("Select at least one channel pair")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 107
108 let mut mask = 0u64;

Bind mutable mask to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 108
109 for pair in pairs {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Validate channel-pair selection”.

Link to line 109
110 let first = usize::try_from(pair.as_u64().ok_or("Invalid channel pair")?)?;

Bind first to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 110
111 if first >= channels || first >= 64 || first % 2 != 0 || mask & (1u64 << first) != 0 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Validate channel-pair selection”.

Link to line 111
112 return Err("Invalid or duplicate channel pair".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 112
113 }

Close the surrounding scope, value or argument list in “Validate channel-pair selection”.

Link to line 113
114 mask |= 1u64 << first;

Set the selected bits in mask. The right-hand expression supplies the new value for this step.

Link to line 114
115 if first + 1 < channels {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Validate channel-pair selection”.

Link to line 115
116 mask |= 1u64 << (first + 1);

Set the selected bits in mask. The right-hand expression supplies the new value for this step.

Link to line 116
117 }

Close the surrounding scope, value or argument list in “Validate channel-pair selection”.

Link to line 117
118 }

Close the surrounding scope, value or argument list in “Validate channel-pair selection”.

Link to line 118
119 Ok(mask)

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 119
120}

Close the surrounding scope, value or argument list in “Validate channel-pair selection”.

Link to line 120
121

Blank line separating the surrounding statements.

Link to line 121

Own output, duplex or test rendering

Running distinguishes a live output stream, a live clocked duplex stream and a hardware-free PreparedOutput. stop pauses native playback. errors inspects processor faults, panics and backend errors without inventing a successful recovery.

122enum Running {

Declare the state/type or implementation used by this chapter. Running distinguishes a live output stream, a live clocked duplex stream and a hardware-free PreparedOutput. stop pauses native playback. errors inspects processor faults, panics and backend errors without inventing a successful recovery.

Link to line 122
123 Output(OutputStream),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Own output, duplex or test rendering” explanation above.

Link to line 123
124 Duplex(ClockedDuplexStream),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Own output, duplex or test rendering” explanation above.

Link to line 124
125 Test(Box<PreparedOutput<Audio>>),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Own output, duplex or test rendering” explanation above.

Link to line 125
126}

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 126
127impl Running {

Declare the state/type or implementation used by this chapter. Running distinguishes a live output stream, a live clocked duplex stream and a hardware-free PreparedOutput. stop pauses native playback. errors inspects processor faults, panics and backend errors without inventing a successful recovery.

Link to line 127
128 fn stop(&self) {

Define stop. Running distinguishes a live output stream, a live clocked duplex stream and a hardware-free PreparedOutput. stop pauses native playback. errors inspects processor faults, panics and backend errors without inventing a successful recovery.

Link to line 128
129 match self {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Own output, duplex or test rendering”.

Link to line 129
130 Self::Output(s) => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 130
131 let _ = s.pause();

Bind _ to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 131
132 }

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 132
133 Self::Duplex(s) => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 133
134 let _ = s.pause();

Bind _ to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 134
135 }

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 135
136 Self::Test(_) => {}

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 136
137 }

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 137
138 }

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 138
139 fn errors(&self) -> bool {

Define errors. Running distinguishes a live output stream, a live clocked duplex stream and a hardware-free PreparedOutput. stop pauses native playback. errors inspects processor faults, panics and backend errors without inventing a successful recovery.

Link to line 139
140 let s = match self {

Bind s to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 140
141 Self::Output(s) => s.statistics(),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 141
142 Self::Duplex(s) => s.output_statistics(),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 142
143 Self::Test(s) => s.statistics(),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 143
144 };

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 144
145 s.processor_faults != 0 || s.panics != 0 || s.backend_errors != 0

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Own output, duplex or test rendering” explanation above.

Link to line 145
146 }

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 146
147}

Close the surrounding scope, value or argument list in “Own output, duplex or test rendering”.

Link to line 147

Keep UI state outside the callback

State stores mode, control values, device inventories, command producer, running owner, MIDI streams, snapshot words and inspector packets. These allocating values stay on the main thread. Audio sees only prepared commands and the shared mailbox.

148struct State {

Declare the state/type or implementation used by this chapter. State stores mode, control values, device inventories, command producer, running owner, MIDI streams, snapshot words and inspector packets. These allocating values stay on the main thread. Audio sees only prepared commands and the shared mailbox.

Link to line 148
149 mode: String,

Define or initialize mode with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 149
150 values: [f32; 9],

Requested physical controls in the order documented for this processor.

Link to line 150
151 delay: [f32; 5],

Define or initialize delay with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 151
152 demo: bool,

Whether the effect input uses the synthetic demonstration source.

Link to line 152
153 rate: f64,

Sample rate used to design this patch’s envelope and coefficients.

Link to line 153
154 status: String,

Define or initialize status with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 154
155 outputs: Vec<Value>,

Define or initialize outputs with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 155
156 inputs: Vec<Value>,

Define or initialize inputs with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 156
157 midis: Vec<Value>,

Define or initialize midis with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 157
158 producer: Option<rtrb::Producer<Command>>,

Define or initialize producer with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 158
159 running: Option<Running>,

Define or initialize running with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 159
160 midi: Vec<ravet_midi_device::MidiInputStream>,

Prepared native input receivers and their last observed loss counts.

Link to line 160
161 shared: Arc<Shared>,

Reference-counted mailbox and reset flag shared with the main-thread owner.

Link to line 161
162 words: [u32; 80],

Define or initialize words with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 162
163 test: bool,

Define or initialize test with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 163
164 packets: Vec<String>,

Define or initialize packets with the displayed type/value. Its ownership and use are described in “Keep UI state outside the callback”.

Link to line 164
165}

Close the surrounding scope, value or argument list in “Keep UI state outside the callback”.

Link to line 165

Initialize and explicitly refresh inventories

new starts inactive with defaults and refreshes inventory. Test mode provides deterministic fake output/input/MIDI records. The MIDI 2.0 inspector avoids audio enumeration. Native enumeration maps stable IDs and supported channel/rate/buffer ranges for explicit user selection.

166impl State {

Declare the state/type or implementation used by this chapter. new starts inactive with defaults and refreshes inventory. Test mode provides deterministic fake output/input/MIDI records. The MIDI 2.0 inspector avoids audio enumeration. Native enumeration maps stable IDs and supported channel/rate/buffer ranges for explicit user selection.

Link to line 166
167 fn new(mode: &str, test: bool) -> Self {

Define new. new starts inactive with defaults and refreshes inventory. Test mode provides deterministic fake output/input/MIDI records. The MIDI 2.0 inspector avoids audio enumeration. Native enumeration maps stable IDs and supported channel/rate/buffer ranges for explicit user selection.

Link to line 167
168 let mut state = Self {

Bind mutable state to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 168
169 mode: mode.to_owned(),

Define or initialize mode with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 169
170 values: DEFAULT_VALUES,

Requested physical controls in the order documented for this processor.

Link to line 170
171 delay: crate::delay::DEFAULT_VALUES,

Define or initialize delay with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 171
172 demo: true,

Whether the effect input uses the synthetic demonstration source.

Link to line 172
173 rate: 48_000.,

Sample rate used to design this patch’s envelope and coefficients.

Link to line 173
174 status: "Ready · choose an output and press Start".into(),

Define or initialize status with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 174
175 outputs: Vec::new(),

Define or initialize outputs with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 175
176 inputs: Vec::new(),

Define or initialize inputs with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 176
177 midis: Vec::new(),

Define or initialize midis with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 177
178 producer: None,

Define or initialize producer with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 178
179 running: None,

Define or initialize running with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 179
180 midi: Vec::new(),

Prepared native input receivers and their last observed loss counts.

Link to line 180
181 shared: Shared::new(),

Reference-counted mailbox and reset flag shared with the main-thread owner.

Link to line 181
182 words: [0; 80],

Define or initialize words with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 182
183 test,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 183
184 packets: Vec::new(),

Define or initialize packets with the displayed type/value. Its ownership and use are described in “Initialize and explicitly refresh inventories”.

Link to line 184
185 };

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 185
186 if let Err(e) = state.refresh() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Initialize and explicitly refresh inventories”.

Link to line 186
187 state.status = e.to_string();

Assign the computed value to state.status. The right-hand expression supplies the new value for this step.

Link to line 187
188 }

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 188
189 state

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 189
190 }

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 190
191 fn refresh(&mut self) -> Result<()> {

Define refresh. new starts inactive with defaults and refreshes inventory. Test mode provides deterministic fake output/input/MIDI records. The MIDI 2.0 inspector avoids audio enumeration. Native enumeration maps stable IDs and supported channel/rate/buffer ranges for explicit user selection.

Link to line 191
192 if self.test {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Initialize and explicitly refresh inventories”.

Link to line 192
193 self.outputs = vec![

Assign the computed value to self.outputs. The right-hand expression supplies the new value for this step.

Link to line 193
194 json!({"id":"test-output","name":"Offline UI fixture","channels":6,"rates":[44100,48000,96000],"default_rate":48000,"buffers":[64,128,256,512,1024]}),

Build the main-thread presentation JSON from these named values; the audio owner publishes fixed words instead of serializing JSON.

Link to line 194
195 ];

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 195
196 self.inputs = vec![

Assign the computed value to self.inputs. The right-hand expression supplies the new value for this step.

Link to line 196
197 json!({"id":"test-input","name":"Offline capture fixture","channels":4,"rates":[48000],"default_rate":48000,"buffers":[128,256]}),

Build the main-thread presentation JSON from these named values; the audio owner publishes fixed words instead of serializing JSON.

Link to line 197
198 ];

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 198
199 self.midis = vec![

Assign the computed value to self.midis. The right-hand expression supplies the new value for this step.

Link to line 199
200 json!({"id":"midi-a","name":"Fixture keyboard"}),

Build the main-thread presentation JSON from these named values; the audio owner publishes fixed words instead of serializing JSON.

Link to line 200
201 json!({"id":"midi-b","name":"Fixture MPE controller"}),

Build the main-thread presentation JSON from these named values; the audio owner publishes fixed words instead of serializing JSON.

Link to line 201
202 ];

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 202
203 return Ok(());

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 203
204 }

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 204
205 if self.mode == "midi2" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Initialize and explicitly refresh inventories”.

Link to line 205
206 return Ok(());

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 206
207 }

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 207
208 self.outputs = ravet_device::output_devices()?

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 208
209 .into_iter()

Consume the collection into an owning iterator; its elements are moved into the following transformation.

Link to line 209
210 .map(|d| {

Transform each iterator entry, or the successful value of an Option/Result, using the supplied closure.

Link to line 210
211 let device =

Bind device to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 211
212 ravet_device::output_device(Some(&d.id))?.ok_or("Output disappeared")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 212
213 device_info(

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 213
214 d.id,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 214
215 d.name,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 215
216 d.configurations,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 216
217 device.default_output_config()?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 217
218 )

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 218
219 })

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 219
220 .collect::<Result<Vec<_>>>()?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 220
221 self.inputs = ravet_device::input_devices()?

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 221
222 .into_iter()

Consume the collection into an owning iterator; its elements are moved into the following transformation.

Link to line 222
223 .map(|d| {

Transform each iterator entry, or the successful value of an Option/Result, using the supplied closure.

Link to line 223
224 let device = ravet_device::input_device(Some(&d.id))?.ok_or("Input disappeared")?;

Bind device to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 224
225 device_info(

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 225
226 d.id,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 226
227 d.name,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 227
228 d.configurations,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Initialize and explicitly refresh inventories” explanation above.

Link to line 228
229 device.default_input_config()?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 229
230 )

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 230
231 })

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 231
232 .collect::<Result<Vec<_>>>()?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 232
233 self.midis = ravet_midi_device::input_ports()?

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 233
234 .into_iter()

Consume the collection into an owning iterator; its elements are moved into the following transformation.

Link to line 234
235 .map(|p| json!({"id":p.id,"name":p.name}))

Transform each iterator entry, or the successful value of an Option/Result, using the supplied closure.

Link to line 235
236 .collect();

Call the displayed operation with these arguments as the next step in “Initialize and explicitly refresh inventories”. The chapter describes its role and validation.

Link to line 236
237 Ok(())

Report successful completion without returning a payload.

Link to line 237
238 }

Close the surrounding scope, value or argument list in “Initialize and explicitly refresh inventories”.

Link to line 238

Stop and release native ownership

Take/pause/drop the running stream, close MIDI inputs, remove the producer and replace telemetry with empty shared state. The selected physical controls remain in State for a subsequent start.

239 fn stop(&mut self) {

Define stop. Take/pause/drop the running stream, close MIDI inputs, remove the producer and replace telemetry with empty shared state. The selected physical controls remain in State for a subsequent start.

Link to line 239
240 if let Some(running) = self.running.take() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Stop and release native ownership”.

Link to line 240
241 running.stop();

Call the displayed operation with these arguments as the next step in “Stop and release native ownership”. The chapter describes its role and validation.

Link to line 241
242 drop(running);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 242
243 }

Close the surrounding scope, value or argument list in “Stop and release native ownership”.

Link to line 243
244 for midi in self.midi.drain(..) {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Stop and release native ownership”.

Link to line 244
245 drop(midi.close());

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 245
246 }

Close the surrounding scope, value or argument list in “Stop and release native ownership”.

Link to line 246
247 self.producer = None;

Assign the computed value to self.producer. The right-hand expression supplies the new value for this step.

Link to line 247
248 self.words = [0; 80];

Assign the computed value to self.words. The right-hand expression supplies the new value for this step.

Link to line 248
249 self.shared = Shared::new();

Assign the computed value to self.shared. The right-hand expression supplies the new value for this step.

Link to line 249
250 self.status = "Stopped".into();

Assign the computed value to self.status. The right-hand expression supplies the new value for this step.

Link to line 250
251 }

Close the surrounding scope, value or argument list in “Stop and release native ownership”.

Link to line 251

Report a full control queue

Reject note/control delivery while stopped. A full queue atomically requests a panic/reset and returns a retryable UI error. It does not claim the rejected command reached the processor.

252 fn push(&mut self, command: Command) -> Result<()> {

Define push. Reject note/control delivery while stopped. A full queue atomically requests a panic/reset and returns a retryable UI error. It does not claim the rejected command reached the processor.

Link to line 252
253 let Some(producer) = &mut self.producer else {

Bind Some to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 253
254 return Err("Press Start before playing notes".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 254
255 };

Close the surrounding scope, value or argument list in “Report a full control queue”.

Link to line 255
256 if producer.push(command).is_err() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Report a full control queue”.

Link to line 256
257 self.shared

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Report a full control queue” explanation above.

Link to line 257
258 .panic

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Report a full control queue” explanation above.

Link to line 258
259 .store(true, std::sync::atomic::Ordering::Release);

Publish the new atomic flag/value using the specified memory ordering.

Link to line 259
260 return Err("Control queue full · notes cleared; retry the control".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 260
261 }

Close the surrounding scope, value or argument list in “Report a full control queue”.

Link to line 261
262 Ok(())

Report successful completion without returning a payload.

Link to line 262
263 }

Close the surrounding scope, value or argument list in “Report a full control queue”.

Link to line 263

Start from validated settings

Stop the old session before selecting a new output. Create the bounded command ring. Test mode constructs fake prepared output. Native mode validates f32 output/routing, opens at most 16 unique MIDI inputs for a synth and optionally selects a default-f32 input.

264 fn start(&mut self, message: &Value) -> Result<()> {

Define start. Stop the old session before selecting a new output. Create the bounded command ring. Test mode constructs fake prepared output. Native mode validates f32 output/routing, opens at most 16 unique MIDI inputs for a synth and optionally selects a default-f32 input.

Link to line 264
265 self.stop();

Call the displayed operation with these arguments as the next step in “Start from validated settings”. The chapter describes its role and validation.

Link to line 265
266 let synth = self.mode != "effect";

Bind synth to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 266
267 let output_id = message["output"]

Bind output_id to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 267
268 .as_str()

Require a JSON string and borrow its text; incompatible JSON produces None.

Link to line 268
269 .filter(|s| !s.is_empty())

Keep only entries for which this predicate returns true.

Link to line 269
270 .ok_or("Choose an audio output")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 270
271 let source = message["input"].as_str().unwrap_or("");

Bind source to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 271
272 let demo = !synth && self.demo;

Bind demo to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 272
273 let (producer, consumer) = rtrb::RingBuffer::new(QUEUE);

Call the displayed operation with these arguments as the next step in “Start from validated settings”. The chapter describes its role and validation.

Link to line 273
274 self.producer = Some(producer);

Assign the computed value to self.producer. The right-hand expression supplies the new value for this step.

Link to line 274
275 let result = (|| -> Result<Running> {

Bind result to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 275
276 if self.test {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 276
277 self.rate = message["sample_rate"].as_u64().unwrap_or(48000) as f64;

Accept a JSON unsigned integer. Missing, negative or incompatible values produce None for the subsequent validation.

Link to line 277
278 if ![44100., 48000., 96000.].contains(&self.rate) {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 278
279 return Err("Unsupported fixture sample rate".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 279
280 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 280
281 let routing = Routing {

Bind routing to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 281
282 input: 3,

Select input channels zero and one: bitmask 3 is binary 11.

Link to line 282
283 output: channel_mask(&message["output_pairs"], 6)?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 283
284 };

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 284
285 let audio = Audio::new(

Bind audio to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 285
286 synth,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 286
287 demo,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 287
288 consumer,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 288
289 Vec::new(),

Define or initialize Vec with the displayed type/value. Its ownership and use are described in “Start from validated settings”.

Link to line 289
290 self.shared.clone(),

Clone this value. Fixed arrays copy their entries; owned strings/vectors may allocate and remain outside the callback.

Link to line 290
291 routing,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 291
292 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 292
293 return Ok(Running::Test(Box::new(PreparedOutput::new(

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 293
294 audio,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 294
295 self.rate as u32,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Start from validated settings” explanation above.

Link to line 295
296 6,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 296
297 MAX_FRAMES,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 297
298 )?)));

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 298
299 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 299
300 let output = ravet_device::output_device(Some(output_id))?

Bind output to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 300
301 .ok_or("Selected output is unavailable")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 301
302 let config = selected_output_config(&output, message)?;

Bind config to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 302
303 self.rate = f64::from(config.sample_rate);

Assign the computed value to self.rate. The right-hand expression supplies the new value for this step.

Link to line 303
304 let mut receivers = Vec::new();

Bind mutable receivers to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 304
305 if synth {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 305
306 let ids = message["midis"]

Bind ids to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 306
307 .as_array()

Require a JSON array and borrow its entries; incompatible JSON produces None.

Link to line 307
308 .ok_or("MIDI inputs must be a list")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 308
309 if ids.len() > 16 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 309
310 return Err("Select at most 16 MIDI inputs".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 310
311 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 311
312 let mut unique = std::collections::BTreeSet::new();

Bind mutable unique to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 312
313 for value in ids {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 313
314 let id = value.as_str().ok_or("Invalid MIDI input ID")?;

Bind id to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 314
315 if !unique.insert(id) {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 315
316 return Err("Duplicate MIDI input".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 316
317 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 317
318 let (stream, receiver) = ravet_midi_device::open_input(id, 256)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 318
319 self.midi.push(stream);

Append the supplied item to this owned collection. UI/fixture collections grow outside the audio callback.

Link to line 319
320 receivers.push(receiver);

Append the supplied item to this owned collection. UI/fixture collections grow outside the audio callback.

Link to line 320
321 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 321
322 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 322
323 let output_mask = channel_mask(&message["output_pairs"], usize::from(config.channels))?;

Bind output_mask to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 323
324 let input = if !source.is_empty() {

Bind input to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 324
325 Some(

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Start from validated settings” explanation above.

Link to line 325
326 ravet_device::input_device(Some(source))?

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 326
327 .ok_or("Selected input is unavailable")?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 327
328 )

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 328
329 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Start from validated settings” explanation above.

Link to line 329
330 None

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Start from validated settings” explanation above.

Link to line 330
331 };

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 331
332 let input_config = input

Bind input_config to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 332
333 .as_ref()

Borrow the contained value without taking ownership; an absent Option stays absent.

Link to line 333
334 .map(|device| device.default_input_config())

Transform each iterator entry, or the successful value of an Option/Result, using the supplied closure.

Link to line 334
335 .transpose()?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 335
336 if input_config

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Start from validated settings”.

Link to line 336
337 .as_ref()

Borrow the contained value without taking ownership; an absent Option stays absent.

Link to line 337
338 .is_some_and(|c| c.sample_format() != cpal::SampleFormat::F32)

Call the displayed operation with these arguments as the next step in “Start from validated settings”. The chapter describes its role and validation.

Link to line 338
339 {

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 339
340 return Err("Selected input's default format must be f32".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 340
341 }

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 341
342 let input_mask = if let Some(c) = &input_config {

Bind input_mask to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 342
343 channel_mask(&message["input_pairs"], usize::from(c.channels()))?

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 343
344 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Start from validated settings” explanation above.

Link to line 344
345 3

Supply this literal numeric entry to the array or argument list being constructed. Its units/addressing follow the containing fixture or configuration.

Link to line 345
346 };

Close the surrounding scope, value or argument list in “Start from validated settings”.

Link to line 346

Choose output-only or clocked duplex ownership

Pass selected routing, prepared MIDI receivers and shared telemetry into Audio. A selected input uses open_clocked_duplex with a 512-frame prepared bound; output-only uses open_output. Any setup error runs cleanup before returning.

347 let audio = Audio::new(

Bind audio to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 347
348 synth,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 348
349 demo,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 349
350 consumer,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 350
351 receivers,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 351
352 self.shared.clone(),

Clone this value. Fixed arrays copy their entries; owned strings/vectors may allocate and remain outside the callback.

Link to line 352
353 Routing {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 353
354 input: input_mask,

Define or initialize input with the displayed type/value. Its ownership and use are described in “Choose output-only or clocked duplex ownership”.

Link to line 354
355 output: output_mask,

Define or initialize output with the displayed type/value. Its ownership and use are described in “Choose output-only or clocked duplex ownership”.

Link to line 355
356 },

Close the surrounding scope, value or argument list in “Choose output-only or clocked duplex ownership”.

Link to line 356
357 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 357
358 if let Some(input) = input {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Choose output-only or clocked duplex ownership”.

Link to line 358
359 let input_config = input_config.expect("selected input config");

Bind input_config to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 359
360 let options = ClockedDuplexOptions {

Bind options to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 360
361 maximum_frames: MAX_FRAMES,

Define or initialize maximum_frames with the displayed type/value. Its ownership and use are described in “Choose output-only or clocked duplex ownership”.

Link to line 361
362 ..ClockedDuplexOptions::default()

Call the displayed operation with these arguments as the next step in “Choose output-only or clocked duplex ownership”. The chapter describes its role and validation.

Link to line 362
363 };

Close the surrounding scope, value or argument list in “Choose output-only or clocked duplex ownership”.

Link to line 363
364 Ok(Running::Duplex(open_clocked_duplex(

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 364
365 &input,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 365
366 &output,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 366
367 input_config.config(),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 367
368 config,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 368
369 options.clock.capacity_frames,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 369
370 audio,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 370
371 options,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 371
372 )?))

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 372
373 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 373
374 Ok(Running::Output(open_output(

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 374
375 &output, config, MAX_FRAMES, audio,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 375
376 )?))

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 376
377 }

Close the surrounding scope, value or argument list in “Choose output-only or clocked duplex ownership”.

Link to line 377
378 })();

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Choose output-only or clocked duplex ownership” explanation above.

Link to line 378
379 match result {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Choose output-only or clocked duplex ownership”.

Link to line 379
380 Ok(r) => self.running = Some(r),

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 380
381 Err(e) => {

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 381
382 self.stop();

Call the displayed operation with these arguments as the next step in “Choose output-only or clocked duplex ownership”. The chapter describes its role and validation.

Link to line 382
383 return Err(e);

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 383
384 }

Close the surrounding scope, value or argument list in “Choose output-only or clocked duplex ownership”.

Link to line 384
385 }

Close the surrounding scope, value or argument list in “Choose output-only or clocked duplex ownership”.

Link to line 385

Send the prepared patch before playback

Queue a rate-matched synth patch or complete delay controls. MPE mode also queues lower-zone RPN negotiation. Request playback only after setup and queued initial controls succeed. Play failure cleans up ownership; success updates the status string.

386 if synth {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Send the prepared patch before playback”.

Link to line 386
387 self.push(Command::Patch(SynthPatch::new(self.rate, self.values)?))?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 387
388 if self.mode == "mpe" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Send the prepared patch before playback”.

Link to line 388
389 for bytes in [

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Send the prepared patch before playback”.

Link to line 389
390 [0xb0, 101, 0],

Set the RPN most-significant selector to zero on master channel 0. The next selector identifies the specific RPN.

Link to line 390
391 [0xb0, 100, 6],

Select RPN 6, the MPE zone configuration, on the lower-zone master channel.

Link to line 391
392 [0xb0, 6, 2],

Use Data Entry to request two lower-zone member channels, 1 and 2.

Link to line 392
393 [0xb0, 101, 127],

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Send the prepared patch before playback” explanation above.

Link to line 393
394 [0xb0, 100, 127],

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Send the prepared patch before playback” explanation above.

Link to line 394
395 ] {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Send the prepared patch before playback” explanation above.

Link to line 395
396 self.push(Command::Midi(MidiMessage::from_bytes(&bytes).expect("RPN")))?;

Require the invariant “RPN”. expect panics if it is broken; external inputs must be validated before relying on it.

Link to line 396
397 }

Close the surrounding scope, value or argument list in “Send the prepared patch before playback”.

Link to line 397
398 }

Close the surrounding scope, value or argument list in “Send the prepared patch before playback”.

Link to line 398
399 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Send the prepared patch before playback” explanation above.

Link to line 399
400 self.push(Command::Delay(self.delay))?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 400
401 }

Close the surrounding scope, value or argument list in “Send the prepared patch before playback”.

Link to line 401
402 let play = match self.running.as_ref().expect("opened stream") {

Bind play to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 402
403 Running::Output(s) => s.play().map_err(|e| e.into()),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 403
404 Running::Duplex(s) => s.play().map_err(|e| e.into()),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 404
405 Running::Test(_) => Ok(()),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 405
406 };

Close the surrounding scope, value or argument list in “Send the prepared patch before playback”.

Link to line 406
407 if let Err(e) = play {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Send the prepared patch before playback”.

Link to line 407
408 self.stop();

Call the displayed operation with these arguments as the next step in “Send the prepared patch before playback”. The chapter describes its role and validation.

Link to line 408
409 return Err(e);

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 409
410 }

Close the surrounding scope, value or argument list in “Send the prepared patch before playback”.

Link to line 410
411

Blank line separating the surrounding statements.

Link to line 411
412 self.status = format!("Running · {} Hz · selected channels", self.rate);

Assign the computed value to self.status. The right-hand expression supplies the new value for this step.

Link to line 412
413 Ok(())

Report successful completion without returning a payload.

Link to line 413
414 }

Close the surrounding scope, value or argument list in “Send the prepared patch before playback”.

Link to line 414

Dispatch and validate page messages

begin/end mark gesture boundaries but need no separate action here. edit/value must contain a finite physical value. Candidate delay/synth patches validate before UI values commit; only a running session queues a prepared command. Effect control 6 selects the demo source.

415 fn handle(&mut self, message: &Value) -> Result<()> {

Define handle. begin/end mark gesture boundaries but need no separate action here. edit/value must contain a finite physical value. Candidate delay/synth patches validate before UI values commit; only a running session queues a prepared command. Effect control 6 selects the demo source.

Link to line 415
416 match message["type"].as_str().ok_or("Missing message type")? {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 416
417 "begin" | "end" => {}

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 417
418 "edit" | "value" => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 418
419 let id = message["id"].as_u64().ok_or("Invalid control ID")?;

Bind id to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 419
420 let value = message["value"]

Bind value to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 420
421 .as_f64()

Read a JSON numeric value as f64; separate bounds/finite checks still determine whether the control is acceptable.

Link to line 421
422 .filter(|v| v.is_finite())

Keep only entries for which this predicate returns true.

Link to line 422
423 .ok_or("Invalid control value")? as f32;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 423
424 if self.mode == "effect" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 424
425 if id == 6 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 425
426 if value != 0. && value != 1. {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 426
427 return Err("Invalid demo selection".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 427
428 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 428
429 if self.running.is_some() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 429
430 self.push(Command::Demo(value == 1.))?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 430
431 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 431
432 self.demo = value == 1.;

Assign the computed value to self.demo. The right-hand expression supplies the new value for this step.

Link to line 432
433 return Ok(());

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 433
434 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 434
435 let index = usize::try_from(id)

Bind index to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 435
436 .ok()

Call the displayed operation with these arguments as the next step in “Dispatch and validate page messages”. The chapter describes its role and validation.

Link to line 436
437 .and_then(|id| id.checked_sub(1))

Call the displayed operation with these arguments as the next step in “Dispatch and validate page messages”. The chapter describes its role and validation.

Link to line 437
438 .filter(|i| *i < 5)

Keep only entries for which this predicate returns true.

Link to line 438
439 .ok_or("Invalid effect control")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 439
440 let mut values = self.delay;

Bind mutable values to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 440
441 values[index] = value;

Assign the computed value to values[index]. The right-hand expression supplies the new value for this step.

Link to line 441
442 let mut validation = crate::delay::DelayProcessor::default();

Bind mutable validation to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 442
443 validation.set_controls(values)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 443
444 if self.running.is_some() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 444
445 self.push(Command::Delay(values))?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 445
446 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 446
447 self.delay = values;

Assign the computed value to self.delay. The right-hand expression supplies the new value for this step.

Link to line 447
448 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Dispatch and validate page messages” explanation above.

Link to line 448
449 let index = usize::try_from(id)

Bind index to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 449
450 .ok()

Call the displayed operation with these arguments as the next step in “Dispatch and validate page messages”. The chapter describes its role and validation.

Link to line 450
451 .and_then(|id| id.checked_sub(1))

Call the displayed operation with these arguments as the next step in “Dispatch and validate page messages”. The chapter describes its role and validation.

Link to line 451
452 .filter(|i| *i < 9)

Keep only entries for which this predicate returns true.

Link to line 452
453 .ok_or("Unknown synth control")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 453
454 let mut values = self.values;

Copy the requested control array into a mutable candidate. Fixed-array copying does not allocate.

Link to line 454
455 values[index] = value;

Assign the computed value to values[index]. The right-hand expression supplies the new value for this step.

Link to line 455
456 let patch = SynthPatch::new(self.rate, values)?;

Bind patch to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 456
457 if self.running.is_some() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Dispatch and validate page messages”.

Link to line 457
458 self.push(Command::Patch(patch))?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 458
459 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 459
460 self.values = values;

Commit the validated whole control array. Validation above completes before this assignment.

Link to line 460
461 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 461
462 }

Close the surrounding scope, value or argument list in “Dispatch and validate page messages”.

Link to line 462

Validate short MIDI at the bridge

Require at most three unsigned byte values, convert them safely to u8 and validate message shape with MidiMessage::from_bytes. Queue the typed result; raw browser arrays never reach the DSP unchecked.

463 "midi" => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 463
464 let bytes = message["bytes"]

Bind bytes to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 464
465 .as_array()

Require a JSON array and borrow its entries; incompatible JSON produces None.

Link to line 465
466 .filter(|b| b.len() <= 3)

Keep only entries for which this predicate returns true.

Link to line 466
467 .ok_or("Invalid MIDI bytes")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 467
468 let mut data = [0; 3];

Bind mutable data to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 468
469 for (i, value) in bytes.iter().enumerate() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Validate short MIDI at the bridge”.

Link to line 469
470 data[i] = u8::try_from(value.as_u64().ok_or("Invalid MIDI byte")?)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 470
471 }

Close the surrounding scope, value or argument list in “Validate short MIDI at the bridge”.

Link to line 471
472 let midi = MidiMessage::from_bytes(&data[..bytes.len()])

Bind midi to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 472
473 .map_err(|_| "Invalid MIDI message")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 473
474 self.push(Command::Midi(midi))?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 474
475 }

Close the surrounding scope, value or argument list in “Validate short MIDI at the bridge”.

Link to line 475

Inspect exact MIDI 2.0 fields

Validate group/channel/key/velocity/expression against their full bounds. Choose NoteOn, NoteOff, PerNotePitchBend or PolyPressure, encode then decode a typed packet, and retain at most 16 printable packet records. This path does not route MIDI 2.0 into synthesis.

476 "packet" => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 476
477 let field = |name: &str, max: u64| -> Result<u64> {

Bind field to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 477
478 message[name]

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Inspect exact MIDI 2.0 fields” explanation above.

Link to line 478
479 .as_u64()

Accept a JSON unsigned integer. Missing, negative or incompatible values produce None for the subsequent validation.

Link to line 479
480 .filter(|n| *n <= max)

Keep only entries for which this predicate returns true.

Link to line 480
481 .ok_or_else(|| format!("Invalid MIDI 2.0 {name}").into())

Call the displayed operation with these arguments as the next step in “Inspect exact MIDI 2.0 fields”. The chapter describes its role and validation.

Link to line 481
482 };

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 482
483 let group = field("group", 15)? as u8;

Bind group to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 483
484 let channel = field("channel", 15)? as u8;

Bind channel to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 484
485 let key = field("key", 127)? as u8;

Bind key to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 485
486 let kind = match message["kind"].as_str() {

Bind kind to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 486
487 Some("on") => Midi2Kind::NoteOn {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 487
488 key,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 488
489 velocity: field("velocity", 65535)? as u16,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 489
490 attribute_type: 0,

Define or initialize attribute_type with the displayed type/value. Its ownership and use are described in “Inspect exact MIDI 2.0 fields”.

Link to line 490
491 attribute: 0,

Define or initialize attribute with the displayed type/value. Its ownership and use are described in “Inspect exact MIDI 2.0 fields”.

Link to line 491
492 },

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 492
493 Some("off") => Midi2Kind::NoteOff {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 493
494 key,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 494
495 velocity: field("velocity", 65535)? as u16,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 495
496 attribute_type: 0,

Define or initialize attribute_type with the displayed type/value. Its ownership and use are described in “Inspect exact MIDI 2.0 fields”.

Link to line 496
497 attribute: 0,

Define or initialize attribute with the displayed type/value. Its ownership and use are described in “Inspect exact MIDI 2.0 fields”.

Link to line 497
498 },

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 498
499 Some("bend") => Midi2Kind::PerNotePitchBend {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 499
500 key,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 500
501 value: field("expression", u32::MAX as u64)? as u32,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 501
502 },

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 502
503 Some("pressure") => Midi2Kind::PolyPressure {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 503
504 key,

Supply these names as the remaining imports, arguments or fields of the surrounding declaration.

Link to line 504
505 value: field("expression", u32::MAX as u64)? as u32,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 505
506 },

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 506
507 _ => return Err("Unknown MIDI 2.0 kind".into()),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 507
508 };

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 508
509 let typed = Midi2Message::new(group, channel, kind)

Bind typed to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 509
510 .map_err(|_| "Invalid MIDI 2.0 fields")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 510
511 let packet = typed.packet();

Bind packet to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 511
512 let decoded = Midi2Message::from_packet(packet).map_err(|_| "Invalid packet")?;

Bind decoded to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 512
513 let words = packet

Bind words to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 513
514 .as_words()

Call the displayed operation with these arguments as the next step in “Inspect exact MIDI 2.0 fields”. The chapter describes its role and validation.

Link to line 514
515 .iter()

Borrow collection entries for iteration without moving or copying the whole collection.

Link to line 515
516 .map(|w| format!("{w:08x}"))

Transform each iterator entry, or the successful value of an Option/Result, using the supplied closure.

Link to line 516
517 .collect::<Vec<_>>()

Collect the iterator into an owned Vec. This may allocate and belongs to setup, offline fixtures or the main-thread UI path.

Link to line 517
518 .join(" ");

Call the displayed operation with these arguments as the next step in “Inspect exact MIDI 2.0 fields”. The chapter describes its role and validation.

Link to line 518
519 if self.packets.len() == 16 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Inspect exact MIDI 2.0 fields”.

Link to line 519
520 self.packets.remove(0);

Call the displayed operation with these arguments as the next step in “Inspect exact MIDI 2.0 fields”. The chapter describes its role and validation.

Link to line 520
521 }

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 521
522 self.packets.push(format!(

Append the supplied item to this owned collection. UI/fixture collections grow outside the audio callback.

Link to line 522
523 "{words}\nGroup {group} · Channel {channel} · {:?}",

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 523
524 decoded.kind()

Call the displayed operation with these arguments as the next step in “Inspect exact MIDI 2.0 fields”. The chapter describes its role and validation.

Link to line 524
525 ));

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 525
526 self.status = "MIDI 2.0 fields preserved · packet inspector".into();

Assign the computed value to self.status. The right-hand expression supplies the new value for this step.

Link to line 526
527 }

Close the surrounding scope, value or argument list in “Inspect exact MIDI 2.0 fields”.

Link to line 527

Handle explicit device and mode actions

Start, stop, panic and refresh are explicit actions. Mode changes accept only the four example modes, stop the old owner and refresh settings. Unknown types or actions return errors for the status display.

528 "action" => match message["action"].as_str() {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 528
529 Some("start") => self.start(message)?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 529
530 Some("stop") => self.stop(),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 530
531 Some("panic") => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 531
532 self.shared

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Handle explicit device and mode actions” explanation above.

Link to line 532
533 .panic

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Handle explicit device and mode actions” explanation above.

Link to line 533
534 .store(true, std::sync::atomic::Ordering::Release);

Publish the new atomic flag/value using the specified memory ordering.

Link to line 534
535 self.status = "All notes off".into();

Assign the computed value to self.status. The right-hand expression supplies the new value for this step.

Link to line 535
536 }

Close the surrounding scope, value or argument list in “Handle explicit device and mode actions”.

Link to line 536
537 Some("refresh") => self.refresh()?,

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 537
538 Some("mode") => {

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 538
539 let mode = message["mode"]

Bind mode to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 539
540 .as_str()

Require a JSON string and borrow its text; incompatible JSON produces None.

Link to line 540
541 .filter(|m| ["synth", "effect", "mpe", "midi2"].contains(m))

Keep only entries for which this predicate returns true.

Link to line 541
542 .ok_or("Unknown example")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 542
543 self.stop();

Call the displayed operation with these arguments as the next step in “Handle explicit device and mode actions”. The chapter describes its role and validation.

Link to line 543
544 self.mode = mode.to_owned();

Assign the computed value to self.mode. The right-hand expression supplies the new value for this step.

Link to line 544
545 self.refresh()?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 545
546 }

Close the surrounding scope, value or argument list in “Handle explicit device and mode actions”.

Link to line 546
547 _ => return Err("Unknown action".into()),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 547
548 },

Close the surrounding scope, value or argument list in “Handle explicit device and mode actions”.

Link to line 548
549 _ => return Err("Unknown message".into()),

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 549
550 }

Close the surrounding scope, value or argument list in “Handle explicit device and mode actions”.

Link to line 550
551 Ok(())

Report successful completion without returning a payload.

Link to line 551
552 }

Close the surrounding scope, value or argument list in “Handle explicit device and mode actions”.

Link to line 552

Render a hardware-free UI probe

Only Running::Test renders this fixed sample buffer. It exercises prepared audio and telemetry for hidden UI checks without opening an actual native device.

553 fn render_test(&mut self) {

Define render_test. Only Running::Test renders this fixed sample buffer. It exercises prepared audio and telemetry for hidden UI checks without opening an actual native device.

Link to line 553
554 if let Some(Running::Test(renderer)) = &mut self.running {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Render a hardware-free UI probe”.

Link to line 554
555 let mut samples = [0.; 768];

Bind mutable samples to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 555
556 renderer.render(&mut samples);

Call the displayed operation with these arguments as the next step in “Render a hardware-free UI probe”. The chapter describes its role and validation.

Link to line 556
557 }

Close the surrounding scope, value or argument list in “Render a hardware-free UI probe”.

Link to line 557
558 }

Close the surrounding scope, value or argument list in “Render a hardware-free UI probe”.

Link to line 558

Convert coherent words into presentation JSON

Read a newer mailbox record when available, otherwise retain the previous words. Decode meter float bits, packed channel/key/phase and eight-slot voice expression. Combine this with controls, settings, inspector packets and a reconstructed 64-bit frame counter for the page.

559 fn snapshot(&mut self) -> Value {

Define snapshot. Read a newer mailbox record when available, otherwise retain the previous words. Decode meter float bits, packed channel/key/phase and eight-slot voice expression. Combine this with controls, settings, inspector packets and a reconstructed 64-bit frame counter for the page.

Link to line 559
560 if let Some(snapshot) = self.shared.telemetry.try_read() {

Attempt to read a complete coherent word snapshot. If none is available, the UI retains its previous record.

Link to line 560
561 self.words = snapshot.words;

Assign the computed value to self.words. The right-hand expression supplies the new value for this step.

Link to line 561
562 }

Close the surrounding scope, value or argument list in “Convert coherent words into presentation JSON”.

Link to line 562
563 if self.running.as_ref().is_some_and(|r| r.errors()) {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Convert coherent words into presentation JSON”.

Link to line 563
564 self.status = "Audio backend/processor fault · stop and choose the device again".into();

Assign the computed value to self.status. The right-hand expression supplies the new value for this step.

Link to line 564
565 }

Close the surrounding scope, value or argument list in “Convert coherent words into presentation JSON”.

Link to line 565
566 let word = |index: usize| f32::from_bits(self.words[index]);

Reconstruct a displayed float from the exact word representation published by the audio owner.

Link to line 566
567 let meters = (0..4)

Bind meters to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 567
568 .map(|i| json!({"peak":word(2+i*2),"rms":word(3+i*2),"nonfinite":false}))

Transform each iterator entry, or the successful value of an Option/Result, using the supplied closure.

Link to line 568
569 .collect::<Vec<_>>();

Collect the iterator into an owned Vec. This may allocate and belongs to setup, offline fixtures or the main-thread UI path.

Link to line 569
570 let voices=(0..8).filter_map(|i|{let s=12+i*8;let id=self.words[s];let phase=(id>>16)&255;

Bind voices to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 570
571 (phase!=0).then(||json!({"channel":id&255,"key":(id>>8)&255,"phase":(["Idle","Held","Sustained","Released"][phase as usize]),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Convert coherent words into presentation JSON” explanation above.

Link to line 571
572 "velocity":word(s+1),"bend":word(s+2)+word(s+3),"pressure":word(s+4),"timbre":word(s+5),"envelope":word(s+6)}))}).collect::<Vec<_>>();

Collect the iterator into an owned Vec. This may allocate and belongs to setup, offline fixtures or the main-thread UI path.

Link to line 572
573 json!({"mode":self.mode,"values":self.values,"delay":self.delay,"demo":self.demo,"running":self.running.is_some(),"status":self.status,

Build the main-thread presentation JSON from these named values; the audio owner publishes fixed words instead of serializing JSON.

Link to line 573
574 "io":{"outputs":self.outputs,"inputs":self.inputs,"midis":self.midis,"audio":self.mode!="midi2","midi":self.mode=="synth"||self.mode=="mpe","input":self.mode!="midi2","note":if self.mode=="effect" {"Stop audio to change settings. Selected input pairs are mixed to stereo."} else {"Stop audio to change settings. Audio input is optional; notes come from MIDI or the keyboard."}},"meters":meters,"voices":voices,"packets":self.packets,

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Convert coherent words into presentation JSON” explanation above.

Link to line 574
575 "frames":u64::from(self.words[0])|(u64::from(self.words[1])<<32),"midiDrops":self.words[10],"ranges":RANGES})

Call the displayed operation with these arguments as the next step in “Convert coherent words into presentation JSON”. The chapter describes its role and validation.

Link to line 575
576 }

Close the surrounding scope, value or argument list in “Convert coherent words into presentation JSON”.

Link to line 576
577}

Close the surrounding scope, value or argument list in “Convert coherent words into presentation JSON”.

Link to line 577

Clean up and implement the native bridge

Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

578impl Drop for State {

Declare the state/type or implementation used by this chapter. Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

Link to line 578
579 fn drop(&mut self) {

Define drop. Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

Link to line 579
580 self.stop();

Call the displayed operation with these arguments as the next step in “Clean up and implement the native bridge”. The chapter describes its role and validation.

Link to line 580
581 }

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 581
582}

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 582
583struct Bridge(Rc<RefCell<State>>);

Declare the state/type or implementation used by this chapter. Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

Link to line 583
584impl Callbacks for Bridge {

Declare the state/type or implementation used by this chapter. Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

Link to line 584
585 fn message(&mut self, text: &str) {

Define message. Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

Link to line 585
586 let mut state = self.0.borrow_mut();

Bind mutable state to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 586
587 let result = (|| -> Result<()> {

Bind result to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 587
588 if text.len() > 4096 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Clean up and implement the native bridge”.

Link to line 588
589 return Err("Message too large".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 589
590 }

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 590
591 let message: Value = serde_json::from_str(text)?;

Bind message to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 591
592 state.handle(&message)

Call the displayed operation with these arguments as the next step in “Clean up and implement the native bridge”. The chapter describes its role and validation.

Link to line 592
593 })();

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Clean up and implement the native bridge” explanation above.

Link to line 593
594 if let Err(e) = result {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Clean up and implement the native bridge”.

Link to line 594
595 state.status = e.to_string();

Assign the computed value to state.status. The right-hand expression supplies the new value for this step.

Link to line 595
596 }

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 596
597 }

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 597
598 fn snapshot(&mut self) -> Option<String> {

Define snapshot. Dropping State stops the session. Bridge owns Rc<RefCell<State>> and implements Callbacks. Reject messages over 4,096 bytes before JSON parsing, dispatch valid messages and turn errors into status text. Snapshot serialization remains on the main thread.

Link to line 598
599 Some(self.0.borrow_mut().snapshot().to_string())

Call the displayed operation with these arguments as the next step in “Clean up and implement the native bridge”. The chapter describes its role and validation.

Link to line 599
600 }

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 600
601}

Close the surrounding scope, value or argument list in “Clean up and implement the native bridge”.

Link to line 601
602

Blank line separating the surrounding statements.

Link to line 602

Open the window with the default I/O settings

Accept only the four modes and either no UI arguments or --ui-test plus a directory. Create a StandaloneWindow with aspect-ratio locking and default settings enabled. Inject shared controls into the HTML placeholder, embed the bridge, show the editor and pump the native loop. Stop and tear down on exit.

603/// Open the native example window. Devices start only from the page's Start action.

Source note: Open the native example window. Devices start only from the page's Start action.

Link to line 603
604/// `--ui-test directory` runs a hidden, hardware-free WebKit/audio fixture instead.

Source note: `--ui-test directory` runs a hidden, hardware-free WebKit/audio fixture instead.

Link to line 604
605pub fn run(mode: &str) -> Result<()> {

Define run. Accept only the four modes and either no UI arguments or --ui-test plus a directory. Create a StandaloneWindow with aspect-ratio locking and default settings enabled. Inject shared controls into the HTML placeholder, embed the bridge, show the editor and pump the native loop. Stop and tear down on exit.

Link to line 605
606 if !["synth", "effect", "mpe", "midi2"].contains(&mode) {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Open the window with the default I/O settings”.

Link to line 606
607 return Err("Unknown example".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 607
608 }

Close the surrounding scope, value or argument list in “Open the window with the default I/O settings”.

Link to line 608
609 let args: Vec<_> = std::env::args_os().skip(1).collect();

Bind args to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 609
610 if args.first().is_some_and(|a| a == "--ui-test") {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Open the window with the default I/O settings”.

Link to line 610
611 if args.len() != 2 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Open the window with the default I/O settings”.

Link to line 611
612 return Err("usage: --ui-test <screenshot-directory>".into());

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 612
613 }

Close the surrounding scope, value or argument list in “Open the window with the default I/O settings”.

Link to line 613
614 return probe(std::path::Path::new(&args[1]));

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 614
615 }

Close the surrounding scope, value or argument list in “Open the window with the default I/O settings”.

Link to line 615
616 if !args.is_empty() {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Open the window with the default I/O settings”.

Link to line 616
617 return Err(

Exit this path with an explicit error/fault; the caller must not treat this branch as successfully applied state.

Link to line 617
618 "usage: no arguments for live UI; --render [file.wav] or --offline for fixtures".into(),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Open the window with the default I/O settings” explanation above.

Link to line 618
619 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 619
620 }

Close the surrounding scope, value or argument list in “Open the window with the default I/O settings”.

Link to line 620
621 let state = Rc::new(RefCell::new(State::new(mode, false)));

Bind state to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 621
622 let window = StandaloneWindow::new(StandaloneOptions {

Bind window to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 622
623 title: "RAVET · Live examples".into(),

Define or initialize title with the displayed type/value. Its ownership and use are described in “Open the window with the default I/O settings”.

Link to line 623
624 lock_aspect_ratio: true,

Define or initialize lock_aspect_ratio with the displayed type/value. Its ownership and use are described in “Open the window with the default I/O settings”.

Link to line 624
625 ..StandaloneOptions::default()

Call the displayed operation with these arguments as the next step in “Open the window with the default I/O settings”. The chapter describes its role and validation.

Link to line 625
626 })?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 626
627 let html = ravet_surface::embed_web_controls(include_str!("../../editor/index.html"))

Bind html to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 627
628 .ok_or("Missing example control placeholders")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 628
629 let editor = window.embed(&html, Bridge(state.clone()))?;

Bind editor to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 629
630 editor.set_visible(true);

Call the displayed operation with these arguments as the next step in “Open the window with the default I/O settings”. The chapter describes its role and validation.

Link to line 630
631 while window.pump(0.01) {}

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Open the window with the default I/O settings”.

Link to line 631
632 state.borrow_mut().stop();

Call the displayed operation with these arguments as the next step in “Open the window with the default I/O settings”. The chapter describes its role and validation.

Link to line 632
633 drop(editor);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 633
634 drop(window);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 634
635 Ok(())

Report successful completion without returning a payload.

Link to line 635
636}

Close the surrounding scope, value or argument list in “Open the window with the default I/O settings”.

Link to line 636
637

Blank line separating the surrounding statements.

Link to line 637

Exercise all modes without device I/O

Create a screenshot directory and hidden windows using test State. Drive mode tabs, synth/effect controls, fake channel/rate/buffer choices, voice release and packet inspection. Capture screenshots after the corresponding checks. These probes validate the UI contract, not a physical audio deadline.

638fn probe(directory: &std::path::Path) -> Result<()> {

Define probe. Create a screenshot directory and hidden windows using test State. Drive mode tabs, synth/effect controls, fake channel/rate/buffer choices, voice release and packet inspection. Capture screenshots after the corresponding checks. These probes validate the UI contract, not a physical audio deadline.

Link to line 638
639 std::fs::create_dir_all(directory)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 639
640 {

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 640
641 let state = Rc::new(RefCell::new(State::new("synth", true)));

Bind state to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 641
642 let window = StandaloneWindow::new(StandaloneOptions {

Bind window to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 642
643 hidden: true,

Define or initialize hidden with the displayed type/value. Its ownership and use are described in “Exercise all modes without device I/O”.

Link to line 643
644 io_settings: false,

Define or initialize io_settings with the displayed type/value. Its ownership and use are described in “Exercise all modes without device I/O”.

Link to line 644
645 ..StandaloneOptions::default()

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 645
646 })?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 646
647 let editor = window.embed(

Bind editor to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 647
648 "<body><script>window.ready=true</script></body>",

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 648
649 Bridge(state),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 649
650 )?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 650
651 for _ in 0..20 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 651
652 window.pump(0.02);

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 652
653 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 653
654 assert!(!window.open_settings());

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 654
655 assert!(window.eval("window.ready===true&&!document.getElementById('io-settings')")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 655
656 drop(editor);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 656
657 drop(window);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 657
658 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 658
659

Blank line separating the surrounding statements.

Link to line 659
660 for mode in ["synth", "effect", "mpe", "midi2"] {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 660
661 let state = Rc::new(RefCell::new(State::new(mode, true)));

Bind state to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 661
662 let window = StandaloneWindow::new(StandaloneOptions {

Bind window to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 662
663 hidden: true,

Define or initialize hidden with the displayed type/value. Its ownership and use are described in “Exercise all modes without device I/O”.

Link to line 663
664 title: format!("RAVET · UI fixture · {mode}"),

Define or initialize title with the displayed type/value. Its ownership and use are described in “Exercise all modes without device I/O”.

Link to line 664
665 lock_aspect_ratio: true,

Define or initialize lock_aspect_ratio with the displayed type/value. Its ownership and use are described in “Exercise all modes without device I/O”.

Link to line 665
666 ..StandaloneOptions::default()

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 666
667 })?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 667
668 let html = ravet_surface::embed_web_controls(include_str!("../../editor/index.html"))

Bind html to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 668
669 .ok_or("Missing example control placeholders")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 669
670 let editor = window.embed(&html, Bridge(state.clone()))?;

Bind editor to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 670
671 editor.set_visible(true);

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 671
672 let wait = |script: &str| -> Result<()> {

Bind wait to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 672
673 for _ in 0..80 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 673
674 if window.eval(script)? {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 674
675 return Ok(());

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 675
676 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 676
677 window.pump(0.05);

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 677
678 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 678
679 Err(format!("UI assertion timed out: {script}").into())

Construct the success/error variant selected by the surrounding match or function return. The enclosed value becomes its payload.

Link to line 679
680 };

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 680
681 wait("window.ravetExampleReady===true")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 681
682 assert!(window.open_settings());

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 682
683 wait("document.getElementById('io-settings').open")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 683
684 if mode != "midi2" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 684
685 assert!(window.eval("document.getElementById('audio-output').value='test-output';document.getElementById('audio-output').dispatchEvent(new Event('change'));true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 685
686 wait(

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 686
687 "document.getElementById('sample-rate').value==='48000'&&document.querySelectorAll('#output-channels input').length===3",

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 687
688 )?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 688
689 assert!(window.eval("document.getElementById('buffer-size').value='128';document.getElementById('buffer-size').selectedOptions[0].textContent.includes('2.7 ms')")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 689
690 if mode != "effect" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 690
691 assert!(window.eval("document.querySelectorAll('#midi-inputs input').length===2&&document.querySelectorAll('#midi-inputs input:checked').length===0")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 691
692 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 692
693 assert!(window.eval("document.getElementById('audio-input').value='test-input';document.getElementById('audio-input').dispatchEvent(new Event('change'));document.querySelectorAll('#input-channels input').length===2")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 693
694 assert!(window.snapshot(&directory.join(format!("{mode}-settings.png")))?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 694
695 assert!(window.eval("document.getElementById('audio-input').value='';document.getElementById('audio-input').dispatchEvent(new Event('change'));true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 695
696 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 696
697 assert!(window.eval("document.getElementById('close-settings').click();true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 697
698 if mode == "synth" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 698
699 assert!(window.eval("Array.from(document.querySelectorAll('#keyboard .ravet-piano-key')).every(key=>key.disabled&&getComputedStyle(key).opacity==='1')")?, "stopped piano keys must remain opaque");

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 699
700 assert!(window.snapshot(&directory.join("synth-stopped.png"))?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 700
701 knob_fixture(&window)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 701
702 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 702
703

Blank line separating the surrounding statements.

Link to line 703
704 if mode == "midi2" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 704
705 assert!(window.eval("document.getElementById('encode').click();true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 705
706 wait("document.getElementById('packets').textContent.includes('41923c00 abcd0000')")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 706
707 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 707
708 assert!(window.eval(

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 708
709 "window.ravetOpenSettings();document.getElementById('start').click();true"

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 709
710 )?);

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 710
711 for _ in 0..20 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 711
712 state.borrow_mut().render_test();

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 712
713 window.pump(0.02);

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 713
714 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 714
715 assert!(

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 715
716 state.borrow().running.is_some(),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 716
717 "{}",

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 717
718 state.borrow().status

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 718
719 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 719
720 wait("!document.getElementById('io-settings').open")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 720
721 if mode == "synth" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 721
722 piano_fixture(&window)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 722
723 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 723
724

Blank line separating the surrounding statements.

Link to line 724
725 if mode == "effect" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 725
726 assert!(window.eval("window.ravetPost({type:'edit',id:1,value:250});window.ravetPost({type:'edit',id:2,value:0.5});window.ravetPost({type:'edit',id:3,value:0.6});window.ravetPost({type:'edit',id:5,value:1});true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 726
727 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 727
728 assert!(window.eval("window.ravetPost({type:'edit',id:1,value:2});document.querySelector('[data-note=\"60\"]').dispatchEvent(new PointerEvent('pointerdown',{pointerId:1,bubbles:true}));true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 728
729 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 729
730 for _ in 0..if mode == "effect" { 100 } else { 30 } {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 730
731 state.borrow_mut().render_test();

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 731
732 window.pump(0.02);

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 732
733 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 733
734 assert!(state.borrow().words[0] > 0);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 734
735 assert!(f32::from_bits(state.borrow().words[6]) > 0.0001);

Reconstruct a displayed float from the exact word representation published by the audio owner.

Link to line 735
736 assert!(window.snapshot(&directory.join(format!("{mode}-playing.png")))?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 736
737 if mode == "effect" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 737
738 assert_eq!(state.borrow().delay, [250., 0.5, 0.6, 0., 1.]);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 738
739 wait(

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 739
740 "document.getElementById('title').textContent==='Stereo delay'&&document.querySelectorAll('#delay-controls [role=slider]').length===3&&document.getElementById('delay-number-1').value==='250'&&document.getElementById('ping-pong').checked",

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 740
741 )?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 741
742 assert!(window.eval("document.getElementById('bypass').click();true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 742
743 wait("document.getElementById('bypass').checked")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 743
744 assert_eq!(state.borrow().delay[3], 1.);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 744
745 assert!(window.eval("document.getElementById('main-stop').click();true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 745
746 wait(

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 746
747 "document.getElementById('main-stop').textContent==='Start audio'&&!document.getElementById('main-stop').disabled",

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 747
748 )?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 748
749 assert!(state.borrow().running.is_none());

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 749
750 assert!(window.eval("document.getElementById('main-stop').click();true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 750
751 wait("document.getElementById('main-stop').textContent==='Stop audio'")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 751
752 assert!(state.borrow().running.is_some());

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 752
753 assert!(window.eval("document.getElementById('demo-loop').click();true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 753
754 wait("!document.getElementById('demo-loop').checked")?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 754
755 assert!(!state.borrow().demo);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 755
756 assert!(window.eval("Array.from(document.getElementById('audio-input').options).every(option=>!option.textContent.includes('Demo')&&option.value!=='demo')")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 756
757 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 757
758 if mode != "effect" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 758
759 assert_eq!(state.borrow().values[0], 2.);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 759
760 assert!(window.eval("document.querySelector('[data-note=\"60\"]').dispatchEvent(new PointerEvent('pointerup',{pointerId:1,bubbles:true}));true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 760
761 for _ in 0..150 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Exercise all modes without device I/O”.

Link to line 761
762 state.borrow_mut().render_test();

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 762
763 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 763
764 assert!(

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 764
765 state.borrow_mut().snapshot()["voices"]

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Exercise all modes without device I/O” explanation above.

Link to line 765
766 .as_array()

Require a JSON array and borrow its entries; incompatible JSON produces None.

Link to line 766
767 .expect("voices")

Require the invariant “voices”. expect panics if it is broken; external inputs must be validated before relying on it.

Link to line 767
768 .is_empty()

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 768
769 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 769
770 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 770
771 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 771
772 window.pump(0.1);

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 772
773 layout_fixture(&window, mode, directory)?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 773
774 assert!(window.snapshot(&directory.join(format!("{mode}.png")))?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 774
775 state.borrow_mut().stop();

Call the displayed operation with these arguments as the next step in “Exercise all modes without device I/O”. The chapter describes its role and validation.

Link to line 775
776 drop(editor);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 776
777 drop(window);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 777
778 println!("PASS {mode} native UI/control/audio fixture (no device opened)");

Report this explicit fixture result to stdout; printing belongs to the offline/control path, not the audio callback.

Link to line 778
779 }

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 779
780 settings_fixture()?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 780
781 Ok(())

Report successful completion without returning a payload.

Link to line 781
782}

Close the surrounding scope, value or argument list in “Exercise all modes without device I/O”.

Link to line 782
783

Blank line separating the surrounding statements.

Link to line 783

Check uniform design-canvas scaling

Request several viewport sizes, query the page’s actual layout and verify the 900×780 content scales uniformly. Wide/short and narrow/tall requests are constrained by the locked aspect ratio. Validate dimensions and unclipped controls rather than relying on a screenshot alone.

784fn layout_fixture(

Define layout_fixture. Request several viewport sizes, query the page’s actual layout and verify the 900×780 content scales uniformly. Wide/short and narrow/tall requests are constrained by the locked aspect ratio. Validate dimensions and unclipped controls rather than relying on a screenshot alone.

Link to line 784
785 window: &StandaloneWindow,

Define or initialize window with the displayed type/value. Its ownership and use are described in “Check uniform design-canvas scaling”.

Link to line 785
786 mode: &str,

Define or initialize mode with the displayed type/value. Its ownership and use are described in “Check uniform design-canvas scaling”.

Link to line 786
787 directory: &std::path::Path,

Define or initialize directory with the displayed type/value. Its ownership and use are described in “Check uniform design-canvas scaling”.

Link to line 787
788) -> Result<()> {

Complete the function’s parameter list and specify the return type. A Result preserves the explicit success/error distinction.

Link to line 788
789 assert!(window.eval("window.ravetLayoutBaseline=Array.from(document.querySelectorAll('header,h1,.tabs,.dial,.panel,input[type=number],footer')).filter(node=>{const rect=node.getBoundingClientRect();return rect.width>0&&rect.height>0}).map(node=>({node,rect:node.getBoundingClientRect()}));window.ravetExampleScale===1")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 789
790 for (width, height, actual_width, actual_height, scale, label) in [

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Check uniform design-canvas scaling”.

Link to line 790
791 (720., 624., 720, 624, 0.8, "minimum"),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 791
792 (1080., 936., 1080, 936, 1.2, "large"),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 792
793 (1200., 624., 720, 624, 0.8, "wide-short"),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 793
794 (720., 1000., 720, 624, 0.8, "narrow-tall"),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 794
795 (900., 780., 900, 780, 1., "default"),

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 795
796 ] {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 796
797 assert!(window.set_size(width, height));

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 797
798 let check = format!(

Bind check to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 798
799 "window.innerWidth==={actual_width}&&window.innerHeight==={actual_height}&&Math.abs(window.ravetExampleScale-{scale})<0.001"

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check uniform design-canvas scaling” explanation above.

Link to line 799
800 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 800
801 let mut ready = false;

Bind mutable ready to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 801
802 for _ in 0..80 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Check uniform design-canvas scaling”.

Link to line 802
803 if window.eval(&check)? {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Check uniform design-canvas scaling”.

Link to line 803
804 ready = true;

Assign the computed value to ready. The right-hand expression supplies the new value for this step.

Link to line 804
805 break;

End the nearest loop when its bounded work or input condition is complete.

Link to line 805
806 }

Close the surrounding scope, value or argument list in “Check uniform design-canvas scaling”.

Link to line 806
807 window.pump(0.05);

Call the displayed operation with these arguments as the next step in “Check uniform design-canvas scaling”. The chapter describes its role and validation.

Link to line 807
808 }

Close the surrounding scope, value or argument list in “Check uniform design-canvas scaling”.

Link to line 808
809 assert!(ready, "{mode} {label} native aspect/viewport mismatch");

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 809
810 assert!(window.eval(&format!("window.ravetLayoutBaseline.every(item=>{{const rect=item.node.getBoundingClientRect();return Math.abs(rect.width-item.rect.width*{scale})<1&&Math.abs(rect.height-item.rect.height*{scale})<1&&Math.abs(rect.top-item.rect.top*{scale})<1&&Math.abs(rect.left-item.rect.left*{scale})<1}})"))?,"{mode} {label} must scale all UI dimensions and positions uniformly");

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 810
811 assert!(window.eval("window.ravetLayoutBaseline.every(item=>{const rect=item.node.getBoundingClientRect();return rect.left>=-1&&rect.top>=-1&&rect.right<=window.innerWidth+1&&rect.bottom<=window.innerHeight+1})&&document.documentElement.scrollHeight<=window.innerHeight+1&&document.documentElement.scrollWidth<=window.innerWidth+1")?,"{mode} {label} content clipped/overflows");

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 811
812 if mode != "midi2" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Check uniform design-canvas scaling”.

Link to line 812
813 assert!(window.eval("Array.from(document.querySelectorAll('#meters-panel .reading')).every(reading=>reading.getBoundingClientRect().bottom<=document.getElementById('meters-panel').getBoundingClientRect().bottom-1)")?,"{mode} {label} meter readings overflow");

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 813
814 }

Close the surrounding scope, value or argument list in “Check uniform design-canvas scaling”.

Link to line 814
815 if label == "minimum" || label == "large" {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Check uniform design-canvas scaling”.

Link to line 815
816 assert!(window.snapshot(&directory.join(format!("{mode}-{label}.png")))?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 816
817 }

Close the surrounding scope, value or argument list in “Check uniform design-canvas scaling”.

Link to line 817
818 }

Close the surrounding scope, value or argument list in “Check uniform design-canvas scaling”.

Link to line 818
819 Ok(())

Report successful completion without returning a payload.

Link to line 819
820}

Close the surrounding scope, value or argument list in “Check uniform design-canvas scaling”.

Link to line 820
821

Blank line separating the surrounding statements.

Link to line 821

Verify settings opt-out and default behavior

Open three successive hidden windows with an in-memory native preferences fixture. Save device IDs, channel pairs, a 96 kHz rate, a 256-frame buffer and one MIDI input; confirm the next window restores these selections without starting audio. Then save unavailable IDs and confirm the next window clears them.

822fn settings_fixture() -> Result<()> {

Define settings_fixture. Open three successive hidden windows with an in-memory native preferences fixture. Save device IDs, channel pairs, a 96 kHz rate, a 256-frame buffer and one MIDI input; confirm the next window restores these selections without starting audio. Then save unavailable IDs and confirm the next window clears them.

Link to line 822
823 for pass in 0..3 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Verify settings opt-out and default behavior”.

Link to line 823
824 let state = Rc::new(RefCell::new(State::new("synth", true)));

Bind state to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 824
825 let window = StandaloneWindow::new(StandaloneOptions {

Bind window to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 825
826 hidden: true,

Define or initialize hidden with the displayed type/value. Its ownership and use are described in “Verify settings opt-out and default behavior”.

Link to line 826
827 title: "RAVET · settings restore fixture".into(),

Define or initialize title with the displayed type/value. Its ownership and use are described in “Verify settings opt-out and default behavior”.

Link to line 827
828 ..Default::default()

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 828
829 })?;

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 829
830 let html =

Bind html to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 830
831 ravet_surface::embed_web_controls(include_str!("../../editor/index.html")).unwrap();

Define or initialize ravet_surface with the displayed type/value. Its ownership and use are described in “Verify settings opt-out and default behavior”.

Link to line 831
832 let editor = window.embed(&html, Bridge(state.clone()))?;

Bind editor to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 832
833 editor.set_visible(true);

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 833
834 for _ in 0..80 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Verify settings opt-out and default behavior”.

Link to line 834
835 if window.eval("window.ravetExampleReady===true")? {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Verify settings opt-out and default behavior”.

Link to line 835
836 break;

End the nearest loop when its bounded work or input condition is complete.

Link to line 836
837 }

Close the surrounding scope, value or argument list in “Verify settings opt-out and default behavior”.

Link to line 837
838 window.pump(0.05);

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 838
839 }

Close the surrounding scope, value or argument list in “Verify settings opt-out and default behavior”.

Link to line 839
840 assert!(window.eval("window.ravetExampleReady===true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 840
841 if pass == 0 {

Evaluate this condition or visit this range in source order. The statements in the following scope implement “Verify settings opt-out and default behavior”.

Link to line 841
842 assert!(window.eval(r#"(()=>{

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 842
843 const get=id=>document.getElementById(id),change=node=>node.dispatchEvent(new Event('change',{bubbles:true}));

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 843
844 get('audio-output').value='test-output';change(get('audio-output'));

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 844
845 get('audio-input').value='test-input';change(get('audio-input'));

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 845
846 get('sample-rate').value='96000';change(get('sample-rate'));

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 846
847 get('buffer-size').value='256';change(get('buffer-size'));

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 847
848 for(const [id,value] of [['output-channels','4'],['input-channels','2'],['midi-inputs','midi-b']]){

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Verify settings opt-out and default behavior” explanation above.

Link to line 848
849 for(const check of get(id).querySelectorAll('input'))check.checked=check.value===value;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Verify settings opt-out and default behavior” explanation above.

Link to line 849
850 change(get(id));

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 850
851 }return true;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Verify settings opt-out and default behavior” explanation above.

Link to line 851
852 })()"#)?);

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 852
853 window.pump(0.1);

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 853
854 } else if pass == 1 {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Verify settings opt-out and default behavior” explanation above.

Link to line 854
855 assert!(window.eval(r#"document.getElementById('audio-output').value==='test-output'&&document.getElementById('audio-input').value==='test-input'&&document.getElementById('sample-rate').value==='96000'&&document.getElementById('buffer-size').value==='256'&&['output-channels','input-channels','midi-inputs'].every(id=>document.querySelectorAll('#'+id+' input:checked').length===1)&&document.querySelector('#output-channels input:checked').value==='4'&&document.querySelector('#input-channels input:checked').value==='2'&&document.querySelector('#midi-inputs input:checked').value==='midi-b'"#)?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 855
856 assert!(state.borrow().running.is_none());

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 856
857 assert!(window.eval("window.webkit.messageHandlers.ravetSettings.postMessage({version:1,output:'missing-output',input:'missing-input',sample_rate:96000,buffer_size:256,output_pairs:[0],input_pairs:[0],midis:['missing-midi']});true")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 857
858 window.pump(0.1);

Call the displayed operation with these arguments as the next step in “Verify settings opt-out and default behavior”. The chapter describes its role and validation.

Link to line 858
859 } else {

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Verify settings opt-out and default behavior” explanation above.

Link to line 859
860 assert!(window.eval("document.getElementById('audio-output').value===''&&document.getElementById('audio-input').value===''&&document.querySelectorAll('#midi-inputs input:checked').length===0")?);

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 860
861 }

Close the surrounding scope, value or argument list in “Verify settings opt-out and default behavior”.

Link to line 861
862 drop(editor);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 862
863 drop(window);

Release this owner on the control/offline thread after its running activity has been stopped.

Link to line 863
864 }

Close the surrounding scope, value or argument list in “Verify settings opt-out and default behavior”.

Link to line 864
865 println!(

Report this explicit fixture result to stdout; printing belongs to the offline/control path, not the audio callback.

Link to line 865
866 "PASS Audio/MIDI selection restore, unavailable devices and no automatic start (in-memory native preferences fixture)"

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Verify settings opt-out and default behavior” explanation above.

Link to line 866
867 );

Close the current expression or scope; no additional processing operation occurs on this line.

Link to line 867
868 Ok(())

Report successful completion without returning a payload.

Link to line 868
869}

Close the surrounding scope, value or argument list in “Verify settings opt-out and default behavior”.

Link to line 869
870

Blank line separating the surrounding statements.

Link to line 870

Check keyboard and numeric control gestures

Drive the shared knob through keyboard changes and numeric entry, then inspect its displayed values. These tests exercise the control component’s edit/refresh contract, not a host automation lane.

871fn knob_fixture(window: &StandaloneWindow) -> Result<()> {

Define knob_fixture. Drive the shared knob through keyboard changes and numeric entry, then inspect its displayed values. These tests exercise the control component’s edit/refresh contract, not a host automation lane.

Link to line 871
872 assert!(window.eval(r#"(()=>{

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 872
873 if(document.querySelectorAll('input[type=range]').length!==0)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check keyboard and numeric control gestures” explanation above.

Link to line 873
874 const dial=document.createElement('div'),number=document.createElement('input');number.type='number';

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 874
875 const messages=[],knob=new RavetControls.Knob(dial,number,{id:90,minimum:20,maximum:20000,step:1,value:200,logarithmic:true},m=>{messages.push(m);return true});

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 875
876 dial.dispatchEvent(new PointerEvent('pointerdown',{button:0,pointerId:99,clientY:100}));

Call the displayed operation with these arguments as the next step in “Check keyboard and numeric control gestures”. The chapter describes its role and validation.

Link to line 876
877 dial.dispatchEvent(new PointerEvent('pointermove',{pointerId:99,clientY:50}));

Call the displayed operation with these arguments as the next step in “Check keyboard and numeric control gestures”. The chapter describes its role and validation.

Link to line 877
878 if(knob.update(400)||Math.abs(knob.current-2000)>1)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check keyboard and numeric control gestures” explanation above.

Link to line 878
879 dial.dispatchEvent(new PointerEvent('pointercancel',{pointerId:99}));

Call the displayed operation with these arguments as the next step in “Check keyboard and numeric control gestures”. The chapter describes its role and validation.

Link to line 879
880 if(messages.map(m=>m.type).join(',')!=='begin,value,end')return false;

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 880
881 knob.update(200);dial.dispatchEvent(new KeyboardEvent('keydown',{key:'End'}));dial.dispatchEvent(new KeyboardEvent('keyup',{key:'End'}));

Call the displayed operation with these arguments as the next step in “Check keyboard and numeric control gestures”. The chapter describes its role and validation.

Link to line 881
882 if(knob.current!==20000)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check keyboard and numeric control gestures” explanation above.

Link to line 882
883 number.value='-1';number.dispatchEvent(new Event('change'));if(knob.current!==20)return false;

Assign the computed value to number.value. The right-hand expression supplies the new value for this step.

Link to line 883
884 if(!knob.dispose())return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check keyboard and numeric control gestures” explanation above.

Link to line 884
885 let rejected=true;const retry=new RavetControls.Knob(dial,null,{id:91,minimum:0,maximum:1,value:.6},m=>m.type!=='end'||!rejected);

Bind rejected to the expression on this and any following continuation lines. The chapter above explains how this intermediate value is used.

Link to line 885
886 retry.begin();if(retry.dispose()||!retry.active)return false;rejected=false;if(!retry.dispose())return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check keyboard and numeric control gestures” explanation above.

Link to line 886
887 const denied=new RavetControls.Knob(dial,null,{id:92,minimum:0,maximum:1},()=>false);if(denied.begin()||denied.active||!denied.dispose())return false;

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 887
888 return true;

Return this result to the caller; the remaining statements in the function are skipped.

Link to line 888
889 })()"#)?);

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 889
890 Ok(())

Report successful completion without returning a payload.

Link to line 890
891}

Close the surrounding scope, value or argument list in “Check keyboard and numeric control gestures”.

Link to line 891
892

Blank line separating the surrounding statements.

Link to line 892

Check pointer-held notes and cancellation

Drive the shared piano widget and inspect held-note state. Verify release on cancellation/focus transitions so a lost UI interaction does not leave an on-screen note held.

893fn piano_fixture(window: &StandaloneWindow) -> Result<()> {

Define piano_fixture. Drive the shared piano widget and inspect held-note state. Verify release on cancellation/focus transitions so a lost UI interaction does not leave an on-screen note held.

Link to line 893
894 assert!(window.eval(r#"(()=>{

Verify the fixture’s expected result. A mismatch fails the test rather than becoming a successful support claim.

Link to line 894
895 const root=document.getElementById('keyboard'),white=root.querySelector('[data-note="60"]'),black=root.querySelector('[data-note="61"]');

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 895
896 const w=white.getBoundingClientRect(),b=black.getBoundingClientRect();

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 896
897 if(b.height>=w.height*.7||b.width>=w.width||b.left>=w.right||b.left<=w.left||root.querySelectorAll('.white').length!==15||root.querySelectorAll('.black').length!==10)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check pointer-held notes and cancellation” explanation above.

Link to line 897
898 const outer=document.createElement('div');outer.style.cssText='position:fixed;left:10px;top:10px;width:300px;height:100px;z-index:1000';document.body.append(outer);

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 898
899 const messages=[],active=new Map();

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 899
900 const piano=new RavetControls.PianoKeyboard(outer,{firstNote:60,lastNote:72,onNoteOn:(note,source)=>{active.set(source,note);messages.push(['on',note]);return true},onNoteOff:source=>{messages.push(['off',active.get(source)]);active.delete(source)}});

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 900
901 const key=note=>outer.querySelector(`[data-note="${note}"]`),pointer=(node,type,id,x,y)=>node.dispatchEvent(new PointerEvent(type,{button:0,pointerId:id,clientX:x,clientY:y,bubbles:true}));

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 901
902 const c=key(60).getBoundingClientRect(),e=key(64).getBoundingClientRect(),d=key(62).getBoundingClientRect();

Declare this compile-time constant or fixed array. The value and physical/capacity meaning are given by its source comment and this chapter.

Link to line 902
903 pointer(key(60),'pointerdown',31,c.left+5,c.bottom-5);pointer(key(64),'pointerdown',32,e.left+5,e.bottom-5);

Call the displayed operation with these arguments as the next step in “Check pointer-held notes and cancellation”. The chapter describes its role and validation.

Link to line 903
904 if(active.size!==2)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check pointer-held notes and cancellation” explanation above.

Link to line 904
905 pointer(outer,'pointermove',31,d.left+5,d.bottom-5);if(messages.slice(-2).map(m=>m.join(':')).join(',')!=='off:60,on:62')return false;

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 905
906 pointer(outer,'pointercancel',31,0,0);if(active.size!==1)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check pointer-held notes and cancellation” explanation above.

Link to line 906
907 piano.releaseAll();if(active.size!==0)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check pointer-held notes and cancellation” explanation above.

Link to line 907
908 piano.setActiveNotes([61]);if(!key(61).classList.contains('held')||messages.length!==6)return false;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check pointer-held notes and cancellation” explanation above.

Link to line 908
909 key(60).dispatchEvent(new KeyboardEvent('keydown',{key:' ',bubbles:true}));key(60).dispatchEvent(new KeyboardEvent('keyup',{key:' ',bubbles:true}));

Call the displayed operation with these arguments as the next step in “Check pointer-held notes and cancellation”. The chapter describes its role and validation.

Link to line 909
910 if(active.size!==0||messages.slice(-2).map(m=>m.join(':')).join(',')!=='on:60,off:60')return false;

Handle the matching pattern on the left using the expression or scope on the right. Other variants are handled by the following arms.

Link to line 910
911 piano.dispose();outer.remove();return true;

Continue the surrounding value or expression with this exact operand. Read it together with the preceding statement and the “Check pointer-held notes and cancellation” explanation above.

Link to line 911
912 })()"#)?);

The ? operator returns an error immediately on failure and unwraps the success value for the next step.

Link to line 912
913 Ok(())

Report successful completion without returning a payload.

Link to line 913
914}

Close the surrounding scope, value or argument list in “Check pointer-held notes and cancellation”.

Link to line 914

Source SHA-256: c7eea42fb4f5a9922adb3933204dbbca319ab1a0a076dcd2c7eac42558a5d0cf

API: ravet_device · ravet_foundation · ravet_midi_device · ravet_surface · ravet_webview

All tutorial walkthroughs