From 4d80833bbd0d1f9a67cddb2657e023a60f4fad80 Mon Sep 17 00:00:00 2001 From: Breval Ferrari Date: Mon, 17 Mar 2025 00:33:38 -0400 Subject: [PATCH] add symphonia codec support for opening and exporting encoded files (not bendable since that would lead to data corruption) --- bingus/src/snd/simphonia.rs | 115 +++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 14 deletions(-) diff --git a/bingus/src/snd/simphonia.rs b/bingus/src/snd/simphonia.rs index a9d24af..9be1ce4 100644 --- a/bingus/src/snd/simphonia.rs +++ b/bingus/src/snd/simphonia.rs @@ -1,31 +1,40 @@ -use std::io; +use std::io::{self, Read}; +use derive_new::new; use symphonia::{ core::{ - audio::{RawSample, RawSampleBuffer}, + audio::Signal, + codecs::Decoder, + conv::FromSample, + errors::Error, + formats::FormatReader, io::MediaSourceStream, probe::Hint, - sample::Sample, + sample::{i24, u24}, }, default, }; -use crate::TryFromDataBytes; +use crate::{IntoDataBytes, TryFromDataBytes}; -pub struct Audio(RawSampleBuffer) -where - S: Sample + RawSample; +use super::{RawSamples, Sample}; -impl TryFromDataBytes for Audio -where - S: Sample + RawSample, -{ - type Error = symphonia::core::errors::Error; +/// The new hot thing: this represents audio in any format. You can open any file and make this thing with the file's bytes. +/// You can then modify its bytes and see what it gives. Maybe it won't work anymore. +/// You can also decode it to raw samples and play with it freely without corrupting anything. +#[derive(new)] +pub struct Audio { + reader: Box, + decoder: Box, +} + +impl TryFromDataBytes for Audio { + type Error = Error; type Format = Hint; fn try_from_data_bytes( bytes: crate::Bytes, format: Self::Format, - crop: crate::Crop, + _crop: crate::Crop, ) -> Result where Self: Sized, @@ -37,6 +46,84 @@ where let reader = probe .format(&format, mss, &Default::default(), &Default::default())? .format; - todo!() + let decoder = registry.make(&Default::default(), &Default::default())?; + Ok(Audio::new(reader, decoder)) + } +} + +impl IntoDataBytes for Audio { + fn into_data_bytes(self) -> crate::Bytes { + self.reader.into_inner().bytes().flatten().collect() + } +} + +macro_rules! dynamic_map( + ($dynimage: expr, $image: pat => $action: expr) => ({ + match $dynimage { + symphonia::core::audio::AudioBufferRef::U8($image) => symphonia::core::audio::AudioBufferRef::U8($action), + symphonia::core::audio::AudioBufferRef::U16($image) => symphonia::core::audio::AudioBufferRef::U16($action), + symphonia::core::audio::AudioBufferRef::U24($image) => symphonia::core::audio::AudioBufferRef::U24($action), + symphonia::core::audio::AudioBufferRef::U32($image) => symphonia::core::audio::AudioBufferRef::U32($action), + symphonia::core::audio::AudioBufferRef::S8($image) => symphonia::core::audio::AudioBufferRef::S8($action), + symphonia::core::audio::AudioBufferRef::S16($image) => symphonia::core::audio::AudioBufferRef::S16($action), + symphonia::core::audio::AudioBufferRef::S24($image) => symphonia::core::audio::AudioBufferRef::S24($action), + symphonia::core::audio::AudioBufferRef::S32($image) => symphonia::core::audio::AudioBufferRef::S32($action), + symphonia::core::audio::AudioBufferRef::F32($image) => symphonia::core::audio::AudioBufferRef::F32($action), + symphonia::core::audio::AudioBufferRef::F64($image) => symphonia::core::audio::AudioBufferRef::F64($action), + } + }); + + ($dynimage: expr, $image:pat_param, $action: expr) => ( + match $dynimage { + symphonia::core::audio::AudioBufferRef::U8($image) => $action, + symphonia::core::audio::AudioBufferRef::U16($image) => $action, + symphonia::core::audio::AudioBufferRef::U24($image) => $action, + symphonia::core::audio::AudioBufferRef::U32($image) => $action, + symphonia::core::audio::AudioBufferRef::S8($image) => $action, + symphonia::core::audio::AudioBufferRef::S16($image) => $action, + symphonia::core::audio::AudioBufferRef::S24($image) => $action, + symphonia::core::audio::AudioBufferRef::S32($image) => $action, + symphonia::core::audio::AudioBufferRef::F32($image) => $action, + symphonia::core::audio::AudioBufferRef::F64($image) => $action, + } + ); +); + +impl From