4 releases

0.1.3 Jan 26, 2025
0.1.2 Jan 25, 2025
0.1.1 Jan 25, 2025
0.1.0 Jan 23, 2025

#774 in Parser implementations

Download history 255/week @ 2025-01-21 39/week @ 2025-01-28 4/week @ 2025-02-04 104/week @ 2025-02-11

402 downloads per month

MIT license

150KB
1.5K SLoC

Banner

parsing midi files is not as scary as it sounds. 🐔

crates.io Tests

A lightweight, minimal dependency MIDI file parser and binary writer designed for resource-constrained environments, making it great for WebAssembly applications.

Features

  • Efficient MIDI Parsing: Parse MIDI chunks and their associated data with minimal overhead.
  • Error Handling: Comprehensive error reporting for invalid or unsupported chunks.
  • MIDI Format Writing: Serialize Parsed or Generating MIDI chunks back into MIDI format binary.

Getting Started

Installation

Add the following to your Cargo.toml:

[dependencies]
miami = "{whatever version you want}"

For serde support include the serde feature flag ;)

Example Usage

The following example demonstrates how to read and process MIDI chunks from a file:

let mut data = "path/to/midi/file.mid"
    .get_midi_bytes()
    .expect("Failed to load MIDI file");

let midi = RawMidi::try_from_midi_stream(data).expect("Parse data as a MIDI stream");

for chunk in midi.chunks.iter() {
    println!("{chunk:?}");
}

A RawMidi can also be sanitized and upgraded into a Midi struct that contains a single header and a subsequent list of tracks:

let sanitized: Midi = midi.check_into_midi().expect("Upgrade to Midi");

Writing a RawMidi or Midi to a file:

let mut output = File::create("output.mid").unwrap();

// Works for `Midi` and `RawMidi` types!
output.write_all(&midi.to_midi_bytes()).unwrap()

Core Concepts

Raw MIDI Chunk

A raw MIDI chunk consists of a 4-character ASCII type identifier and a 32-bit unsigned integer specifying the length of its data:

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Chunk {
    pub chunk_type: [char; 4],
    pub length: u32,
}

Parsed MIDI Chunk

Parsed chunks are categorized into meaningful types such as HeaderChunk and TrackChunk:

#[derive(Debug, Clone, PartialEq)]
pub enum ParsedChunk {
    Header(HeaderChunk),
    Track(TrackChunk),
}

Header Chunk

The HeaderChunk struct stores essential MIDI metadata:

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct HeaderChunk {
    format: Format,
    ntrks: u16,
    division: Division,
}

Contributions

Contributions are welcome! If you find a bug or have a feature request, feel free to open an issue or submit a pull request.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Dependencies