1use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct SourceLocation {
14 pub file: Option<String>,
15 pub line: Option<u32>,
16 pub column: Option<u32>,
17}
18
19#[derive(Debug, Serialize)]
24pub struct TransportState {
25 pub bpm: f64,
26 pub time_signature: TimeSignature,
27 pub running: bool,
28 pub current_beat: f64,
29 pub quantization_beats: f64,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub loop_beats: Option<f64>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub loop_beat: Option<f64>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub server_time_ms: Option<u64>,
39}
40
41#[derive(Debug, Serialize, Deserialize)]
42pub struct TimeSignature {
43 pub numerator: u8,
44 pub denominator: u8,
45}
46
47#[derive(Debug, Deserialize)]
48pub struct TransportUpdate {
49 pub bpm: Option<f64>,
50 pub time_signature: Option<TimeSignature>,
51 pub quantization_beats: Option<f64>,
52}
53
54#[derive(Debug, Deserialize)]
55pub struct SeekRequest {
56 pub beat: f64,
57}
58
59#[derive(Debug, Serialize)]
64pub struct Group {
65 pub name: String,
66 pub path: String,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub parent_path: Option<String>,
69 pub children: Vec<String>,
70 pub node_id: i32,
71 pub audio_bus: i32,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub link_synth_node_id: Option<i32>,
74 pub muted: bool,
75 pub soloed: bool,
76 pub params: HashMap<String, f32>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub synth_node_ids: Option<Vec<i32>>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub source_location: Option<SourceLocation>,
81}
82
83#[derive(Debug, Deserialize)]
84pub struct GroupCreate {
85 pub name: String,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub parent_path: Option<String>,
88 #[serde(default)]
89 pub params: HashMap<String, f32>,
90}
91
92#[derive(Debug, Deserialize)]
93pub struct GroupUpdate {
94 #[serde(default)]
95 pub params: HashMap<String, f32>,
96}
97
98#[derive(Debug, Deserialize)]
99pub struct ParamSet {
100 pub value: f32,
101 pub fade_beats: Option<f64>,
102}
103
104#[derive(Debug, Serialize)]
109pub struct Voice {
110 pub name: String,
111 pub synth_name: String,
112 pub polyphony: u8,
113 pub gain: f32,
114 pub group_path: String,
115 #[serde(skip_serializing_if = "Option::is_none")]
116 pub group_name: Option<String>,
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub output_bus: Option<i32>,
119 pub muted: bool,
120 pub soloed: bool,
121 pub params: HashMap<String, f32>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub sfz_instrument: Option<String>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub vst_instrument: Option<String>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub active_notes: Option<Vec<u8>>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub sustained_notes: Option<Vec<u8>>,
130 pub running: bool,
131 #[serde(skip_serializing_if = "Option::is_none")]
132 pub running_node_id: Option<i32>,
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub source_location: Option<SourceLocation>,
135}
136
137#[derive(Debug, Deserialize)]
138pub struct VoiceCreate {
139 pub name: Option<String>,
140 #[serde(alias = "synthdef")]
141 pub synth_name: Option<String>,
142 pub polyphony: Option<u8>,
143 pub gain: Option<f32>,
144 #[serde(alias = "group_id")]
145 pub group_path: Option<String>,
146 #[serde(default)]
147 pub params: HashMap<String, f32>,
148 pub sample: Option<String>,
149 pub sfz: Option<String>,
150}
151
152#[derive(Debug, Deserialize)]
153pub struct VoiceUpdate {
154 pub synth_name: Option<String>,
155 pub polyphony: Option<u8>,
156 pub gain: Option<f32>,
157 #[serde(default)]
158 pub params: HashMap<String, f32>,
159}
160
161#[derive(Debug, Deserialize)]
162pub struct TriggerRequest {
163 #[serde(default)]
164 pub params: HashMap<String, f32>,
165}
166
167#[derive(Debug, Deserialize)]
168pub struct NoteOnRequest {
169 pub note: u8,
170 #[serde(default = "default_velocity")]
171 pub velocity: f32,
172}
173
174fn default_velocity() -> f32 {
175 0.8
176}
177
178#[derive(Debug, Deserialize)]
179pub struct NoteOffRequest {
180 pub note: u8,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(rename_all = "snake_case")]
189pub enum LoopState {
190 Stopped,
191 Queued,
192 Playing,
193 QueuedStop,
194}
195
196#[derive(Debug, Clone, Serialize)]
197pub struct LoopStatus {
198 pub state: LoopState,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 pub start_beat: Option<f64>,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 pub stop_beat: Option<f64>,
203}
204
205#[derive(Debug, Serialize)]
210pub struct Pattern {
211 pub name: String,
212 pub voice_name: String,
213 pub group_path: String,
214 pub loop_beats: f64,
215 pub events: Vec<PatternEvent>,
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub params: Option<HashMap<String, f32>>,
218 pub status: LoopStatus,
219 pub is_looping: bool,
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub source_location: Option<SourceLocation>,
222 #[serde(skip_serializing_if = "Option::is_none")]
224 pub step_pattern: Option<String>,
225}
226
227#[derive(Debug, Serialize, Deserialize)]
228pub struct PatternEvent {
229 pub beat: f64,
230 #[serde(default, skip_serializing_if = "Option::is_none")]
231 pub params: Option<HashMap<String, f32>>,
232}
233
234#[derive(Debug, Deserialize)]
235pub struct PatternUpdate {
236 pub events: Option<Vec<PatternEvent>>,
237 pub pattern_string: Option<String>,
238 pub loop_beats: Option<f64>,
239 #[serde(default)]
240 pub params: HashMap<String, f32>,
241}
242
243#[derive(Debug, Deserialize)]
244pub struct PatternCreate {
245 pub name: String,
247 pub voice_name: String,
249 #[serde(default = "default_loop_beats")]
251 pub loop_beats: f64,
252 #[serde(default)]
254 pub events: Vec<PatternEvent>,
255 pub pattern_string: Option<String>,
257 #[serde(default)]
259 pub params: HashMap<String, f32>,
260 #[serde(default)]
262 pub swing: f32,
263}
264
265fn default_loop_beats() -> f64 {
266 4.0
267}
268
269#[derive(Debug, Deserialize)]
270pub struct StartRequest {
271 pub quantize_beats: Option<f64>,
272}
273
274#[derive(Debug, Deserialize)]
275pub struct StopRequest {
276 pub quantize_beats: Option<f64>,
277}
278
279#[derive(Debug, Serialize)]
284pub struct Melody {
285 pub name: String,
286 pub voice_name: String,
287 pub group_path: String,
288 pub loop_beats: f64,
289 pub events: Vec<MelodyEvent>,
290 #[serde(skip_serializing_if = "Option::is_none")]
291 pub params: Option<HashMap<String, f32>>,
292 pub status: LoopStatus,
293 pub is_looping: bool,
294 #[serde(skip_serializing_if = "Option::is_none")]
295 pub source_location: Option<SourceLocation>,
296 #[serde(skip_serializing_if = "Option::is_none")]
298 pub notes_patterns: Option<Vec<String>>,
299}
300
301#[derive(Debug, Serialize, Deserialize)]
302pub struct MelodyEvent {
303 pub beat: f64,
304 pub note: String,
305 #[serde(skip_serializing_if = "Option::is_none")]
306 pub frequency: Option<f64>,
307 #[serde(skip_serializing_if = "Option::is_none")]
308 pub duration: Option<f64>,
309 #[serde(skip_serializing_if = "Option::is_none")]
310 pub velocity: Option<f32>,
311 #[serde(default, skip_serializing_if = "Option::is_none")]
312 pub params: Option<HashMap<String, f32>>,
313}
314
315#[derive(Debug, Deserialize)]
316pub struct MelodyCreate {
317 pub name: String,
319 pub voice_name: String,
321 #[serde(default = "default_loop_beats")]
323 pub loop_beats: f64,
324 #[serde(default)]
326 pub events: Vec<MelodyEvent>,
327 pub melody_string: Option<String>,
329 #[serde(default)]
331 pub params: HashMap<String, f32>,
332}
333
334#[derive(Debug, Deserialize)]
335pub struct MelodyUpdate {
336 pub events: Option<Vec<MelodyEvent>>,
337 pub melody_string: Option<String>,
338 pub lanes: Option<Vec<String>>,
339 pub loop_beats: Option<f64>,
340 #[serde(default)]
341 pub params: HashMap<String, f32>,
342}
343
344#[derive(Debug, Serialize)]
349pub struct Sequence {
350 pub name: String,
351 pub loop_beats: f64,
352 pub clips: Vec<SequenceClip>,
353 #[serde(skip_serializing_if = "Option::is_none")]
354 pub play_once: Option<bool>,
355 #[serde(skip_serializing_if = "Option::is_none")]
356 pub active: Option<bool>,
357 #[serde(skip_serializing_if = "Option::is_none")]
358 pub source_location: Option<SourceLocation>,
359}
360
361#[derive(Debug, Serialize, Deserialize)]
362pub struct SequenceClip {
363 #[serde(rename = "type")]
364 pub clip_type: String,
365 pub name: String,
366 pub start_beat: f64,
367 #[serde(skip_serializing_if = "Option::is_none")]
368 pub end_beat: Option<f64>,
369 #[serde(skip_serializing_if = "Option::is_none")]
370 pub duration_beats: Option<f64>,
371 #[serde(skip_serializing_if = "Option::is_none")]
372 pub once: Option<bool>,
373}
374
375#[derive(Debug, Deserialize)]
376pub struct SequenceCreate {
377 pub name: String,
379 #[serde(default = "default_sequence_length")]
381 pub loop_beats: f64,
382 #[serde(default)]
384 pub clips: Vec<SequenceClip>,
385}
386
387fn default_sequence_length() -> f64 {
388 16.0
389}
390
391#[derive(Debug, Deserialize)]
392pub struct SequenceUpdate {
393 pub loop_beats: Option<f64>,
394 pub clips: Option<Vec<SequenceClip>>,
395}
396
397#[derive(Debug, Deserialize)]
398pub struct SequenceStartRequest {
399 #[serde(default)]
400 pub play_once: bool,
401}
402
403#[derive(Debug, Serialize)]
408pub struct Effect {
409 pub id: String,
410 pub synthdef_name: String,
411 pub group_path: String,
412 #[serde(skip_serializing_if = "Option::is_none")]
413 pub node_id: Option<i32>,
414 #[serde(skip_serializing_if = "Option::is_none")]
415 pub bus_in: Option<i32>,
416 #[serde(skip_serializing_if = "Option::is_none")]
417 pub bus_out: Option<i32>,
418 pub params: HashMap<String, f32>,
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub position: Option<i32>,
421 #[serde(skip_serializing_if = "Option::is_none")]
422 pub vst_plugin: Option<String>,
423 #[serde(skip_serializing_if = "Option::is_none")]
424 pub source_location: Option<SourceLocation>,
425}
426
427#[derive(Debug, Deserialize)]
428pub struct EffectCreate {
429 pub id: Option<String>,
430 pub synthdef_name: String,
431 pub group_path: String,
432 #[serde(default)]
433 pub params: HashMap<String, f32>,
434 pub position: Option<i32>,
435}
436
437#[derive(Debug, Deserialize)]
438pub struct EffectUpdate {
439 #[serde(default)]
440 pub params: HashMap<String, f32>,
441}
442
443#[derive(Debug, Serialize)]
448pub struct SampleSlice {
449 pub name: String,
450 pub start_frame: i64,
451 pub end_frame: i64,
452}
453
454#[derive(Debug, Serialize)]
455pub struct Sample {
456 pub id: String,
457 pub path: String,
458 pub buffer_id: i32,
459 pub num_channels: i32,
460 pub num_frames: i64,
461 pub sample_rate: f32,
462 pub synthdef_name: String,
463 #[serde(skip_serializing_if = "Option::is_none")]
464 pub slices: Option<Vec<SampleSlice>>,
465}
466
467#[derive(Debug, Deserialize)]
468pub struct SampleLoad {
469 pub path: String,
471 pub id: Option<String>,
473}
474
475#[derive(Debug, Serialize)]
480pub struct SynthDefParam {
481 pub name: String,
482 pub default_value: f32,
483 #[serde(skip_serializing_if = "Option::is_none")]
484 pub min_value: Option<f32>,
485 #[serde(skip_serializing_if = "Option::is_none")]
486 pub max_value: Option<f32>,
487}
488
489#[derive(Debug, Clone, Serialize, Deserialize)]
490#[serde(rename_all = "snake_case")]
491pub enum SynthDefSource {
492 Builtin,
493 User,
494 Stdlib,
495}
496
497#[derive(Debug, Serialize)]
498pub struct SynthDefInfo {
499 pub name: String,
500 pub params: Vec<SynthDefParam>,
501 #[serde(skip_serializing_if = "Option::is_none")]
502 pub source: Option<SynthDefSource>,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
510#[serde(rename_all = "snake_case")]
511pub enum FadeTargetType {
512 Group,
513 Voice,
514 Effect,
515}
516
517#[derive(Debug, Serialize)]
518pub struct ActiveFade {
519 pub id: String,
520 #[serde(skip_serializing_if = "Option::is_none")]
521 pub name: Option<String>,
522 pub target_type: FadeTargetType,
523 pub target_name: String,
524 pub param_name: String,
525 pub start_value: f32,
526 pub target_value: f32,
527 #[serde(skip_serializing_if = "Option::is_none")]
528 pub current_value: Option<f32>,
529 pub duration_beats: f64,
530 #[serde(skip_serializing_if = "Option::is_none")]
531 pub start_beat: Option<f64>,
532 pub progress: f64,
533}
534
535#[derive(Debug, Deserialize)]
536pub struct FadeCreate {
537 pub target_type: FadeTargetType,
538 pub target_name: String,
539 pub param_name: String,
540 pub start_value: Option<f32>,
541 pub target_value: f32,
542 pub duration_beats: f64,
543}
544
545#[derive(Debug, Serialize)]
550pub struct ActiveSynth {
551 pub node_id: i32,
552 pub synthdef_name: String,
553 #[serde(skip_serializing_if = "Option::is_none")]
554 pub voice_name: Option<String>,
555 #[serde(skip_serializing_if = "Option::is_none")]
556 pub group_path: Option<String>,
557 #[serde(skip_serializing_if = "Option::is_none")]
558 pub created_at_beat: Option<f64>,
559}
560
561#[derive(Debug, Serialize)]
562pub struct ActiveSequence {
563 pub name: String,
564 pub start_beat: f64,
565 pub current_position: f64,
566 pub loop_beats: f64,
567 #[serde(skip_serializing_if = "Option::is_none")]
568 pub iteration: Option<u32>,
569 #[serde(skip_serializing_if = "Option::is_none")]
570 pub play_once: Option<bool>,
571}
572
573#[derive(Debug, Serialize)]
574pub struct LiveState {
575 pub transport: TransportState,
576 pub active_synths: Vec<ActiveSynth>,
577 pub active_sequences: Vec<ActiveSequence>,
578 pub active_fades: Vec<ActiveFade>,
579 #[serde(skip_serializing_if = "Option::is_none")]
580 pub active_notes: Option<HashMap<String, Vec<u8>>>,
581 #[serde(skip_serializing_if = "Option::is_none")]
582 pub patterns_status: Option<HashMap<String, LoopStatus>>,
583 #[serde(skip_serializing_if = "Option::is_none")]
584 pub melodies_status: Option<HashMap<String, LoopStatus>>,
585}
586
587#[derive(Debug, Serialize)]
592pub struct MeterLevel {
593 pub peak_left: f32,
594 pub peak_right: f32,
595 pub rms_left: f32,
596 pub rms_right: f32,
597}
598
599pub type MeterLevels = HashMap<String, MeterLevel>;
601
602#[derive(Debug, Serialize)]
607pub struct ErrorResponse {
608 pub error: String,
609 pub message: String,
610}
611
612impl ErrorResponse {
613 pub fn new(error: &str, message: &str) -> Self {
614 Self {
615 error: error.to_string(),
616 message: message.to_string(),
617 }
618 }
619
620 pub fn not_found(message: &str) -> Self {
621 Self::new("not_found", message)
622 }
623
624 pub fn bad_request(message: &str) -> Self {
625 Self::new("bad_request", message)
626 }
627
628 pub fn internal(message: &str) -> Self {
629 Self::new("internal_error", message)
630 }
631}