Encode empty song sectors as CDXA Mode 1 for support with XEBRA
This commit is contained in:
parent
c9a115282b
commit
e740e86503
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue