midly/
primitive.rs

1//! Simple building-block data that can be read in one go.
2//! All primitives have a known, fixed size.
3//! Also, primitives advance the file pointer when read.
4
5use crate::prelude::*;
6
7pub(crate) trait SplitChecked: Sized {
8    fn split_checked(&mut self, at: usize) -> Option<Self>;
9}
10impl<'a> SplitChecked for &'a [u8] {
11    #[inline]
12    fn split_checked(&mut self, at: usize) -> Option<&'a [u8]> {
13        if at > self.len() {
14            None
15        } else {
16            let (extracted, remainder) = self.split_at(at);
17            *self = remainder;
18            Some(extracted)
19        }
20    }
21}
22
23/// Implemented on integer types for reading as big-endian.
24pub(crate) trait IntRead: Sized {
25    /// Reads a big-endian integer.
26    fn read(data: &mut &[u8]) -> StdResult<Self, &'static ErrorKind>;
27}
28/// Reads the int from u7 bytes, that is, the top bit in all bytes is ignored.
29/// For raw reading on integer types, use `read_raw`.
30pub(crate) trait IntReadBottom7: Sized {
31    /// Read an int from bytes, but only using the bottom 7 bits of each byte.
32    fn read_u7(data: &mut &[u8]) -> StdResult<Self, &'static ErrorKind>;
33}
34
35/// Implement simple big endian integer reads.
36macro_rules! impl_read_int {
37    {$( $int:ty ),*} => {
38        $(
39            impl IntRead for $int {
40                #[inline]
41                fn read(raw: &mut &[u8]) -> StdResult<$int, &'static ErrorKind> {
42                    let bytes = raw.split_checked(mem::size_of::<$int>())
43                        .ok_or(err_invalid!("failed to read the expected integer"))?;
44                    Ok(bytes.iter().fold(0,|mut acc,byte| {
45                        acc=acc.checked_shl(8).unwrap_or(0);
46                        acc|=*byte as $int;
47                        acc
48                    }))
49                }
50            }
51        )*
52    }
53}
54impl_read_int! {u8,u16,u32}
55
56/// Slightly restricted integers.
57macro_rules! int_feature {
58    { $name:ident ; $inner:tt : read_u7 } => {
59        impl IntReadBottom7 for $name {
60            fn read_u7(raw: &mut &[u8]) -> StdResult<$name, &'static ErrorKind> {
61                let bytes = raw.split_checked(mem::size_of::<$inner>())
62                    .ok_or(err_invalid!("failed to read the expected integer"))?;
63                if cfg!(feature = "strict") {
64                    ensure!(bytes.iter().all(|byte| bit_range!(*byte, 7..8)==0), err_malformed!("invalid byte with top bit set"));
65                }
66                let raw = bytes.iter().fold(0, |mut acc,byte| {
67                    acc <<= 7;
68                    acc |= bit_range!(*byte, 0..7) as $inner;
69                    acc
70                });
71                Ok(if cfg!(feature = "strict") {
72                    Self::try_from(raw).ok_or(err_malformed!(stringify!("expected " $name ", found " $inner)))?
73                }else{
74                    //Ignore and truncate extra bits
75                    Self::from(raw)
76                })
77            }
78        }
79    };
80    { $name:ident ; $inner:tt : read } => {
81        impl IntRead for $name {
82            #[inline]
83            fn read(raw: &mut &[u8]) -> StdResult<Self, &'static ErrorKind> {
84                let raw = $inner::read(raw)?;
85                if cfg!(feature = "strict") {
86                    Ok(Self::try_from(raw).ok_or(err_malformed!(concat!("expected ", stringify!($name), ", found ", stringify!($inner))))?)
87                }else{
88                    //Throw away extra bits
89                    Ok(Self::from(raw))
90                }
91            }
92        }
93    };
94}
95macro_rules! restricted_int {
96    {$(#[$attr:meta])* $name:ident : $inner:tt => $bits:expr ; $( $feature:tt )* } => {
97        $(#[$attr])*
98        #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
99        #[repr(transparent)]
100        #[allow(non_camel_case_types)]
101        pub struct $name($inner);
102        impl From<$inner> for $name {
103            /// Lossy convertion, loses top bit.
104            #[inline]
105            fn from(raw: $inner) -> $name {
106                $name::from_int_lossy(raw)
107            }
108        }
109        impl From<$name> for $inner {
110            #[inline]
111            fn from(restricted: $name) -> $inner {restricted.0}
112        }
113        impl fmt::Display for $name {
114            #[inline]
115            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
116                fmt::Display::fmt(&self.0, f)
117            }
118        }
119        impl $name {
120            const MASK: $inner = (1 << $bits) - 1;
121
122            /// The maximum value that this restricted integer can hold.
123            #[inline]
124            pub const fn max_value() -> $name {
125                $name (Self::MASK)
126            }
127
128            /// Creates a restricted int from its non-restricted counterpart by masking off the
129            /// extra bits.
130            #[inline]
131            pub const fn new(raw: $inner) -> $name {
132                $name (raw & Self::MASK)
133            }
134
135            /// Creates a restricted int from its non-restricted counterpart by masking off the
136            /// extra bits.
137            #[inline]
138            pub const fn from_int_lossy(raw: $inner) -> $name {
139                $name (raw & Self::MASK)
140            }
141
142            /// Returns `Some` if the raw integer is within range of the restricted integer, and
143            /// `None` otherwise.
144            #[inline]
145            pub fn try_from(raw: $inner) -> Option<$name> {
146                if raw <= Self::MASK {
147                    Some($name(raw))
148                }else{
149                    None
150                }
151            }
152
153            /// Get the inner integer out of the wrapper.
154            /// The inner integer is guaranteed to be in range of the restricted wrapper.
155            #[inline]
156            pub fn as_int(self) -> $inner {
157                Into::into(self)
158            }
159
160            /// Cast a slice of raw integers to a slice of restricted integers, only if there are
161            /// no out-of-range integers.
162            #[inline]
163            pub fn slice_try_from_int(raw: &[$inner]) -> Option<&[$name]> {
164                for &int in raw {
165                    if int > Self::MASK {
166                        return None;
167                    }
168                }
169                unsafe {
170                    Some(Self::slice_from_int_unchecked(raw))
171                }
172            }
173
174            /// Cast a slice of raw integers to a slice of restricted integers.
175            ///
176            /// The slice is truncated up to the first out-of-range integer, if there is any.
177            #[inline]
178            pub fn slice_from_int(raw: &[$inner]) -> &[$name] {
179                let first_oob = raw
180                    .iter()
181                    .position(|&b| b > Self::MASK)
182                    .unwrap_or(raw.len());
183                unsafe {
184                    Self::slice_from_int_unchecked(&raw[..first_oob])
185                }
186            }
187
188            /// Cast a slice of raw integers to a slice of restricted integers.
189            ///
190            /// # Safety
191            ///
192            /// The input slice must not contain any out-of-range integers.
193            #[inline]
194            pub unsafe fn slice_from_int_unchecked(raw: &[$inner]) -> &[$name] {
195                &*( raw as *const [$inner] as *const [$name] )
196            }
197
198            /// Cast a slice of mutable raw integers to a slice of mutable restricted integers, only
199            /// if there are no out-of-range integers.
200            #[inline]
201            pub fn slice_try_from_int_mut(raw: &mut [$inner]) -> Option<&mut [$name]> {
202                for &int in raw.iter() {
203                    if int > Self::MASK {
204                        return None;
205                    }
206                }
207                unsafe {
208                    Some(Self::slice_from_int_unchecked_mut(raw))
209                }
210            }
211
212            /// Cast a slice of mutable raw integers to a slice of mutable restricted integers.
213            ///
214            /// The slice is truncated up to the first out-of-range integer, if there is any.
215            #[inline]
216            pub fn slice_from_int_mut(raw: &mut [$inner]) -> &mut [$name] {
217                let first_oob = raw
218                    .iter()
219                    .position(|&b| b > Self::MASK)
220                    .unwrap_or(raw.len());
221                unsafe {
222                    Self::slice_from_int_unchecked_mut(&mut raw[..first_oob])
223                }
224            }
225
226            /// Cast a slice of mutable raw integers to a slice of mutable restricted integers.
227            ///
228            /// # Safety
229            ///
230            /// The input slice must not contain any out-of-range integers.
231            #[inline]
232            pub unsafe fn slice_from_int_unchecked_mut(raw: &mut [$inner]) -> &mut [$name] {
233                &mut *( raw as *mut [$inner] as *mut [$name] )
234            }
235
236            /// Cast a slice of restricted integers to the corresponding raw integers.
237            ///
238            /// All integers are guaranteed to be within range of the restricted int.
239            #[inline]
240            pub fn slice_as_int(slice: &[$name]) -> &[$inner] {
241                unsafe { &*(slice as *const [$name] as *const [$inner]) }
242            }
243
244            #[allow(dead_code)]
245            #[inline]
246            pub(crate) fn check_int(raw: $inner) -> StdResult<$name, &'static ErrorKind> {
247                Self::try_from(raw).ok_or_else(
248                    || err_invalid!("invalid integer with top bits set")
249                )
250            }
251        }
252        impl PartialEq<$inner> for $name {
253            fn eq(&self, rhs: &$inner) -> bool {
254                self.as_int() == *rhs
255            }
256        }
257        impl PartialOrd<$inner> for $name {
258            fn partial_cmp(&self, rhs: &$inner) -> Option<core::cmp::Ordering> {
259                Some(self.as_int().cmp(rhs))
260            }
261        }
262        impl PartialEq<$name> for $inner {
263            fn eq(&self, rhs: &$name) -> bool {
264                *self == rhs.as_int()
265            }
266        }
267        impl PartialOrd<$name> for $inner {
268            fn partial_cmp(&self, rhs: &$name) -> Option<core::cmp::Ordering> {
269                Some(self.cmp(&rhs.as_int()))
270            }
271        }
272        impl core::ops::Add for $name {
273            type Output = Self;
274            fn add(self, other: Self) -> Self {
275                Self::new(self.as_int() + other.as_int())
276            }
277        }
278        impl core::ops::Sub for $name {
279            type Output = Self;
280            fn sub(self, other: Self) -> Self {
281                Self::new(self.as_int() - other.as_int())
282            }
283        }
284        impl core::ops::AddAssign for $name {
285            fn add_assign(&mut self, other: Self) {
286                *self = *self + other
287            }
288        }
289        impl core::ops::SubAssign for $name {
290            fn sub_assign(&mut self, other: Self) {
291                *self = *self - other
292            }
293        }
294
295        $( int_feature!{$name ; $inner : $feature} )*
296    };
297}
298restricted_int! {
299    /// A 15-bit integer type.
300    ///
301    /// Wraps the `u16` type and ensures that the top bit is always zero.
302    u15: u16 => 15; read
303}
304restricted_int! {
305    /// A 14-bit integer type.
306    ///
307    /// Wraps the `u16` type and ensures that the top two bits are always zero.
308    u14: u16 => 14; read read_u7
309}
310restricted_int! {
311    /// A 7-bit integer type.
312    ///
313    /// Wraps the `u8` type and ensures that the top bit is always zero.
314    u7: u8 => 7; read
315}
316restricted_int! {
317    /// A 4-bit integer type.
318    ///
319    /// Wraps the `u8` type and ensures that the top 4 bits are always zero.
320    u4: u8 => 4; read
321}
322restricted_int! {
323    /// A 2-bit integer type.
324    ///
325    /// Wraps the `u8` type and ensures that the top 6 bits are always zero.
326    u2: u8 => 2; read
327}
328restricted_int! {
329    /// A 24-bit integer type.
330    ///
331    /// Wraps the `u32` type and ensures that the top 8 bits are always zero.
332    u24: u32 => 24;
333}
334impl IntRead for u24 {
335    fn read(raw: &mut &[u8]) -> StdResult<u24, &'static ErrorKind> {
336        let bytes = raw
337            .split_checked(3)
338            .ok_or(err_invalid!("failed to read u24 bytes"))?;
339        //Using lossy `from` because value is guaranteed to be 24 bits (3 bytes)
340        Ok(u24::from(bytes.iter().fold(0, |mut acc, byte| {
341            acc <<= 8;
342            acc |= *byte as u32;
343            acc
344        })))
345    }
346}
347
348restricted_int! {
349    /// Referred to in the MIDI spec as "variable length int".
350    u28: u32 => 28;
351}
352impl IntReadBottom7 for u28 {
353    fn read_u7(raw: &mut &[u8]) -> StdResult<u28, &'static ErrorKind> {
354        let mut int: u32 = 0;
355        for _ in 0..4 {
356            let byte = match raw.split_checked(1) {
357                Some(slice) => slice[0],
358                None => {
359                    if cfg!(feature = "strict") {
360                        bail!(err_malformed!("unexpected eof while reading varlen int"))
361                    } else {
362                        //Stay with what was read
363                        break;
364                    }
365                }
366            };
367            int <<= 7;
368            int |= bit_range!(byte, 0..7) as u32;
369            if bit_range!(byte, 7..8) == 0 {
370                //Since we did at max 4 reads of 7 bits each, there MUST be at max 28 bits in this int
371                //Therefore it's safe to call lossy `from`
372                return Ok(u28::from(int));
373            }
374        }
375        if cfg!(feature = "strict") {
376            Err(err_malformed!("varlen integer larger than 4 bytes"))
377        } else {
378            //Use the 4 bytes as-is
379            Ok(u28::from(int))
380        }
381    }
382}
383
384impl u28 {
385    pub(crate) fn write_varlen<W: Write>(&self, out: &mut W) -> WriteResult<W> {
386        let int = self.as_int();
387        let mut skipping = true;
388        for i in (0..4).rev() {
389            let byte = ((int >> (i * 7)) & 0x7F) as u8;
390            if skipping && byte == 0 && i != 0 {
391                //Skip these leading zeros
392            } else {
393                //Write down this u7
394                skipping = false;
395                let byte = if i == 0 {
396                    //Last byte
397                    byte
398                } else {
399                    //Leading byte
400                    byte | 0x80
401                };
402                out.write(&[byte])?;
403            }
404        }
405        Ok(())
406    }
407}
408
409/// Reads a slice represented in the input as a `u28` `len` followed by `len` bytes.
410pub(crate) fn read_varlen_slice<'a>(raw: &mut &'a [u8]) -> Result<&'a [u8]> {
411    let len = u28::read_u7(raw)
412        .context(err_invalid!("failed to read varlen slice length"))?
413        .as_int();
414    Ok(match raw.split_checked(len as usize) {
415        Some(slice) => slice,
416        None => {
417            if cfg!(feature = "strict") {
418                bail!(err_malformed!("incomplete varlen slice"))
419            } else {
420                mem::replace(raw, &[])
421            }
422        }
423    })
424}
425
426/// Write a slice represented as a varlen `u28` as its length and then the raw bytes.
427pub(crate) fn write_varlen_slice<W: Write>(slice: &[u8], out: &mut W) -> WriteResult<W> {
428    let len = u32::try_from(slice.len())
429        .ok()
430        .and_then(u28::try_from)
431        .ok_or_else(|| W::invalid_input("varlen slice exceeds 28 bits"))?;
432    len.write_varlen(out)?;
433    out.write(slice)?;
434    Ok(())
435}
436
437/// The order in which tracks should be laid out when playing back this SMF file.
438#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
439pub enum Format {
440    /// This file should have a single track only.
441    ///
442    /// If the `strict` feature is enabled, an error is raised if the format is
443    /// `Format::SingleTrack` and there is not exactly one track.
444    SingleTrack,
445    /// This file has several tracks that should be played simultaneously.
446    ///
447    /// Usually the first track controls tempo and other song metadata.
448    Parallel,
449    /// This file has several tracks, each one a separate song.
450    ///
451    /// The tracks should be played sequentially, as completely separate MIDI tracks packaged
452    /// within a single SMF file.
453    Sequential,
454}
455impl Format {
456    pub(crate) fn read(raw: &mut &[u8]) -> Result<Format> {
457        let format = u16::read(raw)?;
458        Ok(match format {
459            0 => Format::SingleTrack,
460            1 => Format::Parallel,
461            2 => Format::Sequential,
462            _ => bail!(err_invalid!("invalid smf format")),
463        })
464    }
465
466    pub(crate) fn encode(&self) -> [u8; 2] {
467        let code: u16 = match self {
468            Format::SingleTrack => 0,
469            Format::Parallel => 1,
470            Format::Sequential => 2,
471        };
472        code.to_be_bytes()
473    }
474}
475
476/// The timing for an SMF file.
477/// This can be in ticks/beat or ticks/second.
478#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
479pub enum Timing {
480    /// Specifies ticks/beat as a 15-bit integer.
481    ///
482    /// The length of a beat is not standard, so in order to fully describe the length of a MIDI
483    /// tick the [`MetaMessage::Tempo`](enum.MetaMessage.html#Tempo.v) event should be present.
484    Metrical(u15),
485    /// Specifies ticks/second by dividing a second into frames and then into subframes.
486    /// Therefore the length of of a tick is `1/fps/subframe`.
487    Timecode(Fps, u8),
488}
489impl Timing {
490    pub(crate) fn read(raw: &mut &[u8]) -> Result<Timing> {
491        let raw =
492            u16::read(raw).context(err_invalid!("unexpected eof when reading midi timing"))?;
493        if bit_range!(raw, 15..16) != 0 {
494            //Timecode
495            let fps = -(bit_range!(raw, 8..16) as i8);
496            let subframe = bit_range!(raw, 0..8) as u8;
497            Ok(Timing::Timecode(
498                Fps::from_int(fps as u8).ok_or(err_invalid!("invalid smpte fps"))?,
499                subframe,
500            ))
501        } else {
502            //Metrical
503            Ok(Timing::Metrical(u15::from(raw)))
504        }
505    }
506
507    pub(crate) fn encode(&self) -> [u8; 2] {
508        match self {
509            Timing::Metrical(ticksperbeat) => ticksperbeat.as_int().to_be_bytes(),
510            Timing::Timecode(framespersec, ticksperframe) => {
511                [(-(framespersec.as_int() as i8)) as u8, *ticksperframe]
512            }
513        }
514    }
515}
516
517/// A timestamp encoding an SMPTE time of the day.
518///
519/// Enforces several guarantees:
520///
521/// - `hour` is inside [0,23]
522/// - `minute` is inside [0,59]
523/// - `second` is inside [0,59]
524/// - `frame` is inside [0,fps[
525/// - `subframe` is inside [0,99]
526#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
527pub struct SmpteTime {
528    hour: u8,
529    minute: u8,
530    second: u8,
531    frame: u8,
532    subframe: u8,
533    fps: Fps,
534}
535impl SmpteTime {
536    /// Create a new SMPTE timestamp with the given information.
537    #[inline]
538    pub fn new(
539        hour: u8,
540        minute: u8,
541        second: u8,
542        frame: u8,
543        subframe: u8,
544        fps: Fps,
545    ) -> Option<SmpteTime> {
546        macro_rules! check {
547            ($cond:expr) => {{
548                if !{ $cond } {
549                    return None;
550                }
551            }};
552        }
553        check!(hour < 24);
554        check!(minute < 60);
555        check!(second < 60);
556        check!(frame < fps.as_int());
557        check!(subframe < 100);
558        Some(SmpteTime {
559            hour,
560            minute,
561            second,
562            frame,
563            subframe,
564            fps,
565        })
566    }
567
568    /// Get the hour component of this timestamp.
569    #[inline]
570    pub fn hour(&self) -> u8 {
571        self.hour
572    }
573
574    /// Get the minute component of this timestamp.
575    #[inline]
576    pub fn minute(&self) -> u8 {
577        self.minute
578    }
579
580    /// Get the second component of this timestamp.
581    #[inline]
582    pub fn second(&self) -> u8 {
583        self.second
584    }
585
586    /// Get the frame component of this timestamp.
587    /// The meaning of this value depends on the value of `fps`.
588    #[inline]
589    pub fn frame(&self) -> u8 {
590        self.frame
591    }
592
593    /// Get the subframe component of this timestamp (hundredths of a frame).
594    #[inline]
595    pub fn subframe(&self) -> u8 {
596        self.subframe
597    }
598
599    /// Get the FPS component of this timestamp.
600    #[inline]
601    pub fn fps(&self) -> Fps {
602        self.fps
603    }
604
605    /// Convert the second + frame + subframe components of this timestamp into a single
606    /// floating-point number of seconds.
607    /// Note that this does not include the hour and minute components.
608    #[inline]
609    pub fn second_f32(&self) -> f32 {
610        self.second as f32
611            + ((self.frame as f32 + self.subframe as f32 / 100.0) / self.fps.as_f32())
612    }
613
614    pub(crate) fn read(raw: &mut &[u8]) -> Result<SmpteTime> {
615        let data = raw
616            .split_checked(5)
617            .ok_or(err_invalid!("failed to read smpte time data"))?;
618        let hour_fps = data[0];
619        let (hour, fps) = (bit_range!(hour_fps, 0..5), bit_range!(hour_fps, 5..7));
620        let fps = Fps::from_code(u2::from(fps));
621        let minute = data[1];
622        let second = data[2];
623        let frame = data[3];
624        let subframe = data[4];
625        Ok(SmpteTime::new(hour, minute, second, frame, subframe, fps)
626            .ok_or(err_invalid!("invalid smpte time"))?)
627    }
628
629    pub(crate) fn encode(&self) -> [u8; 5] {
630        let hour_fps = self.hour() | self.fps().as_code().as_int() << 5;
631        [
632            hour_fps,
633            self.minute(),
634            self.second(),
635            self.frame(),
636            self.subframe(),
637        ]
638    }
639}
640
641/// One of the four FPS values available for SMPTE times, as defined by the MIDI standard.
642#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
643pub enum Fps {
644    /// 24 frames per second.
645    Fps24,
646    /// 25 frames per second.
647    Fps25,
648    /// Actually `29.97 = 30 / 1.001` frames per second.
649    ///
650    /// Quite an exotic value because of interesting historical reasons.
651    Fps29,
652    /// 30 frames per second.
653    Fps30,
654}
655impl Fps {
656    /// Does the conversion from a 2-bit fps code to an `Fps` value.
657    pub(crate) fn from_code(code: u2) -> Fps {
658        match code.as_int() {
659            0 => Fps::Fps24,
660            1 => Fps::Fps25,
661            2 => Fps::Fps29,
662            3 => Fps::Fps30,
663            _ => unreachable!(),
664        }
665    }
666
667    /// Does the conversion to a 2-bit fps code.
668    pub(crate) fn as_code(self) -> u2 {
669        u2::from(match self {
670            Fps::Fps24 => 0,
671            Fps::Fps25 => 1,
672            Fps::Fps29 => 2,
673            Fps::Fps30 => 3,
674        })
675    }
676
677    /// Converts an integer representing the semantic fps to an `Fps` value (ie. `24` -> `Fps24`).
678    #[inline]
679    pub fn from_int(raw: u8) -> Option<Fps> {
680        Some(match raw {
681            24 => Fps::Fps24,
682            25 => Fps::Fps25,
683            29 => Fps::Fps29,
684            30 => Fps::Fps30,
685            _ => return None,
686        })
687    }
688
689    /// Get the integral approximate fps out.
690    #[inline]
691    pub fn as_int(self) -> u8 {
692        match self {
693            Fps::Fps24 => 24,
694            Fps::Fps25 => 25,
695            Fps::Fps29 => 29,
696            Fps::Fps30 => 30,
697        }
698    }
699
700    /// Get the actual `f32` fps out.
701    #[inline]
702    pub fn as_f32(self) -> f32 {
703        match self.as_int() {
704            24 => 24.0,
705            25 => 25.0,
706            29 => 30.0 / 1.001,
707            30 => 30.0,
708            _ => unreachable!(),
709        }
710    }
711}
712impl From<Fps> for f32 {
713    fn from(x: Fps) -> Self {
714        x.as_f32()
715    }
716}
717impl From<Fps> for u8 {
718    fn from(x: Fps) -> Self {
719        x.as_int()
720    }
721}