From 236d33f4e722dc79dc143c6c3aa4fead46b90e6f Mon Sep 17 00:00:00 2001 From: morkt Date: Thu, 10 Mar 2016 15:04:49 +0400 Subject: [PATCH] refined AdxInput.Read. --- ArcFormats/Cri/AudioADX.cs | 46 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/ArcFormats/Cri/AudioADX.cs b/ArcFormats/Cri/AudioADX.cs index 0ecdbf4b..d2083054 100644 --- a/ArcFormats/Cri/AudioADX.cs +++ b/ArcFormats/Cri/AudioADX.cs @@ -64,7 +64,7 @@ namespace GameRes.Formats.Cri long m_position; int m_buffered_sample; int m_buffered_count; - int m_bytes_per_sample; + int m_bytes_per_frame; ThreadLocal m_frame_buffer; public override string SourceFormat { get { return "adx"; } } @@ -77,45 +77,45 @@ namespace GameRes.Formats.Cri this.Format = m_reader.Format; this.PcmSize = m_reader.SampleCount * Format.BlockAlign; m_bitrate = (int)(Format.SamplesPerSecond * (file.Length-m_data_offset) * 8 / m_reader.SampleCount); - m_frame_buffer = new ThreadLocal (() => new short[m_reader.SamplesPerFrame * m_reader.Format.Channels]); - m_bytes_per_sample = Format.BitsPerSample / 8; + int frame_buffer_length = m_reader.SamplesPerFrame * m_reader.Format.Channels; + m_frame_buffer = new ThreadLocal (() => new short[frame_buffer_length]); + m_bytes_per_frame = frame_buffer_length * Format.BitsPerSample / 8; } public override int Read (byte[] buffer, int offset, int count) { int total_read = 0; int current_sample = (int)(m_position / Format.BlockAlign); - if (current_sample >= m_buffered_sample && current_sample < m_buffered_sample + m_buffered_count) + bool need_refill = !(current_sample >= m_buffered_sample && current_sample < m_buffered_sample + m_buffered_count); + int src_offset = (int)(m_position % m_bytes_per_frame); + while (count > 0 && m_position < PcmSize) { - int src_offset = (int)(m_position % (m_frame_buffer.Value.Length * m_bytes_per_sample)); + if (need_refill) + FillBuffer(); int available = Math.Min (count, m_buffered_count * Format.BlockAlign - src_offset); Buffer.BlockCopy (m_frame_buffer.Value, src_offset, buffer, offset, available); offset += available; count -= available; total_read += available; m_position += available; - } - int bytes_per_frame = m_reader.SamplesPerFrame * m_bytes_per_sample * Format.Channels; - while (count > 0 && m_position < PcmSize) - { - int frame_number = (int)(m_position / bytes_per_frame); - m_reader.SetPosition (m_data_offset + frame_number * m_reader.FrameSize * Format.Channels); - for (int i = 0; i < Format.Channels; ++i) - { - m_reader.DecodeFrame (i, m_frame_buffer.Value); - } - m_buffered_sample = frame_number * m_reader.SamplesPerFrame; - m_buffered_count = Math.Min (m_reader.SampleCount - m_buffered_sample, m_reader.SamplesPerFrame); - int available = Math.Min (count, m_buffered_count * Format.BlockAlign); - Buffer.BlockCopy (m_frame_buffer.Value, 0, buffer, offset, available); - offset += available; - count -= available; - total_read += available; - m_position += available; + src_offset = 0; + need_refill = true; } return total_read; } + void FillBuffer () + { + int frame_number = (int)(m_position / m_bytes_per_frame); + m_reader.SetPosition (m_data_offset + frame_number * m_reader.FrameSize * Format.Channels); + for (int i = 0; i < Format.Channels; ++i) + { + m_reader.DecodeFrame (i, m_frame_buffer.Value); + } + m_buffered_sample = frame_number * m_reader.SamplesPerFrame; + m_buffered_count = Math.Min (m_reader.SampleCount - m_buffered_sample, m_reader.SamplesPerFrame); + } + // FIXME // such implementation of seek is broken since it doesn't take into account ADPCM decoder 'history', // therefore CanSeek returns false.