Support XA-Audio (buggy)
This commit is contained in:
parent
c8ccd44a71
commit
61c300e37e
|
@ -7,6 +7,6 @@ edition = "2021"
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.5.0"
|
byteorder = "1.5.0"
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.31"
|
||||||
paste = "1.0.14"
|
paste = "1.0.14"
|
|
@ -27,7 +27,7 @@ impl<'a> Reader<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_audio_sector(&mut self) -> Result<Option<Sector>, Error> {
|
fn process_audio_sector(&mut self, _force: bool) -> Result<Option<Sector>, Error> {
|
||||||
let mut buffer = [0;std::mem::size_of::<Audio>()];
|
let mut buffer = [0;std::mem::size_of::<Audio>()];
|
||||||
let bytes = self.file.read(&mut buffer)?;
|
let bytes = self.file.read(&mut buffer)?;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ impl<'a> Reader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_binary_sector(&mut self) -> Result<Option<Sector>, Error> {
|
fn process_binary_sector(&mut self, force: bool) -> Result<Option<Sector>, Error> {
|
||||||
fn make_ok_some(sector: Sector) -> Result<Option<Sector>, Error> {
|
fn make_ok_some(sector: Sector) -> Result<Option<Sector>, Error> {
|
||||||
Ok(Some(sector))
|
Ok(Some(sector))
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,15 @@ impl<'a> Reader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(mode) => {
|
Err(mode) => {
|
||||||
return Err(Error::TypeError(format!("Unkown Mode: {} @LBA: {}", mode, self.lba - 1)));
|
let error_str = format!("Unknown Mode: {} @LBA: {}", mode, self.lba - 1);
|
||||||
|
if force {
|
||||||
|
println!("Warning: {}", error_str);
|
||||||
|
return make_ok_some(Sector::Empty(Mode0::new()));
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return Err(Error::TypeError(error_str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +98,7 @@ impl<'a> std::iter::Iterator for Reader<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match function(self) {
|
match function(self, true) {
|
||||||
Ok(sector) => {
|
Ok(sector) => {
|
||||||
if let Some(sector) = sector {
|
if let Some(sector) = sector {
|
||||||
Some(Ok(sector))
|
Some(Ok(sector))
|
||||||
|
|
|
@ -23,13 +23,6 @@ impl Quality {
|
||||||
Self::High => 37800,
|
Self::High => 37800,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bith_depth(&self) -> u64 {
|
|
||||||
match self {
|
|
||||||
Self::Low => 4,
|
|
||||||
Self::High => 8,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, ValueEnum)]
|
#[derive(Copy, Clone, ValueEnum)]
|
||||||
|
@ -67,7 +60,7 @@ pub fn convert(args: Arguments, input: PathBuf, output: PathBuf) -> Result<(), E
|
||||||
let result = Command::new(tool_path).args([
|
let result = Command::new(tool_path).args([
|
||||||
"-t", "xacd",
|
"-t", "xacd",
|
||||||
"-f", quality.get_frequency().to_string().as_ref(),
|
"-f", quality.get_frequency().to_string().as_ref(),
|
||||||
"-b", quality.get_bith_depth().to_string().as_ref(),
|
"-b", "4",
|
||||||
"-c", sample.get_channel().to_string().as_ref(),
|
"-c", sample.get_channel().to_string().as_ref(),
|
||||||
"-F", "0",
|
"-F", "0",
|
||||||
"-C", "0",
|
"-C", "0",
|
||||||
|
|
|
@ -49,13 +49,14 @@ pub fn create_xa_data_for_raw(mut sub_mode: SubMode, data: &[u8; Mode2Form1::DAT
|
||||||
sector
|
sector
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_xa_audio_for_raw(mut sub_mode: SubMode, channel: u8, data: &[u8; Mode2Form2::DATA_SIZE]) -> Mode2Form2 {
|
pub fn create_xa_audio_for_raw(mut sub_mode: SubMode, coding_info: CodingInfo, channel: u8, data: &[u8; Mode2Form2::DATA_SIZE]) -> Mode2Form2 {
|
||||||
let mut sector = Mode2Form2::new();
|
let mut sector = Mode2Form2::new();
|
||||||
|
|
||||||
sub_mode.set_audio();
|
sub_mode.set_audio();
|
||||||
|
|
||||||
sector.sub_header.channel_number = channel;
|
sector.sub_header.channel_number = channel;
|
||||||
sector.sub_header.sub_mode = sub_mode;
|
sector.sub_header.sub_mode = sub_mode;
|
||||||
|
sector.sub_header.coding_info = coding_info;
|
||||||
sector.data = *data;
|
sector.data = *data;
|
||||||
sector
|
sector
|
||||||
}
|
}
|
||||||
|
@ -124,6 +125,7 @@ pub fn create_xa_audio_for(data: &Vec<RawData>) -> Vec<Mode2Form2> {
|
||||||
let mut channel_id = 0;
|
let mut channel_id = 0;
|
||||||
let sub_mode = {
|
let sub_mode = {
|
||||||
let mut sub_mode = SubMode::default_form2();
|
let mut sub_mode = SubMode::default_form2();
|
||||||
|
sub_mode.set_real_time();
|
||||||
|
|
||||||
if sector_id + 1 == sectors_to_parse {
|
if sector_id + 1 == sectors_to_parse {
|
||||||
sub_mode.set_eof();
|
sub_mode.set_eof();
|
||||||
|
@ -133,24 +135,28 @@ pub fn create_xa_audio_for(data: &Vec<RawData>) -> Vec<Mode2Form2> {
|
||||||
};
|
};
|
||||||
|
|
||||||
for channel in &mut channels {
|
for channel in &mut channels {
|
||||||
let raw_data = {
|
let (raw_data, coding_info) = {
|
||||||
if channel.is_empty() {
|
if channel.is_empty() {
|
||||||
[0u8; Mode2Form2::DATA_SIZE]
|
([0u8; Mode2Form2::DATA_SIZE], CodingInfo::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
let mut raw_data = [0u8; Mode2Form2::DATA_SIZE];
|
let mut sub_header = SubHeader::default();
|
||||||
|
let mut raw_data = [0u8; Mode2Form2::DATA_SIZE];
|
||||||
|
|
||||||
// v Skip header stuff
|
// v Skip sync and header
|
||||||
*channel = &channel[0x18..channel.len()];
|
*channel = &channel[0x10..channel.len()];
|
||||||
*channel = copy_array(&mut raw_data, &channel);
|
*channel = copy_object(&mut sub_header, &channel);
|
||||||
|
// v Copy of sub-header
|
||||||
*channel = &channel[0x4..channel.len()];
|
*channel = &channel[0x4..channel.len()];
|
||||||
// ^ Skip EDC
|
*channel = copy_array(&mut raw_data, &channel);
|
||||||
raw_data
|
// v Skip EDC
|
||||||
|
*channel = &channel[0x4..channel.len()];
|
||||||
|
|
||||||
|
(raw_data, sub_header.coding_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
sectors[cur_sector_id] = create_xa_audio_for_raw(sub_mode, channel_id, &raw_data);
|
sectors[cur_sector_id] = create_xa_audio_for_raw(sub_mode, coding_info, channel_id, &raw_data);
|
||||||
channel_id += 1;
|
channel_id += 1;
|
||||||
cur_sector_id += 1;
|
cur_sector_id += 1;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +169,16 @@ pub fn create_xa_data_zero() -> Mode2Form1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_xa_audio_zero(channel: u8) -> Mode2Form2 {
|
pub fn create_xa_audio_zero(channel: u8) -> Mode2Form2 {
|
||||||
create_xa_audio_for_raw(SubMode::default_form2(), channel, &[0u8; Mode2Form2::DATA_SIZE])
|
create_xa_audio_for_raw(SubMode::default_form2(), CodingInfo::default_form2(), channel, &[0u8; Mode2Form2::DATA_SIZE])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_object<'a, T, S>(dst: &mut T, src: &'a [S]) -> &'a [S] {
|
||||||
|
let data_size = std::mem::size_of::<T>();
|
||||||
|
unsafe{
|
||||||
|
let dst:*mut T = &mut *dst;
|
||||||
|
std::ptr::copy_nonoverlapping(src.as_ptr(), dst as *mut S, data_size)
|
||||||
|
};
|
||||||
|
&src[data_size..src.len()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_array<'a, T, const SIZE:usize>(dst: &mut [T; SIZE], src: &'a [T]) -> &'a [T] {
|
fn copy_array<'a, T, const SIZE:usize>(dst: &mut [T; SIZE], src: &'a [T]) -> &'a [T] {
|
||||||
|
|
Loading…
Reference in New Issue