308 lines
6.6 KiB
C++
308 lines
6.6 KiB
C++
/*
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
AVIFileWriter.cpp
|
|
|
|
Abstract:
|
|
|
|
Implementation of CAVIFileWriter class
|
|
|
|
*/
|
|
|
|
|
|
#include "common.h"
|
|
#include "AVIFileWriter.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAVIFileWriter::CAVIFileWriter
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
CAVIFileWriter::CAVIFileWriter()
|
|
:m_pAVIFile(NULL),
|
|
m_pAudioStream(NULL),
|
|
m_nSampleSize(0)
|
|
{
|
|
|
|
LogMessage("CAVIFileWriter::CAVIFileWriter");
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAVIFileWriter::Initialize
|
|
//
|
|
// initialize avi library. attempt to create a file with the given name and
|
|
// format.
|
|
//
|
|
// if file creation fails, subsequent calls to write will fail.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CAVIFileWriter::Initialize(IN const CHAR *pszFileName,
|
|
IN const WAVEFORMATEX &WaveFormat)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
//
|
|
// if initialization fails, the object's stream and file will be NULL, so
|
|
// subsequent Write() calls will fail
|
|
//
|
|
|
|
|
|
//
|
|
// would do a better argument checking in a real-life application
|
|
//
|
|
|
|
_ASSERTE(pszFileName);
|
|
|
|
|
|
//
|
|
// log file name and requested wave format
|
|
//
|
|
|
|
|
|
LogMessage("CAVIFileWriter::Initialize started.");
|
|
|
|
LogMessage(" file [%s] ", pszFileName);
|
|
|
|
LogFormat(&WaveFormat);
|
|
|
|
|
|
//
|
|
// initialize avi file library.
|
|
// when done with it, call AVIFileExit should be called on the same thread
|
|
//
|
|
|
|
AVIFileInit();
|
|
|
|
|
|
//
|
|
// create file
|
|
//
|
|
|
|
hr = AVIFileOpen(&m_pAVIFile,
|
|
pszFileName,
|
|
OF_WRITE | OF_CREATE | OF_SHARE_DENY_WRITE,
|
|
NULL);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
LogError("CAVIFileWriter::Initialize Failed to create file %s",
|
|
pszFileName);
|
|
|
|
m_pAVIFile = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// fill in stream information
|
|
//
|
|
|
|
AVISTREAMINFO StreamInfo;
|
|
|
|
memset(&StreamInfo, 0, sizeof(StreamInfo));
|
|
|
|
StreamInfo.fccType = streamtypeAUDIO;
|
|
StreamInfo.dwQuality = -1;
|
|
m_nSampleSize = StreamInfo.dwSampleSize = WaveFormat.nBlockAlign;
|
|
strcpy(&StreamInfo.szName[0], "test audio stream");
|
|
|
|
|
|
//
|
|
// add an audio stream to the file
|
|
//
|
|
|
|
hr = AVIFileCreateStream(m_pAVIFile, &m_pAudioStream, &StreamInfo);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
LogError("CAVIFileWriter::CAVIFileWriter "
|
|
"failed to create audio stream");
|
|
|
|
AVIFileRelease(m_pAVIFile);
|
|
m_pAVIFile = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// set format for the stream
|
|
//
|
|
|
|
hr = AVIStreamSetFormat(m_pAudioStream,
|
|
0,
|
|
(void*)&WaveFormat,
|
|
sizeof(WaveFormat) + WaveFormat.cbSize);
|
|
|
|
if ( FAILED(hr))
|
|
{
|
|
LogError("Failed to set stream format");
|
|
|
|
AVIFileRelease(m_pAVIFile);
|
|
m_pAVIFile = NULL;
|
|
|
|
AVIStreamRelease(m_pAudioStream);
|
|
m_pAudioStream = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
LogMessage("CAVIFileWriter::Initialize succeeded");
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAVIFileWriter::~CAVIFileWriter
|
|
//
|
|
// if the file and stream were open, close them.
|
|
//
|
|
// uninitialize AVI library
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
CAVIFileWriter::~CAVIFileWriter()
|
|
{
|
|
|
|
LogMessage("CAVIFileWriter::~CAVIFileWriter started");
|
|
|
|
|
|
if (NULL != m_pAudioStream)
|
|
{
|
|
AVIStreamRelease(m_pAudioStream);
|
|
m_pAudioStream = NULL;
|
|
}
|
|
|
|
|
|
if (NULL != m_pAVIFile)
|
|
{
|
|
AVIFileRelease(m_pAVIFile);
|
|
m_pAVIFile = NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// uninitialize avi file libraries
|
|
//
|
|
|
|
AVIFileExit();
|
|
|
|
LogMessage("CAVIFileWriter::~CAVIFileWriter finished");
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAVIFileWriter::Write
|
|
//
|
|
// write the buffer into the open stream. return the number of bytes recorded.
|
|
//
|
|
// return S_OK on success, error code on failure
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CAVIFileWriter::Write(IN BYTE *pBuffer,
|
|
IN ULONG nBytesToWrite,
|
|
IN OUT ULONG *pnBytesWritten)
|
|
{
|
|
|
|
if ( (NULL == m_pAudioStream) || (NULL == m_pAVIFile))
|
|
{
|
|
LogError("CAVIFileWriter::Write file or stream is not open");
|
|
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
|
|
//
|
|
// AVIStreamWrite wants the number of samples we are recording
|
|
//
|
|
|
|
LONG nSamples2Write = nBytesToWrite / m_nSampleSize;
|
|
|
|
|
|
//
|
|
// write to file until dumped the whole buffer of until failure
|
|
//
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ULONG nTotalBytesWritten = 0;
|
|
|
|
|
|
while ((hr == S_OK) && (nTotalBytesWritten < nBytesToWrite))
|
|
{
|
|
|
|
//
|
|
// bytes and samples written with the call
|
|
//
|
|
|
|
LONG nBytesWritten = 0;
|
|
|
|
LONG nSamplesWritten = 0;
|
|
|
|
hr = AVIStreamWrite(m_pAudioStream,
|
|
-1, // append at the end of the stream
|
|
nSamples2Write, // how many samples to write
|
|
pBuffer, // where the data is
|
|
nBytesToWrite, // how much data do we have
|
|
AVIIF_KEYFRAME, // self-sufficient data
|
|
&nSamplesWritten,// how many samples were written
|
|
&nBytesWritten); // how many bytes were written
|
|
|
|
|
|
//
|
|
// keep track of how many bytes made it into the file
|
|
//
|
|
|
|
nTotalBytesWritten += nBytesWritten;
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// will return the number of bytes written
|
|
//
|
|
|
|
if (NULL != pnBytesWritten)
|
|
{
|
|
*pnBytesWritten = nTotalBytesWritten;
|
|
}
|
|
|
|
|
|
//
|
|
// either dumped the whole buffer or failed.
|
|
//
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
|
|
LogError("CAVIFileWriter::Write Failed to write buffer hr = 0x%lx, "
|
|
"wrote %ld bytes", hr, nTotalBytesWritten);
|
|
}
|
|
else
|
|
{
|
|
|
|
LogMessage("CAVIFileWriter::Write Succeeded. Wrote %ld bytes",
|
|
nTotalBytesWritten);
|
|
}
|
|
|
|
return hr;
|
|
|
|
} |