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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IStreamWrapper.cs" />
|
||||
<Compile Include="WMAReader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.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;
|
||||
|
||||
string _path;
|
||||
//Stream _IO;
|
||||
string m_path;
|
||||
Stream m_IO;
|
||||
StreamWrapper m_streamWrapper;
|
||||
|
||||
public WMAReader(string path, Stream IO)
|
||||
{
|
||||
m_path = path;
|
||||
isValid(path);
|
||||
bool pfIsProtected;
|
||||
WMUtils.WMIsContentProtected(path, out pfIsProtected);
|
||||
@@ -52,8 +54,16 @@ namespace CUETools.Codecs.WMA
|
||||
throw new Exception("DRM present");
|
||||
WMUtils.WMCreateSyncReader(IntPtr.Zero, Rights.None, out m_syncReader);
|
||||
|
||||
//m_syncReader.OpenStream()
|
||||
m_syncReader.Open(path);
|
||||
if (path == null)
|
||||
{
|
||||
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);
|
||||
int 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);
|
||||
_path = path;
|
||||
|
||||
//int cbMax;
|
||||
//m_syncReader.GetMaxOutputSampleSize(m_dwAudioOutputNum, out cbMax);
|
||||
@@ -214,7 +223,10 @@ namespace CUETools.Codecs.WMA
|
||||
|
||||
public void Close()
|
||||
{
|
||||
//_IO.Close();
|
||||
//if (m_streamWrapper != null)
|
||||
// m_streamWrapper.Close();
|
||||
if (m_IO != null)
|
||||
m_IO.Close();
|
||||
if (m_pSample != null)
|
||||
Marshal.ReleaseComObject(m_pSample);
|
||||
if (m_syncReader != null)
|
||||
@@ -222,6 +234,7 @@ namespace CUETools.Codecs.WMA
|
||||
m_syncReader.Close();
|
||||
Marshal.ReleaseComObject(m_syncReader);
|
||||
}
|
||||
m_IO = null;
|
||||
m_pSample = null;
|
||||
m_syncReader = null;
|
||||
}
|
||||
@@ -252,48 +265,13 @@ namespace CUETools.Codecs.WMA
|
||||
{
|
||||
if (m_sampleCount < 0 || value > m_sampleCount)
|
||||
throw new Exception("seeking past end of stream");
|
||||
throw new NotSupportedException();
|
||||
//if (value < Position || value > _sampleOffset)
|
||||
//{
|
||||
// if (seek_table != null && _IO.CanSeek)
|
||||
// {
|
||||
// int best_st = -1;
|
||||
// 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;
|
||||
if (value < Position)
|
||||
throw new NotSupportedException();
|
||||
if (value < Position)
|
||||
throw new Exception("cannot seek backwards");
|
||||
var buff = new AudioBuffer(this, 0x10000);
|
||||
while (value > Position && Read(buff, (int)Math.Min(Int32.MaxValue, value - Position)) != 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +287,7 @@ namespace CUETools.Codecs.WMA
|
||||
{
|
||||
get
|
||||
{
|
||||
return _path;
|
||||
return m_path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user