Support CDDA alignment (can not be specified yet)

This commit is contained in:
Jaby 2024-07-28 21:42:09 -05:00
parent 4cb6e05e62
commit 73bbe0e805
7 changed files with 38 additions and 11 deletions

View File

@ -80,6 +80,10 @@ impl Time {
self.sector as usize + self.second as usize*Self::MAX_SECTORS + self.minute as usize*Self::MAX_SECONDS*Self::MAX_SECTORS
}
pub const fn get(&self) -> (i32, i32, i32) {
(self.minute as i32, self.second as i32, self.sector as i32)
}
pub fn dump(&self) -> String {
format!("min: {}, sec: {}, sector: {}", self.minute, self.second, self.sector)
}

View File

@ -1,7 +1,7 @@
use super::{*, SectorWriter, {CDDesc, Error}};
use super::{*, SectorWriter, {CDDATrack, CDDesc, Error}};
use super::super::types::{FileType, 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, sector_count_mode2_form2}, 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::Mode2Form1};
use tool_helper::{BufferedInputFile, format_if_error, open_input_file_buffered, print_warning};
use std::io::{Read, Seek, SeekFrom};
@ -420,13 +420,20 @@ fn process_lead_out(sectors: usize, sec_writer: &mut dyn SectorWriter) -> Result
}
fn process_end_dummy_section(padding: usize, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
// The padding required for the PS3
write_dummy(sec_writer, sector_count_mode2_form1(padding))
}
fn process_cd_da(cd_da_tracks: &Vec<Vec<AudioSample>>, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
fn process_cd_da(cd_da_tracks: &Vec<CDDATrack>, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
for cd_da_track in cd_da_tracks {
// The padding required for CDDA to start on a full second
if cd_da_track.align {
let missing_sectors = sec_writer.sectors_to_next_second();
write_dummy(sec_writer, missing_sectors)?;
}
sec_writer.cd_da_start()?;
for audio in builder::create_audio_for_vec(cd_da_track) {
for audio in builder::create_audio_for_vec(&cd_da_track.samples) {
sec_writer.write_audio(audio)?;
}
}

View File

@ -1,4 +1,4 @@
use super::{file_writer::SectorWriter, types::{CDDesc, Error}};
use super::{file_writer::SectorWriter, types::{CDDATrack, CDDesc, Error}};
pub mod cd;
pub mod builder;

View File

@ -51,7 +51,6 @@ impl SectorWriter for BinCueWriter {
self.track += 1;
self.cue.push(CueSpecifier::Track{number: self.track, data_type: CueDataType::Audio});
if self.track == 2 {
self.cue.push(CueSpecifier::PreGap{time: Time::cd_pregap()});
}
@ -63,4 +62,9 @@ impl SectorWriter for BinCueWriter {
self.cue.push(CueSpecifier::Index{number: 1, time: self.cd_time.clone()});
Ok(())
}
fn sectors_to_next_second(&self) -> usize {
let (_, _, sectors) = self.cd_time.get();
Time::MAX_SECTORS - sectors as usize
}
}

View File

@ -46,6 +46,7 @@ pub trait SectorWriter {
fn write(&mut self, sector: Sector) -> Result<usize, Error>;
fn cd_da_start(&mut self) -> Result<(), Error>;
fn sectors_to_next_second(&self) -> usize;
}
pub fn write_image(cd_desc: &CDDesc, image_type: ImageType, mut output_path: PathBuf) -> Result<(), Error> {

View File

@ -10,7 +10,7 @@ use cdtypes::types::sector::AudioSample;
use config_reader::LZ4State;
use encoder::{cd::{self, calculate_lbas, calculate_length_for}, SizeInfo};
use tool_helper::{format_if_error, Output, read_file};
use types::{layout::Layout, CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr};
use types::{layout::Layout, CDDATrack, CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr};
use std::path::PathBuf;
pub type LBAEmbeddedFiles = Vec<SharedPtr<File>>;
@ -204,7 +204,7 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc,
Ok(())
}
fn parse_cd_da(cd_da_tracks: &mut Vec<Vec<AudioSample>>, cd_da_files: Vec<PathBuf>) -> Result<(), Error> {
fn parse_cd_da(cd_da_tracks: &mut Vec<CDDATrack>, cd_da_files: Vec<PathBuf>) -> Result<(), Error> {
fn convert_into_16<R:std::io::Read, S:hound::Sample>(samples: hound::WavSamples<R,S>, file_path: &PathBuf) -> Result<Vec<AudioSample>, Error> {
let mut sample_buffer = 0;
let mut sample_id = 0;
@ -244,7 +244,7 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc,
return Err(Error::from_text(format!("{}: Only a sampling rate of 44.1kHz is supported for Audio tracks", cd_da_file.display())));
}
cd_da_tracks.push(convert_into_16(audio_io.samples::<i16>(), &cd_da_file)?);
cd_da_tracks.push(CDDATrack::new(convert_into_16(audio_io.samples::<i16>(), &cd_da_file)?, false));
}
Ok(())
}

View File

@ -17,15 +17,26 @@ pub fn new_shared_ptr<T>(value: T) -> SharedPtr<T> {
Rc::new(RefCell::new(value))
}
pub struct CDDATrack {
pub(super) samples: Vec<AudioSample>,
pub(super) align: bool,
}
impl CDDATrack {
pub fn new(samples: Vec<AudioSample>, align: bool) -> CDDATrack {
CDDATrack{samples, align}
}
}
pub struct CDDesc {
pub(super) system_area: SharedPtr<SystemArea>,
pub(super) path_table: SharedPtr<PathTable>,
pub(super) pvd: SharedPtr<PrimaryVolumeDescriptor>,
pub(super) root: SharedPtr<Directory>,
pub(super) cd_da_tracks: Vec<Vec<AudioSample>>,
pub(super) cd_da_tracks: Vec<CDDATrack>,
pub(super) vol_sector_count: usize,
pub lead_out_sectors: usize,
pub end_dummy_padding: usize
pub end_dummy_padding: usize,
}
impl CDDesc {