1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! # miami
//!
//! A minimal dependency MIDI file parser designed for both standard and WASM targets,
//! This crate provides core MIDI "chunks" and utilities for reading and parsing them,
//! without introducing any extra overhead or dependencies.
//!
//! ## Overview
//!
//! MIDI files are structured as a series of chunks. Each chunk contains a 4-character ASCII
//! type identifier and a 32-bit length that specifies how many bytes of data follow. The
//! `Chunk` struct and related APIs in this crate make it straightforward to inspect and
//! parse these sections of a MIDI file.
//!
//! - **Minimal dependencies**: Keeps your application lightweight and minimizes build complexity.
//! Opt in to serde support and only require `thiserror` by default
//! - **Streaming-friendly**: Exposes traits and functions that can parse MIDI data from any
//! implementor of [`reader::MidiStream`], making it easier to handle data on the fly.
//!
//! ## Example Usage
//!
//! ```rust
//! use miami::{
//! chunk::ParsedChunk,
//! reader::{MidiReadable, MidiStream},
//! };
//!
//! // Load MIDI bytes (replace with your own source as needed).
//! let mut data = "test/test.mid"
//! .get_midi_bytes()
//! .expect("Get `test.mid` file and read bytes");
//!
//! // Continuously read chunk-type/data pairs from the stream.
//! // Each read returns an option containing the chunk plus its raw data.
//! while let Some(parsed) = data.read_chunk_data_pair().map(ParsedChunk::try_from) {
//! match parsed {
//! Ok(chunk) => println!("Parsed chunk: {:?}", chunk),
//! Err(e) => eprintln!("Failed to parse chunk: {e}"),
//! }
//! }
//! ```
//!
//! The above example illustrates how to read chunks from a MIDI stream and use
//! [`ParsedChunk::try_from`] to parse them into known types (header or track chunks).
//!
//! ## Library Structure
//!
//! - **[`chunk`]**: Contains the [`Chunk`] struct and associated utilities for identifying
//! chunk types and lengths.
//! - **[`reader`]**: Provides traits and types for streaming MIDI data. The [`MidiStream`]
//! trait and related helpers allow on-the-fly parsing from any data source.
//! - **`chunk_types`, `header`, and `track`**: Provide definitions for recognized MIDI
//! chunk types (e.g., `MThd` for the header and `MTrk` for track data) and the logic for
//! parsing their contents.
//!
//! ## Extensibility
//!
//! While this crate focuses on parsing the structural aspects of MIDI files (chunks and headers),
//! you can use the raw track data to implement custom handling of MIDI events or other logic
//! as needed. Because `miami` exposes chunks in a straightforward format, you remain in full
//! control of the MIDI event parsing layer.
//!
use ;
/// Represents a raw MIDI Chunk.
/// A MIDI Chunk consists of a 4-character ASCII type identifier and a 32-bit unsigned integer specifying the length of its data.