⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavfile.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
}

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 + -