Boilerplate for midi support

This commit is contained in:
Gwilym Inzani 2023-11-01 11:32:41 +00:00
parent 0975530e5c
commit 797fc8394f
5 changed files with 119 additions and 1 deletions

View file

@ -0,0 +1,22 @@
[package]
name = "agb_midi_core"
version = "0.18.0"
authors = ["Gwilym Inzani <gw@ilym.me>"]
edition = "2021"
license = "MPL-2.0"
description = "Library for converting MIDI files for use with agb-tracker on the Game Boy Advance. You shouldn't use this package directly"
repository = "https://github.com/agbrs/agb"
[dependencies]
proc-macro-error = "1"
proc-macro2 = "1"
quote = "1"
syn = "2"
rustysynth = "1.3"
midly = { version = "0.5", default-features = false, features = [
"alloc",
"std",
] }
agb_tracker_interop = { version = "0.18.0", path = "../agb-tracker-interop" }
agb_fixnum = { version = "0.18.0", path = "../../agb-fixnum" }

View file

@ -0,0 +1,70 @@
use std::{error::Error, path::Path};
use proc_macro2::TokenStream;
use proc_macro_error::abort;
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
LitStr, Token,
};
struct MidiCoreInput {
sf2_file: LitStr,
comma: Token![,],
midi_file: LitStr,
}
impl Parse for MidiCoreInput {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
sf2_file: input.parse()?,
comma: input.parse()?,
midi_file: input.parse()?,
})
}
}
pub fn agb_midi_core(args: TokenStream) -> TokenStream {
let input: MidiCoreInput = match syn::parse2(args.clone()) {
Ok(input) => input,
Err(e) => abort!(args, e),
};
let sf2_file = input.sf2_file.value();
let midi_file = input.midi_file.value();
let root = std::env::var("CARGO_MANIFEST_DIR").expect("Failed to get cargo manifest dir");
let sf2_file = Path::new(&root).join(&*sf2_file);
let midi_file = Path::new(&root).join(&*midi_file);
let sf2_include_path = sf2_file.to_string_lossy();
let midi_file_include_path = midi_file.to_string_lossy();
let midi_info = match MidiInfo::load_from_file(&sf2_file, &midi_file) {
Ok(track) => track,
Err(e) => abort!(args, e),
};
let parsed = parse_midi(&midi_info);
quote! {
{
const _: &[u8] = include_bytes!(#sf2_include_path);
const _: &[u8] = include_bytes!(#midi_file_include_path);
#parsed
}
}
}
pub struct MidiInfo {}
impl MidiInfo {
pub fn load_from_file(sf2_file: &Path, midi_file: &Path) -> Result<Self, Box<dyn Error>> {
Ok(Self {})
}
}
pub fn parse_midi(midi_info: &MidiInfo) -> TokenStream {
quote! {}
}

View file

@ -0,0 +1,16 @@
[package]
name = "agb_midi"
version = "0.18.0"
authors = ["Gwilym Inzani <gw@ilym.me>"]
edition = "2021"
license = "MPL-2.0"
description = "Library for converting MIDI files for use with agb-tracker on the Game Boy Advance. You shouldn't use this package directly"
repository = "https://github.com/agbrs/agb"
[lib]
proc-macro = true
[dependencies]
agb_midi_core = { version = "0.18.0", path = "../agb-midi-core" }
proc-macro-error = "1"
proc-macro2 = "1"

View file

@ -0,0 +1,8 @@
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;
#[proc_macro_error]
#[proc_macro]
pub fn include_xm(args: TokenStream) -> TokenStream {
agb_midi_core::agb_midi_core(args.into()).into()
}

View file

@ -8,10 +8,12 @@ description = "Library for playing tracker music. Designed for use with the agb
repository = "https://github.com/agbrs/agb" repository = "https://github.com/agbrs/agb"
[features] [features]
default = ["xm"] default = ["xm", "midi"]
xm = ["dep:agb_xm"] xm = ["dep:agb_xm"]
midi = ["dep:agb_midi"]
[dependencies] [dependencies]
agb_midi = { version = "0.18.1", path = "../agb-midi", optional = true }
agb_xm = { version = "0.18.1", path = "../agb-xm", optional = true } agb_xm = { version = "0.18.1", path = "../agb-xm", optional = true }
agb = { version = "0.18.1", path = "../../agb" } agb = { version = "0.18.1", path = "../../agb" }
agb_tracker_interop = { version = "0.18.1", path = "../agb-tracker-interop", default-features = false } agb_tracker_interop = { version = "0.18.1", path = "../agb-tracker-interop", default-features = false }