📄 wavfile.c
字号:
}
static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile *iface)
{
TRACE("(%p)\n",iface);
/* This is only needed for interleaved files.
* We have only one stream, which can't be interleaved.
*/
return AVIERR_OK;
}
static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType,
LONG lParam)
{
IAVIFileImpl *This = (IAVIFileImpl *)iface;
TRACE("(%p,0x%08X,%d)\n", iface, fccType, lParam);
/* check parameter */
if (lParam < 0)
return AVIERR_BADPARAM;
/* Do we have our audio stream? */
if (lParam != 0 || This->fInfo.dwStreams == 0 ||
(fccType != 0 && fccType != streamtypeAUDIO))
return AVIERR_NODATA;
/* Have user write permissions? */
if ((This->uMode & MMIO_RWMODE) == 0)
return AVIERR_READONLY;
HeapFree(GetProcessHeap(), 0, This->lpFormat);
This->lpFormat = NULL;
This->cbFormat = 0;
/* update infos */
This->ckData.dwDataOffset = 0;
This->ckData.cksize = 0;
This->sInfo.dwScale = 0;
This->sInfo.dwRate = 0;
This->sInfo.dwLength = 0;
This->sInfo.dwSuggestedBufferSize = 0;
This->fInfo.dwStreams = 0;
This->fInfo.dwEditCount++;
This->fDirty = TRUE;
return AVIERR_OK;
}
/***********************************************************************/
static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile *iface,
REFIID refiid, LPVOID *obj)
{
IPersistFileImpl *This = (IPersistFileImpl *)iface;
assert(This->paf != NULL);
return IAVIFile_QueryInterface((PAVIFILE)This->paf, refiid, obj);
}
static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile *iface)
{
IPersistFileImpl *This = (IPersistFileImpl *)iface;
assert(This->paf != NULL);
return IAVIFile_AddRef((PAVIFILE)This->paf);
}
static ULONG WINAPI IPersistFile_fnRelease(IPersistFile *iface)
{
IPersistFileImpl *This = (IPersistFileImpl *)iface;
assert(This->paf != NULL);
return IAVIFile_Release((PAVIFILE)This->paf);
}
static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile *iface,
LPCLSID pClassID)
{
TRACE("(%p,%p)\n", iface, pClassID);
if (pClassID == NULL)
return AVIERR_BADPARAM;
memcpy(pClassID, &CLSID_WAVFile, sizeof(CLSID_WAVFile));
return AVIERR_OK;
}
static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile *iface)
{
IPersistFileImpl *This = (IPersistFileImpl *)iface;
TRACE("(%p)\n", iface);
assert(This->paf != NULL);
return (This->paf->fDirty ? S_OK : S_FALSE);
}
static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface,
LPCOLESTR pszFileName, DWORD dwMode)
{
IAVIFileImpl *This = ((IPersistFileImpl*)iface)->paf;
WCHAR wszStreamFmt[50];
INT len;
TRACE("(%p,%s,0x%08X)\n", iface, debugstr_w(pszFileName), dwMode);
/* check parameter */
if (pszFileName == NULL)
return AVIERR_BADPARAM;
assert(This != NULL);
if (This->hmmio != NULL)
return AVIERR_ERROR; /* No reuse of this object for another file! */
/* remeber mode and name */
This->uMode = dwMode;
len = lstrlenW(pszFileName) + 1;
This->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (This->szFileName == NULL)
return AVIERR_MEMORY;
lstrcpyW(This->szFileName, pszFileName);
/* try to open the file */
This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
if (This->hmmio == NULL) {
/* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
LPSTR szFileName;
len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1,
NULL, 0, NULL, NULL);
szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR));
if (szFileName == NULL)
return AVIERR_MEMORY;
WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName,
len, NULL, NULL);
This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
HeapFree(GetProcessHeap(), 0, szFileName);
if (This->hmmio == NULL)
return AVIERR_FILEOPEN;
}
memset(& This->fInfo, 0, sizeof(This->fInfo));
memset(& This->sInfo, 0, sizeof(This->sInfo));
LoadStringW(AVIFILE_hModule, IDS_WAVEFILETYPE, This->fInfo.szFileType,
sizeof(This->fInfo.szFileType));
if (LoadStringW(AVIFILE_hModule, IDS_WAVESTREAMFORMAT,
wszStreamFmt, sizeof(wszStreamFmt)) > 0) {
wsprintfW(This->sInfo.szName, wszStreamFmt,
AVIFILE_BasenameW(This->szFileName));
}
/* should we create a new file? */
if (dwMode & OF_CREATE) {
/* nothing more to do */
return AVIERR_OK;
} else
return AVIFILE_LoadFile(This);
}
static HRESULT WINAPI IPersistFile_fnSave(IPersistFile *iface,
LPCOLESTR pszFileName,BOOL fRemember)
{
TRACE("(%p,%s,%d)\n", iface, debugstr_w(pszFileName), fRemember);
/* We write directly to disk, so nothing to do. */
return AVIERR_OK;
}
static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile *iface,
LPCOLESTR pszFileName)
{
TRACE("(%p,%s)\n", iface, debugstr_w(pszFileName));
/* We write directly to disk, so nothing to do. */
return AVIERR_OK;
}
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface,
LPOLESTR *ppszFileName)
{
IPersistFileImpl *This = (IPersistFileImpl *)iface;
TRACE("(%p,%p)\n", iface, ppszFileName);
if (ppszFileName == NULL)
return AVIERR_BADPARAM;
*ppszFileName = NULL;
assert(This->paf != NULL);
if (This->paf->szFileName != NULL) {
int len = lstrlenW(This->paf->szFileName) + 1;
*ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR));
if (*ppszFileName == NULL)
return AVIERR_MEMORY;
strcpyW(*ppszFileName, This->paf->szFileName);
}
return AVIERR_OK;
}
/***********************************************************************/
static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface,
REFIID refiid, LPVOID *obj)
{
IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
assert(This->paf != NULL);
return IAVIFile_QueryInterface((PAVIFILE)This->paf, refiid, obj);
}
static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream *iface)
{
IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
assert(This->paf != NULL);
return IAVIFile_AddRef((PAVIFILE)This->paf);
}
static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface)
{
IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
assert(This->paf != NULL);
return IAVIFile_Release((PAVIFILE)This->paf);
}
static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
LPARAM lParam2)
{
TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);
/* This IAVIStream interface needs an WAVFile */
return AVIERR_UNSUPPORTED;
}
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface,LPAVISTREAMINFOW psi,
LONG size)
{
IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
TRACE("(%p,%p,%d)\n", iface, psi, size);
if (psi == NULL)
return AVIERR_BADPARAM;
if (size < 0)
return AVIERR_BADSIZE;
memcpy(psi, &This->paf->sInfo, min((DWORD)size, sizeof(This->paf->sInfo)));
if ((DWORD)size < sizeof(This->paf->sInfo))
return AVIERR_BUFFERTOOSMALL;
return AVIERR_OK;
}
static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos,
LONG flags)
{
IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;
TRACE("(%p,%d,0x%08X)\n",iface,pos,flags);
/* Do we have data? */
if (This->lpFormat == NULL)
return -1;
/* We don't have an index */
if (flags & FIND_INDEX)
return -1;
if (flags & FIND_FROM_START) {
pos = This->sInfo.dwStart;
flags &= ~(FIND_FROM_START|FIND_PREV);
flags |= FIND_NEXT;
}
if (flags & FIND_FORMAT) {
if ((flags & FIND_NEXT) && pos > 0)
pos = -1;
else
pos = 0;
}
if ((flags & FIND_RET) == FIND_LENGTH ||
(flags & FIND_RET) == FIND_SIZE)
return This->sInfo.dwSampleSize;
if ((flags & FIND_RET) == FIND_OFFSET)
return This->ckData.dwDataOffset + pos * This->sInfo.dwSampleSize;
return pos;
}
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos,
LPVOID format, LONG *formatsize)
{
IAVIStreamImpl *This = (IAVIStreamImpl *)iface;
TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize);
if (formatsize == NULL)
return AVIERR_BADPARAM;
/* only interested in needed buffersize? */
if (format == NULL || *formatsize <= 0) {
*formatsize = This->paf->cbFormat;
return AVIERR_OK;
}
/* copy initial format (only as much as will fit) */
memcpy(format, This->paf->lpFormat, min(*formatsize, This->paf->cbFormat));
if (*formatsize < This->paf->cbFormat) {
*formatsize = This->paf->cbFormat;
return AVIERR_BUFFERTOOSMALL;
}
*formatsize = This->paf->cbFormat;
return AVIERR_OK;
}
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos,
LPVOID format, LONG formatsize)
{
IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;
TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize);
/* check parameters */
if (format == NULL || formatsize <= sizeof(PCMWAVEFORMAT))
return AVIERR_BADPARAM;
/* We can only do this to an empty wave file, but ignore call
* if still same format */
if (This->lpFormat != NULL) {
if (formatsize != This->cbFormat ||
memcmp(format, This->lpFormat, formatsize) != 0)
return AVIERR_UNSUPPORTED;
return AVIERR_OK;
}
/* only support start at position 0 */
if (pos != 0)
return AVIERR_UNSUPPORTED;
/* Do we have write permission? */
if ((This->uMode & MMIO_RWMODE) == 0)
return AVIERR_READONLY;
/* get memory for format and copy it */
This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
if (This->lpFormat == NULL)
return AVIERR_MEMORY;
This->cbFormat = formatsize;
memcpy(This->lpFormat, format, formatsize);
/* update info's about 'data' chunk */
This->ckData.dwDataOffset = formatsize + 7 * sizeof(DWORD);
This->ckData.cksize = 0;
/* for non-pcm format we need also a 'fact' chunk */
if (This->lpFormat->wFormatTag != WAVE_FORMAT_PCM)
This->ckData.dwDataOffset += 3 * sizeof(DWORD);
/* update stream and file info */
This->sInfo.dwSampleSize = This->lpFormat->nBlockAlign;
This->sInfo.dwScale = This->lpFormat->nBlockAlign;
This->sInfo.dwRate = This->lpFormat->nAvgBytesPerSec;
This->sInfo.dwLength = 0;
This->sInfo.dwSuggestedBufferSize = 0;
return AVIERR_OK;
}
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start,
LONG samples, LPVOID buffer,
LONG buffersize, LPLONG bytesread,
LPLONG samplesread)
{
IAVIFileImpl *This = ((IAVIStreamImpl*)iface)->paf;
TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
buffersize, bytesread, samplesread);
/* clear return parameters if given */
if (bytesread != NULL)
*bytesread = 0;
if (samplesread != NULL)
*samplesread = 0;
/* positions without data */
if (start < 0 || (DWORD)start > This->sInfo.dwLength)
return AVIERR_OK;
/* check samples */
if (samples < 0)
samples = 0;
if (buffersize > 0) {
if (samples > 0)
samples = min((DWORD)samples, buffersize / This->sInfo.dwSampleSize);
else
samples = buffersize / This->sInfo.dwSampleSize;
}
/* limit to end of stream */
if ((DWORD)(start + samples) > This->sInfo.dwLength)
samples = This->sInfo.dwLength - start;
/* request only the sizes? */
if (buffer == NULL || buffersize <= 0) {
/* then I need at least one parameter for it */
if (bytesread == NULL && samplesread == NULL)
return AVIERR_BADPARAM;
if (bytesread != NULL)
*bytesread = samples * This->sInfo.dwSampleSize;
if (samplesread != NULL)
*samplesread = samples;
return AVIERR_OK;
}
/* nothing to read? */
if (samples == 0)
return AVIERR_OK;
/* Can I read at least one sample? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -