mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Optimized WMA decoder
This commit is contained in:
@@ -31,14 +31,14 @@ namespace CUETools.Codecs.WMA
|
|||||||
public class WMAReader : IAudioSource
|
public class WMAReader : IAudioSource
|
||||||
{
|
{
|
||||||
IWMSyncReader m_syncReader;
|
IWMSyncReader m_syncReader;
|
||||||
|
INSSBuffer m_pSample;
|
||||||
|
int m_pSampleOffset = 0, m_pSampleSize = 0;
|
||||||
short m_wStreamNum = -1;
|
short m_wStreamNum = -1;
|
||||||
int m_dwAudioOutputNum = -1;
|
int m_dwAudioOutputNum = -1;
|
||||||
|
|
||||||
AudioPCMConfig pcm;
|
AudioPCMConfig pcm;
|
||||||
|
|
||||||
byte[] samplesBuffer;
|
long m_sampleCount = -1, m_sampleOffset = 0;
|
||||||
int _samplesInBuffer, _samplesBufferOffset;
|
|
||||||
long _sampleCount = -1, _sampleOffset = 0;
|
|
||||||
|
|
||||||
string _path;
|
string _path;
|
||||||
//Stream _IO;
|
//Stream _IO;
|
||||||
@@ -195,13 +195,8 @@ namespace CUETools.Codecs.WMA
|
|||||||
pcm = new AudioPCMConfig(m_pWfx.wBitsPerSample, m_pWfx.nChannels, m_pWfx.nSamplesPerSec);
|
pcm = new AudioPCMConfig(m_pWfx.wBitsPerSample, m_pWfx.nChannels, m_pWfx.nSamplesPerSec);
|
||||||
_path = path;
|
_path = path;
|
||||||
|
|
||||||
int cbMax;
|
//int cbMax;
|
||||||
m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax);
|
//m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax);
|
||||||
//m_syncReader.GetMaxStreamSampleSize(m_wStreamNum, out cbMax);
|
|
||||||
//var ra = m_syncReader as IWMReaderAdvanced;
|
|
||||||
//ra.SetAllocateForOutput(m_dwAudioOutputNum, true);
|
|
||||||
|
|
||||||
samplesBuffer = new byte[cbMax];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void isValid(string filename)
|
public void isValid(string filename)
|
||||||
@@ -220,15 +215,22 @@ namespace CUETools.Codecs.WMA
|
|||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
//_IO.Close();
|
//_IO.Close();
|
||||||
|
if (m_pSample != null)
|
||||||
|
Marshal.ReleaseComObject(m_pSample);
|
||||||
|
if (m_syncReader != null)
|
||||||
|
{
|
||||||
m_syncReader.Close();
|
m_syncReader.Close();
|
||||||
Marshal.ReleaseComObject(m_syncReader);
|
Marshal.ReleaseComObject(m_syncReader);
|
||||||
}
|
}
|
||||||
|
m_pSample = null;
|
||||||
|
m_syncReader = null;
|
||||||
|
}
|
||||||
|
|
||||||
public long Length
|
public long Length
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _sampleCount;
|
return m_sampleCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,11 +246,11 @@ namespace CUETools.Codecs.WMA
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _sampleOffset - _samplesInBuffer;
|
return m_sampleOffset / PCM.BlockAlign;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_sampleCount < 0 || value > _sampleCount)
|
if (m_sampleCount < 0 || value > m_sampleCount)
|
||||||
throw new Exception("seeking past end of stream");
|
throw new Exception("seeking past end of stream");
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
//if (value < Position || value > _sampleOffset)
|
//if (value < Position || value > _sampleOffset)
|
||||||
@@ -311,67 +313,72 @@ namespace CUETools.Codecs.WMA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int BS = 4;
|
|
||||||
|
|
||||||
public int Read(AudioBuffer buff, int maxLength)
|
public int Read(AudioBuffer buff, int maxLength)
|
||||||
{
|
{
|
||||||
buff.Prepare(this, maxLength);
|
buff.Prepare(this, maxLength);
|
||||||
|
|
||||||
int offset = 0;
|
int buff_offset = 0;
|
||||||
int sampleCount = buff.Length;
|
int buff_size = buff.ByteLength;
|
||||||
|
|
||||||
while (_samplesInBuffer < sampleCount)
|
while (m_pSampleSize < buff_size)
|
||||||
{
|
{
|
||||||
if (_samplesInBuffer > 0)
|
if (m_pSampleSize > 0)
|
||||||
{
|
{
|
||||||
Array.Copy(samplesBuffer, _samplesBufferOffset * BS, buff.Bytes, offset * BS, _samplesInBuffer * BS);
|
IntPtr pdwBuffer;
|
||||||
sampleCount -= _samplesInBuffer;
|
m_pSample.GetBuffer(out pdwBuffer);
|
||||||
offset += _samplesInBuffer;
|
Marshal.Copy((IntPtr)(pdwBuffer.ToInt64() + m_pSampleOffset), buff.Bytes, buff_offset, m_pSampleSize);
|
||||||
_samplesInBuffer = 0;
|
buff_size -= m_pSampleSize;
|
||||||
_samplesBufferOffset = 0;
|
buff_offset += m_pSampleSize;
|
||||||
|
m_sampleOffset += m_pSampleSize;
|
||||||
|
m_pSampleSize = 0;
|
||||||
|
Marshal.ReleaseComObject(m_pSample);
|
||||||
|
m_pSample = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
INSSBuffer pSample;
|
|
||||||
long cnsSampleTime;
|
long cnsSampleTime;
|
||||||
long cnsDuration;
|
long cnsDuration;
|
||||||
SampleFlag flags;
|
SampleFlag flags;
|
||||||
int dwOutputNum;
|
int dwOutputNum;
|
||||||
short wStreamNum;
|
short wStreamNum;
|
||||||
int dwLength;
|
|
||||||
IntPtr pdwBuffer;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_syncReader.GetNextSample(m_wStreamNum, out pSample, out cnsSampleTime, out cnsDuration, out flags, out dwOutputNum, out wStreamNum);
|
m_syncReader.GetNextSample(m_wStreamNum, out m_pSample, out cnsSampleTime, out cnsDuration, out flags, out dwOutputNum, out wStreamNum);
|
||||||
}
|
}
|
||||||
catch (COMException ex)
|
catch (COMException ex)
|
||||||
{
|
{
|
||||||
// EOF
|
// EOF
|
||||||
if (ex.ErrorCode == NSResults.E_NO_MORE_SAMPLES)
|
if (ex.ErrorCode == NSResults.E_NO_MORE_SAMPLES)
|
||||||
{
|
{
|
||||||
_sampleCount = _sampleOffset;
|
if ((m_sampleOffset % PCM.BlockAlign) != 0)
|
||||||
return offset;
|
throw new Exception("(m_sampleOffset % PCM.BlockAlign) != 0");
|
||||||
|
m_sampleCount = m_sampleOffset / PCM.BlockAlign;
|
||||||
|
if ((buff_offset % PCM.BlockAlign) != 0)
|
||||||
|
throw new Exception("(buff_offset % PCM.BlockAlign) != 0");
|
||||||
|
return buff_offset / PCM.BlockAlign;
|
||||||
}
|
}
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
//if (dwOutputNum != m_dwAudioOutputNum || wStreamNum != m_wStreamNum)
|
//if (dwOutputNum != m_dwAudioOutputNum || wStreamNum != m_wStreamNum)
|
||||||
//{
|
//{
|
||||||
//}
|
//}
|
||||||
pSample.GetBufferAndLength(out pdwBuffer, out dwLength);
|
m_pSampleOffset = 0;
|
||||||
Marshal.Copy(pdwBuffer, samplesBuffer, 0, dwLength);
|
m_pSample.GetLength(out m_pSampleSize);
|
||||||
Marshal.ReleaseComObject(pSample);
|
|
||||||
_samplesInBuffer = dwLength / BS;
|
|
||||||
_sampleOffset += _samplesInBuffer;
|
|
||||||
|
|
||||||
//_samplesInBuffer -= _samplesBufferOffset; // can be set by Seek, otherwise zero
|
|
||||||
//_sampleOffset += _samplesInBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.Copy(samplesBuffer, _samplesBufferOffset * BS, buff.Bytes, offset * BS, sampleCount * BS);
|
if (buff_size > 0)
|
||||||
_samplesInBuffer -= sampleCount;
|
{
|
||||||
_samplesBufferOffset += sampleCount;
|
IntPtr pdwBuffer;
|
||||||
if (_samplesInBuffer == 0)
|
m_pSample.GetBuffer(out pdwBuffer);
|
||||||
_samplesBufferOffset = 0;
|
Marshal.Copy((IntPtr)(pdwBuffer.ToInt64() + m_pSampleOffset), buff.Bytes, buff_offset, buff_size);
|
||||||
return offset + sampleCount;
|
m_pSampleOffset += buff_size;
|
||||||
|
m_pSampleSize -= buff_size;
|
||||||
|
m_sampleOffset += buff_size;
|
||||||
|
buff_offset += buff_size;
|
||||||
|
buff_size = 0;
|
||||||
|
}
|
||||||
|
if ((buff_offset % PCM.BlockAlign) != 0)
|
||||||
|
throw new Exception("(buff_offset % PCM.BlockAlign) != 0");
|
||||||
|
return buff_offset / PCM.BlockAlign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user