Integrate all the progress into master #6
|
@ -13,7 +13,7 @@ pub struct Encoder<'a> {
|
|||
|
||||
impl<'a> Encoder<'a> {
|
||||
const BLOCKS_PER_SECTOR:usize = 18;
|
||||
const XA_ADPCM_FILTER_COUNT: i32 = 3;
|
||||
const XA_ADPCM_FILTER_COUNT: i32 = 4;
|
||||
const FILTER_K1: [i16; 5] = [0, 60, 115, 98, 122];
|
||||
const FILTER_K2: [i16; 5] = [0, 0, -52, -55, -60];
|
||||
|
||||
|
@ -85,7 +85,7 @@ impl<'a> Encoder<'a> {
|
|||
let mut best_sample_shift = 0;
|
||||
|
||||
for filter in 0..filter_count {
|
||||
let true_min_shift = Self::find_min_shift(channel_state, samples, sample_limit, pitch, filter as usize, shift_range)?;
|
||||
let true_min_shift = Self::find_min_shift(channel_state, samples, sample_limit, pitch, filter, shift_range)?;
|
||||
|
||||
// Testing has shown that the optimal shift can be off the true minimum shift
|
||||
// by 1 in *either* direction.
|
||||
|
@ -121,8 +121,8 @@ impl<'a> Encoder<'a> {
|
|||
|
||||
for i in 0..28 {
|
||||
// TODO: Code duplication with `find_min_shift`?
|
||||
let sample = if i >= sample_limit {0} else {samples[(i*pitch) as usize] as i32 + out_channel_state.qerr};
|
||||
let previous_value = (k1*out_channel_state.prev1 + k2*out_channel_state.prev2 + (1 << 5)) >> 6;
|
||||
let sample = (if i >= sample_limit {0} else {samples[(i*pitch) as usize] as i32}) + out_channel_state.qerr;
|
||||
let previous_value = (k1*out_channel_state.prev1 + k2*out_channel_state.prev2 + (1 << 5)) >> 6;
|
||||
|
||||
let mut sample_enc = sample - previous_value;
|
||||
sample_enc <<= min_shift;
|
||||
|
@ -130,15 +130,15 @@ impl<'a> Encoder<'a> {
|
|||
sample_enc >>= shift_range;
|
||||
|
||||
// TODO: And this?
|
||||
if sample_enc < (-0x8000 >> shift_range) {sample_enc = -0x8000 >> shift_range}
|
||||
if sample_enc > ( 0x7FFF >> shift_range) {sample_enc = 0x7FFF >> shift_range}
|
||||
if sample_enc < (std::i16::MIN as i32 >> shift_range) {sample_enc = std::i16::MIN as i32 >> shift_range}
|
||||
if sample_enc > (std::i16::MAX as i32 >> shift_range) {sample_enc = std::i16::MAX as i32 >> shift_range}
|
||||
sample_enc &= sample_mask as i32; //< v TODO: Redundant!
|
||||
|
||||
let mut sample_dec = (((sample_enc & sample_mask as i32) << shift_range) as i16) as i32;
|
||||
sample_dec >>= min_shift;
|
||||
sample_dec += previous_value;
|
||||
if sample_dec > 0x7FFF {sample_dec = 0x7FFF}
|
||||
if sample_dec < -0x8000 {sample_dec = -0x8000}
|
||||
if sample_dec > std::i16::MAX as i32 {sample_dec = std::i16::MAX as i32}
|
||||
if sample_dec < std::i16::MIN as i32 {sample_dec = std::i16::MIN as i32}
|
||||
|
||||
let sample_error = sample_dec - sample;
|
||||
if sample_error >= (1 << 30) || sample_error <= -(1 << 30) {
|
||||
|
@ -147,7 +147,7 @@ impl<'a> Encoder<'a> {
|
|||
|
||||
data[(i*data_pitch) as usize] = ((data[(i*pitch) as usize] & nondata_mask) as i32 | (sample_enc << data_shift)) as u8;
|
||||
|
||||
out_channel_state.mse += sample_error as i64*sample_error as i64;
|
||||
out_channel_state.mse += (sample_error as u64*sample_error as u64) as i64;
|
||||
out_channel_state.prev2 = out_channel_state.prev1;
|
||||
out_channel_state.prev1 = sample_dec;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ impl<'a> Encoder<'a> {
|
|||
Ok(hdr)
|
||||
}
|
||||
|
||||
fn find_min_shift(channel_state: &ChannelState, samples: &[i16], sample_limit: i32, pitch: i32, filter: usize, shift_range: i32) -> Result<i32, Error> {
|
||||
fn find_min_shift(channel_state: &ChannelState, samples: &[i16], sample_limit: i32, pitch: i32, filter: i32, shift_range: i32) -> Result<i32, Error> {
|
||||
/*
|
||||
Assumption made:
|
||||
There is value in shifting right one step further to allow the nibbles to clip.
|
||||
|
@ -167,8 +167,8 @@ impl<'a> Encoder<'a> {
|
|||
|
||||
let mut prev1 = channel_state.prev1;
|
||||
let mut prev2 = channel_state.prev2;
|
||||
let k1 = Self::FILTER_K1[filter] as i32;
|
||||
let k2 = Self::FILTER_K2[filter] as i32;
|
||||
let k1 = Self::FILTER_K1[filter as usize] as i32;
|
||||
let k2 = Self::FILTER_K2[filter as usize] as i32;
|
||||
let mut right_shift = 0;
|
||||
let mut s_min = 0;
|
||||
let mut s_max = 0;
|
||||
|
@ -190,11 +190,11 @@ impl<'a> Encoder<'a> {
|
|||
prev1 = raw_sample;
|
||||
}
|
||||
|
||||
while right_shift < shift_range && (s_max >> right_shift) > (0x7FFF >> shift_range) {
|
||||
while right_shift < shift_range && (s_max >> right_shift) > (std::i16::MAX as i32 >> shift_range) {
|
||||
right_shift += 1;
|
||||
}
|
||||
|
||||
while right_shift < shift_range && (s_min >> right_shift) < (-0x8000 >> shift_range) {
|
||||
while right_shift < shift_range && (s_min >> right_shift) < (std::i16::MIN as i32 >> shift_range) {
|
||||
right_shift += 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue