From 5bc0c28739d4f9ea0f418445244efcf17a175502 Mon Sep 17 00:00:00 2001 From: Jaby Date: Fri, 24 May 2024 19:14:02 +0200 Subject: [PATCH] Handle more files --- .../psxcdgen_ex/src/config_reader/mod.rs | 2 +- .../psxcdgen_ex/src/config_reader/xml.rs | 2 +- src/Tools/psxcdgen_ex/src/encoder/builder.rs | 57 +++++++++++++++++-- src/Tools/psxcdgen_ex/src/encoder/psx.rs | 26 ++++++--- src/Tools/psxcdgen_ex/src/lib.rs | 2 +- src/Tools/psxcdgen_ex/src/types/mod.rs | 16 +++++- 6 files changed, 88 insertions(+), 17 deletions(-) diff --git a/src/Tools/psxcdgen_ex/src/config_reader/mod.rs b/src/Tools/psxcdgen_ex/src/config_reader/mod.rs index 406111d5..a6ff6481 100644 --- a/src/Tools/psxcdgen_ex/src/config_reader/mod.rs +++ b/src/Tools/psxcdgen_ex/src/config_reader/mod.rs @@ -32,7 +32,7 @@ pub enum FileKind { Regular, Main(PathBuf), Overlay(PathBuf), - XA_Audio(Vec), + XAAudio(Vec), } pub struct File { diff --git a/src/Tools/psxcdgen_ex/src/config_reader/xml.rs b/src/Tools/psxcdgen_ex/src/config_reader/xml.rs index 65ca1e5a..2e8e84bc 100644 --- a/src/Tools/psxcdgen_ex/src/config_reader/xml.rs +++ b/src/Tools/psxcdgen_ex/src/config_reader/xml.rs @@ -99,7 +99,7 @@ fn parse_track(track: roxmltree::Node, config: &mut Configuration) -> Result<(), channel }; - Ok(File{common, path: PathBuf::new(), kind: FileKind::XA_Audio(channel)}) + Ok(File{common, path: PathBuf::new(), kind: FileKind::XAAudio(channel)}) } fn parse_file_system(cur_node: roxmltree::Node, root: &mut Directory, mut is_hidden: bool) -> Result<(), Error> { diff --git a/src/Tools/psxcdgen_ex/src/encoder/builder.rs b/src/Tools/psxcdgen_ex/src/encoder/builder.rs index a0c1859d..5326e9ec 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/builder.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/builder.rs @@ -1,5 +1,6 @@ use crate::types::RawData; use cdtypes::types::{helper::*, sector::*}; +use tool_helper::print_warning; pub struct SubModeBuilder { sub_mode: SubMode @@ -49,13 +50,14 @@ pub fn create_xa_data_for_raw(mut sub_mode: SubMode, data: &[u8; Mode2Form1::DAT sector } -pub fn create_xa_audio_for_raw(mut sub_mode: SubMode, data: &[u8; Mode2Form2::DATA_SIZE]) -> Mode2Form2 { +pub fn create_xa_audio_for_raw(mut sub_mode: SubMode, channel: u8, data: &[u8; Mode2Form2::DATA_SIZE]) -> Mode2Form2 { let mut sector = Mode2Form2::new(); sub_mode.set_audio(); - sector.sub_header.sub_mode = sub_mode; - sector.data = *data; + sector.sub_header.channel_number = channel; + sector.sub_header.sub_mode = sub_mode; + sector.data = *data; sector } @@ -97,12 +99,57 @@ pub fn create_xa_data_for_vec(sub_mode: Option, data: &RawData) -> Vec< sectors } +pub fn create_xa_audio_for(data: &Vec) -> Vec { + let channel_count = data.len(); + let sectors_to_parse = { + let mut biggest_size = 0; + + for channel in data { + if channel.len() > biggest_size { + biggest_size = channel.len(); + } + } + sector_count_mode2_form2(biggest_size) + }; + let channels = { + let mut new_channel = Vec::new(); + for channel in data { + new_channel.push(&channel[0..channel.len()]); + } + new_channel + }; + let mut sectors = vec![Mode2Form2::new(); sectors_to_parse*channel_count]; + let mut cur_sector_id = 0; + + for sector_id in 0..sectors_to_parse { + let mut channel_id = 0; + + for channel in &channels { + let raw_data = { + if channel.is_empty() { + [0u8; Mode2Form2::DATA_SIZE] + } + + else { + print_warning(format!("Encoding XA-Audio sector #{} for file {} not supported yet", sector_id, channel_id)); + [0u8; Mode2Form2::DATA_SIZE] + } + + }; + sectors[cur_sector_id] = create_xa_audio_for_raw(SubMode::default_form2(), channel_id, &raw_data); + channel_id += 1; + cur_sector_id += 1; + } + } + sectors +} + pub fn create_xa_data_zero() -> Mode2Form1 { create_xa_data_for_raw(SubMode::default_form1(), &[0u8; Mode2Form1::DATA_SIZE]) } -pub fn create_xa_audio_zero() -> Mode2Form2 { - create_xa_audio_for_raw(SubMode::default_form2(), &[0u8; Mode2Form2::DATA_SIZE]) +pub fn create_xa_audio_zero(channel: u8) -> Mode2Form2 { + create_xa_audio_for_raw(SubMode::default_form2(), channel, &[0u8; Mode2Form2::DATA_SIZE]) } fn copy_array<'a, T, const SIZE:usize>(dst: &mut [T; SIZE], src: &'a [T]) -> &'a [T] { diff --git a/src/Tools/psxcdgen_ex/src/encoder/psx.rs b/src/Tools/psxcdgen_ex/src/encoder/psx.rs index e881f637..6fee7db2 100644 --- a/src/Tools/psxcdgen_ex/src/encoder/psx.rs +++ b/src/Tools/psxcdgen_ex/src/encoder/psx.rs @@ -1,7 +1,7 @@ use super::{*, SectorWriter, {CDDesc, Error}}; use super::super::types::{helper::{DirectoryRecordMember, PathTableMember}, layout::Layout, *}; use builder::SubModeBuilder; -use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::*, helper::{round_bytes_mode2_form1, sector_count_mode2_form1}, lsb_msb::*, path_table::*, pvd as cd_pvd, sector::{AudioSample, Mode2Form1}}; +use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::*, helper::{round_bytes_mode2_form1, sector_count_mode2_form1, sector_count_mode2_form2}, lsb_msb::*, path_table::*, pvd as cd_pvd, sector::{AudioSample, Mode2Form1}}; use tool_helper::{BufferedInputFile, format_if_error, open_input_file_buffered, print_warning}; use std::io::{Read, Seek, SeekFrom}; @@ -168,7 +168,7 @@ fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWrit fn write_audio_zeros(sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { for _ in 0..4 { let sector = { - let mut sector = builder::create_xa_audio_zero(); + let mut sector = builder::create_xa_audio_zero(0); sector.sub_header.sub_mode.clear_audio(); sector @@ -326,7 +326,7 @@ fn process_directory_record(dir: &Directory, sec_writer: &mut dyn SectorWriter) fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { fn process_regular_file(content: &RawData, sec_writer: &mut dyn SectorWriter, padded_size: usize) -> Result<(), Error> { - let content_sectors = builder::create_xa_data_for_vec(None, content); + let content_sectors = builder::create_xa_data_for_vec(None, content); let content_sector_count = content_sectors.len(); for sector in content_sectors { @@ -341,8 +341,20 @@ fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Er Ok(()) } - fn process_cd_xa_file(_content: &Vec, _sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { - Err(Error::not_implemented("Encoding XA Audio")) + fn process_cd_xa_file(content: &Vec, sec_writer: &mut dyn SectorWriter, padded_size: usize) -> Result<(), Error> { + let content_sectors = builder::create_xa_audio_for(content); + let content_sector_count = content_sectors.len(); + + for sector in content_sectors { + sec_writer.write_cd_xa_audio(sector)?; + } + + let extended_sector_count = sector_count_mode2_form2(padded_size) - content_sector_count; + for _ in 0..extended_sector_count { + sec_writer.write_cd_xa_audio(builder::create_xa_audio_zero(0))?; + } + + Ok(()) } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -353,8 +365,8 @@ fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Er match &file.content { FileType::Regular(raw) => process_regular_file(raw, sec_writer, file.properties.get_padded_size()), - FileType::XA_Audio(raw) => process_cd_xa_file(raw, sec_writer), - FileType::Main(_, _) => Err(Error::from_str("Trying to encode an unprocssed main file")), + FileType::XAAudio(raw) => process_cd_xa_file(raw, sec_writer, file.properties.get_padded_size()), + FileType::Main(_, _) => Err(Error::from_str("Trying to encode an unprocessed main file")), FileType::Overlay(_, _) => Err(Error::from_str("Trying to encode an unprocessed overlay file")), } } diff --git a/src/Tools/psxcdgen_ex/src/lib.rs b/src/Tools/psxcdgen_ex/src/lib.rs index 79e89eb2..004b27a7 100644 --- a/src/Tools/psxcdgen_ex/src/lib.rs +++ b/src/Tools/psxcdgen_ex/src/lib.rs @@ -187,7 +187,7 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc, config_reader::FileKind::Regular => (types::File::new_regular(file.common.name.as_str(), handle_file_load(&file.path, &lz4_state)?)?, false), config_reader::FileKind::Main(lba_source) => (types::overlay::load_for_main(file.common.name.as_str(), handle_file_load(&file.path, &lz4_state)?, lba_source)?, true), config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), &file.path, lba_source)?, true), - config_reader::FileKind::XA_Audio(channels) => (types::File::new_xa_audio(file.common.name.as_str(), handle_multiple_file_load(channels, &lz4_state)?)?, false), + config_reader::FileKind::XAAudio(channels) => (types::File::new_xa_audio(file.common.name.as_str(), handle_multiple_file_load(channels, &lz4_state)?)?, false), } }; diff --git a/src/Tools/psxcdgen_ex/src/types/mod.rs b/src/Tools/psxcdgen_ex/src/types/mod.rs index 281392a1..836f90b2 100644 --- a/src/Tools/psxcdgen_ex/src/types/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/mod.rs @@ -220,7 +220,7 @@ pub(super) enum FileType { Regular(RawData), Main(RawData, overlay::LBANameVec), Overlay(RawData, overlay::LBANameVec), - XA_Audio(Vec), + XAAudio(Vec), } pub struct File { @@ -248,6 +248,18 @@ impl File { } pub fn new_xa_audio(file_name: &str, content: Vec) -> Result { + fn increase_content(mut content: Vec) -> Vec { + let channel_count = content.len(); + let xa_channel_count = xa_audio_interleave_count(channel_count); + if channel_count < xa_channel_count { + for _ in 0..(xa_channel_count - channel_count) { + content.push(RawData::new()); + } + } + content + } + + let content = increase_content(content); let channel_count = content.len(); let highest_size = { let mut size = 0; @@ -258,7 +270,7 @@ impl File { } size }; - Self::new_from_content(file_name, FileType::XA_Audio(content), highest_size*xa_audio_interleave_count(channel_count)) + Self::new_from_content(file_name, FileType::XAAudio(content), highest_size*channel_count) } pub fn get_track_rel_lba(&self) -> usize {