Encode empty song sectors as CDXA Mode 1 for support with XEBRA

This commit is contained in:
Jaby 2024-06-19 20:28:04 +02:00 committed by Jaby
parent 053cbaf80a
commit fc11053b72
5 changed files with 51 additions and 15 deletions

View File

@ -1,4 +1,4 @@
use crate::types::{helper::InterleavedXASizes, RawData}; use crate::types::{helper::{InterleavedXASector, InterleavedXASizes}, RawData};
use cdtypes::types::{helper::*, sector::*}; use cdtypes::types::{helper::*, sector::*};
pub struct SubModeBuilder { pub struct SubModeBuilder {
@ -100,7 +100,7 @@ pub fn create_xa_data_for_vec(sub_mode: Option<SubMode>, data: &RawData) -> Vec<
sectors sectors
} }
pub fn create_xa_audio_for(data: &Vec<RawData>) -> Vec<Mode2Form2> { pub fn create_xa_audio_for(data: &Vec<RawData>) -> Vec<InterleavedXASector> {
let (channel_count, sectors_to_parse) = { let (channel_count, sectors_to_parse) = {
let size_info = InterleavedXASizes::new(data); let size_info = InterleavedXASizes::new(data);
(size_info.channels, size_info.biggest_file_sectors) (size_info.channels, size_info.biggest_file_sectors)
@ -112,19 +112,19 @@ pub fn create_xa_audio_for(data: &Vec<RawData>) -> Vec<Mode2Form2> {
} }
new_channel new_channel
}; };
let mut sectors = vec![Mode2Form2::new(); sectors_to_parse*channel_count]; let mut sectors = vec![InterleavedXASector::empty(); sectors_to_parse*channel_count];
let mut cur_sector_id = 0; let mut cur_sector_id = 0;
for _sector_id in 0..sectors_to_parse { for _sector_id in 0..sectors_to_parse {
let mut channel_id = 0; let mut channel_id = 0;
for channel in &mut channels { for channel in &mut channels {
let mut sub_mode = SubMode::default_form2(); let sector = {
let (raw_data, coding_info) = {
if channel.is_empty() { if channel.is_empty() {
sub_mode.set_eof(); InterleavedXASector::data({
sub_mode.set_eor(); let mut sector = create_xa_data_zero();
sector.sub_header.channel_number = channel_id;
([0xFFu8; Mode2Form2::DATA_SIZE], CodingInfo::default()) sector
})
} }
else { else {
@ -140,12 +140,17 @@ pub fn create_xa_audio_for(data: &Vec<RawData>) -> Vec<Mode2Form2> {
// v Skip EDC // v Skip EDC
*channel = &channel[0x4..channel.len()]; *channel = &channel[0x4..channel.len()];
sub_mode.set_real_time(); let sub_mode = {
(raw_data, sub_header.coding_info) let mut sub_mode = SubMode::default_form2();
sub_mode.set_real_time();
sub_mode
};
InterleavedXASector::audio(create_xa_audio_for_raw(sub_mode, sub_header.coding_info, channel_id, &raw_data))
} }
}; };
sectors[cur_sector_id] = create_xa_audio_for_raw(sub_mode, coding_info, channel_id, &raw_data); sectors[cur_sector_id] = sector;
channel_id += 1; channel_id += 1;
cur_sector_id += 1; cur_sector_id += 1;
} }

View File

@ -346,7 +346,7 @@ fn process_file(file: &File, sec_writer: &mut dyn SectorWriter) -> Result<(), Er
let content_sector_count = content_sectors.len(); let content_sector_count = content_sectors.len();
for sector in content_sectors { for sector in content_sectors {
sec_writer.write_cd_xa_audio(sector)?; sec_writer.write_interleaved(sector)?;
} }
let extended_sector_count = sector_count_mode2_form2(padded_size) - content_sector_count; let extended_sector_count = sector_count_mode2_form2(padded_size) - content_sector_count;

View File

@ -1,7 +1,9 @@
pub mod bin_cue; pub mod bin_cue;
pub use cdtypes::{cd::sector::Sector, types::*}; pub use cdtypes::{cd::sector::Sector, types::*};
use sector::Mode0;
use crate::types::helper::InterleavedXASector;
use super::{encoder::ImageEncoderFunction, types::CDDesc}; use super::{encoder::ImageEncoderFunction, types::CDDesc};
use bin_cue::BinCueWriter; use bin_cue::BinCueWriter;
use clap::ValueEnum; use clap::ValueEnum;
@ -34,6 +36,14 @@ pub trait SectorWriter {
self.write(Sector::CDXAAudio(sector)) self.write(Sector::CDXAAudio(sector))
} }
fn write_interleaved(&mut self, sector: InterleavedXASector) -> Result<usize, Error> {
match sector {
InterleavedXASector::Empty => self.write_empty(Mode0::new()),
InterleavedXASector::Data(sector) => self.write_cd_xa_data(sector),
InterleavedXASector::Audio(sector) => self.write_cd_xa_audio(sector),
}
}
fn write(&mut self, sector: Sector) -> Result<usize, Error>; fn write(&mut self, sector: Sector) -> Result<usize, Error>;
fn cd_da_start(&mut self) -> Result<(), Error>; fn cd_da_start(&mut self) -> Result<(), Error>;
} }

View File

@ -1,10 +1,31 @@
use cdtypes::types::helper::sector_count_audio; use cdtypes::types::{helper::sector_count_audio, sector::{Mode2Form1, Mode2Form2}};
use super::*; use super::*;
const CURRENT_DIR_NAME:&'static str = "\x00"; const CURRENT_DIR_NAME:&'static str = "\x00";
const PARENT_DIR_NAME:&'static str = "\x01"; const PARENT_DIR_NAME:&'static str = "\x01";
#[derive(Clone)]
pub enum InterleavedXASector {
Empty,
Data(Mode2Form1),
Audio(Mode2Form2)
}
impl InterleavedXASector {
pub fn empty() -> InterleavedXASector {
InterleavedXASector::Empty
}
pub fn data(sector: Mode2Form1) -> InterleavedXASector {
InterleavedXASector::Data(sector)
}
pub fn audio(sector: Mode2Form2) -> InterleavedXASector {
InterleavedXASector::Audio(sector)
}
}
pub struct PathTableMember { pub struct PathTableMember {
pub name: String, pub name: String,
pub track_rel_lba: usize, pub track_rel_lba: usize,

View File

@ -3,7 +3,7 @@ pub mod layout;
pub mod file_map; pub mod file_map;
pub mod overlay; pub mod overlay;
use cdtypes::types::{cdstring::DString, dir_record::DirectoryRecord, helper::xa_audio_interleave_count, path_table::PathTableL, sector::{AudioSample, Mode2Form2}}; use cdtypes::types::{cdstring::DString, dir_record::DirectoryRecord, helper::xa_audio_interleave_count, path_table::PathTableL, sector::AudioSample};
use std::{cell::RefCell, path::PathBuf, rc::Rc}; use std::{cell::RefCell, path::PathBuf, rc::Rc};
pub use file_map::FileSystemMap; pub use file_map::FileSystemMap;