1use num;
3use num_derive;
4use num_derive::FromPrimitive;
5use std::ops::{Add, Sub};
6
7use crate::elements::Program;
8use redact_composer_core::{derive::Element, IntoSegment};
9use redact_composer_core::{
10 elements::PlayNote,
11 render::{AdhocRenderer, RenderEngine, Renderer, Result},
12 Segment,
13};
14
15#[cfg(feature = "serde")]
16use serde::{Deserialize, Serialize};
17
18pub fn renderers() -> RenderEngine {
21 RenderEngine::new() + Instrument::renderer() + DrumHit::renderer()
22}
23
24pub mod elements {
26 pub use super::{DrumHit, Instrument};
27}
28
29#[derive(Element, Debug, Hash, FromPrimitive, PartialEq, Clone, Copy)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[allow(missing_docs)]
34pub enum Instrument {
35 AcousticGrandPiano,
37 BrightAcousticPiano,
38 ElectricGrandPiano,
39 HonkyTonkPiano,
40 ElectricPiano1,
41 ElectricPiano2,
42 Harpsichord,
43 Clavi,
44
45 Celesta,
47 Glockenspiel,
48 MusicBox,
49 Vibraphone,
50 Marimba,
51 Xylophone,
52 TubularBells,
53 Dulcimer,
54
55 DrawbarOrgan,
57 PercussiveOrgan,
58 RockOrgan,
59 ChurchOrgan,
60 ReedOrgan,
61 Accordion,
62 Harmonica,
63 TangoAccordion,
64
65 AcousticGuitarNylon,
67 AcousticGuitarSteel,
68 ElectricGuitarJazz,
69 ElectricGuitarClean,
70 ElectricGuitarMuted,
71 OverdrivenGuitar,
72 DistortionGuitar,
73 GuitarHarmonics,
74
75 AcousticBass,
77 ElectricBassFinger,
78 ElectricBassPick,
79 FretlessBass,
80 SlapBass1,
81 SlapBass2,
82 SynthBass1,
83 SynthBass2,
84
85 Violin,
87 Viola,
88 Cello,
89 Contrabass,
90 TremoloStrings,
91 PizzicatoStrings,
92 OrchestralHarp,
93 Timpani,
94
95 StringEnsemble1,
97 StringEnsemble2,
98 SynthStrings1,
99 SynthStrings2,
100 ChoirAahs,
101 ChoirOohs,
102 SynthVoice,
103 OrchestraHit,
104
105 Trumpet,
107 Trombone,
108 Tuba,
109 MutedTrumpet,
110 FrenchHorn,
111 BrassSection,
112 SynthBrass1,
113 SynthBrass2,
114
115 SopranoSax,
117 AltoSax,
118 TenorSax,
119 BaritoneSax,
120 Oboe,
121 EnglishHorn,
122 Bassoon,
123 Clarinet,
124
125 Piccolo,
127 Flute,
128 Recorder,
129 PanFlute,
130 BlownBottle,
131 Shakuhachi,
132 Whistle,
133 Ocarina,
134
135 LeadSquare,
137 LeadSawtooth,
138 LeadCalliope,
139 LeadChiff,
140 LeadCharang,
141 LeadVoice,
142 LeadFifths,
143 LeadBassPlusLead,
144
145 PadNewAge,
147 PadWarm,
148 PadPolySynth,
149 PadChoir,
150 PadBowed,
151 PadMetallic,
152 PadHalo,
153 PadSweep,
154
155 FXRain,
157 FXSoundtrack,
158 FXCrystal,
159 FXAtmosphere,
160 FXBrightness,
161 FXGoblins,
162 FXEchoes,
163 FXSciFi,
164
165 Sitar,
167 Banjo,
168 Shamisen,
169 Koto,
170 Kalimba,
171 BagPipe,
172 Fiddle,
173 Shanai,
174
175 TinkleBell,
177 Agogo,
178 SteelDrums,
179 Woodblock,
180 TaikoDrum,
181 MelodicTom,
182 SynthDrum,
183 ReverseCymbal,
184
185 GuitarFretNoise,
187 BreathNoise,
188 Seashore,
189 BirdTweet,
190 TelephoneRing,
191 Helicopter,
192 Applause,
193 Gunshot,
194}
195
196impl From<Instrument> for Program {
197 fn from(value: Instrument) -> Program {
198 Program(value as u8)
199 }
200}
201
202impl Instrument {
203 pub fn renderer() -> impl Renderer<Element = Self> {
205 AdhocRenderer::<Self>::new(|segment, _| {
206 Result::Ok(vec![Program::from(*segment.element).over(segment.timing)])
207 })
208 }
209}
210
211impl Add for Instrument {
220 type Output = Instruments;
221
222 fn add(self, rhs: Self) -> Self::Output {
223 Instruments {
224 instruments: vec![self, rhs],
225 }
226 }
227}
228
229impl Add<Instruments> for Instrument {
239 type Output = Instruments;
240
241 fn add(self, rhs: Instruments) -> Self::Output {
242 Instruments {
243 instruments: vec![self],
244 } + rhs
245 }
246}
247
248impl From<u8> for Instrument {
255 fn from(value: u8) -> Self {
256 num::FromPrimitive::from_u8(value).unwrap()
257 }
258}
259
260impl From<Instrument> for u8 {
261 fn from(value: Instrument) -> Self {
262 value as u8
263 }
264}
265
266#[derive(Debug, Clone, PartialEq)]
268pub struct Instruments {
269 pub instruments: Vec<Instrument>,
271}
272
273impl Instruments {
274 pub fn all() -> Instruments {
276 Instruments {
277 instruments: (0..128).map(Instrument::from).collect(),
278 }
279 }
280
281 pub fn piano() -> Instruments {
283 Instruments {
284 instruments: (0..8).map(Instrument::from).collect(),
285 }
286 }
287
288 pub fn tonal_percussive() -> Instruments {
290 Instruments {
291 instruments: (8..16).map(Instrument::from).collect(),
292 }
293 }
294
295 pub fn organ() -> Instruments {
297 Instruments {
298 instruments: (16..24).map(Instrument::from).collect(),
299 }
300 }
301
302 pub fn guitar() -> Instruments {
304 Instruments {
305 instruments: (24..32).map(Instrument::from).collect(),
306 }
307 }
308
309 pub fn bass() -> Instruments {
311 Instruments {
312 instruments: (32..40).map(Instrument::from).collect(),
313 }
314 }
315
316 pub fn strings() -> Instruments {
318 Instruments {
319 instruments: (40..48).map(Instrument::from).collect(),
320 }
321 }
322
323 pub fn ensemble() -> Instruments {
325 Instruments {
326 instruments: (48..56).map(Instrument::from).collect(),
327 }
328 }
329
330 pub fn brass() -> Instruments {
332 Instruments {
333 instruments: (56..64).map(Instrument::from).collect(),
334 }
335 }
336
337 pub fn reed() -> Instruments {
339 Instruments {
340 instruments: (64..72).map(Instrument::from).collect(),
341 }
342 }
343
344 pub fn pipe() -> Instruments {
346 Instruments {
347 instruments: (72..80).map(Instrument::from).collect(),
348 }
349 }
350
351 pub fn synth_lead() -> Instruments {
353 Instruments {
354 instruments: (80..88).map(Instrument::from).collect(),
355 }
356 }
357
358 pub fn synth_pad() -> Instruments {
360 Instruments {
361 instruments: (88..96).map(Instrument::from).collect(),
362 }
363 }
364
365 pub fn synth_fx() -> Instruments {
367 Instruments {
368 instruments: (96..104).map(Instrument::from).collect(),
369 }
370 }
371
372 pub fn ethnic() -> Instruments {
374 Instruments {
375 instruments: (104..112).map(Instrument::from).collect(),
376 }
377 }
378
379 pub fn percussive() -> Instruments {
381 Instruments {
382 instruments: (112..120).map(Instrument::from).collect(),
383 }
384 }
385
386 pub fn sound_fx() -> Instruments {
388 Instruments {
389 instruments: (120..128).map(Instrument::from).collect(),
390 }
391 }
392
393 pub fn melodic() -> Instruments {
395 Self::all()
396 - Self::percussive()
397 - Self::sound_fx()
398 - Self::synth_fx()
399 - Instrument::Timpani
400 - Instrument::TubularBells
401 - Instrument::PadBowed
402 - Instrument::LeadFifths
403 - Instrument::OrchestraHit
404 - Instrument::Kalimba
405 - Instrument::GuitarHarmonics
406 }
407}
408
409impl IntoIterator for Instruments {
410 type Item = Instrument;
411
412 type IntoIter = std::vec::IntoIter<Self::Item>;
413
414 fn into_iter(self) -> Self::IntoIter {
415 self.instruments.into_iter()
416 }
417}
418
419impl Add for Instruments {
429 type Output = Self;
430
431 fn add(self, rhs: Self) -> Self::Output {
432 Instruments {
433 instruments: self.into_iter().chain(rhs).collect(),
434 }
435 }
436}
437
438impl Add<Instrument> for Instruments {
448 type Output = Self;
449
450 fn add(self, rhs: Instrument) -> Self::Output {
451 Instruments {
452 instruments: self.into_iter().chain(vec![rhs]).collect(),
453 }
454 }
455}
456
457impl Sub for Instruments {
467 type Output = Self;
468
469 fn sub(self, rhs: Self) -> Self::Output {
470 Instruments {
471 instruments: self
472 .into_iter()
473 .filter(|i| !rhs.instruments.contains(i))
474 .collect(),
475 }
476 }
477}
478
479impl Sub<Instrument> for Instruments {
491 type Output = Self;
492
493 fn sub(self, rhs: Instrument) -> Self::Output {
494 Instruments {
495 instruments: self.into_iter().filter(|i| *i != rhs).collect(),
496 }
497 }
498}
499
500impl From<Instruments> for Vec<Instrument> {
513 fn from(value: Instruments) -> Self {
514 value.instruments
515 }
516}
517
518#[derive(Element, Clone, Copy, Debug)]
520#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
521pub struct DrumHit {
522 pub hit: DrumHitType,
524 pub velocity: u8,
526}
527
528impl DrumHit {
529 pub fn renderer() -> impl Renderer<Element = Self> {
531 AdhocRenderer::<Self>::new(|segment, _| {
532 Result::Ok(vec![Segment::new(
533 PlayNote {
534 note: segment.element.hit.into(),
535 velocity: segment.element.velocity,
536 },
537 segment.timing,
538 )])
539 })
540 }
541}
542
543#[derive(Debug, Hash, FromPrimitive, PartialEq, Clone, Copy)]
546#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
547#[allow(missing_docs)]
548pub enum DrumHitType {
549 AcousticBassDrum = 35,
550 BassDrum,
551 SideStick,
552 AcousticSnare,
553 HandClap,
554 ElectricSnare,
555 LowFloorTom,
556 ClosedHiHat,
557 HighFloorTom,
558 PedalHiHat,
559 LowTom,
560 OpenHiHat,
561 LowMidTom,
562 HighMidTom,
563 CrashCymbal1,
564 HighTom,
565 RideCymbal1,
566 ChineseCymbal,
567 RideBell,
568 Tambourine,
569 SplashCymbal,
570 Cowbell,
571 CrashCymbal2,
572 Vibraslap,
573 RideCymbal2,
574 HighBongo,
575 LowBongo,
576 MuteHighConga,
577 OpenHighConga,
578 LowConga,
579 HighTimbale,
580 LowTimbale,
581 HighAgogo,
582 LowAgogo,
583 Cabasa,
584 Maracas,
585 ShortWhistle,
586 LongWhistle,
587 ShortGuiro,
588 LongGuiro,
589 Claves,
590 HighWoodblock,
591 LowWoodblock,
592 MuteCuica,
593 OpenCuica,
594 MuteTriangle,
595 OpenTriangle,
596}
597
598impl From<u8> for DrumHitType {
599 fn from(value: u8) -> Self {
600 num::FromPrimitive::from_u8(value).unwrap()
601 }
602}
603
604impl From<DrumHitType> for u8 {
605 fn from(value: DrumHitType) -> Self {
606 value as u8
607 }
608}