diff --git a/tracker/agb-midi-core/Cargo.toml b/tracker/agb-midi-core/Cargo.toml index 092e1b3f..9a8f156e 100644 --- a/tracker/agb-midi-core/Cargo.toml +++ b/tracker/agb-midi-core/Cargo.toml @@ -8,10 +8,6 @@ description = "Library for converting MIDI files for use with agb-tracker on the 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", diff --git a/tracker/agb-midi-core/src/lib.rs b/tracker/agb-midi-core/src/lib.rs index 0c012cbc..7eb6d61f 100644 --- a/tracker/agb-midi-core/src/lib.rs +++ b/tracker/agb-midi-core/src/lib.rs @@ -10,63 +10,7 @@ use std::{ use agb_fixnum::Num; use agb_tracker_interop::{Envelope, Pattern, PatternEffect, PatternSlot, Sample, Track}; use midly::{Format, MetaMessage, Smf, Timing, TrackEventKind}; -use proc_macro2::TokenStream; -use proc_macro_error::abort; -use quote::quote; use rustysynth::SoundFont; -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 { - 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 { sound_font: SoundFont, @@ -88,7 +32,7 @@ impl MidiInfo { } } -pub fn parse_midi(midi_info: &MidiInfo) -> TokenStream { +pub fn parse_midi(midi_info: &MidiInfo) -> Track { let mut samples = vec![]; let sf2 = &midi_info.sound_font; let sf2_data = sf2.get_wave_data(); @@ -417,7 +361,7 @@ pub fn parse_midi(midi_info: &MidiInfo) -> TokenStream { }) .collect(); - let track = Track { + Track { samples: samples.into(), envelopes: envelopes.into(), patterns: Cow::from(vec![Pattern { @@ -430,9 +374,7 @@ pub fn parse_midi(midi_info: &MidiInfo) -> TokenStream { frames_per_tick: Num::from_f64(frames_per_tick), ticks_per_step: 1, repeat: 0, - }; - - quote!(#track) + } } #[derive(Clone, Default)] diff --git a/tracker/agb-midi/Cargo.toml b/tracker/agb-midi/Cargo.toml index 73d77ead..8a0ac4aa 100644 --- a/tracker/agb-midi/Cargo.toml +++ b/tracker/agb-midi/Cargo.toml @@ -14,3 +14,11 @@ proc-macro = true agb_midi_core = { version = "0.20.5", path = "../agb-midi-core" } proc-macro-error = "1" proc-macro2 = "1" + +quote = "1" +syn = "2" +rustysynth = "1.3" +midly = { version = "0.5", default-features = false, features = [ + "alloc", + "std", +] } diff --git a/tracker/agb-midi/src/lib.rs b/tracker/agb-midi/src/lib.rs index 7918f3ca..1bf4ff78 100644 --- a/tracker/agb-midi/src/lib.rs +++ b/tracker/agb-midi/src/lib.rs @@ -1,8 +1,66 @@ +use std::path::Path; + +use agb_midi_core::{parse_midi, MidiInfo}; use proc_macro::TokenStream; -use proc_macro_error::proc_macro_error; +use proc_macro_error::{abort, proc_macro_error}; +use quote::quote; +use syn::{ + parse::{Parse, ParseStream}, + LitStr, Token, +}; #[proc_macro_error] #[proc_macro] pub fn include_midi(args: TokenStream) -> TokenStream { - agb_midi_core::agb_midi_core(args.into()).into() + agb_midi_core(args) +} + +struct MidiCoreInput { + sf2_file: LitStr, + _comma: Token![,], + midi_file: LitStr, +} + +impl Parse for MidiCoreInput { + fn parse(input: ParseStream) -> syn::Result { + Ok(Self { + sf2_file: input.parse()?, + _comma: input.parse()?, + midi_file: input.parse()?, + }) + } +} + +fn agb_midi_core(args: TokenStream) -> TokenStream { + let input: MidiCoreInput = match syn::parse(args.clone()) { + Ok(input) => input, + Err(e) => abort!(proc_macro2::TokenStream::from(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!(proc_macro2::TokenStream::from(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 + } + } + .into() }