use super::streamed_resource::StreamedResource; use crate::{ fmod::FmodSoundBank, object::{Value, parser::FromValue}, unityfs::UnityFS, }; use anyhow::{Ok, Result, anyhow, bail}; use log::{debug, info}; use serde::Serialize; use std::io::{Cursor, Read, Seek}; #[derive(Debug, Serialize)] pub struct AudioClip { pub resource: StreamedResource, pub channels: i32, pub ambisonic: bool, pub bits_per_sample: i32, pub compression_format: AudioCompressionFormat, pub frequency: i32, pub is_tracker_format: bool, pub legacy_3d: bool, pub length: f32, pub name: String, pub subsound_index: i32, } impl FromValue for AudioClip { fn from_value(v: Value) -> Result { let mut fields = v.as_class("AudioClip")?; Ok(AudioClip { resource: fields.field("m_Resource")?, ambisonic: fields.field("m_Ambisonic")?, bits_per_sample: fields.field("m_BitsPerSample")?, compression_format: fields.field("m_CompressionFormat")?, channels: fields.field("m_Channels")?, frequency: fields.field("m_Frequency")?, is_tracker_format: fields.field("m_IsTrackerFormat")?, legacy_3d: fields.field("m_Legacy3D")?, length: fields.field("m_Length")?, name: fields.field("m_Name")?, subsound_index: fields.field("m_SubsoundIndex")?, }) } } impl AudioClip { pub fn read_ogg(&self, fs: &UnityFS) -> Result> { let data = self.resource.read(&fs)?; match self.compression_format { AudioCompressionFormat::Vorbis => { info!("reading vorbis FMOD sound bank"); let mut bank = FmodSoundBank::open(Cursor::new(data))?; // Ok(buf.into_inner()) for i in 0..bank.streams.len() { let data = bank.read_stream(i)?; } Ok(Vec::new()) } x => todo!("audio format {x:?}"), } } } impl FromValue for AudioCompressionFormat { fn from_value(v: Value) -> Result { let x = v .as_i32() .ok_or(anyhow!("expected i32 AudioCompressionFormat"))?; if x < 10 { Ok(unsafe { std::mem::transmute(x) }) } else { bail!("AudioCompressionFormat out of range") } } } #[allow(non_camel_case_types)] #[repr(i32)] #[derive(Debug, Serialize, PartialEq, Clone, Copy)] pub enum AudioCompressionFormat { PCM, Vorbis, ADPCM, MP3, PSMVAG, HEVAG, XMA, AAC, GCADPCM, ATRAC9, }