mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-09 08:31:33 +11:00
Do the same changes for midi
This commit is contained in:
parent
3a755107aa
commit
f452070154
|
@ -8,10 +8,6 @@ description = "Library for converting MIDI files for use with agb-tracker on the
|
||||||
repository = "https://github.com/agbrs/agb"
|
repository = "https://github.com/agbrs/agb"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro-error = "1"
|
|
||||||
proc-macro2 = "1"
|
|
||||||
quote = "1"
|
|
||||||
syn = "2"
|
|
||||||
rustysynth = "1.3"
|
rustysynth = "1.3"
|
||||||
midly = { version = "0.5", default-features = false, features = [
|
midly = { version = "0.5", default-features = false, features = [
|
||||||
"alloc",
|
"alloc",
|
||||||
|
|
|
@ -10,63 +10,7 @@ use std::{
|
||||||
use agb_fixnum::Num;
|
use agb_fixnum::Num;
|
||||||
use agb_tracker_interop::{Envelope, Pattern, PatternEffect, PatternSlot, Sample, Track};
|
use agb_tracker_interop::{Envelope, Pattern, PatternEffect, PatternSlot, Sample, Track};
|
||||||
use midly::{Format, MetaMessage, Smf, Timing, TrackEventKind};
|
use midly::{Format, MetaMessage, Smf, Timing, TrackEventKind};
|
||||||
use proc_macro2::TokenStream;
|
|
||||||
use proc_macro_error::abort;
|
|
||||||
use quote::quote;
|
|
||||||
use rustysynth::SoundFont;
|
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<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 {
|
pub struct MidiInfo {
|
||||||
sound_font: SoundFont,
|
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 mut samples = vec![];
|
||||||
let sf2 = &midi_info.sound_font;
|
let sf2 = &midi_info.sound_font;
|
||||||
let sf2_data = sf2.get_wave_data();
|
let sf2_data = sf2.get_wave_data();
|
||||||
|
@ -417,7 +361,7 @@ pub fn parse_midi(midi_info: &MidiInfo) -> TokenStream {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let track = Track {
|
Track {
|
||||||
samples: samples.into(),
|
samples: samples.into(),
|
||||||
envelopes: envelopes.into(),
|
envelopes: envelopes.into(),
|
||||||
patterns: Cow::from(vec![Pattern {
|
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),
|
frames_per_tick: Num::from_f64(frames_per_tick),
|
||||||
ticks_per_step: 1,
|
ticks_per_step: 1,
|
||||||
repeat: 0,
|
repeat: 0,
|
||||||
};
|
}
|
||||||
|
|
||||||
quote!(#track)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
|
|
|
@ -14,3 +14,11 @@ proc-macro = true
|
||||||
agb_midi_core = { version = "0.20.5", path = "../agb-midi-core" }
|
agb_midi_core = { version = "0.20.5", path = "../agb-midi-core" }
|
||||||
proc-macro-error = "1"
|
proc-macro-error = "1"
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
|
|
||||||
|
quote = "1"
|
||||||
|
syn = "2"
|
||||||
|
rustysynth = "1.3"
|
||||||
|
midly = { version = "0.5", default-features = false, features = [
|
||||||
|
"alloc",
|
||||||
|
"std",
|
||||||
|
] }
|
||||||
|
|
|
@ -1,8 +1,66 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use agb_midi_core::{parse_midi, MidiInfo};
|
||||||
use proc_macro::TokenStream;
|
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_error]
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn include_midi(args: TokenStream) -> TokenStream {
|
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<Self> {
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue