mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
WMA decoder: support streams as input
This commit is contained in:
@@ -59,6 +59,7 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="IStreamWrapper.cs" />
|
||||||
<Compile Include="WMAReader.cs" />
|
<Compile Include="WMAReader.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
|||||||
82
CUETools.Codecs.WMA/IStreamWrapper.cs
Normal file
82
CUETools.Codecs.WMA/IStreamWrapper.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace CUETools.Codecs.WMA
|
||||||
|
{
|
||||||
|
public class StreamWrapper : IStream
|
||||||
|
{
|
||||||
|
public StreamWrapper(Stream stream)
|
||||||
|
{
|
||||||
|
if (stream == null)
|
||||||
|
throw new ArgumentNullException("stream", "Can't wrap null stream.");
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream stream;
|
||||||
|
|
||||||
|
public void Read(byte[] pv, int cb, System.IntPtr pcbRead)
|
||||||
|
{
|
||||||
|
Marshal.WriteInt32(pcbRead, (Int32)stream.Read(pv, 0, cb));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Seek(long dlibMove, int dwOrigin, System.IntPtr plibNewPosition)
|
||||||
|
{
|
||||||
|
var res = stream.Seek(dlibMove, (SeekOrigin)dwOrigin);
|
||||||
|
if (plibNewPosition != IntPtr.Zero) Marshal.WriteInt32(plibNewPosition, (int)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag)
|
||||||
|
{
|
||||||
|
if (grfStatFlag != 1) // STATFLAG_NONAME
|
||||||
|
throw new NotSupportedException();
|
||||||
|
var statstg = new System.Runtime.InteropServices.ComTypes.STATSTG();
|
||||||
|
statstg.type = 2; // STGTY.STREAM
|
||||||
|
statstg.cbSize = stream.Length;
|
||||||
|
pstatstg = statstg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clone(out IStream ppstm)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Commit(int grfCommitFlags)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LockRegion(long libOffset, long cb, int dwLockType)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Revert()
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSize(long libNewSize)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnlockRegion(long libOffset, long cb, int dwLockType)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(byte[] pv, int cb, IntPtr pcbWritten)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,11 +40,13 @@ namespace CUETools.Codecs.WMA
|
|||||||
|
|
||||||
long m_sampleCount = -1, m_sampleOffset = 0;
|
long m_sampleCount = -1, m_sampleOffset = 0;
|
||||||
|
|
||||||
string _path;
|
string m_path;
|
||||||
//Stream _IO;
|
Stream m_IO;
|
||||||
|
StreamWrapper m_streamWrapper;
|
||||||
|
|
||||||
public WMAReader(string path, Stream IO)
|
public WMAReader(string path, Stream IO)
|
||||||
{
|
{
|
||||||
|
m_path = path;
|
||||||
isValid(path);
|
isValid(path);
|
||||||
bool pfIsProtected;
|
bool pfIsProtected;
|
||||||
WMUtils.WMIsContentProtected(path, out pfIsProtected);
|
WMUtils.WMIsContentProtected(path, out pfIsProtected);
|
||||||
@@ -52,8 +54,16 @@ namespace CUETools.Codecs.WMA
|
|||||||
throw new Exception("DRM present");
|
throw new Exception("DRM present");
|
||||||
WMUtils.WMCreateSyncReader(IntPtr.Zero, Rights.None, out m_syncReader);
|
WMUtils.WMCreateSyncReader(IntPtr.Zero, Rights.None, out m_syncReader);
|
||||||
|
|
||||||
//m_syncReader.OpenStream()
|
if (path == null)
|
||||||
m_syncReader.Open(path);
|
{
|
||||||
|
m_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
|
||||||
|
m_streamWrapper = new StreamWrapper(m_IO);
|
||||||
|
m_syncReader.OpenStream(m_streamWrapper);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_syncReader.Open(path);
|
||||||
|
}
|
||||||
var pProfile = (m_syncReader as IWMProfile);
|
var pProfile = (m_syncReader as IWMProfile);
|
||||||
int dwStreamCount;
|
int dwStreamCount;
|
||||||
pProfile.GetStreamCount(out dwStreamCount);
|
pProfile.GetStreamCount(out dwStreamCount);
|
||||||
@@ -193,7 +203,6 @@ 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;
|
|
||||||
|
|
||||||
//int cbMax;
|
//int cbMax;
|
||||||
//m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax);
|
//m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax);
|
||||||
@@ -214,7 +223,10 @@ namespace CUETools.Codecs.WMA
|
|||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
//_IO.Close();
|
//if (m_streamWrapper != null)
|
||||||
|
// m_streamWrapper.Close();
|
||||||
|
if (m_IO != null)
|
||||||
|
m_IO.Close();
|
||||||
if (m_pSample != null)
|
if (m_pSample != null)
|
||||||
Marshal.ReleaseComObject(m_pSample);
|
Marshal.ReleaseComObject(m_pSample);
|
||||||
if (m_syncReader != null)
|
if (m_syncReader != null)
|
||||||
@@ -222,6 +234,7 @@ namespace CUETools.Codecs.WMA
|
|||||||
m_syncReader.Close();
|
m_syncReader.Close();
|
||||||
Marshal.ReleaseComObject(m_syncReader);
|
Marshal.ReleaseComObject(m_syncReader);
|
||||||
}
|
}
|
||||||
|
m_IO = null;
|
||||||
m_pSample = null;
|
m_pSample = null;
|
||||||
m_syncReader = null;
|
m_syncReader = null;
|
||||||
}
|
}
|
||||||
@@ -252,48 +265,13 @@ namespace CUETools.Codecs.WMA
|
|||||||
{
|
{
|
||||||
if (m_sampleCount < 0 || value > m_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();
|
if (value < Position)
|
||||||
//if (value < Position || value > _sampleOffset)
|
throw new NotSupportedException();
|
||||||
//{
|
if (value < Position)
|
||||||
// if (seek_table != null && _IO.CanSeek)
|
throw new Exception("cannot seek backwards");
|
||||||
// {
|
var buff = new AudioBuffer(this, 0x10000);
|
||||||
// int best_st = -1;
|
while (value > Position && Read(buff, (int)Math.Min(Int32.MaxValue, value - Position)) != 0)
|
||||||
// for (int st = 0; st < seek_table.Length; st++)
|
;
|
||||||
// {
|
|
||||||
// if (seek_table[st].number <= value &&
|
|
||||||
// (best_st == -1 || seek_table[st].number > seek_table[best_st].number))
|
|
||||||
// best_st = st;
|
|
||||||
// }
|
|
||||||
// if (best_st != -1)
|
|
||||||
// {
|
|
||||||
// _framesBufferLength = 0;
|
|
||||||
// _samplesInBuffer = 0;
|
|
||||||
// _samplesBufferOffset = 0;
|
|
||||||
// _IO.Position = (long)seek_table[best_st].offset + first_frame_offset;
|
|
||||||
// _sampleOffset = seek_table[best_st].number;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (value < Position)
|
|
||||||
// throw new Exception("cannot seek backwards without seek table");
|
|
||||||
//}
|
|
||||||
//while (value > _sampleOffset)
|
|
||||||
//{
|
|
||||||
// _samplesInBuffer = 0;
|
|
||||||
// _samplesBufferOffset = 0;
|
|
||||||
|
|
||||||
// fill_frames_buffer();
|
|
||||||
// if (_framesBufferLength == 0)
|
|
||||||
// throw new Exception("seek failed");
|
|
||||||
|
|
||||||
// int bytesDecoded = DecodeFrame(_framesBuffer, _framesBufferOffset, _framesBufferLength);
|
|
||||||
// _framesBufferLength -= bytesDecoded;
|
|
||||||
// _framesBufferOffset += bytesDecoded;
|
|
||||||
|
|
||||||
// _sampleOffset += _samplesInBuffer;
|
|
||||||
//};
|
|
||||||
//int diff = _samplesInBuffer - (int)(_sampleOffset - value);
|
|
||||||
//_samplesInBuffer -= diff;
|
|
||||||
//_samplesBufferOffset += diff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +287,7 @@ namespace CUETools.Codecs.WMA
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _path;
|
return m_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user