From d0a238da9e381e2364ef3f2ce8628397b2bf60a4 Mon Sep 17 00:00:00 2001 From: Corwin Date: Thu, 4 Aug 2022 22:53:25 +0100 Subject: [PATCH] emit sound directly as a single token --- agb-sound-converter/src/lib.rs | 78 ++++++++++------------------------ 1 file changed, 22 insertions(+), 56 deletions(-) diff --git a/agb-sound-converter/src/lib.rs b/agb-sound-converter/src/lib.rs index 368e74d..b04f280 100644 --- a/agb-sound-converter/src/lib.rs +++ b/agb-sound-converter/src/lib.rs @@ -1,15 +1,9 @@ #![deny(clippy::all)] use proc_macro::TokenStream; -use quote::quote; -use std::{ - collections::hash_map::DefaultHasher, - fs, - fs::File, - hash::{Hash, Hasher}, - io::Write, - path::Path, -}; +use proc_macro2::Literal; +use quote::{quote, ToTokens}; +use std::path::Path; use syn::parse_macro_input; #[cfg(all(not(feature = "freq18157"), not(feature = "freq32768")))] @@ -21,6 +15,14 @@ const FREQUENCY: u32 = 32768; #[cfg(all(feature = "freq18157", feature = "freq32768"))] compile_error!("Must have at most one of freq18157 or freq32768 features enabled"); +use quote::TokenStreamExt; +struct ByteString<'a>(&'a [u8]); +impl ToTokens for ByteString<'_> { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + tokens.append(Literal::byte_string(self.0)); + } +} + #[proc_macro] pub fn include_wav(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as syn::LitStr); @@ -32,47 +34,18 @@ pub fn include_wav(input: TokenStream) -> TokenStream { let include_path = path.to_string_lossy(); - let out_file_path_include = { - let out_dir = std::env::var("OUT_DIR").expect("Expected OUT_DIR"); - let out_filename = get_out_filename(&path); + let wav_reader = hound::WavReader::open(&path) + .unwrap_or_else(|_| panic!("Failed to load file {}", include_path)); - let out_file_path = Path::new(&out_dir).with_file_name(&out_filename); + assert_eq!( + wav_reader.spec().sample_rate, + FREQUENCY, + "agb currently only supports sample rate of {}Hz", + FREQUENCY + ); - let out_file_mtime = fs::metadata(&out_file_path).and_then(|metadata| metadata.modified()); - let in_file_mtime = fs::metadata(&path).and_then(|metadata| metadata.modified()); - - let should_write = match (out_file_mtime, in_file_mtime) { - (Ok(out_file_mtime), Ok(in_file_mtime)) => out_file_mtime <= in_file_mtime, - _ => true, - }; - - if should_write { - let wav_reader = hound::WavReader::open(&path) - .unwrap_or_else(|_| panic!("Failed to load file {}", include_path)); - - assert_eq!( - wav_reader.spec().sample_rate, - FREQUENCY, - "agb currently only supports sample rate of {}Hz", - FREQUENCY - ); - - let samples = samples_from_reader(wav_reader); - - let mut out_file = - File::create(&out_file_path).expect("Failed to open file for writing"); - - out_file - .write_all(&samples.collect::>()) - .expect("Failed to write to temporary file"); - } - - out_file_path - } - .canonicalize() - .expect("Failed to canonicalize"); - - let out_file_path_include = out_file_path_include.to_string_lossy(); + let samples: Vec = samples_from_reader(wav_reader).collect(); + let samples = ByteString(&samples); let result = quote! { { @@ -81,7 +54,7 @@ pub fn include_wav(input: TokenStream) -> TokenStream { const _: &[u8] = include_bytes!(#include_path); - &AlignmentWrapper(*include_bytes!(#out_file_path_include)).0 + &AlignmentWrapper(*#samples).0 } }; @@ -108,10 +81,3 @@ where ), } } - -fn get_out_filename(path: &Path) -> String { - let mut hasher = DefaultHasher::new(); - path.hash(&mut hasher); - - format!("{}.raw", hasher.finish()) -}