Support CDDA alignment (can not be specified yet)
This commit is contained in:
parent
5ec7acb803
commit
10554c7a6e
|
@ -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
|
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 {
|
pub fn dump(&self) -> String {
|
||||||
format!("min: {}, sec: {}, sector: {}", self.minute, self.second, self.sector)
|
format!("min: {}, sec: {}, sector: {}", self.minute, self.second, self.sector)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 super::super::types::{FileType, helper::{DirectoryRecordMember, PathTableMember}, layout::Layout, *};
|
||||||
use builder::SubModeBuilder;
|
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 tool_helper::{BufferedInputFile, format_if_error, open_input_file_buffered, print_warning};
|
||||||
use std::io::{Read, Seek, SeekFrom};
|
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> {
|
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))
|
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 {
|
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()?;
|
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)?;
|
sec_writer.write_audio(audio)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 cd;
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
|
|
|
@ -51,7 +51,6 @@ impl SectorWriter for BinCueWriter {
|
||||||
self.track += 1;
|
self.track += 1;
|
||||||
self.cue.push(CueSpecifier::Track{number: self.track, data_type: CueDataType::Audio});
|
self.cue.push(CueSpecifier::Track{number: self.track, data_type: CueDataType::Audio});
|
||||||
|
|
||||||
|
|
||||||
if self.track == 2 {
|
if self.track == 2 {
|
||||||
self.cue.push(CueSpecifier::PreGap{time: Time::cd_pregap()});
|
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()});
|
self.cue.push(CueSpecifier::Index{number: 1, time: self.cd_time.clone()});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sectors_to_next_second(&self) -> usize {
|
||||||
|
let (_, _, sectors) = self.cd_time.get();
|
||||||
|
Time::MAX_SECTORS - sectors as usize
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -46,6 +46,7 @@ pub trait SectorWriter {
|
||||||
|
|
||||||
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>;
|
||||||
|
fn sectors_to_next_second(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_image(cd_desc: &CDDesc, image_type: ImageType, mut output_path: PathBuf) -> Result<(), Error> {
|
pub fn write_image(cd_desc: &CDDesc, image_type: ImageType, mut output_path: PathBuf) -> Result<(), Error> {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use cdtypes::types::sector::AudioSample;
|
||||||
use config_reader::LZ4State;
|
use config_reader::LZ4State;
|
||||||
use encoder::{cd::{self, calculate_lbas, calculate_length_for}, SizeInfo};
|
use encoder::{cd::{self, calculate_lbas, calculate_length_for}, SizeInfo};
|
||||||
use tool_helper::{format_if_error, Output, read_file};
|
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;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub type LBAEmbeddedFiles = Vec<SharedPtr<File>>;
|
pub type LBAEmbeddedFiles = Vec<SharedPtr<File>>;
|
||||||
|
@ -204,7 +204,7 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc,
|
||||||
Ok(())
|
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> {
|
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_buffer = 0;
|
||||||
let mut sample_id = 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())));
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,26 @@ pub fn new_shared_ptr<T>(value: T) -> SharedPtr<T> {
|
||||||
Rc::new(RefCell::new(value))
|
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 struct CDDesc {
|
||||||
pub(super) system_area: SharedPtr<SystemArea>,
|
pub(super) system_area: SharedPtr<SystemArea>,
|
||||||
pub(super) path_table: SharedPtr<PathTable>,
|
pub(super) path_table: SharedPtr<PathTable>,
|
||||||
pub(super) pvd: SharedPtr<PrimaryVolumeDescriptor>,
|
pub(super) pvd: SharedPtr<PrimaryVolumeDescriptor>,
|
||||||
pub(super) root: SharedPtr<Directory>,
|
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(super) vol_sector_count: usize,
|
||||||
pub lead_out_sectors: usize,
|
pub lead_out_sectors: usize,
|
||||||
pub end_dummy_padding: usize
|
pub end_dummy_padding: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CDDesc {
|
impl CDDesc {
|
||||||
|
|
Loading…
Reference in New Issue