www.pudn.com > WMACompressor.zip > yeti.WmaWriter.h
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER
// REMAINS UNCHANGED.
//
// Email: yetiicb@hotmail.com
//
// Copyright (C) 2002-2004 Idael Cardoso.
//
#pragma once
#include "WmaWriterConfig.h"
#include "WriterSink.h"
#include "WmaWriter.h"
using namespace System;
using namespace System::IO;
using namespace System::Runtime::InteropServices;
using namespace WaveLib;
using namespace Yeti::MMedia;
namespace Yeti
{
namespace MMedia
{
namespace Wmf
{
public __gc class WmaWriter : public AudioWriter, public IWriterSink
{
protected:
CWmaWriter* m_Writer;
bool m_HeaderWrote;
int m_HeaderSize;
__int64 m_HeaderPos;
void Init(WmaWriterProfile* Profile)
{
m_Writer = NULL;
m_HeaderWrote = false;
CProfile* pPrf = Profile->pProfile;
if (pPrf != NULL)
{
try
{
CComPtr Sink;
CWriterSink::Create( dynamic_cast(this), &Sink);
try
{
GCHandle h = GCHandle::Alloc(m_InputDataFormat, GCHandleType::Pinned);
try
{
WAVEFORMATEX* pf = (WAVEFORMATEX*)h.AddrOfPinnedObject().ToPointer();
m_Writer = new CWmaWriter(pf, pPrf->m_Profile, Sink);
}
__finally
{
h.Free();
}
}
__finally
{
Sink = NULL;
}
}
__finally
{
delete pPrf;
}
}
else
{
throw new ArgumentException("Invalid profile", "Profile");
}
}
public:
WmaWriter(System::IO::Stream* Output, WaveLib::WaveFormat __gc* Format, WmaWriterProfile __gc* Profile)
:AudioWriter(Output, Format)
{
Init(Profile);
}
WmaWriter(System::IO::Stream* Output, WmaWriterConfig* Config)
:AudioWriter(Output, Config)
{
Init(Config->Profile);
}
WmaWriter(System::IO::Stream* Output, WaveLib::WaveFormat* Format)
:AudioWriter(Output, Format)
{
Init(WmaWriterProfileManager::AudioSystemProfiles[0]);
}
public: //IWriterSink
HRESULT OnHeader(/* [in] */INSSBuffer *pHeader)
{
try
{
DWORD Length = 0;
Byte buffer[] = NULL;
CComPtr pManRef;
if ( SUCCEEDED(pHeader->QueryInterface(__uuidof(IManBufferRef), (void**)&pManRef)) )
{
void* IntfHandle = NULL;
pManRef->GetManBuffer(&IntfHandle);
GCHandle h = GCHandle::op_Explicit(IntPtr(IntfHandle));
IManBuffer* ManBuff = static_cast(h.Target);
Length = ManBuff->UsedLength;
buffer = ManBuff->Buffer;
}
else
{
BYTE* pBuffer = NULL;
if ( SUCCEEDED(pHeader->GetBufferAndLength(&pBuffer, &Length)) )
{
buffer = new Byte[Length];
Marshal::Copy(IntPtr(pBuffer), buffer, 0, Length);
}
}
if ( !m_HeaderWrote )
{
if (BaseStream->CanSeek)
{
m_HeaderPos = BaseStream->Position;
}
__super::Write(buffer, 0, Length);
m_HeaderSize = Length;
m_HeaderWrote = true;
}
else
if ( (m_HeaderSize == Length) && (BaseStream->CanSeek) )
{
__int64 pos = BaseStream->Position;
BaseStream->Position = m_HeaderPos;
__super::Write(buffer, 0, Length);
BaseStream->Position = pos;
}
}
catch(...)
{
}
return S_OK;
}
HRESULT AllocateDataUnit(/* [in] */DWORD cbDataUnit,/* [out] */ INSSBuffer **ppDataUnit)
{
IManBuffer* ManBuff = new ManBuffer(cbDataUnit);
CBuffer::Create(ManBuff, ppDataUnit);
return S_OK;
}
HRESULT IsRealTime(/* [out] */ BOOL *pfRealTime)
{
*pfRealTime = false;
return S_OK;
}
HRESULT OnDataUnit(/* [in] */INSSBuffer *pDataUnit)
{
try
{
CComPtr pManRef;
if ( SUCCEEDED(pDataUnit->QueryInterface(__uuidof(IManBufferRef), (void**)&pManRef)) )
{
void* IntfHandle = NULL;
pManRef->GetManBuffer(&IntfHandle);
GCHandle h = GCHandle::op_Explicit(IntPtr(IntfHandle));
IManBuffer* ManBuffer = static_cast(h.Target);
__super::Write(ManBuffer->Buffer, 0, ManBuffer->UsedLength);
}
else
{
DWORD size = 0;
BYTE* pBuffer = NULL;
if ( SUCCEEDED(pDataUnit->GetBufferAndLength(&pBuffer, &size)) )
{
Byte Buffer[] = new Byte[size];
Marshal::Copy(IntPtr(pBuffer), Buffer, 0, size);
__super::Write(Buffer, 0, size);
}
}
}
catch(...)
{
}
return S_OK;
}
HRESULT OnEndWriting( void)
{
return S_OK;
}
protected:
virtual int GetOptimalBufferSize()
{
return m_InputDataFormat->nAvgBytesPerSec /10;
}
virtual String* GetDefaultAudioFileExtension()
{
return S"wma";
}
public: //overrides
virtual void Close()
{
if (m_Writer != NULL)
{
delete m_Writer;
m_Writer = NULL;
}
__super::Close();
}
virtual void Write(Byte Buffer[], int index, int count)
{
if ( (count % m_InputDataFormat->nBlockAlign) == 0 )
{
if ( (index+count) > Buffer->Length )
{
throw new IndexOutOfRangeException();
}
Byte __pin* pBuffer = &Buffer[index];
m_Writer->Write(pBuffer, count);
}
else
{
throw new ArgumentException(String::Format(S"Invalid buffer size. Buffer size must be aligned to {0} bytes.", __box(m_InputDataFormat->nBlockAlign)), String::Format(S"count={0}", __box(count)));
}
}
virtual void Write(Byte Buffer[])
{
Write(Buffer, 0, Buffer->Length);
}
};
}
}
}