/* 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; }