mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-04 10:55:36 +08:00
refined AdxInput.Read.
This commit is contained in:
parent
eb12144780
commit
236d33f4e7
@ -64,7 +64,7 @@ namespace GameRes.Formats.Cri
|
|||||||
long m_position;
|
long m_position;
|
||||||
int m_buffered_sample;
|
int m_buffered_sample;
|
||||||
int m_buffered_count;
|
int m_buffered_count;
|
||||||
int m_bytes_per_sample;
|
int m_bytes_per_frame;
|
||||||
ThreadLocal<short[]> m_frame_buffer;
|
ThreadLocal<short[]> m_frame_buffer;
|
||||||
|
|
||||||
public override string SourceFormat { get { return "adx"; } }
|
public override string SourceFormat { get { return "adx"; } }
|
||||||
@ -77,45 +77,45 @@ namespace GameRes.Formats.Cri
|
|||||||
this.Format = m_reader.Format;
|
this.Format = m_reader.Format;
|
||||||
this.PcmSize = m_reader.SampleCount * Format.BlockAlign;
|
this.PcmSize = m_reader.SampleCount * Format.BlockAlign;
|
||||||
m_bitrate = (int)(Format.SamplesPerSecond * (file.Length-m_data_offset) * 8 / m_reader.SampleCount);
|
m_bitrate = (int)(Format.SamplesPerSecond * (file.Length-m_data_offset) * 8 / m_reader.SampleCount);
|
||||||
m_frame_buffer = new ThreadLocal<short[]> (() => new short[m_reader.SamplesPerFrame * m_reader.Format.Channels]);
|
int frame_buffer_length = m_reader.SamplesPerFrame * m_reader.Format.Channels;
|
||||||
m_bytes_per_sample = Format.BitsPerSample / 8;
|
m_frame_buffer = new ThreadLocal<short[]> (() => 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)
|
public override int Read (byte[] buffer, int offset, int count)
|
||||||
{
|
{
|
||||||
int total_read = 0;
|
int total_read = 0;
|
||||||
int current_sample = (int)(m_position / Format.BlockAlign);
|
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);
|
int available = Math.Min (count, m_buffered_count * Format.BlockAlign - src_offset);
|
||||||
Buffer.BlockCopy (m_frame_buffer.Value, src_offset, buffer, offset, available);
|
Buffer.BlockCopy (m_frame_buffer.Value, src_offset, buffer, offset, available);
|
||||||
offset += available;
|
offset += available;
|
||||||
count -= available;
|
count -= available;
|
||||||
total_read += available;
|
total_read += available;
|
||||||
m_position += available;
|
m_position += available;
|
||||||
}
|
src_offset = 0;
|
||||||
int bytes_per_frame = m_reader.SamplesPerFrame * m_bytes_per_sample * Format.Channels;
|
need_refill = true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return total_read;
|
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
|
// FIXME
|
||||||
// such implementation of seek is broken since it doesn't take into account ADPCM decoder 'history',
|
// such implementation of seek is broken since it doesn't take into account ADPCM decoder 'history',
|
||||||
// therefore CanSeek returns false.
|
// therefore CanSeek returns false.
|
||||||
|
Loading…
Reference in New Issue
Block a user