1use std::{
4 fmt::{Display, Formatter},
5 mem,
6 ptr::{null_mut, slice_from_raw_parts},
7};
8
9use crate::{
10 ffi::{
11 CLAP_CORE_EVENT_SPACE_ID, CLAP_EVENT_DONT_RECORD, CLAP_EVENT_IS_LIVE, CLAP_EVENT_MIDI,
12 CLAP_EVENT_MIDI2, CLAP_EVENT_NOTE_CHOKE, CLAP_EVENT_NOTE_END, CLAP_EVENT_NOTE_EXPRESSION,
13 CLAP_EVENT_NOTE_OFF, CLAP_EVENT_NOTE_ON, CLAP_EVENT_PARAM_MOD, CLAP_EVENT_PARAM_VALUE,
14 CLAP_EVENT_TRANSPORT, CLAP_NOTE_EXPRESSION_BRIGHTNESS, CLAP_NOTE_EXPRESSION_EXPRESSION,
15 CLAP_NOTE_EXPRESSION_PAN, CLAP_NOTE_EXPRESSION_PRESSURE, CLAP_NOTE_EXPRESSION_TUNING,
16 CLAP_NOTE_EXPRESSION_VIBRATO, CLAP_NOTE_EXPRESSION_VOLUME,
17 CLAP_TRANSPORT_HAS_BEATS_TIMELINE, CLAP_TRANSPORT_HAS_SECONDS_TIMELINE,
18 CLAP_TRANSPORT_HAS_TEMPO, CLAP_TRANSPORT_HAS_TIME_SIGNATURE, CLAP_TRANSPORT_IS_LOOP_ACTIVE,
19 CLAP_TRANSPORT_IS_PLAYING, CLAP_TRANSPORT_IS_RECORDING, CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL,
20 clap_event_header, clap_event_midi, clap_event_midi2, clap_event_note,
21 clap_event_note_expression, clap_event_param_mod, clap_event_param_value,
22 clap_event_transport, clap_input_events, clap_note_expression, clap_output_events,
23 },
24 fixedpoint::{BeatTime, SecTime},
25 id::ClapId,
26 impl_flags_u32,
27};
28
29#[derive(Debug, Copy, Clone, PartialEq, Eq)]
30#[repr(u32)]
31pub enum EventFlags {
32 IsLive = CLAP_EVENT_IS_LIVE,
35 DontRecord = CLAP_EVENT_DONT_RECORD,
40}
41
42impl_flags_u32!(EventFlags);
43
44macro_rules! impl_event_cast_methods {
45 ($name:tt, $name_unchecked:tt, $type:ty, $cast_type:ty, $clap_id:ident $(,)?) => {
46 #[doc = concat!("The caller must ensure that this `Header` has correct \
48 size and type to contain the header and the payload of event of the \
49 returned type: `", stringify!($name), "`.")]
50 pub const unsafe fn $name_unchecked(&self) -> $type {
51 unsafe { <$type>::new_unchecked(self) }
52 }
53
54 pub const fn $name(&self) -> Result<$type, Error> {
55 if self.r#type() != $clap_id as u16 {
56 return Err(Error::OtherType(self.r#type()));
57 }
58 if self.size() != size_of::<$cast_type>() as u32 {
59 return Err(Error::PayloadSize(self.size()));
60 }
61 Ok(unsafe { <$type>::new_unchecked(self) })
63 }
64 };
65}
66
67#[derive(Debug, PartialEq)]
68pub struct Header([u8]);
69
70impl Header {
71 pub const unsafe fn new_unchecked(header: &clap_event_header) -> &Self {
86 let len = header.size as usize;
87 let data = &raw const *header as *const _;
88 unsafe { &*(slice_from_raw_parts::<u8>(data, len) as *const _) }
89 }
90
91 const unsafe fn cast_unchecked<T>(&self) -> &T {
97 unsafe { &*self.0.as_ptr().cast() }
98 }
99
100 pub const fn as_clap_event_header(&self) -> &clap_event_header {
101 unsafe { self.cast_unchecked() }
104 }
105
106 #[doc(hidden)]
107 pub const fn to_bytes(&self) -> &[u8] {
108 &self.0
109 }
110
111 pub const fn flags(&self) -> u32 {
112 self.as_clap_event_header().flags
113 }
114
115 pub const fn size(&self) -> u32 {
116 self.0.len() as u32
117 }
118
119 pub const fn space_id(&self) -> u16 {
120 self.as_clap_event_header().space_id
121 }
122
123 pub const fn time(&self) -> u32 {
124 self.as_clap_event_header().time
125 }
126
127 pub const fn r#type(&self) -> u16 {
128 self.as_clap_event_header().r#type
129 }
130
131 pub const unsafe fn note_unchecked(&self) -> Note {
136 unsafe { Note::new_unchecked(self) }
137 }
138
139 pub const fn note(&self) -> Result<Note, Error> {
140 if self.r#type() != CLAP_EVENT_NOTE_ON as u16
141 && self.r#type() != CLAP_EVENT_NOTE_OFF as u16
142 && self.r#type() != CLAP_EVENT_NOTE_CHOKE as u16
143 && self.r#type() != CLAP_EVENT_NOTE_END as u16
144 {
145 return Err(Error::OtherType(self.r#type()));
146 }
147
148 if self.size() != size_of::<clap_event_note>() as u32 {
149 return Err(Error::PayloadSize(self.size()));
150 }
151 Ok(unsafe { Note::new_unchecked(self) })
153 }
154
155 impl_event_cast_methods!(
156 note_expression,
157 note_expression_unchecked,
158 NoteExpression,
159 clap_event_note_expression,
160 CLAP_EVENT_NOTE_EXPRESSION
161 );
162
163 impl_event_cast_methods!(
164 param_value,
165 param_value_unchecked,
166 ParamValue,
167 clap_event_param_value,
168 CLAP_EVENT_PARAM_VALUE
169 );
170
171 impl_event_cast_methods!(
172 param_mod,
173 param_mod_unchecked,
174 ParamMod,
175 clap_event_param_mod,
176 CLAP_EVENT_PARAM_MOD
177 );
178
179 impl_event_cast_methods!(
180 transport,
181 transport_unchecked,
182 Transport,
183 clap_event_transport,
184 CLAP_EVENT_TRANSPORT
185 );
186
187 impl_event_cast_methods!(midi, midi_unchecked, Midi, clap_event_midi, CLAP_EVENT_MIDI);
188
189 impl_event_cast_methods!(
190 midi2,
191 midi2_unchecked,
192 Midi2,
193 clap_event_midi2,
194 CLAP_EVENT_MIDI2
195 );
196}
197
198pub trait Event {
199 fn header(&self) -> &Header;
200
201 fn to_bytes(&self) -> &[u8] {
202 self.header().to_bytes()
203 }
204}
205
206pub trait EventBuilder {
207 type Event<'a>: Event
208 where
209 Self: 'a;
210
211 fn time(self, value: u32) -> Self;
212 fn space_id(self, value: u16) -> Self;
213 fn flags(self, value: u32) -> Self;
214
215 fn event(&self) -> Self::Event<'_>;
216}
217
218macro_rules! impl_event_const_getter {
219 ($name:tt, $cast_method:ident, $type:ty $(,)?) => {
220 pub const fn $name(&self) -> $type {
221 self.$cast_method().$name
222 }
223 };
224}
225
226macro_rules! impl_event_builder_setter {
227 ($name:tt, $type:ty $(,)*) => {
228 #[must_use]
229 pub const fn $name(self, value: $type) -> Self {
230 let mut build = self;
231 build.0.$name = value;
232 build
233 }
234 };
235}
236
237macro_rules! impl_event_builder {
238 ($type:ty, $event_type:ty, $cast_method:ident $(,)?) => {
239 impl EventBuilder for $type {
240 type Event<'a>
241 = $event_type
242 where
243 Self: 'a;
244
245 fn time(self, value: u32) -> Self {
246 let mut build = self;
247 build.0.header.time = value;
248 build
249 }
250
251 fn space_id(self, value: u16) -> Self {
252 let mut build = self;
253 build.0.header.space_id = value;
254 build
255 }
256
257 fn flags(self, value: u32) -> Self {
258 let mut build = self;
259 build.0.header.flags = value;
260 build
261 }
262
263 fn event(&self) -> Self::Event<'_> {
264 let header = unsafe { Header::new_unchecked(&self.0.header) };
266 unsafe { header.$cast_method() }
267 }
268 }
269 };
270}
271
272#[derive(Debug, Copy, Clone, PartialEq)]
273#[repr(u16)]
274pub enum NoteKind {
275 On = CLAP_EVENT_NOTE_ON as u16,
276 Off = CLAP_EVENT_NOTE_OFF as u16,
277 Choke = CLAP_EVENT_NOTE_CHOKE as u16,
278 End = CLAP_EVENT_NOTE_END as u16,
279}
280
281#[derive(Debug, Copy, Clone, PartialEq)]
282pub struct Note<'a> {
283 header: &'a Header,
284 pub kind: NoteKind,
285}
286
287impl<'a> Note<'a> {
288 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
292 let kind: NoteKind = unsafe { mem::transmute(header.r#type()) };
295
296 Self { header, kind }
297 }
298
299 const fn as_clap_event_note(&self) -> &clap_event_note {
300 unsafe { self.header.cast_unchecked() }
302 }
303
304 impl_event_const_getter!(note_id, as_clap_event_note, i32);
305 impl_event_const_getter!(port_index, as_clap_event_note, i16);
306 impl_event_const_getter!(channel, as_clap_event_note, i16);
307 impl_event_const_getter!(key, as_clap_event_note, i16);
308 impl_event_const_getter!(velocity, as_clap_event_note, f64);
309
310 pub const fn build(kind: NoteKind) -> NoteBuilder {
311 NoteBuilder::new(kind)
312 }
313
314 pub fn update(&self) -> NoteBuilder {
315 NoteBuilder::with_note(self)
316 }
317}
318
319impl Event for Note<'_> {
320 fn header(&self) -> &Header {
321 self.header
322 }
323}
324
325#[derive(Debug, Copy, Clone, PartialEq)]
326pub struct NoteBuilder(clap_event_note);
327
328impl NoteBuilder {
329 pub const fn new(kind: NoteKind) -> Self {
330 Self(clap_event_note {
331 header: clap_event_header {
332 size: size_of::<clap_event_note>() as u32,
333 time: 0,
334 space_id: CLAP_CORE_EVENT_SPACE_ID,
335 r#type: kind as u16,
336 flags: 0,
337 },
338 note_id: 0,
339 port_index: 0,
340 channel: 0,
341 key: 0,
342 velocity: 0.0,
343 })
344 }
345
346 pub fn with_note(note: &Note<'_>) -> Self {
347 Self(*unsafe { note.header().cast_unchecked() })
350 }
351
352 impl_event_builder_setter!(note_id, i32);
353 impl_event_builder_setter!(port_index, i16);
354 impl_event_builder_setter!(channel, i16);
355 impl_event_builder_setter!(key, i16);
356 impl_event_builder_setter!(velocity, f64);
357
358 pub const fn kind(self, value: NoteKind) -> Self {
359 let mut build = self;
360 build.0.header.r#type = value as u16;
361 build
362 }
363}
364
365impl Default for NoteBuilder {
366 fn default() -> Self {
367 Self::new(NoteKind::On)
368 }
369}
370
371impl From<clap_event_note> for NoteBuilder {
372 fn from(value: clap_event_note) -> Self {
373 Self(value)
374 }
375}
376
377impl_event_builder!(NoteBuilder, Note<'a>, note_unchecked);
378
379#[derive(Debug, Copy, Clone, PartialEq)]
380#[repr(u32)]
381pub enum NoteExpressionId {
382 Volume = CLAP_NOTE_EXPRESSION_VOLUME as u32,
384
385 Pan = CLAP_NOTE_EXPRESSION_PAN as u32,
387
388 Tuning = CLAP_NOTE_EXPRESSION_TUNING as u32,
392
393 Vibrato = CLAP_NOTE_EXPRESSION_VIBRATO as u32,
395 Expression = CLAP_NOTE_EXPRESSION_EXPRESSION as u32,
396 Brightness = CLAP_NOTE_EXPRESSION_BRIGHTNESS as u32,
397 Pressure = CLAP_NOTE_EXPRESSION_PRESSURE as u32,
398}
399
400#[derive(Debug, Copy, Clone, PartialEq)]
401pub struct NoteExpression<'a> {
402 header: &'a Header,
403}
404
405impl<'a> NoteExpression<'a> {
406 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
410 Self { header }
411 }
412
413 const fn as_clap_event_note_expression(&self) -> &clap_event_note_expression {
414 unsafe { self.header.cast_unchecked() }
416 }
417
418 impl_event_const_getter!(note_id, as_clap_event_note_expression, i32);
419 impl_event_const_getter!(port_index, as_clap_event_note_expression, i16);
420 impl_event_const_getter!(channel, as_clap_event_note_expression, i16);
421 impl_event_const_getter!(key, as_clap_event_note_expression, i16);
422 impl_event_const_getter!(value, as_clap_event_note_expression, f64);
423
424 pub const fn expression_id(&self) -> NoteExpressionId {
425 let id = self.as_clap_event_note_expression().expression_id;
426 unsafe { mem::transmute(id) }
429 }
430
431 pub const fn build(expression_id: NoteExpressionId) -> NoteExpressionBuilder {
432 NoteExpressionBuilder::new(expression_id)
433 }
434
435 pub fn update(&self) -> NoteExpressionBuilder {
436 NoteExpressionBuilder::with_note_expression(self)
437 }
438}
439
440impl Event for NoteExpression<'_> {
441 fn header(&self) -> &Header {
442 self.header
443 }
444}
445
446#[derive(Debug, Copy, Clone, PartialEq)]
447pub struct NoteExpressionBuilder(clap_event_note_expression);
448
449impl NoteExpressionBuilder {
450 pub const fn new(expression_id: NoteExpressionId) -> Self {
451 Self(clap_event_note_expression {
452 header: clap_event_header {
453 size: size_of::<clap_event_note_expression>() as u32,
454 time: 0,
455 space_id: CLAP_CORE_EVENT_SPACE_ID,
456 r#type: CLAP_EVENT_NOTE_EXPRESSION as u16,
457 flags: 0,
458 },
459 expression_id: expression_id as clap_note_expression,
460 note_id: 0,
461 port_index: 0,
462 channel: 0,
463 key: 0,
464 value: 0.0,
465 })
466 }
467
468 pub fn with_note_expression(expression: &NoteExpression<'_>) -> Self {
469 Self(*unsafe { expression.header().cast_unchecked() })
472 }
473
474 impl_event_builder_setter!(note_id, i32);
475 impl_event_builder_setter!(port_index, i16);
476 impl_event_builder_setter!(channel, i16);
477 impl_event_builder_setter!(key, i16);
478 impl_event_builder_setter!(value, f64);
479
480 pub const fn expression_id(self, value: NoteExpressionId) -> Self {
481 let mut build = self;
482 build.0.expression_id = value as clap_note_expression;
483 build
484 }
485}
486
487impl Default for NoteExpressionBuilder {
488 fn default() -> Self {
489 Self::new(NoteExpressionId::Volume)
490 }
491}
492
493impl From<clap_event_note_expression> for NoteExpressionBuilder {
494 fn from(value: clap_event_note_expression) -> Self {
495 Self(value)
496 }
497}
498
499impl_event_builder!(
500 NoteExpressionBuilder,
501 NoteExpression<'a>,
502 note_expression_unchecked
503);
504
505#[derive(Debug, Copy, Clone, PartialEq)]
506pub struct ParamValue<'a> {
507 header: &'a Header,
508}
509
510impl<'a> ParamValue<'a> {
511 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
515 Self { header }
516 }
517
518 const fn as_clap_event_param_value(&self) -> &clap_event_param_value {
519 unsafe { self.header.cast_unchecked() }
521 }
522
523 impl_event_const_getter!(channel, as_clap_event_param_value, i16);
524 impl_event_const_getter!(key, as_clap_event_param_value, i16);
525 impl_event_const_getter!(note_id, as_clap_event_param_value, i32);
526
527 pub fn param_id(&self) -> ClapId {
532 self.as_clap_event_param_value()
533 .param_id
534 .try_into()
535 .unwrap_or(ClapId::invalid_id())
536 }
537
538 impl_event_const_getter!(port_index, as_clap_event_param_value, i16);
539 impl_event_const_getter!(value, as_clap_event_param_value, f64);
540
541 pub const fn build() -> ParamValueBuilder {
542 ParamValueBuilder::new()
543 }
544
545 pub fn update(&self) -> ParamValueBuilder {
546 ParamValueBuilder::with_param_value(self)
547 }
548}
549
550impl Event for ParamValue<'_> {
551 fn header(&self) -> &Header {
552 self.header
553 }
554}
555
556#[derive(Debug, Copy, Clone, PartialEq)]
557pub struct ParamValueBuilder(clap_event_param_value);
558
559impl ParamValueBuilder {
560 pub const fn new() -> Self {
561 Self(clap_event_param_value {
562 header: clap_event_header {
563 size: size_of::<clap_event_param_value>() as u32,
564 time: 0,
565 space_id: CLAP_CORE_EVENT_SPACE_ID,
566 r#type: CLAP_EVENT_PARAM_VALUE as u16,
567 flags: 0,
568 },
569 param_id: 0,
570 cookie: null_mut(),
571 note_id: 0,
572 port_index: 0,
573 channel: 0,
574 key: 0,
575 value: 0.0,
576 })
577 }
578
579 pub fn with_param_value(param_value: &ParamValue<'_>) -> Self {
580 Self(*unsafe { param_value.header().cast_unchecked() })
583 }
584
585 impl_event_builder_setter!(port_index, i16);
586 impl_event_builder_setter!(channel, i16);
587 impl_event_builder_setter!(key, i16);
588 impl_event_builder_setter!(note_id, i32);
589
590 pub fn param_id(self, value: ClapId) -> Self {
597 let mut builder = self;
598 builder.0.param_id = value.into();
599 builder
600 }
601
602 impl_event_builder_setter!(value, f64);
603}
604
605impl Default for ParamValueBuilder {
606 fn default() -> Self {
607 Self::new()
608 }
609}
610
611impl From<clap_event_param_value> for ParamValueBuilder {
612 fn from(value: clap_event_param_value) -> Self {
613 Self(value)
614 }
615}
616
617impl_event_builder!(ParamValueBuilder, ParamValue<'a>, param_value_unchecked);
618
619#[derive(Debug, Copy, Clone, PartialEq)]
620pub struct ParamMod<'a> {
621 header: &'a Header,
622}
623
624impl<'a> ParamMod<'a> {
625 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
629 Self { header }
630 }
631
632 const fn as_clap_event_param_mod(&self) -> &clap_event_param_mod {
633 unsafe { self.header.cast_unchecked() }
635 }
636
637 impl_event_const_getter!(channel, as_clap_event_param_mod, i16);
638 impl_event_const_getter!(key, as_clap_event_param_mod, i16);
639 impl_event_const_getter!(note_id, as_clap_event_param_mod, i32);
640
641 pub fn param_id(&self) -> ClapId {
646 self.as_clap_event_param_mod()
647 .param_id
648 .try_into()
649 .unwrap_or(ClapId::invalid_id())
650 }
651
652 impl_event_const_getter!(port_index, as_clap_event_param_mod, i16);
653 impl_event_const_getter!(amount, as_clap_event_param_mod, f64);
654
655 pub const fn build() -> ParamModBuilder {
656 ParamModBuilder::new()
657 }
658
659 pub fn update(&self) -> ParamModBuilder {
660 ParamModBuilder::with_param_mod(self)
661 }
662}
663
664impl Event for ParamMod<'_> {
665 fn header(&self) -> &Header {
666 self.header
667 }
668}
669
670#[derive(Debug, Copy, Clone, PartialEq)]
671pub struct ParamModBuilder(clap_event_param_mod);
672
673impl ParamModBuilder {
674 pub const fn new() -> Self {
675 Self(clap_event_param_mod {
676 header: clap_event_header {
677 size: size_of::<clap_event_param_mod>() as u32,
678 time: 0,
679 space_id: CLAP_CORE_EVENT_SPACE_ID,
680 r#type: CLAP_EVENT_PARAM_MOD as u16,
681 flags: 0,
682 },
683 param_id: 0,
684 cookie: null_mut(),
685 note_id: 0,
686 port_index: 0,
687 channel: 0,
688 key: 0,
689 amount: 0.0,
690 })
691 }
692
693 pub fn with_param_mod(param_mod: &ParamMod<'_>) -> Self {
694 Self(*unsafe { param_mod.header().cast_unchecked() })
697 }
698
699 impl_event_builder_setter!(port_index, i16);
700 impl_event_builder_setter!(channel, i16);
701 impl_event_builder_setter!(key, i16);
702 impl_event_builder_setter!(note_id, i32);
703
704 pub fn param_id(self, value: ClapId) -> Self {
711 let mut builder = self;
712 builder.0.param_id = value.into();
713 builder
714 }
715
716 impl_event_builder_setter!(amount, f64);
717}
718
719impl Default for ParamModBuilder {
720 fn default() -> Self {
721 Self::new()
722 }
723}
724
725impl From<clap_event_param_mod> for ParamModBuilder {
726 fn from(value: clap_event_param_mod) -> Self {
727 Self(value)
728 }
729}
730
731impl_event_builder!(ParamModBuilder, ParamMod<'a>, param_mod_unchecked);
732
733#[derive(Debug, Copy, Clone, PartialEq, Eq)]
745#[repr(u32)]
746pub enum TransportFlags {
747 HasTempo = CLAP_TRANSPORT_HAS_TEMPO,
748 HasBeatsTimeline = CLAP_TRANSPORT_HAS_BEATS_TIMELINE,
749 HasSecondsTimeline = CLAP_TRANSPORT_HAS_SECONDS_TIMELINE,
750 HasTimeSignature = CLAP_TRANSPORT_HAS_TIME_SIGNATURE,
751 IsPlaying = CLAP_TRANSPORT_IS_PLAYING,
752 IsRecording = CLAP_TRANSPORT_IS_RECORDING,
753 IsLoopActive = CLAP_TRANSPORT_IS_LOOP_ACTIVE,
754 IsWithinPreRoll = CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL,
755}
756
757impl_flags_u32!(TransportFlags);
758
759#[derive(Debug, Copy, Clone, PartialEq)]
760pub struct Transport<'a> {
761 header: &'a Header,
762}
763
764macro_rules! impl_transport_time_getter {
765 ($name:tt, $type:tt $(,)?) => {
766 pub const fn $name(&self) -> $type {
767 $type(self.as_clap_event_transport().$name)
768 }
769 };
770}
771
772impl<'a> Transport<'a> {
773 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
777 Self { header }
778 }
779
780 const fn as_clap_event_transport(&self) -> &clap_event_transport {
781 unsafe { self.header.cast_unchecked() }
783 }
784
785 impl_transport_time_getter!(song_pos_seconds, SecTime);
786 impl_transport_time_getter!(song_pos_beats, BeatTime);
787 impl_transport_time_getter!(loop_start_beats, BeatTime);
788 impl_transport_time_getter!(loop_end_beats, BeatTime);
789 impl_transport_time_getter!(loop_start_seconds, SecTime);
790 impl_transport_time_getter!(loop_end_seconds, SecTime);
791 impl_transport_time_getter!(bar_start, BeatTime);
792
793 impl_event_const_getter!(flags, as_clap_event_transport, u32);
794 impl_event_const_getter!(tempo, as_clap_event_transport, f64);
795 impl_event_const_getter!(tempo_inc, as_clap_event_transport, f64);
796 impl_event_const_getter!(bar_number, as_clap_event_transport, i32);
797 impl_event_const_getter!(tsig_num, as_clap_event_transport, u16);
798 impl_event_const_getter!(tsig_denom, as_clap_event_transport, u16);
799
800 pub const fn build() -> TransportBuilder {
801 TransportBuilder::new()
802 }
803
804 pub fn update(&self) -> TransportBuilder {
805 TransportBuilder::with_transport(self)
806 }
807}
808
809impl Event for Transport<'_> {
810 fn header(&self) -> &Header {
811 self.header
812 }
813}
814
815macro_rules! impl_transport_time_setter {
816 ($name:tt, $type:tt $(,)?) => {
817 pub const fn $name(self, value: $type) -> Self {
818 let mut build = self;
819 build.0.$name = value.0;
820 build
821 }
822 };
823}
824
825#[derive(Debug, Copy, Clone, PartialEq)]
826pub struct TransportBuilder(clap_event_transport);
827
828impl TransportBuilder {
829 pub const fn new() -> Self {
830 Self(clap_event_transport {
831 header: clap_event_header {
832 size: size_of::<clap_event_transport>() as u32,
833 time: 0,
834 space_id: CLAP_CORE_EVENT_SPACE_ID,
835 r#type: CLAP_EVENT_TRANSPORT as u16,
836 flags: 0,
837 },
838 flags: 0,
839 song_pos_beats: 0,
840 song_pos_seconds: 0,
841 tempo: 0.0,
842 tempo_inc: 0.0,
843 loop_start_beats: 0,
844 loop_end_beats: 0,
845 loop_start_seconds: 0,
846 loop_end_seconds: 0,
847 bar_start: 0,
848 bar_number: 0,
849 tsig_num: 0,
850 tsig_denom: 0,
851 })
852 }
853
854 pub fn with_transport(param_value: &Transport<'_>) -> Self {
855 Self(*unsafe { param_value.header().cast_unchecked() })
858 }
859
860 impl_transport_time_setter!(song_pos_seconds, SecTime);
861 impl_transport_time_setter!(song_pos_beats, BeatTime);
862 impl_transport_time_setter!(loop_start_beats, BeatTime);
863 impl_transport_time_setter!(loop_end_beats, BeatTime);
864 impl_transport_time_setter!(loop_start_seconds, SecTime);
865 impl_transport_time_setter!(loop_end_seconds, SecTime);
866 impl_transport_time_setter!(bar_start, BeatTime);
867
868 impl_event_builder_setter!(flags, u32);
869 impl_event_builder_setter!(tempo, f64);
870 impl_event_builder_setter!(tempo_inc, f64);
871 impl_event_builder_setter!(bar_number, i32);
872 impl_event_builder_setter!(tsig_num, u16);
873 impl_event_builder_setter!(tsig_denom, u16);
874}
875
876impl Default for TransportBuilder {
877 fn default() -> Self {
878 Self::new()
879 }
880}
881
882impl From<clap_event_transport> for TransportBuilder {
883 fn from(value: clap_event_transport) -> Self {
884 Self(value)
885 }
886}
887
888impl_event_builder!(TransportBuilder, Transport<'a>, transport_unchecked);
889
890#[derive(Debug, Copy, Clone, PartialEq)]
891pub struct Midi<'a> {
892 header: &'a Header,
893}
894
895impl<'a> Midi<'a> {
896 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
900 Self { header }
901 }
902
903 const fn as_clap_event_midi(&self) -> &clap_event_midi {
904 unsafe { self.header.cast_unchecked() }
906 }
907
908 impl_event_const_getter!(port_index, as_clap_event_midi, u16);
909
910 pub const fn data(&self) -> &[u8; 3] {
911 &self.as_clap_event_midi().data
912 }
913
914 pub const fn build() -> MidiBuilder {
925 MidiBuilder::new()
926 }
927
928 pub fn update(&self) -> MidiBuilder {
945 MidiBuilder::with_midi(self)
946 }
947}
948
949impl Event for Midi<'_> {
950 fn header(&self) -> &Header {
951 self.header
952 }
953}
954
955#[derive(Debug, Copy, Clone, PartialEq)]
956pub struct MidiBuilder(clap_event_midi);
957
958impl MidiBuilder {
959 pub const fn new() -> Self {
960 Self(clap_event_midi {
961 header: clap_event_header {
962 size: size_of::<clap_event_midi>() as u32,
963 time: 0,
964 space_id: CLAP_CORE_EVENT_SPACE_ID,
965 r#type: CLAP_EVENT_MIDI as u16,
966 flags: 0,
967 },
968 port_index: 0,
969 data: [0; 3],
970 })
971 }
972
973 pub fn with_midi(midi: &Midi<'_>) -> Self {
974 Self(*unsafe { midi.header().cast_unchecked() })
977 }
978
979 impl_event_builder_setter!(port_index, u16);
980 impl_event_builder_setter!(data, [u8; 3]);
981}
982
983impl Default for MidiBuilder {
984 fn default() -> Self {
985 Self::new()
986 }
987}
988
989impl From<clap_event_midi> for MidiBuilder {
990 fn from(value: clap_event_midi) -> Self {
991 Self(value)
992 }
993}
994
995impl_event_builder!(MidiBuilder, Midi<'a>, midi_unchecked);
996
997#[derive(Debug, Copy, Clone, PartialEq)]
998pub struct Midi2<'a> {
999 header: &'a Header,
1000}
1001
1002impl<'a> Midi2<'a> {
1003 pub const unsafe fn new_unchecked(header: &'a Header) -> Self {
1007 Self { header }
1008 }
1009
1010 const fn as_clap_event_midi2(&self) -> &clap_event_midi2 {
1011 unsafe { self.header.cast_unchecked() }
1013 }
1014
1015 impl_event_const_getter!(port_index, as_clap_event_midi2, u16);
1016
1017 pub const fn data(&self) -> &[u32; 4] {
1018 &self.as_clap_event_midi2().data
1019 }
1020
1021 pub const fn build() -> Midi2Builder {
1032 Midi2Builder::new()
1033 }
1034
1035 pub fn update(&self) -> Midi2Builder {
1052 Midi2Builder::with_midi2(self)
1053 }
1054}
1055
1056impl Event for Midi2<'_> {
1057 fn header(&self) -> &Header {
1058 self.header
1059 }
1060}
1061
1062#[derive(Debug, Copy, Clone, PartialEq)]
1063pub struct Midi2Builder(clap_event_midi2);
1064
1065impl Midi2Builder {
1066 pub const fn new() -> Self {
1067 Self(clap_event_midi2 {
1068 header: clap_event_header {
1069 size: size_of::<clap_event_midi2>() as u32,
1070 time: 0,
1071 space_id: CLAP_CORE_EVENT_SPACE_ID,
1072 r#type: CLAP_EVENT_MIDI2 as u16,
1073 flags: 0,
1074 },
1075 port_index: 0,
1076 data: [0; 4],
1077 })
1078 }
1079
1080 pub fn with_midi2(midi: &Midi2<'_>) -> Self {
1081 Self(*unsafe { midi.header().cast_unchecked() })
1084 }
1085
1086 impl_event_builder_setter!(port_index, u16);
1087 impl_event_builder_setter!(data, [u32; 4]);
1088}
1089
1090impl Default for Midi2Builder {
1091 fn default() -> Self {
1092 Self::new()
1093 }
1094}
1095
1096impl From<clap_event_midi2> for Midi2Builder {
1097 fn from(value: clap_event_midi2) -> Self {
1098 Self(value)
1099 }
1100}
1101
1102impl_event_builder!(Midi2Builder, Midi2<'a>, midi2_unchecked);
1103
1104pub struct InputEvents<'a>(&'a clap_input_events);
1105
1106impl<'a> InputEvents<'a> {
1107 #[doc(hidden)]
1111 pub const unsafe fn new_unchecked(list: &'a clap_input_events) -> Self {
1112 Self(list)
1113 }
1114
1115 pub fn size(&self) -> u32 {
1116 unsafe { self.0.size.unwrap()(self.0) }
1118 }
1119
1120 pub unsafe fn get_unchecked(&self, index: u32) -> &Header {
1124 let header = unsafe { &*self.0.get.unwrap()(self.0, index) };
1126 unsafe { Header::new_unchecked(header) }
1127 }
1128
1129 pub fn get(&self, index: u32) -> &Header {
1133 assert!(index < self.size(), "index out of bounds");
1134 unsafe { self.get_unchecked(index) }
1135 }
1136}
1137
1138pub struct OutputEvents<'a> {
1139 list: &'a clap_output_events,
1140 last_time: u32,
1141}
1142
1143impl<'a> OutputEvents<'a> {
1144 #[doc(hidden)]
1148 pub const unsafe fn new_unchecked(list: &'a clap_output_events) -> Self {
1149 Self { list, last_time: 0 }
1150 }
1151
1152 pub unsafe fn try_push_unchecked(&mut self, event: impl Event) -> Result<(), Error> {
1158 let time = event.header().time();
1159
1160 if unsafe { self.list.try_push.unwrap()(self.list, event.header().as_clap_event_header()) }
1161 {
1162 self.last_time = time;
1163 Ok(())
1164 } else {
1165 Err(Error::TryPush)
1166 }
1167 }
1168
1169 pub fn try_push(&mut self, event: impl Event) -> Result<(), Error> {
1170 if event.header().time() >= self.last_time {
1171 unsafe { self.try_push_unchecked(event) }
1172 } else {
1173 Err(Error::OutOfOrder {
1174 last_time: self.last_time,
1175 })
1176 }
1177 }
1178}
1179
1180#[derive(Debug, Copy, Clone, PartialEq)]
1181pub enum Error {
1182 OtherType(u16),
1183 PayloadSize(u32),
1184 TryPush,
1185 OutOfOrder { last_time: u32 },
1186}
1187
1188impl Display for Error {
1189 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1190 match self {
1191 Error::PayloadSize(size) => {
1192 write!(f, "payload size for the defined event type: {size}")
1193 }
1194 Error::OtherType(id) => write!(f, "other type, id: {id}"),
1195
1196 Error::TryPush => write!(f, "pushing event failed"),
1197
1198 Error::OutOfOrder { last_time } => {
1199 write!(f, "event out of order, last event's time: {last_time}")
1200 }
1201 }
1202 }
1203}
1204
1205impl std::error::Error for Error {}
1206
1207impl From<Error> for crate::Error {
1208 fn from(value: Error) -> Self {
1209 crate::Error::Events(value)
1210 }
1211}