示例#1
0
文件: mmio.c 项目: Kelimion/wine
static void test_mmio_end_of_file(void)
{
    char test_file[MAX_PATH], buffer[128], data[16];
    MMIOINFO mmio;
    HMMIO hmmio;
    LONG ret;
    MMRESULT res;

    if (!create_test_file(test_file)) return;

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = FOURCC_DOS;
    mmio.pchBuffer = buffer;
    mmio.cchBuffer = sizeof(buffer);
    hmmio = mmioOpen(test_file, &mmio, MMIO_READ);
    ok(hmmio != NULL, "mmioOpen error %u\n", mmio.wErrorRet);
    if (hmmio == NULL) {
        DeleteFileA(test_file);
        return;
    }

    ret = mmioSeek(hmmio, 0, SEEK_END);
    ok(sizeof(RIFF_buf) == ret, "got %d\n", ret);

    ret = mmioRead(hmmio, data, sizeof(data));
    ok(ret == 0, "expected %d, got %d\n", 0, ret);

    res = mmioGetInfo(hmmio, &mmio, 0);
    ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res);

    res = mmioAdvance(hmmio, &mmio, MMIO_READ);
    ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res);
    ok(mmio.pchNext == mmio.pchEndRead, "expected %p, got %p\n", mmio.pchEndRead, mmio.pchNext);

    mmioClose(hmmio, 0);
    DeleteFileA(test_file);
}
示例#2
0
long ogg_mmio_tell(void* mmfp)
{
    STRHDL* hdl = (STRHDL*)mmfp;

    return (mmioSeek(hdl->cfp, 0, SEEK_CUR) - hdl->true_offset);
}
示例#3
0
文件: wavfile.c 项目: UIKit0/wine-1
static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  mmioSeek(This->hmmio, 0, SEEK_SET);

  /* create the RIFF chunk with formtype WAVE */
  ckRIFF.fccType = formtypeWAVE;
  ckRIFF.cksize  = 0;
  if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK)
    return AVIERR_FILEWRITE;

  /* the next chunk is the format */
  ck.ckid   = ckidWAVEFORMAT;
  ck.cksize = This->cbFormat;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (This->lpFormat != NULL && This->cbFormat > 0) {
    if (mmioWrite(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
      return AVIERR_FILEWRITE;
  }
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* fact chunk is needed for non-pcm waveforms */
  if (This->lpFormat != NULL && This->cbFormat > sizeof(PCMWAVEFORMAT) &&
      This->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
    WAVEFORMATEX wfx;
    DWORD        dwFactLength;
    HACMSTREAM   has;

    /* try to open an appropriate audio codec to figure out
     * data for fact-chunk */
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    if (acmFormatSuggest(NULL, This->lpFormat, &wfx,
			 sizeof(wfx), ACM_FORMATSUGGESTF_WFORMATTAG)) {
      acmStreamOpen(&has, NULL, This->lpFormat, &wfx, NULL,
		    0, 0, ACM_STREAMOPENF_NONREALTIME);
      acmStreamSize(has, This->ckData.cksize, &dwFactLength,
		    ACM_STREAMSIZEF_SOURCE);
      dwFactLength /= wfx.nBlockAlign;
      acmStreamClose(has, 0);

      /* create the fact chunk */
      ck.ckid   = ckidWAVEFACT;
      ck.cksize = sizeof(dwFactLength);

      /* test for enough space before data chunk */
      if (mmioSeek(This->hmmio, 0, SEEK_CUR) > This->ckData.dwDataOffset
	  - ck.cksize - 4 * sizeof(DWORD))
	return AVIERR_FILEWRITE;
      if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
      if (mmioWrite(This->hmmio, (HPSTR)&dwFactLength, ck.cksize) != ck.cksize)
	return AVIERR_FILEWRITE;
      if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
	return AVIERR_FILEWRITE;
    } else
      ERR(": fact chunk is needed for non-pcm files -- currently no codec found, so skipped!\n");
  }

  /* if there was extra stuff, we need to fill it with JUNK */
  if (mmioSeek(This->hmmio, 0, SEEK_CUR) + 2 * sizeof(DWORD) < This->ckData.dwDataOffset) {
    ck.ckid   = ckidAVIPADDING;
    ck.cksize = 0;
    if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;

    if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
		 - 2 * sizeof(DWORD), SEEK_SET) == -1)
      return AVIERR_FILEWRITE;
    if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
      return AVIERR_FILEWRITE;
  }

  /* create the data chunk */
  ck.ckid   = ckidWAVEDATA;
  ck.cksize = This->ckData.cksize;
  if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioSeek(This->hmmio, This->ckData.cksize, SEEK_CUR) == -1)
    return AVIERR_FILEWRITE;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEWRITE;

  /* some optional extra chunks? */
  if (This->extra.lp != NULL && This->extra.cb > 0) {
    /* chunk headers are already in structure */
    if (mmioWrite(This->hmmio, This->extra.lp, This->extra.cb) != This->extra.cb)
      return AVIERR_FILEWRITE;
  }

  /* close RIFF chunk */
  if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK)
    return AVIERR_FILEWRITE;
  if (mmioFlush(This->hmmio, 0) != S_OK)
    return AVIERR_FILEWRITE;

  return AVIERR_OK;
}
示例#4
0
文件: wavfile.c 项目: UIKit0/wine-1
static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

  This->sInfo.dwLength = 0; /* just to be sure */
  This->fDirty = FALSE;

  /* search for RIFF chunk */
  ckRIFF.fccType = 0; /* find any */
  if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
    return AVIFILE_LoadSunFile(This);
  }

  if (ckRIFF.fccType != formtypeWAVE)
    return AVIERR_BADFORMAT;

  /* search WAVE format chunk */
  ck.ckid = ckidWAVEFORMAT;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  /* get memory for format and read it */
  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
  if (This->lpFormat == NULL)
    return AVIERR_FILEREAD;
  This->cbFormat = ck.cksize;

  if (mmioRead(This->hmmio, (HPSTR)This->lpFormat, ck.cksize) != ck.cksize)
    return AVIERR_FILEREAD;
  if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
    return AVIERR_FILEREAD;

  /* Non-pcm formats have a fact chunk.
   * We don't need it, so simply add it to the extra chunks.
   */

  /* find the big data chunk */
  This->ckData.ckid = ckidWAVEDATA;
  if (FindChunkAndKeepExtras(&This->extra, This->hmmio, &This->ckData,
			     &ckRIFF, MMIO_FINDCHUNK) != S_OK)
    return AVIERR_FILEREAD;

  memset(&This->sInfo, 0, sizeof(This->sInfo));
  This->sInfo.fccType      = streamtypeAUDIO;
  This->sInfo.dwRate       = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwSampleSize =
    This->sInfo.dwScale    = This->lpFormat->nBlockAlign;
  This->sInfo.dwLength     = This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;

  This->fInfo.dwStreams = 1;

  if (mmioAscend(This->hmmio, &This->ckData, 0) != S_OK) {
    /* seems to be truncated */
    WARN(": file seems to be truncated!\n");
    This->ckData.cksize  = mmioSeek(This->hmmio, 0, SEEK_END) -
      This->ckData.dwDataOffset;
    This->sInfo.dwLength = This->ckData.cksize / This->lpFormat->nBlockAlign;
    This->sInfo.dwSuggestedBufferSize = This->ckData.cksize;
  }

  /* ignore errors */
  FindChunkAndKeepExtras(&This->extra, This->hmmio, &ck, &ckRIFF, 0);

  return AVIERR_OK;
}
示例#5
0
BOOL CreateSoundFromWave(PSOUND sound, PSTR waveFile, BOOL music)
{
    MMRESULT mr = MMSYSERR_ERROR;
    HMMIO hmmio = NULL;

    ZeroMemory(sound, sizeof(SOUND));

    hmmio = mmioOpen(waveFile, NULL, MMIO_ALLOCBUF | MMIO_READ);
    if (hmmio != NULL)
    {
        MMCKINFO riff = {0};
        MMCKINFO chunk = {0};
        PCMWAVEFORMAT pcmFormat = {0};

        mr = mmioDescend(hmmio, &riff, NULL, 0);
        if (mr == 0)
        {
            /* ensure it's a proper wave file */
            if (riff.ckid != FOURCC_RIFF || riff.fccType != mmioFOURCC('W', 'A', 'V', 'E'))
            {
                mr = MMSYSERR_ERROR;
            }
        }

        if (mr == 0)
        {
            /* find the format info */
            chunk.ckid = mmioFOURCC( 'f', 'm', 't', ' ' );
            if (mmioDescend(hmmio, &chunk, &riff, MMIO_FINDCHUNK) == 0)
            {
                if (mmioRead(hmmio, (HPSTR)&pcmFormat, sizeof(PCMWAVEFORMAT)) == sizeof(PCMWAVEFORMAT) &&
                    pcmFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
                {
                    memcpy(&sound->Format, &pcmFormat, sizeof(pcmFormat));
                    sound->Format.cbSize = 0;
                }
                else
                {
                    mr = MMSYSERR_ERROR;
                }
            }
            else
            {
                mr = MMSYSERR_ERROR;
            }
        }

        if (mr == 0)
        {
            /* find the data chunk */
            if (mmioSeek(hmmio, riff.dwDataOffset + sizeof(FOURCC), SEEK_SET) != -1)
            {
                chunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
                mr = mmioDescend(hmmio, &chunk, &riff, MMIO_FINDCHUNK);
            }
            else
            {
                mr = MMSYSERR_ERROR;
            }
        }

        if (mr == 0)
        {
            if (music)
            {
                /* if this is music, store off the streaming info and stop */
                sound->IsMusic = TRUE;
                sound->Stream = (PSTREAMINFO)malloc(sizeof(STREAMINFO));
                sound->Stream->Playing = FALSE;
                sound->Stream->Stream = hmmio;
                sound->Stream->TotalSize = chunk.cksize;
                sound->Stream->Riff = riff;
                sound->Stream->UsedSize = 0;

                mr = mmioGetInfo(hmmio, &sound->Stream->StreamInfo, 0);
            }
            else
            {
                /* if this is sound fx, then copy the buffer to the sound object so we can tear off instances */
                MMIOINFO info = {0};
                DWORD current;
                DWORD size = chunk.cksize;

                sound->IsMusic = FALSE;
                sound->Data = (LPWAVEHDR)malloc(sizeof(WAVEHDR));
                ZeroMemory(sound->Data, sizeof(WAVEHDR));

                mr = mmioGetInfo(hmmio, &info, 0);

                sound->Data->lpData = (LPSTR)malloc(size);
                sound->Data->dwBufferLength = size;

                for (current = 0; current < size && mr == MMSYSERR_NOERROR; ++current)
                {
                    if (info.pchNext == info.pchEndRead)
                    {
                        mr = mmioAdvance(hmmio, &info, MMIO_READ);
                        if (mr == MMSYSERR_NOERROR)
                        {
                            mr = (info.pchNext != info.pchEndRead ? MMSYSERR_NOERROR : MMSYSERR_ERROR);
                        }
                    }

                    if (mr == MMSYSERR_NOERROR)
                    {
                        sound->Data->lpData[current] = *info.pchNext;
                        ++info.pchNext;
                    }
                }
            }
        }
    }

    if (mr == 0)
    {
        if (!music)
        {
            mmioClose(hmmio, 0);
        }

        return TRUE;
    }
    else
    {
        /* clean up any stank */
        DestroySound(sound);

        if (hmmio)
        {
            mmioClose(hmmio, 0);
        }

        return FALSE;
    }
}
//WAVEファイルをロードする
int WaveLoader::ReadWaveData(WAVEFORMATEX* wfx, void** pdata, QWORD dwFrom, QWORD dwSizeToRead, bool isLoopWave)
{
	static MMCKINFO parent, child;
	static char szBefore[MAX_PATH];
	_ASSERT(m_FileInfo->name);
	if(pdata!=NULL) SAFE_GLOBALFREE(*pdata);

	//if(m_hmmio!=NULL && lstrcmp(m_FileInfo->name, szBefore)!=0){//ファイル名が指定されていたら開きなおす
	//	SAFE_MMIOCLOSE(m_hmmio);
	//}
	if( !isLoaded ){
		lstrcpy(szBefore, m_FileInfo->name);

		if( lstrcmp(m_FileInfo->name, CSL_LOAD_MEMORYIMAGE)==0 ){
//			if(!m_hmmio){//最初の一回しかしない処理(ストリーミング用の処置)
			MMIOINFO mmioinfo;
			zeroMem(&mmioinfo, sizeof(MMIOINFO));
			mmioinfo.pchBuffer = (HPSTR)m_FileInfo->pMemBuffer;
			mmioinfo.fccIOProc = FOURCC_MEM;
			mmioinfo.cchBuffer = m_FileInfo->fsize;

			if(NULL == (m_hmmio = mmioOpen(NULL, &mmioinfo, MMIO_READ|MMIO_ALLOCBUF))){
				return CSL_E_UNEXP;
			}
		}else{
			if(NULL == (m_hmmio = mmioOpen((LPSTR)m_FileInfo->name, NULL, MMIO_READ|MMIO_ALLOCBUF))){
				return CSL_E_UNEXP;
			}
		}
		parent.fccType = mmioFOURCC('W', 'A', 'V', 'E');//waveファイルかどうか調べる
		if(mmioDescend(m_hmmio, &parent, NULL, MMIO_FINDRIFF) != MMSYSERR_NOERROR){
			SAFE_MMIOCLOSE(m_hmmio);
			return CSL_E_UNEXP;
		}
		child.ckid = mmioFOURCC('f', 'm', 't', ' ');//fmtチャンクへ移動する
		if(mmioDescend(m_hmmio, &child, &parent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR){
			SAFE_MMIOCLOSE(m_hmmio);
			return CSL_E_UNEXP;
		}

		_ASSERT(wfx);
		if(mmioRead(m_hmmio, (HPSTR)wfx, (LONG)child.cksize) != (LONG)child.cksize){//fmtチャンク(WAVEFORMATEX)読み取り
			SAFE_MMIOCLOSE(m_hmmio);
			return CSL_E_UNEXP;
		}
		_ASSERT((wfx->wFormatTag==WAVE_FORMAT_PCM));
		mmioAscend(m_hmmio, &child, 0);//fmtチャンクから出る
		child.ckid = mmioFOURCC('d', 'a', 't', 'a');//dataチャンクに移動
		if(mmioDescend(m_hmmio, &child, &parent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR) {
			SAFE_MMIOCLOSE(m_hmmio);
			return CSL_E_UNEXP;
		}
		m_dwDataLength = child.cksize;//WAVE領域のサイズ
		m_dwOffsetToWaveData = mmioSeek(m_hmmio, 0, SEEK_CUR);//データまでの位置を保存しておく
	}
	if(pdata){
		if(dwSizeToRead<=0){//ファイル全体を読み込む
			(*pdata) = (LPBYTE)GlobalAlloc(GPTR, m_dwDataLength * sizeof(BYTE));
			_ASSERT(*pdata);

			if(mmioRead(m_hmmio, (HPSTR)*pdata, (LONG)m_dwDataLength) != (LONG)m_dwDataLength){
				GlobalFree(*pdata);
				SAFE_MMIOCLOSE(m_hmmio);
				return CSL_E_UNEXP;
			}
			SAFE_MMIOCLOSE(m_hmmio);	//必要なデータがそろったので、ファイルを閉じる
			m_dwCurrentDecodedPos += dwSizeToRead;
		}else{
			//DWORD dwInnerFinPos = dwFrom + dwSizeToRead;
			////領域サイズ以上だったら収まるように値を補正
			//if(m_dwDataLength < dwInnerFinPos){
			//	dwSizeToRead -= dwInnerFinPos-m_dwDataLength;
			//}

			//開始位置が指定されていれば, データ領域からのオフセットをStartとする.
			//指定されていなければ, それまで進んだカーソル位置から読み込みを開始する
			if(dwFrom>=0) mmioSeek(m_hmmio, (LONG)(m_dwOffsetToWaveData + dwFrom), SEEK_SET);
			
			//要求領域分のメモリ確保
			(*pdata) = (LPBYTE)GlobalAlloc(GPTR, (SIZE_T)(dwSizeToRead * sizeof(BYTE)));
			_ASSERT(*pdata);

			//現在位置からリクエストサイズを読むとオーバーするようなら、ラップアラウンドする。
			DWORD dwNowCursor = mmioSeek(m_hmmio, 0, SEEK_CUR) - m_dwOffsetToWaveData;
			if(m_dwDataLength < (dwNowCursor + dwSizeToRead)){
				if( !isLoopWave ){
					if( dwNowCursor>=m_dwDataLength ){
						fillMem((BYTE*)*pdata, dwSizeToRead, (m_wfx.wBitsPerSample==8) ? 128:0);
						return CSL_E_OUTOFRANGE;
					}
				}

				DWORD dwBeforeWrapAround = m_dwDataLength-dwNowCursor; 
				//とりあえず、最後まで読む
				if(mmioRead(m_hmmio, (HPSTR)*pdata, (LONG)dwBeforeWrapAround) != (LONG)dwBeforeWrapAround){
					GlobalFree(*pdata);
					SAFE_MMIOCLOSE(m_hmmio);
					return CSL_E_UNEXP;
				}
				m_dwCurrentDecodedPos += dwBeforeWrapAround;

				if(isLoopWave){//残った部分を無音で埋めるかどうか
					mmioSeek(m_hmmio, 0, SEEK_SET);
					mmioSeek(m_hmmio, m_dwOffsetToWaveData, SEEK_CUR);	//ポインタをWAVE領域始点に戻す
					//ラップアラウンド分を読む
					if(mmioRead(m_hmmio, (HPSTR)*pdata+dwBeforeWrapAround, (LONG)(dwSizeToRead - dwBeforeWrapAround)) != (LONG)(dwSizeToRead - dwBeforeWrapAround)){
						GlobalFree(*pdata);
						SAFE_MMIOCLOSE(m_hmmio);
						return CSL_E_UNEXP;
					}
					m_dwCurrentDecodedPos =  0;
					m_dwCurrentDecodedPos += dwSizeToRead - dwBeforeWrapAround;
				}else{
					fillMem((BYTE*)*pdata+dwBeforeWrapAround, dwSizeToRead - dwBeforeWrapAround, (m_wfx.wBitsPerSample==8) ? 128:0);
					return CSL_N_FIN;
				}
			}else{ //ラップアラウンドしなかった場合
				if(mmioRead(m_hmmio, (HPSTR)*pdata, (LONG)dwSizeToRead) != (LONG)dwSizeToRead){
					GlobalFree(*pdata);
					SAFE_MMIOCLOSE(m_hmmio);
					return CSL_E_UNEXP;
				}
				m_dwCurrentDecodedPos += dwSizeToRead;
			}//必要なデータはまだあるので、ファイルは閉じない
		}
	}
	return CSL_E_OK;
}
示例#7
0
int WaveCloseWriteFile( 
HMMIO *phmmioOut, // (IN) 
MMCKINFO *pckOut, // (IN) 
MMCKINFO *pckOutRIFF, // (IN) 
MMIOINFO *pmmioinfoOut, // (IN) 
DWORD cSamples // (IN) 
) 
{ 
	int nError; 

	nError = 0; 

	if (*phmmioOut == NULL) return(0); 

	pmmioinfoOut->dwFlags |= MMIO_DIRTY;

	if ((nError = mmioSetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0) 
	{ 
		// cannot flush, probably... 
		goto ERROR_CANNOT_WRITE; 
	} 

	/* Ascend the output file out of the 'data' chunk -- this will cause 
	* the chunk size of the 'data' chunk to be written. 
	*/ 

	if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0) 
		goto ERROR_CANNOT_WRITE; // cannot write file, probably 

	// Do this here instead...

	if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0) 
		goto ERROR_CANNOT_WRITE; // cannot write file, probably 

	nError = mmioSeek(*phmmioOut, 0, SEEK_SET); 

	if ((nError = (int)mmioDescend(*phmmioOut, pckOutRIFF, NULL, 0)) != 0) 
		goto ERROR_CANNOT_WRITE; 

	nError = 0; 

	pckOut->ckid = mmioFOURCC('f', 'a', 'c', 't'); 

	if ((nError = mmioDescend(*phmmioOut, pckOut, pckOutRIFF, MMIO_FINDCHUNK)) == 0) 
	{ 
		// If it didn't fail, write the fact chunk out, if it failed, not critical, just 
		// assert (below). 

		nError = mmioWrite(*phmmioOut, (HPSTR)&cSamples, sizeof(DWORD)); 
		nError = mmioAscend(*phmmioOut, pckOut, 0); 
		nError = 0; 
	} 
	else 
	{ 
		nError = 0; 
//		ASSERT(FALSE); 
	} 

	/* Ascend the output file out of the 'RIFF' chunk -- this will cause 
	* the chunk size of the 'RIFF' chunk to be written. 
	*/ 

	if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0) 
		goto ERROR_CANNOT_WRITE; // cannot write file, probably 

ERROR_CANNOT_WRITE: 
	if (*phmmioOut != NULL) 
	{ 
		mmioClose(*phmmioOut, 0); 
		*phmmioOut = NULL; 
	} 

	return(nError); 
} 
示例#8
0
文件: wave.c 项目: RhodesBard/remind
// Only PCM!!!!, no any check
__rttype_ struct pcm_s *_open_wave (const char *name) {

#ifdef __WINDOWS_
    HMMIO mmioHandle;
    MMCKINFO mmckinfoParent;
    MMCKINFO mmckinfoSubChunk;
    struct pcm_s waveHandle;
    mmioHandle = mmioOpenA((LPSTR)name, NULL, MMIO_ALLOCBUF | MMIO_READ);
    if (!mmioHandle)
        return NULL;
    memset (&mmckinfoParent, 0, sizeof(MMCKINFO));
    memset (&mmckinfoSubChunk, 0, sizeof(MMCKINFO));
    memset (&waveHandle, 0, sizeof(waveHandle));
    mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
    if (MMSYSERR_NOERROR == mmioDescend(mmioHandle, (LPMMCKINFO) & mmckinfoParent, NULL, MMIO_FINDRIFF)) {
        mmckinfoSubChunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
        /* Find 'fmt ' chunk */
        if (MMSYSERR_NOERROR == mmioDescend(mmioHandle, &mmckinfoSubChunk, &mmckinfoParent, MMIO_FINDCHUNK)) {
            waveHandle.infos = dlmalloc (mmckinfoSubChunk.cksize);
            waveHandle.wf_size = mmckinfoSubChunk.cksize;
            if (NULL != waveHandle.infos) {
                if (mmckinfoSubChunk.cksize == mmioRead(mmioHandle, (HPSTR)waveHandle.infos, mmckinfoSubChunk.cksize)) {
                    if (MMSYSERR_NOERROR == mmioAscend(mmioHandle, &mmckinfoSubChunk, 0)) {
                        /* Find 'data' chunk */
                        mmckinfoSubChunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
                        if (MMSYSERR_NOERROR == mmioDescend(mmioHandle, &mmckinfoSubChunk, &mmckinfoParent, MMIO_FINDCHUNK)) {
                            if (0 != mmckinfoSubChunk.cksize) {
                                waveHandle.snd_buf = dlmalloc (mmckinfoSubChunk.cksize + 176400);
                                if (NULL != waveHandle.snd_buf) {
                                    if (-1 != mmioSeek(mmioHandle, mmckinfoSubChunk.dwDataOffset, SEEK_SET)) {
                                        if (-1 != mmioRead(mmioHandle, waveHandle.snd_buf, mmckinfoSubChunk.cksize)) {
                                            /* Read success !!! */
                                            struct pcm_s *p = dlmalloc (sizeof(struct pcm_s));
                                            if (NULL != p) {
                                                mmioClose (mmioHandle, 0);
                                                waveHandle.mb_size = mmckinfoSubChunk.cksize;
                                                waveHandle.fquad_ = ((float)mmckinfoSubChunk.cksize) / (float)waveHandle.infos->average_rate;
                                                waveHandle.quad_ = mmckinfoSubChunk.cksize / waveHandle.infos->average_rate;
                                                waveHandle.fsmall_ =
                                                    fmod((float)mmckinfoSubChunk.cksize,
                                                         (float)waveHandle.infos->average_rate)
                                                    / (float)waveHandle.infos->average_rate;
                                                waveHandle.small_ = (int)(waveHandle.fsmall_ * (float)60.000);
                                                memcpy (p, &waveHandle, sizeof (struct pcm_s));
                                                return p;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (NULL != waveHandle.infos)
        dlfree (waveHandle.infos);

    if (NULL != waveHandle.snd_buf)
        dlfree (waveHandle.snd_buf);

    mmioClose (mmioHandle, 0);
    return NULL;
#else
#endif
}
示例#9
0
int main(int argc, char *argv[])
{

    //
    // initial seconds count, set to zero.
    
    int seconds = 0;

    //
    // Here we say who we are...
    cout << "WavMix Version 1.1 built " << __DATE__ << "  " << __TIME__ << endl;
    cout << "Application mixes 44.1khz stereo wav files only." << endl;
    cout << endl;

    if (argc < 5)
    {
        //
        //
        cout << endl;
        cout << "     Usage:" << endl;
        cout << "     Provide two source filenames, a target file name, the number of seconds" << endl;
        cout << "     you wish to mix, optional flag to just produce a sample mix, " << endl;
        cout << "     This program REQUIRES MMPM/2 to be installed." << endl;
        cout << endl;
        cout << " This application mixes 44.1khz stereo wav files only.  It will mix two" << endl;
        cout << " source wav files and create a target wav file.  You set the amount of " << endl;
        cout << " overlap in seconds.  WavMix will mix using the seconds of overlap.  A " << endl;
        cout << " preview mode is provided.  Since wave files of this type are extremely " << endl;
        cout << " large, it will produce  a target wav file of just the overlap so you " << endl;
        cout << " may preview your mixdowns" << endl;
        cout << endl;
        cout << endl;
        cout << " Sample command line" << endl;
        cout << " [r:\\audio\\mixdown] wavmix track01.wav track02.wav output.wav 5 " << endl;
        cout << "      Above line mixes track01.wav and track02.wav using 5 seconds " << endl;
        cout << "      of overlap creating output.wav" << endl;
        cout << endl;
        cout << " [r:\\audio\\mixdown] wavmix track01.wav track02.wav output.wav 5 S" << endl;
        cout << "      Above line mixes 5 seconds of audio from the end of track01.wav and the" << endl;
        cout << "      start of track02.wav creating output.wav" << endl;
        
        cout << endl;
        cout << endl;
        cout << "     Support questions or comments to [email protected]" << endl;
            
            
        cout << "Provide filename1 filename2 destinationfile secondtomix (Longcut)" << endl;
        return 1;
    }

    //
    // set the type of mix we are going to do.  if this is true, we do a full mix, if its
    // false, we only will do a "sample" of the mix part.
   short longcut = TRUE;

   if (argc > 5)
   {
       if (strcmp(argv[5],"S")==0)
       {
           cout << "Output file will only be the overlap." << endl;
           longcut = FALSE;
       }
   }
       
   
   seconds= atoi(argv[4]);

   if (seconds == 0)
   {
       cout << " ERROR:  You cannot set seconds-to-mix to 0. " << endl;
       return 5;
   }

  
   MMAUDIOHEADER mmAudioHeader,mmAudioHeader2;
    
    //
    // open file1
   HMMIO hmmio = mmioOpen(argv[1],NULL,MMIO_READ | MMIO_ALLOCBUF);
   if (hmmio==0)
   {
       cout << "Failed to open file " << argv[1] << endl;
       return 1;
   }

   long BytesRead;
   int rc = mmioGetHeader(hmmio,(PVOID)&mmAudioHeader,sizeof(MMAUDIOHEADER),&BytesRead,NULL,NULL);
   if (rc)
   {
       cout << "Error on mmioGetHeader for file " << argv[1] <<  endl;
   }

   //
   // now open the second file

   HMMIO hmmio2 = mmioOpen(argv[2],NULL,MMIO_READ | MMIO_ALLOCBUF);
   if (hmmio2==0)
   {
       cout << "ERROR: Failed to open file " << argv[2] << endl;
       return 2;
   }
   
   rc = mmioGetHeader(hmmio2,(PVOID)&mmAudioHeader2,sizeof(MMAUDIOHEADER),&BytesRead,NULL,NULL);
   if (rc)
   {
       cout << "ERROR on mmioGetHeader 2 " << endl;
       return 3;
   }
   
   //
   // now we are going to create another wave file

   MMIOINFO mmioinfo;

   memset(&mmioinfo,'\0',sizeof(mmioinfo));

   mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER+MMIO_TRANSLATEDATA;
   mmioinfo.aulInfo[3] = MMIO_MEDIATYPE_AUDIO;
   mmioinfo.fccIOProc = mmioFOURCC('W','A','V','E');
   HMMIO hmmioTo = mmioOpen(argv[3],&mmioinfo,MMIO_CREATE+MMIO_WRITE);
 
   if (!hmmioTo)
   {
       cout << "ERROR : Could not create file." << argv[3] <<  endl;
       return 1;
   }


   // here we calculate the OFFSET from the back of the file for the 5 second overlay
   long audiosize = 176400 * seconds; // seconds of audio
   long filesize1 = mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes;
   long filesize2 = mmAudioHeader2.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes;
   if (audiosize > filesize1)
   {
       cout << "ERROR, you cannot have a mix area that is larger than your source audio file. " << endl;
       return 1;
   }

   if (longcut != TRUE)
   {
       //
       // install the new file size in the buffer
       mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes = audiosize;
       cout << "Total resulting file size is: " << audiosize << endl;
   }

   if (longcut == TRUE)
   {
       //
       // install the new file size in the buffer
       mmAudioHeader.mmXWAVHeader.XWAVHeaderInfo.ulAudioLengthInBytes = filesize1 + filesize2;
       cout << "Total resulting file size is: " << (filesize1 + filesize2) << endl;
   }
  
  
   //
   // here we calculate the seekto, not necessary really with longcut
   long seekto = filesize1 - audiosize;

   cout << "Attempting to mix " << seconds << " seconds " << endl;

   //
   // first we copy the begining of file 1 to destfile
   if (longcut==TRUE)
   {
       cout << "Copying " << seekto << " bytes" << endl;
       copyaudio(hmmio,hmmioTo,seekto);
   }
   
   
   //
   // now seek to the new location in file 1
   LONG newPos = mmioSeek(hmmio,seekto,0);
   assert(newPos == seekto);

   //
   // allocate a buffer
   PSHORT pAudio = NULL;
   DosAllocMem((void **) &pAudio,audiosize,PAG_WRITE | PAG_COMMIT);

   //
   // now read the FIRST file
   BytesRead = mmioRead(hmmio,(PCHAR)pAudio,audiosize);
   assert(BytesRead == audiosize);

   //
   // now allocate the second buffer

   PSHORT pAudio2 = NULL;
   DosAllocMem((void **) &pAudio2,audiosize,PAG_WRITE | PAG_COMMIT);

   //
   // and read that in
   BytesRead = mmioRead(hmmio2,(PCHAR)pAudio2,audiosize);
   assert(BytesRead == audiosize);

   //
   // now ADD them together?
   long shortsize = audiosize/2;
   for (unsigned long index = 0; index < shortsize ; index++)
   {
       short part1 = *(pAudio+index);
       short part2 = *(pAudio2+index);
       short result = part1 + part2;
       *(pAudio+index) = result;
           //       *(pAudio+index) = *(pAudio2+index) + *(pAudio+index);
   }

 
   //
   // build the header
   rc = mmioSetHeader(hmmioTo,&mmAudioHeader,sizeof(MMAUDIOHEADER),&BytesRead,0,0);
   if (rc)
   {
       cout << "Error in mmioSetHeader" << endl;
       return 1;
   }

   //
   // write the new file
   rc = mmioWrite(hmmioTo,(PCHAR)pAudio,audiosize);
   if (rc < 0)
   {
       cout << "ERROR during a write" << endl;
   }

   //
   // now, copy the rest of file 2
   if (longcut == TRUE)
   {
       cout << "Copying " << filesize2 - audiosize << " bytes" << endl;
       copyaudio(hmmio2,hmmioTo,filesize2 - audiosize);
   }
   DosFreeMem(pAudio);
   DosFreeMem(pAudio2);
   mmioClose(hmmio,0);
   mmioClose(hmmio2,0);
   mmioClose(hmmioTo,0);

   cout << "Finished, output file created" << endl;
    
    
}
示例#10
0
文件: mmio.c 项目: howard5888/wineT
static void test_mmioDescend(void)
{
    MMRESULT ret;
    HMMIO hmmio;
    MMIOINFO mmio;
    MMCKINFO ckRiff, ckList, ck;

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = FOURCC_MEM;
    mmio.cchBuffer = sizeof(RIFF_buf);
    mmio.pchBuffer = (char *)&RIFF_buf;

    /*hmmio = mmioOpen("msrle.avi", NULL, MMIO_READ);*/
    hmmio = mmioOpen(NULL, &mmio, MMIO_READ);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);
    trace("hmmio = %p\n", hmmio);

    /* first normal RIFF AVI parsing */
    ret = mmioDescend(hmmio, &ckRiff, NULL, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckRiff.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ckRiff.ckid);
    ok(ckRiff.fccType == formtypeAVI, "wrong fccType: %04lx\n", ckRiff.fccType);
    trace("ckid %4.4s cksize %04lx fccType %4.4s off %04lx flags %04lx\n",
          (LPCSTR)&ckRiff.ckid, ckRiff.cksize, (LPCSTR)&ckRiff.fccType,
          ckRiff.dwDataOffset, ckRiff.dwFlags);

    ret = mmioDescend(hmmio, &ckList, &ckRiff, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ckList.ckid);
    ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ckList.fccType);
    trace("ckid %4.4s cksize %04lx fccType %4.4s off %04lx flags %04lx\n",
          (LPCSTR)&ckList.ckid, ckList.cksize, (LPCSTR)&ckList.fccType,
          ckList.dwDataOffset, ckList.dwFlags);

    ret = mmioDescend(hmmio, &ck, &ckList, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == ckidAVIMAINHDR, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == 0, "wrong fccType: %04lx\n", ck.fccType);
    trace("ckid %4.4s cksize %04lx fccType %4.4s off %04lx flags %04lx\n",
          (LPCSTR)&ck.ckid, ck.cksize, (LPCSTR)&ck.fccType,
          ck.dwDataOffset, ck.dwFlags);

    /* test various mmioDescend flags */

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ck.ckid = 0;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ck.fccType = 0;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType);

    /* do NOT seek, use current file position */
    memset(&ck, 0x55, sizeof(ck));
    ck.fccType = 0;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDLIST);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ck.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ck.ckid = 0;
    ck.fccType = listtypeAVIHEADER;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType);

    /* do NOT seek, use current file position */
    memset(&ck, 0x55, sizeof(ck));
    ck.ckid = FOURCC_LIST;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ck.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ck.ckid = FOURCC_RIFF;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04lx\n", ck.fccType);

    /* do NOT seek, use current file position */
    memset(&ckList, 0x55, sizeof(ckList));
    ckList.ckid = 0;
    ret = mmioDescend(hmmio, &ckList, &ck, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04lx\n", ckList.ckid);
    ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04lx\n", ckList.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);
    ok(ck.ckid != 0x55555555, "wrong ckid: %04lx\n", ck.ckid);
    ok(ck.fccType != 0x55555555, "wrong fccType: %04lx\n", ck.fccType);
    ok(ck.dwDataOffset != 0x55555555, "wrong dwDataOffset: %04lx\n", ck.dwDataOffset);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x55, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);

    mmioClose(hmmio, 0);
}
示例#11
0
BOOL CWaveFile::PrepareWaveFile(LPCTSTR lpszFileName)
{
	if(lpszFileName == NULL || *lpszFileName == _T('\0'))
	{
		_stprintf(m_szErrorMsg, _T("Empty file name"));
		return FALSE;
	}

	//The previous opened file is not closed yet
	if(m_hWaveFile != NULL)
	{
		_stprintf(m_szErrorMsg, _T("The previous open file [%s] is not closed yet"), m_szFileName);
		return FALSE;
	}

	_tcscpy(m_szFileName, lpszFileName);

	//Open wave file
	m_hWaveFile = mmioOpen(m_szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF);
	if(m_hWaveFile == NULL)
	{
		_stprintf(m_szErrorMsg, _T("mmioOpen file %s failed"), m_szFileName);
		return FALSE;
	}

	//Chunk info structures
	MMCKINFO ckInfoParent, ckInfo;
	MMRESULT mmResult = 0;

	char* fmtBuffer = NULL;
	LONG lVar;
	BOOL bRet = FALSE;

	do
	{
		//Find riff wave
		ckInfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
		mmResult = mmioDescend(m_hWaveFile, &ckInfoParent, NULL, MMIO_FINDRIFF);
		if(mmResult != MMSYSERR_NOERROR)
		{
			_stprintf(m_szErrorMsg, _T("mmioDescend find riff wave failed"));
			break;
		}

		//Find chunk "fmt "
		ckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
		mmResult = mmioDescend(m_hWaveFile, &ckInfo, &ckInfoParent, MMIO_FINDCHUNK);
		if(mmResult != MMSYSERR_NOERROR)
		{
			_stprintf(m_szErrorMsg, _T("mmioDescend find chunk 'fmt ' failed"));
			break;
		}

		//create 'fmt ' buffer
		fmtBuffer = new char[ckInfo.cksize];

		//Read 'fmt ' content
		lVar = mmioRead(m_hWaveFile, (HPSTR)fmtBuffer, ckInfo.cksize);
		if( (DWORD)lVar != ckInfo.cksize )
		{
			_stprintf(m_szErrorMsg, _T("mmioRead read 'fmt ' content failed. fmtSize=%d, read=%d"), 
				ckInfo.cksize, lVar);
			break;
		}
		//remember the fmt
		m_lpWaveFormat = (WAVEFORMATEX*)fmtBuffer;
		m_dwWaveFormatSize = ckInfo.cksize;
		
		//leave chunk 'fmt '
		mmResult = mmioAscend(m_hWaveFile, &ckInfo, 0);
		if(mmResult != MMSYSERR_NOERROR)
		{
			_stprintf(m_szErrorMsg, _T("mmioAscend leave 'fmt ' chunk failed. mmResult=%u"), mmResult);
			break;
		}
		
		//Find chunk 'data'
		ckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
		mmResult = mmioDescend(m_hWaveFile, &ckInfo, &ckInfoParent, MMIO_FINDCHUNK);
		if(mmResult != MMSYSERR_NOERROR)
		{
			_stprintf(m_szErrorMsg, _T("mmioDescend find 'data' chunk failed. mmResult=%u"), mmResult);
			break;
		}
		//remember the data chunk info
		m_ckInfoData = ckInfo;
		m_dwDataReadCount = 0;
		
		//Seek the file position to the chunk 'data' start
		lVar = mmioSeek(m_hWaveFile, m_ckInfoData.dwDataOffset, SEEK_SET);
		if((DWORD)lVar != m_ckInfoData.dwDataOffset)
		{
			_stprintf(m_szErrorMsg, _T("mmioSeek to chunk 'data' failed. position=%d"), lVar);
			break;
		}
		
		//everything is ok
		bRet = TRUE;

	} while (FALSE);
	
	if(!bRet)
	{
		if(fmtBuffer != NULL)
		{
			delete[] fmtBuffer;
			fmtBuffer = NULL;
		}
		m_lpWaveFormat = NULL;
	}

	return bRet;
}
/*************************************************************************
 * Name         : PlayTheWave
 *
 * Description : This function initially opens the wave file to be played
 *               and tells the MCD information about the file
 *               that is about to be played.  The Samples Per Second,
 *               Bits Per Sample, and the number of channels with which
 *               the waveform file was created has to be told to the MCD.
 *               This function initially fills up the allocated buffer
 *               of the playlist with the wave file.  For 0 - MAXBUFF
 *               the wave file is filled into the memory.  The Wave file
 *               is read in continously from 0 -MAXBUFF.
 *               This same buffer is dynamically re-filled again and again
 *               by the PlayThread thread.
 *
 * Concepts     : The wave file is first opened and then continuously read
 *                into the buffer.  If the end of the wave file is reached
 *                then we seek to the starting of the wave and keep on reading
 *                the wave file till the buffer fills up. This displays the
 *                double buffering concept because, while the playlist is
 *                continuously looping and playing the wave file, the
 *                playlist buffers are constantly being filled with data from
 *                the wave file in the PlayThread thread.
 *
 *
 *
 * MMPM/2 API's : mmioOpen
 *                mmioGetHeader
 *                mmioRead
 *                mmioSeek
 *                mciSendCommand
 *                  MCI_SET
 *                  MCI_CUE
 *
 * Parameters   : None.
 *
 * Return       : ulReturn
 *
 *************************************************************************/
ULONG PlayTheWave()
{

   MCI_WAVE_SET_PARMS    lpWaveSet;
   ULONG                 ulReturn;
   MMAUDIOHEADER         mmHeader;
   int i;
   long                  ulBytesRead;


   memset ( &lpWaveSet,
            0,
            sizeof( MCI_WAVE_SET_PARMS ) );

   /* Open the Wave File MyWave.Wav for Reading */
   hmmioFileHandle = mmioOpen(WAVE_FILE_NAME,
                             (PMMIOINFO) NULL,
                             MMIO_READ);

   /* If the Wave File could not be opened */
   if (!hmmioFileHandle)
      {

      ShowAMessage(
         IDS_ERROR_TITLE,
         IDS_CANT_OPEN_WAVE,
         MB_OK | MB_INFORMATION | MB_MOVEABLE | MB_HELP |
         MB_APPLMODAL,
         FALSE );

      return ( TRUE );
      }

   /*
    * Get the Header Information for the file so that we can set the channels,
    * Samples Per Second and Bits Per Sample to play the memory playlist.
    */

   ulReturn = mmioGetHeader(hmmioFileHandle,
                            (PVOID) &mmHeader,
                            sizeof(MMAUDIOHEADER),
                            (PLONG) &ulBytesRead,
                            (ULONG) NULL,
                            (ULONG) NULL);
   if (ulReturn != 0 )
     return ( ulReturn );

   /* Set the WaveSet Structure */

   lpWaveSet.ulLevel = 100;
   lpWaveSet.ulSamplesPerSec = mmHeader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec;
   lpWaveSet.usBitsPerSample = mmHeader.mmXWAVHeader.WAVEHeader.usBitsPerSample;
   lpWaveSet.usChannels = mmHeader.mmXWAVHeader.WAVEHeader.usChannels;
   lpWaveSet.ulAudio = MCI_SET_AUDIO_ALL;
   lpWaveSet.hwndCallback = (HWND) NULL;

   /* Set the Channels for the MCD */
   ulReturn
        = mciSendCommand(usWaveDeviceId,
                         MCI_SET,
                         MCI_WAIT | MCI_WAVE_SET_CHANNELS,
                         (PVOID) &lpWaveSet,
                         (USHORT)NULL);
   if (ulReturn != 0 )
     return ( ulReturn );

   /* Set the Samples Per Second */
   ulReturn
        = mciSendCommand(usWaveDeviceId,
                         MCI_SET,
                         MCI_WAIT | MCI_WAVE_SET_SAMPLESPERSEC,
                         (PVOID) &lpWaveSet,
                         (USHORT)NULL);

   if (ulReturn != 0 )
     return ( ulReturn );

   /* Set the Bits per Sample */
   ulReturn
        = mciSendCommand(usWaveDeviceId,
                         MCI_SET,
                         MCI_WAIT | MCI_WAVE_SET_BITSPERSAMPLE,
                         (PVOID) &lpWaveSet,
                         (USHORT)NULL);

   if (ulReturn != 0 )
     return ( ulReturn );


  /* From 0 - MAXBUFF, fill the memory Playlist buffer with the wave file. */

   for (i=0; i<MAXBUFF; i++)
   {

     ulBytesRead =
           mmioRead(hmmioFileHandle,
                    (HPSTR) achDataBuffer[i],
                    MAXSIZE);
     /*
      * If the end of the wave file is reached then Seek to the starting
      * of the wave file and start reading the wave into the appropriate
      * buffer
     */
     if (ulBytesRead < MAXSIZE)
        {
         mmioSeek(hmmioFileHandle, 0, SEEK_SET);

         ulBytesRead =
           mmioRead(hmmioFileHandle,
                    (HPSTR) achDataBuffer[i],
                    MAXSIZE);
         }


   }


   /*
    * Create the thread that will maintain the playlist buffer
    */
   fEndPlay = FALSE;
   if ( DosCreateThread ( &tidPlayThread,
                         (PFNTHREAD) PlayThread,
                         0L, 0L, 8192L))
      return ( TRUE );

   return ( FALSE );

}
VOID  APIENTRY PlayThread ( ULONG parm1 )
{

   ULONG    ulBytesRead;
   ULONG    ulBufferNum;
   ULONG    ulPostCount;
   ULONG    ulReturn;
   MCI_PLAY_PARMS        mciPlayParameters;



   mciPlayParameters.hwndCallback =  hwndDiag;

   /*
    * Send the Play Command to begin the playing of the memory playlist.
    */
   ulReturn = mciSendCommand(usWaveDeviceId,
                             MCI_PLAY,
                             MCI_NOTIFY,
                             (PVOID) &mciPlayParameters,
                             0);

   /*
    * Loop until the playlist is stopped.
    */
   while( !fEndPlay )
   {

      for( ulBufferNum = 0; ulBufferNum < MAXBUFF; ulBufferNum++ )
      {

         /*
          * Use DosWaitEventSem to pause util the playlist plays this
          * buffer. Then refill the buffer and post the semaphore.
          */
         ulReturn = DosWaitEventSem ( hevSem[ulBufferNum], 5000L );

         DosResetEventSem ( hevSem[ulBufferNum], &ulPostCount );

         if( fEndPlay ) break;

            /*
             * Read the Next MAXSIZE bytes of the wave file
             */
            ulBytesRead =
                   mmioRead(hmmioFileHandle,
                            (HPSTR) achDataBuffer[ulBufferNum],
                            MAXSIZE);


            /*
             * If we have reached the end of the wave file then set the file marker
             * to the begining of the file and start reading into the bufferno.
             * This causes the continuous filling and playing of the data buffer
             * again and again as long as the END push button is not pressed.
             * The wave file is going to keep on playing without any interruptions
             * util ther user selects the stop button.
             */
            if (ulBytesRead < MAXSIZE)
              {
               /* Seek to the starting of the wave file */
               mmioSeek(hmmioFileHandle, 0, SEEK_SET);

               /* Read the Next MAXSIZE bytes of the wave file */
               mmioRead(hmmioFileHandle,
                       (HPSTR) achDataBuffer[ulBufferNum],
                       MAXSIZE);


              }


      } /* End of for loop */


   } /* End of while loop */


}   /* End of function PlayThread */
LONG APIENTRY CONVProc( PVOID pmmioStr,
                        USHORT  usMsg,
                        LONG lParam1,
                        LONG lParam2 )

{
   PCONVPROCINFO pInfo;             // Converter I/O Procedure Info Block
   PMMIOINFO pmmioinfo;             // I/O information block
   MMIOINFO mmioinfoSS;             // I/O info block for Storage System
   PMMFORMATINFO pmmformatinfo;     // formatinfo for this ioproc.
   PCONVHEADERINFO pconvHeaderInfo; // pointer to header struct for FFT files.
   PSZ pszFileName;                 // file name passed in from caller
   PSZ pszFormatString;             // format string to return.
   PSZ pszData;
   CHAR szHeaderLength[2];          // storage for header length (USHORT)
   PCHAR pTemp;                     // temp pointer for use in Header manip.
   HFILE hFileHandle;               // file handle created or passed in
   HMMIO hmmioSS;                   // handle for Storage System
   FOURCC fccStorageSystem;         // SS I/O Proc FOURCC
   USHORT usReturnCode;             // return code from mmioClose
   ULONG ulReturnCode;              // return code from mmio API calls
   LONG lReturnCode;                // return code from mmio API calls
   LONG lBytesCopied;               // num of bytes of format string.
   LONG lBytesRead;                 // return from mmioRead
   LONG lBytesWritten;              // return from mmioWrite
   LONG lHeaderLength;              // storage for CONV header length input
   LONG lFilePosition;              // return from mmioSeek
   LONG lSavedFilePosition;         // saved LFP for the file.
   ULONG ulTempFlags;               // temp flags for flags to be removed.

   /*
    *  Initalize local file handle and Return Codes.
    */

   hFileHandle = 0L;
   ulReturnCode = 0L;
   usReturnCode = 0;

   /*
    * Clear the error return before anything happens to insure valid results.
    */

   if (pmmioStr)
      {
      pmmioinfo = (PMMIOINFO) pmmioStr;
      pInfo = (PCONVPROCINFO) &pmmioinfo->aulInfo;
      pmmioinfo->ulErrorRet = MMIO_SUCCESS;
      }
   else
      {
      pmmioinfo = NULL;
      pInfo = NULL;
      }

   /*
    *  Route the MMIO message to the proper code handler.
    */

   switch( usMsg )
      {
      case MMIOM_OPEN:

         /*
          * Get the filename from parameter. Then create a File Format header
          * in memory since this message will use this structure.
          */

         pszFileName = (CHAR *)lParam1;
         pconvHeaderInfo =
            (PCONVHEADERINFO)HhpAllocBuffer( sizeof(CONVHEADERINFO), 0);
         if (!pconvHeaderInfo)
            {
            return (MMIO_ERROR);
            }

         /*
          * If no Storage System I/O proc was determined from mmioOpen,
          * either determine the SS from the name (CREATE case) or
          * search I/O proc list for SS type. If the file is being created
          * and the storage system cannot be determined from the name,
          * default the storage system to DOS.
          */

         if (!pmmioinfo->fccChildIOProc)
            {
            /*
             * Since no Storage system has been determined from mmioOpen, we
             * need to determine the Storage system from the filename. If
             * it cannot be determined from the name, since it's a create we
             * will default the storage system to DOS.
             */

            if (pmmioinfo->ulFlags & MMIO_CREATE)
               {
               if (mmioDetermineSSIOProc( pszFileName,
                                          pmmioinfo,
                                          &fccStorageSystem,
                                          NULL ))
                  {
                  fccStorageSystem = FOURCC_DOS;
                  }
               }
            else
               {

               /*
                * The file already exists, so we need to determine the storage
                * system by looping through all the SS I/O procs until the SS
                * is determined or it is not. If it is not then this file
                * cannot be opened, so return an error.
                */

               if (mmioIdentifyStorageSystem( pszFileName,
                                              pmmioinfo,
                                              &fccStorageSystem ))
                  {
                  return (MMIO_ERROR);
                  }
               }

            /*
             * Now we either have a SS, and if so assign it to the SS I/O
             * proc field of the pmmioinfo sent in, or we don't so return.
             */

            if (!fccStorageSystem)
               {
               return (MMIO_ERROR);
               }
            else
               {
               pmmioinfo->fccChildIOProc = fccStorageSystem;
               }
            }

         /*
          * We have the Storage System FOURCC so open the SS.
          * To set up the mmioOpen call to the storage system :
          *
          *  1. Initialize the mmioinfo passed in for the Storage System.
          *  2. Set fccIOProc to the Storage System FOURCC.
          *  3. Save the hmmcf handle in aulInfo[1] if sent in.
          *  4. IMPORTANT: Use flags sent in EXCEPT Buffered I/O flags.
          *     VERY IMPORTANT: Set the NOIDENTIFY flag before calling the
          *     mmioOpen below to avoid and endless loop.
          *  5. The open call will handle the DELETE flag.
          *  6. Use the name passed in to this I/O proc for the open because
          *     at this point the SS I/O proc will know how to deal with it.
          */

         memset( &mmioinfoSS, '\0', sizeof(MMIOINFO));
         mmioinfoSS.fccIOProc = pmmioinfo->fccChildIOProc;
         memmove( &mmioinfoSS.aulInfo, pmmioinfo->aulInfo,(4*sizeof(ULONG)));
         mmioinfoSS.ulFlags = pmmioinfo->ulFlags;

         ulTempFlags = (MMIO_CREATE|MMIO_READ|MMIO_WRITE|MMIO_READWRITE|
                        MMIO_COMPAT|MMIO_EXCLUSIVE|MMIO_DENYWRITE|
                        MMIO_DENYREAD|MMIO_DENYNONE|MMIO_DELETE|MMIO_VERTBAR|
                        MMIO_APPEND|MMIO_USE_TEMP|MMIO_RWMODE|MMIO_SHAREMODE|
                        MMIO_NOTRANSLATE|MMIO_TRANSLATEDATA|
                        MMIO_TRANSLATEHEADER);

         mmioinfoSS.ulFlags &= ulTempFlags;
         mmioinfoSS.ulFlags |= MMIO_NOIDENTIFY;

         hmmioSS = mmioOpen( pszFileName, &mmioinfoSS, mmioinfoSS.ulFlags );

         if (hmmioSS)
            {
            /*
             * Handle a DELETE request for the file format by returning
             * success if ( hmmio = TRUE = 1).
             */

            if (pmmioinfo->ulFlags & MMIO_DELETE)
               {
               return (MMIO_SUCCESS);
               }
            pInfo->hmmioSS = hmmioSS;
            }
         else
            {
            return (mmioinfoSS.ulErrorRet);
            }

         /*
          * Get the header for the file if it already exists and
          * store it with the MMIOINFO for the file.
          */

         if (!(pmmioinfo->ulFlags & MMIO_CREATE))
            {
            /*
             * Seek the file to the beginning to read in the header.
             */

            lFilePosition = mmioSeek( hmmioSS,
                                      0L,
                                      SEEK_SET );

            if (lFilePosition < 0L)
               {
               mmioClose( hmmioSS, 0L );
               return (MMIO_ERROR);
               }

            /*
             * Read the header of the file into the provided buffer for the
             * given length.
             */

            lBytesRead = mmioRead( hmmioSS,
                                   (PSZ)pconvHeaderInfo,
                                   sizeof(CONVHEADERINFO) );

            if (lBytesRead < 0L)
               {
               mmioClose( hmmioSS, 0L );
               return (MMIO_ERROR);
               }
            }
         else
            {
            /*
             * Make a new header for the file and write it to the beginning.
             */

            pconvHeaderInfo->ulHeaderLength = sizeof(CONVHEADERINFO);
            strcpy( pconvHeaderInfo->szHeaderText, HEADER_STRING );

            lFilePosition = mmioSeek( hmmioSS,
                                      0L,
                                      SEEK_SET );

            if (lFilePosition < 0L)
               {
               mmioClose( hmmioSS, 0L );
               return (MMIO_ERROR);
               }

            /*
             * Write the newly created header to the file.
             */

            lBytesWritten = mmioWrite( hmmioSS,
                                       (PSZ)pconvHeaderInfo,
                                       sizeof(CONVHEADERINFO) );

            if (lBytesWritten < 0L)
               {
               mmioClose( hmmioSS, 0L );
               return (MMIO_ERROR);
               }
            }

         pconvHeaderInfo->ulFlags = 0;
         pmmioinfo->pExtraInfoStruct = (PVOID)pconvHeaderInfo;

         /*
          * Seek the file past the header to allow reads/writes to occur
          * at the first byte of non-header data if the file already exists.
          */

         lReturnCode = mmioSeek( hmmioSS,
                                 sizeof(CONVHEADERINFO),
                                 SEEK_SET );

         if (lReturnCode >= 0L)
            {
            pmmioinfo->lLogicalFilePos = lReturnCode;
            }
         else
            {
            mmioClose( hmmioSS, 0L );
            return (lReturnCode);
            }

         return (0L);

         break;

      case MMIOM_READ:
         /*
          * Call the read API with the Storage System handle using the
          * parameters that have been passed in to this I/O proc.
          */

         lBytesRead = mmioRead( pInfo->hmmioSS,
                                (CHAR *) lParam1,
                                lParam2 );

         /*
          *  Check the return code and determine if read was successful.
          *  Read must return:
          *    -1 - an error occurred with mmioRead or somewhere internally.
          *     x - number of bytes actually read by mmioRead.
          */

         if ( lBytesRead < 0L )
            {
            return( -1L );
            }
         else
            {
            return( lBytesRead );
            }

         break;

      case MMIOM_WRITE:
         /*
          * Call the write API with the Storage System handle using the
          * parameters that have been passed in to this I/O proc.
          */

         lBytesWritten = mmioWrite( pInfo->hmmioSS,
                                    (CHAR *) lParam1,
                                    lParam2 );

         /*
          *  Check the return code and determine if write was successful.
          *  Write must return:
          *    -1 - an error occurred with mmioWrite or somewhere internally.
          *     x - number of bytes actually written by mmioWrite.
          */

         if ( lBytesWritten < 0L )
            {
            return( -1L );
            }
         else if ( lBytesWritten != lParam2 )
            {
            pmmioinfo->ulErrorRet = MMIOERR_CANNOTWRITE;
            return( lBytesWritten );
            }
         else
            {

            /*
             * Set the Flags field in the CONV header to show it was modified.
             */

            pconvHeaderInfo = (PCONVHEADERINFO)pmmioinfo->pExtraInfoStruct;

            if (pconvHeaderInfo)
               pconvHeaderInfo->ulFlags = CONV_MODIFIED_FILE;

            return( lBytesWritten );
            }

         break;

      case MMIOM_SEEK:
         /*
          * Call the seek API with the Storage System handle using the
          * parameters that have been passed in to this I/O proc.
          */

         lReturnCode = mmioSeek( pInfo->hmmioSS,
                                 lParam1,
                                 lParam2 );

         /*
          *  Check the return code and determine if seek was successful.
          *  Seek must return:
          *    -1 - an error occurred with mmioSeek or somewhere internally.
          *     x - new current file postion from the beginning of the file.
          */

         if ( lReturnCode < 0L )
            {
            return( -1L );
            }

         return( lReturnCode );

         break;

      case MMIOM_CLOSE:
            /*
             * If the CONV header structure was maintained in pExtraInfoStruct,
             * write it back to the beginning of the file.
             */

            if (((pmmioinfo->ulFlags & MMIO_WRITE) ||
                 (pmmioinfo->ulFlags & MMIO_READWRITE)) &&
                 (pmmioinfo->pExtraInfoStruct))

               {
               pconvHeaderInfo = (PCONVHEADERINFO)pmmioinfo->pExtraInfoStruct;

               lReturnCode = mmioSeek( pInfo->hmmioSS,
                                       0L,
                                       SEEK_SET );

               if (lReturnCode < 0L)
                  {
                  return (lReturnCode);
                  }

               ulReturnCode = mmioSetHeader( pmmioinfo->hmmio,
                                             (PVOID)pmmioinfo->pExtraInfoStruct,
                                             sizeof(CONVHEADERINFO),
                                             &lBytesWritten,
                                             0L, 0L );
               if (ulReturnCode)
                  {
                  return (ulReturnCode);
                  }
               }

            if (pmmioinfo->pExtraInfoStruct)
               HhpFreeBuffer((PBYTE)pmmioinfo->pExtraInfoStruct);

            /*
             * Call the close API with the Storage System handle using any
             * parameters that have been passed in to this I/O proc.
             */

            usReturnCode = mmioClose( pInfo->hmmioSS, 0L );
            return ((ULONG)usReturnCode);

         break;

      case MMIOM_IDENTIFYFILE:
         /*
          * Get the filename from parameter. Then create a File Format header
          * in memory since this message use this structure.
          */

         pszFileName = (CHAR *)lParam1;  // get the filename from parameter.

         pconvHeaderInfo =
            (PCONVHEADERINFO)HhpAllocBuffer( sizeof(CONVHEADERINFO), 0);

         if (!pconvHeaderInfo)
            {
            return (MMIO_ERROR);
            }

         hmmioSS = (HMMIO)lParam2;       // get the SS handle to the file.

         if ( !hmmioSS )
            {
            HhpFreeBuffer((PBYTE)pconvHeaderInfo);
            return (MMIO_ERROR);
            }
         else
            {

            /*
             * Seek the file to the beginning to read in the file header.
             */

            lFilePosition = mmioSeek( hmmioSS,
                                      0L,
                                      SEEK_SET );

            if (lFilePosition < 0L)
               {
               HhpFreeBuffer((PBYTE)pconvHeaderInfo);
               return (MMIO_ERROR);
               }

            /*
             * Compare convHeaderInfo.szHeaderText with text string defined
             * in the convproc.h header file.
             */

            lBytesRead = mmioRead( hmmioSS,
                                   (PSZ)pconvHeaderInfo,
                                   sizeof(CONVHEADERINFO) );

            if ( lBytesRead <= 0L )
               {
               HhpFreeBuffer((PBYTE)pconvHeaderInfo);
               return( -1L );
               }

            pTemp = (CHAR *)pconvHeaderInfo;
            pTemp += 2 * sizeof(ULONG);

            if (!strncmp( pTemp, HEADER_STRING, strlen(HEADER_STRING) ))
               {
               HhpFreeBuffer((PBYTE)pconvHeaderInfo);
               return( 0L );
               }
            else
               {
               HhpFreeBuffer((PBYTE)pconvHeaderInfo);
               return( -1L );
               }
            }

         break;

      case MMIOM_GETFORMATINFO:

         /*
          * Fill in the mmformatinfo for the CONVProc.
          */

         pmmformatinfo = (PMMFORMATINFO)lParam1;

         if (pmmformatinfo == NULL)
            {
            return( -1L );
            }

         pmmformatinfo->ulStructLen = sizeof(MMFORMATINFO);
         pmmformatinfo->fccIOProc = FOURCC_FFT;
         pmmformatinfo->ulIOProcType = MMIO_IOPROC_FILEFORMAT;
         pmmformatinfo->ulMediaType = MMIO_MEDIATYPE_OTHER;
         pmmformatinfo->ulFlags = MMIO_CANREADUNTRANSLATED      |
                                  MMIO_CANWRITEUNTRANSLATED     |
                                  MMIO_CANREADWRITEUNTRANSLATED |
                                  MMIO_CANSEEKUNTRANSLATED;

         memset( pmmformatinfo->szDefaultFormatExt,  '\0',
            sizeof(pmmformatinfo->szDefaultFormatExt)  );
         strcpy( pmmformatinfo->szDefaultFormatExt,  "FFT" );

         if (convhlpGetNLSData( &pmmformatinfo->ulCodePage,
                                &pmmformatinfo->ulLanguage ))
            {
            return( -1L );
            }

         if (convhlpGetFormatStringLength( FOURCC_FFT,
                                           &(pmmformatinfo->lNameLength) ))
            {
            return( -1L );
            }

         return( 0L );
         break;

      case MMIOM_GETFORMATNAME:

         /*
          * The string is in a resource file (CONVPROC.RC) for NLS purposes.
          */

         pszFormatString = (CHAR *)lParam1;

         lBytesCopied = convhlpGetFormatString( FOURCC_FFT,
                                                pszFormatString,
                                                lParam2 );

         return( lBytesCopied );
         break;

      case MMIOM_QUERYHEADERLENGTH:

         /*
          * Save current file position for later restore. Then
          * seek the file to the beginning to read in the header.
          */

         lSavedFilePosition = pmmioinfo->lLogicalFilePos;

         lFilePosition = mmioSeek( pInfo->hmmioSS,
                                   0L,
                                   SEEK_SET );

         if (lFilePosition < 0L)
            {
            return (0L);
            }

         /*
          * Read in the header length for the file. It is the first 4 bytes.
          */

         lBytesRead = mmioRead( pInfo->hmmioSS,
                                szHeaderLength,
                                sizeof(ULONG) );

         lReturnCode = mmioSeek( pInfo->hmmioSS,
                                 lSavedFilePosition,
                                 SEEK_SET );

         if (lReturnCode != lSavedFilePosition)
            {
            return (0L);
            }

         if (lBytesRead <= 0L)
            {
            return (0L);
            }
         else
            {
            lHeaderLength = (LONG)(*((LONG *)szHeaderLength));
            return (lHeaderLength);
            }

         break;

      case MMIOM_GETHEADER:

         /*
          * Save current file position for later restore. Then
          * seek the file to the beginning to read in the header.
          */

         lSavedFilePosition = pmmioinfo->lLogicalFilePos;

         lFilePosition = mmioSeek( pInfo->hmmioSS,
                                   0L,
                                   SEEK_SET );

         if (lFilePosition < 0L)
            {
            return (0L);
            }

         /*
          * Read the header of the file into the provided buffer for the
          * given length. Then seek the file back to the saved position.
          */

         lBytesRead = mmioRead( pInfo->hmmioSS,
                                (CHAR *)lParam1,
                                lParam2 );

         lReturnCode = mmioSeek( pInfo->hmmioSS,
                                 lSavedFilePosition,
                                 SEEK_SET );

         if (lReturnCode != lSavedFilePosition)
            {
            return (0L);
            }

         if (lBytesRead <= 0L)
            {
            return (0L);
            }
         else
            {
            return (lBytesRead);
            }

         break;

      case MMIOM_SETHEADER:

         /*
          * Save current file position for later restore. Then
          * seek the file to the beginning to read in the header.
          */

         lSavedFilePosition = pmmioinfo->lLogicalFilePos;

         lFilePosition = mmioSeek( pInfo->hmmioSS,
                                   0L,
                                   SEEK_SET );

         if (lFilePosition < 0L)
            {
            return (0L);
            }

         /*
          * Write the entire header to the file. Then seek the file back
          * to the saved file position.
          */

         lBytesWritten = mmioWrite( pInfo->hmmioSS,
                                    (CHAR *)lParam1,
                                    lParam2 );

         lReturnCode = mmioSeek( pInfo->hmmioSS,
                                 lSavedFilePosition,
                                 SEEK_SET );

         if (lReturnCode != lSavedFilePosition)
            {
            return (0L);
            }

         if (lBytesWritten <= 0L)
            {
            return (0L);
            }
         else
            {
            return (lBytesWritten);
            }

         break;

      case CONVM_TOUPPER:

         pszData = (CHAR *)lParam1;
         convhlpToUpper( (PUCHAR)pszData );
         return (MMIO_SUCCESS);

         break;

      case CONVM_TOLOWER:

         pszData = (CHAR *)lParam1;
         convhlpToLower( (PUCHAR)pszData );
         return (MMIO_SUCCESS);

         break;

      default:

         /*
          * If an IO Proc has a child IO Proc, then instead of
          * returning UNSUPPORTED_MESSAGE, send the message to
          * the child IO Proc to see if it can understand and
          * process the message.
          *
          * Since message is unexpected, need to check for valid
          * pointers.
          */

         if (pInfo)
            {
            if (pInfo->hmmioSS)
               {
               lReturnCode = ( mmioSendMessage( pInfo->hmmioSS,
                                                usMsg,
                                                lParam1,
                                                lParam2 ));
           
               if (!lReturnCode)
                   pmmioinfo->ulErrorRet = mmioGetLastError(pInfo->hmmioSS);
               return (lReturnCode);
               }
            }
          else
            {
            if (pmmioinfo)
                pmmioinfo->ulErrorRet = MMIOERR_UNSUPPORTED_MESSAGE;
            }

          return (MMIOERR_UNSUPPORTED_MESSAGE);

      }

}
示例#15
0
int main(int argc, char* argv[])
{
//    LPWSTR szFileName;//声音文件名
    MMCKINFO mmckinfoParent;
    MMCKINFO mmckinfoSubChunk;
    DWORD dwFmtSize;
    HMMIO m_hmmio;//音频文件句柄
    DWORD m_WaveLong;
    HPSTR lpData;//音频数据
    HANDLE m_hData=NULL;
    HANDLE m_hFormat;
    WAVEFORMATEX * lpFormat;
    DWORD m_dwDataOffset;
    DWORD m_dwDataSize;
    WAVEHDR pWaveOutHdr;
    WAVEOUTCAPS pwoc;
    HWAVEOUT hWaveOut;
    int SoundOffset=0;
    int SoundLong=0;
    int DevsNum;
    //打开波形文件
    if(!(m_hmmio=mmioOpen(argv[1],NULL,MMIO_READ|MMIO_ALLOCBUF)))
    {
    //File open Error
        printf("Failed to open the file.");//错误处理函数
        return false;
    }
    //检查打开文件是否是声音文件
    mmckinfoParent.fccType =mmioFOURCC('W','A','V','E');
    if(mmioDescend(m_hmmio,(LPMMCKINFO)&mmckinfoParent,NULL,MMIO_FINDRIFF))
    {
        printf("NOT WAVE FILE AND QUIT");
        return 0;
    }
    //寻找 'fmt' 块
    mmckinfoSubChunk.ckid =mmioFOURCC('f','m','t',' ');
    if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))
    {
        printf("Can't find 'fmt' chunk");
        return 0;
    }
    //获得 'fmt '块的大小,申请内存
    dwFmtSize=mmckinfoSubChunk.cksize ;
    m_hFormat=LocalAlloc(LMEM_MOVEABLE,LOWORD(dwFmtSize));
    if(!m_hFormat)
    {
        printf("failed alloc memory");
        return 0;
    }
    lpFormat=(WAVEFORMATEX*)LocalLock(m_hFormat);
    if(!lpFormat)
    {
        printf("failed to lock the memory");
        return 0;
    }
    if((unsigned long)mmioRead(m_hmmio,(HPSTR)lpFormat,dwFmtSize)!=dwFmtSize)
    {
        printf("failed to read format chunk");
        return 0;
    }
    //离开 fmt 块
    mmioAscend(m_hmmio,&mmckinfoSubChunk,0);
    //寻找 'data' 块
    mmckinfoSubChunk.ckid=mmioFOURCC('d','a','t','a');
    if(mmioDescend(m_hmmio,&mmckinfoSubChunk,&mmckinfoParent,MMIO_FINDCHUNK))
    {
        printf("Can't find 'data' chunk");
        return 0;
    }
    //获得 'data'块的大小
    m_dwDataSize=mmckinfoSubChunk.cksize ;
    m_dwDataOffset =mmckinfoSubChunk.dwDataOffset ;
    if(m_dwDataSize==0L)
    {
        printf("no data in the 'data' chunk");
        return 0;
    }
    //为音频数据分配内存
    lpData=new char[m_dwDataSize];
    if(!lpData)
    {
        printf("\ncan not alloc mem");
        return 0;
    }
    if(mmioSeek(m_hmmio,m_dwDataOffset,SEEK_SET)<0)
    {
        printf("Failed to read the data chunk");
        return 0;
    }
//    m_WaveLong=mmioRead(m_hmmio,lpData,SoundLong);
    m_WaveLong=mmioRead(m_hmmio,lpData,m_dwDataSize);
   
    if(m_WaveLong<0)
    {
        printf("Failed to read the data chunk");
        return 0;
    }
    //检查音频设备,返回音频输出设备的性能
    if(waveOutGetDevCaps(WAVE_MAPPER,&pwoc,sizeof(WAVEOUTCAPS))!=0)
    {
        printf("Unable to allocate or lock memory");
        return 0;
    }

    //检查音频输出设备是否能播放指定的音频文件
    DevsNum = WAVE_MAPPER;
    if(waveOutOpen(&hWaveOut,DevsNum,lpFormat,NULL,NULL,CALLBACK_NULL)!=0)
    {
        printf("Failed to OPEN the wave out devices");
//        return 0;
    }
    //准备待播放的数据
    pWaveOutHdr.lpData =(HPSTR)lpData;
    pWaveOutHdr.dwBufferLength =m_WaveLong;
    pWaveOutHdr.dwFlags =0;
	pWaveOutHdr.dwLoops = 10;
    if(waveOutPrepareHeader(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)
    {
        printf("Failed to prepare the wave data buffer");
        return 0;
    }
	printFlags(pWaveOutHdr.dwFlags, "after [waveOutPrepareHeader]");

	pWaveOutHdr.dwFlags |= (WHDR_BEGINLOOP | WHDR_ENDLOOP);
    //播放音频数据文件
    if(waveOutWrite(hWaveOut,&pWaveOutHdr,sizeof(WAVEHDR))!=0)
    {
        printf("Failed to write the wave data buffer");
        return 0;
    }
	printFlags(pWaveOutHdr.dwFlags, "after [waveOutWrite]");
    //关闭音频输出设备,释放内存
//     printf("\npress any key");
//     getchar();
	Sleep(20000);
	printFlags(pWaveOutHdr.dwFlags, "after [Sleep]");

	if(waveOutUnprepareHeader(hWaveOut, &pWaveOutHdr, sizeof(pWaveOutHdr)) != 0)
	{
		printf("Failed to unPrepare the wave data buffer");
        return 0;
	}
	printFlags(pWaveOutHdr.dwFlags, "after [waveOutUnprepareHeader]");

    waveOutReset(hWaveOut);
	printFlags(pWaveOutHdr.dwFlags, "after [waveOutReset]");

    waveOutClose(hWaveOut);
	printFlags(pWaveOutHdr.dwFlags, "after [waveOutClose]");

    LocalUnlock(m_hFormat);
    LocalFree(m_hFormat);
    delete [] lpData;

    return 0;
}
示例#16
0
static DWORD WINAPI proc_PlaySound(LPVOID arg)
{
    WINE_PLAYSOUND*     wps = arg;
    BOOL		bRet = FALSE;
    HMMIO		hmmio = 0;
    MMCKINFO		ckMainRIFF;
    MMCKINFO        	mmckInfo;
    LPWAVEFORMATEX      lpWaveFormat = NULL;
    HWAVEOUT		hWave = 0;
    LPWAVEHDR		waveHdr = NULL;
    INT			count, bufsize, left, index;
    struct playsound_data	s;
    void*               data;

    s.hEvent = 0;

    TRACE("SoundName=%s !\n", debugstr_w(wps->pszSound));

    /* if resource, grab it */
    if ((wps->fdwSound & SND_RESOURCE) == SND_RESOURCE) {
        static const WCHAR wszWave[] = {'W','A','V','E',0};
        HRSRC	hRes;
        HGLOBAL	hGlob;

        if ((hRes = FindResourceW(wps->hMod, wps->pszSound, wszWave)) == 0 ||
            (hGlob = LoadResource(wps->hMod, hRes)) == 0)
            goto errCleanUp;
        if ((data = LockResource(hGlob)) == NULL) {
            FreeResource(hGlob);
            goto errCleanUp;
        }
        FreeResource(hGlob);
    } else
        data = (void*)wps->pszSound;

    /* construct an MMIO stream (either in memory, or from a file */
    if (wps->fdwSound & SND_MEMORY)
    { /* NOTE: SND_RESOURCE has the SND_MEMORY bit set */
	MMIOINFO	mminfo;

	memset(&mminfo, 0, sizeof(mminfo));
	mminfo.fccIOProc = FOURCC_MEM;
	mminfo.pchBuffer = data;
	mminfo.cchBuffer = -1; /* FIXME: when a resource, could grab real size */
	TRACE("Memory sound %p\n", data);
	hmmio = mmioOpenW(NULL, &mminfo, MMIO_READ);
    }
    if (!hmmio && wps->fdwSound & SND_ALIAS)
    {
        if ((wps->fdwSound & SND_ALIAS_ID) == SND_ALIAS_ID)
        {
            static const WCHAR  wszSystemAsterisk[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0};
            static const WCHAR  wszSystemDefault[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t',0};
            static const WCHAR  wszSystemExclamation[] = {'S','y','s','t','e','m','E','x','c','l','a','m','a','t','i','o','n',0};
            static const WCHAR  wszSystemExit[] = {'S','y','s','t','e','m','E','x','i','t',0};
            static const WCHAR  wszSystemHand[] = {'S','y','s','t','e','m','H','a','n','d',0};
            static const WCHAR  wszSystemQuestion[] = {'S','y','s','t','e','m','Q','u','e','s','t','i','o','n',0};
            static const WCHAR  wszSystemStart[] = {'S','y','s','t','e','m','S','t','a','r','t',0};
            static const WCHAR  wszSystemWelcome[] = {'S','y','s','t','e','m','W','e','l','c','o','m','e',0};

            wps->fdwSound &= ~(SND_ALIAS_ID ^ SND_ALIAS);
            if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMASTERISK)
                wps->pszSound = wszSystemAsterisk;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMDEFAULT)
                wps->pszSound = wszSystemDefault;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXCLAMATION)
                wps->pszSound = wszSystemExclamation;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMEXIT)
                wps->pszSound = wszSystemExit;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMHAND)
                wps->pszSound = wszSystemHand;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMQUESTION)
                wps->pszSound = wszSystemQuestion;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMSTART)
                wps->pszSound = wszSystemStart;
            else if (wps->pszSound == (LPCWSTR)SND_ALIAS_SYSTEMWELCOME)
                wps->pszSound = wszSystemWelcome;
            else goto errCleanUp;
        }
        hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
        if (!hmmio)
        {
            wps->fdwSound &= ~SND_ALIAS;
            wps->fdwSound |= SND_FILENAME;
        }
    }
    if (!hmmio && wps->fdwSound & SND_FILENAME)
    {
        hmmio = get_mmioFromFile(wps->pszSound);
    }
    if (!(wps->fdwSound & (SND_FILENAME|SND_ALIAS|SND_MEMORY)))
    {
        if ((hmmio = get_mmioFromProfile(wps->fdwSound | SND_NODEFAULT, wps->pszSound)) == 0)
        {
            if ((hmmio = get_mmioFromFile(wps->pszSound)) == 0)
            {
                hmmio = get_mmioFromProfile(wps->fdwSound, wps->pszSound);
            }
        }
    }
    if (hmmio == 0) goto errCleanUp;

    if (mmioDescend(hmmio, &ckMainRIFF, NULL, 0))
	goto errCleanUp;

    TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
	  (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);

    if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
	(ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E')))
	goto errCleanUp;

    mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
	goto errCleanUp;

    TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
	  (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);

    lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
    if (!lpWaveFormat)
	goto errCleanUp;
    if (mmioRead(hmmio, (HPSTR)lpWaveFormat, mmckInfo.cksize) < sizeof(PCMWAVEFORMAT))
	goto errCleanUp;

    TRACE("wFormatTag=%04X !\n", 	lpWaveFormat->wFormatTag);
    TRACE("nChannels=%d\n", 		lpWaveFormat->nChannels);
    TRACE("nSamplesPerSec=%d\n", 	lpWaveFormat->nSamplesPerSec);
    TRACE("nAvgBytesPerSec=%d\n", 	lpWaveFormat->nAvgBytesPerSec);
    TRACE("nBlockAlign=%d\n", 		lpWaveFormat->nBlockAlign);
    TRACE("wBitsPerSample=%u !\n", 	lpWaveFormat->wBitsPerSample);

    /* move to end of 'fmt ' chunk */
    mmioAscend(hmmio, &mmckInfo, 0);

    mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
    if (mmioDescend(hmmio, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK))
	goto errCleanUp;

    TRACE("Chunk Found ckid=%.4s fccType=%08x cksize=%08X\n",
	  (LPSTR)&mmckInfo.ckid, mmckInfo.fccType, mmckInfo.cksize);

    s.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    if (!s.hEvent || bPlaySoundStop)
	goto errCleanUp;

    if (waveOutOpen(&hWave, WAVE_MAPPER, lpWaveFormat, (DWORD_PTR)PlaySound_Callback,
		    (DWORD_PTR)&s, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
	goto errCleanUp;

    /* make it so that 3 buffers per second are needed */
    bufsize = (((lpWaveFormat->nAvgBytesPerSec / 3) - 1) / lpWaveFormat->nBlockAlign + 1) *
	lpWaveFormat->nBlockAlign;
    waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
    if (!waveHdr)
	goto errCleanUp;
    waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
    waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
    waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
    waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
    waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
    waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
    if (waveOutPrepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
	waveOutPrepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR))) {
	goto errCleanUp;
    }

    wps->hWave = hWave;
    s.dwEventCount = 1L; /* for first buffer */
    index = 0;

    do {
	left = mmckInfo.cksize;

	mmioSeek(hmmio, mmckInfo.dwDataOffset, SEEK_SET);
	while (left)
        {
	    if (bPlaySoundStop)
            {
		wps->bLoop = FALSE;
		break;
	    }
	    count = mmioRead(hmmio, waveHdr[index].lpData, min(bufsize, left));
	    if (count < 1) break;
	    left -= count;
	    waveHdr[index].dwBufferLength = count;
	    if (waveOutWrite(hWave, &waveHdr[index], sizeof(WAVEHDR)) == MMSYSERR_NOERROR) {
                index ^= 1;
                PlaySound_WaitDone(&s);
            }
            else {
		ERR("Aborting play loop, waveOutWrite error\n");
		wps->bLoop = FALSE;
		break;
	    }
	}
	bRet = TRUE;
    } while (wps->bLoop);

    PlaySound_WaitDone(&s); /* to balance first buffer */
    waveOutReset(hWave);

    waveOutUnprepareHeader(hWave, &waveHdr[0], sizeof(WAVEHDR));
    waveOutUnprepareHeader(hWave, &waveHdr[1], sizeof(WAVEHDR));

errCleanUp:
    TRACE("Done playing=%s => %s!\n", debugstr_w(wps->pszSound), bRet ? "ok" : "ko");
    HeapFree(GetProcessHeap(), 0, lpWaveFormat);
    if (hWave)
    {
        EnterCriticalSection(&WINMM_cs);
        /* the CS prevents a concurrent waveOutReset */
        wps->hWave = 0;
        LeaveCriticalSection(&WINMM_cs);
        while (waveOutClose(hWave) == WAVERR_STILLPLAYING)
            Sleep(100);
    }
    CloseHandle(s.hEvent);
    HeapFree(GetProcessHeap(), 0, waveHdr);
    if (hmmio) 		mmioClose(hmmio, 0);

    PlaySound_Free(wps);

    return bRet;
}
/* ------------------------------------------------------------------------------------ */
int StreamingAudio::Create(char *szFileName)
{
	int nError = 0;

	if(CCD->GetLogging())
	{
		char szDebug[512];
		sprintf(szDebug, "[INFO] Loaded %s", szFileName);
		CCD->ReportError(szDebug, false);
	}

	// Sanity check parameters
	if(szFileName == NULL)
		return RGF_FAILURE;										// Wrong.

// changed RF064
	int len = strlen(szFileName)-4;
	if(stricmp((szFileName+len),".mp3") == 0)
	{
		if(Mpeg3 != NULL)
			return RGF_FAILURE;
		Mpeg3 = new CMp3Manager;
		Mpeg3->OpenMediaFile(szFileName);
		mp3 = true;
		m_fActive = true;

		// start a timer for this stream.

		MMRESULT nTimer = timeSetEvent(125, 5, &TimerFunction, (DWORD)this,
										TIME_PERIODIC | TIME_CALLBACK_FUNCTION);

		if(nTimer == NULL)
		{
			CCD->ReportError("[WARNING] StreamingAudio: Timer callback set-up failed", false);
			return RGF_FAILURE;									// Timer startup failed.
		}

		m_nTimerID = nTimer;					// Save timer ID
		return RGF_SUCCESS;
	}

	mp3 = false;

	if(stricmp((szFileName+len), ".ogg") == 0)
	{
		if(Ogg != NULL)
			return RGF_FAILURE;

		Ogg = new OggAudio(m_pDS);
		Ogg->Load(szFileName);
		ogg = true;
		m_fActive = true;
		return RGF_SUCCESS;
	}

	ogg = false;

	//	start a timer for this stream.
	MMRESULT nTimer = timeSetEvent(125, 5, &TimerFunction, (DWORD)this,
						TIME_PERIODIC | TIME_CALLBACK_FUNCTION);

	if(nTimer == NULL)
	{
		CCD->ReportError("[WARNING] StreamingAudio: Timer callback set-up failed", false);
		return RGF_FAILURE;									// Timer startup failed.
	}

	m_nTimerID = nTimer;									// Save timer ID
// end change RF064

	//	Check for stream availability
	if(m_pStream != NULL)
		return RGF_FAILURE;									// Already loaded!

	// Open up the WAVE file.
	nError = WaveOpen(szFileName, &m_hWaveFile, &m_pWaveFormat,	&m_rRiffData);

	if(nError != RGF_SUCCESS)
	{
		char szBug[128];
		sprintf(szBug, "[WARNING] File %s - Line %d: Failed to open wave file '%s'\n(Note: streamig audio can't be placed in VFS)",
				__FILE__, __LINE__, szFileName);
		CCD->ReportError(szBug, false);
		return RGF_FAILURE;									// Problem here, too!
	}

	// Get current position in file, which will be the start of the
	// ..WAVE data.
	m_nDataPosition = mmioSeek(m_hWaveFile, 0, SEEK_CUR);
	m_nDataSize = m_rRiffData.cksize;						// Save data size

	// Fetch DirectSound interface we want
	LPDIRECTSOUND pDSIF;
	nError = m_pDS->QueryInterface(IID_IDirectSound, (LPVOID *)&pDSIF);

	// Create a DSound buffer to stream into
	DSBUFFERDESC theDesc;

	memset(&theDesc, 0, sizeof(DSBUFFERDESC));
	theDesc.dwSize = sizeof(DSBUFFERDESC);
	theDesc.dwBufferBytes = kBufferSize;
	theDesc.lpwfxFormat = m_pWaveFormat;
	theDesc.dwFlags = DSBCAPS_CTRLVOLUME;

	nError = pDSIF->CreateSoundBuffer(&theDesc, &m_pStream, NULL);

	pDSIF->Release();									// Done w/ this.

	if(nError != 0)										// Error!  Sick out.
	{
		char szBug[128];
		sprintf(szBug, "StreamingAudio: Failed to create buffer for '%s'\n", szFileName);
		OutputDebugString(szBug);
		mmioClose(m_hWaveFile, 0);
		m_hWaveFile = NULL;
		delete m_pWaveFormat;
		m_pWaveFormat = NULL;
		return RGF_FAILURE;
	}

	m_nOffset = 0;								// Start at top of buffer
// changed RF064
	//m_fActive = true;							// Set as active
// end change RF064
	PumpWave(kBufferSize);				// Initial buffer load

	return RGF_SUCCESS;
}
示例#18
0
文件: mmio.c 项目: hoangduit/reactos
/**************************************************************************
 * 				mmioDescend         	[WINMM.@]
 */
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck,
                            const MMCKINFO* lpckParent, UINT uFlags)
{
    DWORD		dwOldPos;
    FOURCC		srchCkId;
    FOURCC		srchType;

    TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);

    if (lpck == NULL)
	return MMSYSERR_INVALPARAM;

    dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
    TRACE("dwOldPos=%d\n", dwOldPos);

    if (lpckParent != NULL) {
	TRACE("seek inside parent at %d !\n", lpckParent->dwDataOffset);
	/* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
	if (dwOldPos < lpckParent->dwDataOffset ||
	    dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
	    WARN("outside parent chunk\n");
	    return MMIOERR_CHUNKNOTFOUND;
	}
    }

    /* The SDK docu says 'ckid' is used for all cases. Real World
     * examples disagree -Marcus,990216.
     */

    srchCkId = 0;
    srchType = 0;

    /* find_chunk looks for 'ckid' */
    if (uFlags & MMIO_FINDCHUNK)
	srchCkId = lpck->ckid;

    /* find_riff and find_list look for 'fccType' */
    if (uFlags & MMIO_FINDLIST)
    {
	srchCkId = FOURCC_LIST;
        srchType = lpck->fccType;
    }

    if (uFlags & MMIO_FINDRIFF)
    {
	srchCkId = FOURCC_RIFF;
        srchType = lpck->fccType;
    }

    TRACE("searching for %4.4s.%4.4s\n",
          (LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any");

    while (TRUE)
    {
        LONG ix;

        ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
        if (ix < 2*sizeof(DWORD))
        {
            mmioSeek(hmmio, dwOldPos, SEEK_SET);
            WARN("return ChunkNotFound\n");
            return MMIOERR_CHUNKNOTFOUND;
        }

        lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
        TRACE("ckid=%4.4s fcc=%4.4s cksize=%08X !\n",
              (LPCSTR)&lpck->ckid,
              srchType ? (LPCSTR)&lpck->fccType:"<na>",
              lpck->cksize);
        if ( (!srchCkId || (srchCkId == lpck->ckid)) &&
             (!srchType || (srchType == lpck->fccType)) )
            break;

        dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
        mmioSeek(hmmio, dwOldPos, SEEK_SET);
    }

    lpck->dwFlags = 0;
    /* If we were looking for RIFF/LIST chunks, the final file position
     * is after the chunkid. If we were just looking for the chunk
     * it is after the cksize. So add 4 in RIFF/LIST case.
     */
    if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
	mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
    else
    {
	mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
	lpck->fccType = 0;
    }
    TRACE("lpck: ckid=%.4s, cksize=%d, dwDataOffset=%d fccType=%08X (%.4s)!\n",
	  (LPSTR)&lpck->ckid, lpck->cksize, lpck->dwDataOffset,
	  lpck->fccType, srchType?(LPSTR)&lpck->fccType:"");
    return MMSYSERR_NOERROR;
}
示例#19
0
STDMETHODIMP CAVIFileRemote::Open(LPCSTR szFile, UINT mode, LPCOLESTR lpszFileName) {
	HMMIO hmmio = NULL;
	MMCKINFO mmiriff, mmi;
	MMRESULT mmerr;
	HRESULT final = S_OK;

	_RPT2(0,"CAVIFileRemote::Open(\"%s\", %08lx)\n", szFile, mode);

	if (pafTunnel) {
		pafTunnel->Release();
		pafTunnel = NULL;
	}

	if (mode & (OF_CREATE|OF_WRITE)) {
		IPersistFile *ppf;

		if (FAILED(CoCreateInstance(CLSID_AVIFile, NULL, CLSCTX_INPROC_SERVER, another_IID_IAVIFile, (void **)&pafTunnel)))
			return (HRESULT)E_FAIL;

		if (FAILED(pafTunnel->QueryInterface(IID_IPersistFile, (void **)&ppf)))
			return (HRESULT)E_FAIL;

		HRESULT hr = ppf->Load(lpszFileName, mode);

		ppf->Release();

		return hr;
	}

	if (!(hmmio = mmioOpen((char *)szFile, NULL, MMIO_READ)))
		return E_FAIL;

	_RPT0(0,"File opened.\n");

	// RIFF <size> VDRM { PATH <remote-path> }

	try {
		char buf[16];

		_RPT0(0,"Checking for Avisynth signature...\n");

		if (16==mmioRead(hmmio, buf, 16)) {
			buf[9] = 0;
			if (!_stricmp(buf, "#avisynth")) {

				mmioClose(hmmio, 0);

				// Hand it off to the Avisynth handler.

				IPersistFile *ppf;

				// Okay, it's not one of our files.  Now try passing it off
				// to the regular AVI handler!

				_RPT0(0,"Attempt avisynth tunnel create\n");

				if (FAILED(CoCreateInstance(CLSID_Avisynth, NULL, CLSCTX_INPROC_SERVER, another_IID_IAVIFile, (void **)&pafTunnel)))
					return (HRESULT)E_FAIL;

				_RPT0(0,"Attempt avisynth tunnel query -> IPersistFile\n");

				if (FAILED(pafTunnel->QueryInterface(IID_IPersistFile, (void **)&ppf)))
					return (HRESULT)E_FAIL;

				_RPT0(0,"Attempt avisynth tunnel load\n");

				HRESULT hr = ppf->Load(lpszFileName, mode);

				ppf->Release();

				return hr;
			}
		}

		mmioSeek(hmmio, 0, SEEK_SET);

		_RPT0(0,"Attempting to find 'VDRM'...\n");

		mmiriff.fccType = 'MRDV';
		mmerr = mmioDescend(hmmio, &mmiriff, NULL, MMIO_FINDRIFF);
		if (mmerr == MMIOERR_CHUNKNOTFOUND) {
			IPersistFile *ppf;

			mmioClose(hmmio, 0);

			// Okay, it's not one of our files.  Now try passing it off
			// to the regular AVI handler!

			_RPT0(0,"Attempt tunnel create\n");

			if (FAILED(CoCreateInstance(CLSID_AVIFile, NULL, CLSCTX_INPROC_SERVER, another_IID_IAVIFile, (void **)&pafTunnel)))
				return (HRESULT)E_FAIL;

			_RPT0(0,"Attempt tunnel query -> IPersistFile\n");

			if (FAILED(pafTunnel->QueryInterface(IID_IPersistFile, (void **)&ppf)))
				return (HRESULT)E_FAIL;

			_RPT0(0,"Attempt tunnel load\n");

			HRESULT hr = ppf->Load(lpszFileName, mode);

			ppf->Release();

			return hr;
		}

		else if (mmerr != MMSYSERR_NOERROR) throw (HRESULT)E_FAIL;

		_RPT0(0,"Attempting to find 'PATH'...\n");
		mmi.ckid = 'HTAP';
		mmerr = mmioDescend(hmmio, &mmi, &mmiriff, MMIO_FINDCHUNK);
		if (mmerr == MMIOERR_CHUNKNOTFOUND) throw (HRESULT)E_FAIL;
		else if (mmerr != MMSYSERR_NOERROR) throw (HRESULT)E_FAIL;

		_RPT0(0,"Allocate path memory...\n");
		if (!(szPath = new char[mmi.cksize+1]))
			throw (HRESULT)E_OUTOFMEMORY;

		szPath[mmi.cksize]=0;

		_RPT0(0,"Read in path...\n");

		if ((LONG)mmi.cksize != mmioRead(hmmio, szPath, mmi.cksize))
			throw (HRESULT)E_FAIL;

		_RPT1(0,"File parsed, remote-path: [%s]\n", szPath);

		// now attempt to open the link

		ivdsl = GetDubServerInterface();
		if (!ivdsl) throw (HRESULT)E_FAIL;

		_RPT0(0,"Have dub server interface.\n");

		ivdac = ivdsl->FrameServerConnect(szPath);
		if (!ivdac) throw (HRESULT)E_FAIL;

		// retrieve streaminfo and format information

		_RPT0(0,"Connected to frameserver.\n");

		fHasAudio = ivdac->hasAudio();

		_RPT0(0,"Reading video stream info...\n");

		if (!ivdac->readStreamInfo(&vStreamInfo, FALSE, &vSampleFirst, &vSampleLast))
			throw (HRESULT)E_FAIL;

		_RPT0(0,"Reading video format length...\n");

		if ((vFormatLen = ivdac->readFormat(NULL, FALSE))<=0)
			throw (HRESULT)E_FAIL;

		_RPT1(0,"Allocating video format (%ld bytes)...\n", vFormatLen);

		if (!(vFormat = (BITMAPINFOHEADER *)malloc(vFormatLen)))
			throw (HRESULT)E_OUTOFMEMORY;

		_RPT0(0,"Reading video format...\n");

		if (ivdac->readFormat(vFormat, FALSE)<=0)
			throw (HRESULT)E_FAIL;

		if (fHasAudio) {
			_RPT0(0,"Reading audio stream info...\n");

			if (!ivdac->readStreamInfo(&aStreamInfo, TRUE, &aSampleFirst, &aSampleLast))
				throw (HRESULT)E_FAIL;

			_RPT0(0,"Reading audio format length...\n");

			if ((aFormatLen = ivdac->readFormat(NULL, TRUE))<=0)
				throw (HRESULT)E_FAIL;

			_RPT1(0,"Allocating audio format (%ld bytes)...\n", aFormatLen);

			if (!(aFormat = (WAVEFORMATEX *)malloc(aFormatLen)))
				throw (HRESULT)E_OUTOFMEMORY;

			_RPT0(0,"Reading audio format...\n");

			if (ivdac->readFormat(aFormat, TRUE)<=0)
				throw (HRESULT)E_FAIL;
		}

	} catch(HRESULT res) {
		_RPT0(0,"*** failed!\n");

		final = res;
	}
示例#20
0
文件: Wave.cpp 项目: mygaldre/mmvari
void __fastcall CWaveStrage::Seek(int n)
{
	mmioSeek(m_Handle, n, SEEK_SET);
	m_pos = n;
}
示例#21
0
int WaveCopyUselessChunks( 
HMMIO *phmmioIn, 
MMCKINFO *pckIn, 
MMCKINFO *pckInRiff, 
HMMIO *phmmioOut, 
MMCKINFO *pckOut, 
MMCKINFO *pckOutRiff) 
{ 
	int nError; 

	nError = 0; 

	// First seek to the stinking start of the file, not including the riff header... 

	if ((nError = mmioSeek(*phmmioIn, pckInRiff->dwDataOffset + sizeof(FOURCC), SEEK_SET)) == -1) 
	{ 
		nError = ER_CANNOTREAD; 
		goto ERROR_IN_PROC; 
	} 

	nError = 0; 

	while (mmioDescend(*phmmioIn, pckIn, pckInRiff, 0) == 0) 
	{ 
		// quickly check for corrupt RIFF file--don't ascend past end! 

		if ((pckIn->dwDataOffset + pckIn->cksize) > (pckInRiff->dwDataOffset + pckInRiff->cksize)) 
			goto ERROR_IN_PROC; 

		switch (pckIn->ckid) 
		{ 
			// explicitly skip these... 

			case mmioFOURCC('f', 'm', 't', ' '): 
			break; 

			case mmioFOURCC('d', 'a', 't', 'a'): 
			break; 

			case mmioFOURCC('f', 'a', 'c', 't'): 
			break; 

			case mmioFOURCC('J', 'U', 'N', 'K'): 
			break; 

			case mmioFOURCC('P', 'A', 'D', ' '): 
			break; 

			case mmioFOURCC('c', 'u', 'e', ' '): 
			break; 

			// copy chunks that are OK to copy 

			case mmioFOURCC('p', 'l', 's', 't'): 

			// although without the 'cue' chunk, it doesn't make much sense 

			riffCopyChunk(*phmmioIn, *phmmioOut, pckIn); 
			break; 

			case mmioFOURCC('D', 'I', 'S', 'P'): 
			riffCopyChunk(*phmmioIn, *phmmioOut, pckIn); 
			break; 

			// don't copy unknown chunks 
			default: 
			break; 
		} 

		// step up to prepare for next chunk.. 

		mmioAscend(*phmmioIn, pckIn, 0); 
	} 

ERROR_IN_PROC: 
	{ 
		int nErrorT; 

		// Seek back to riff header

		nErrorT = mmioSeek(*phmmioIn, pckInRiff->dwDataOffset + sizeof(FOURCC), SEEK_SET); 
	} 

	return(nError); 
} 
示例#22
0
static void test_mmioOpen(char *fname)
{
    char buf[MMIO_DEFAULTBUFFER];
    MMRESULT ret;
    HMMIO hmmio;
    MMIOINFO mmio;

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = sizeof(buf);
    mmio.pchBuffer = buf;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ);
    if (fname && !hmmio)
    {
        skip("%s file is missing, skipping the test\n", fname);
        return;
    }
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == sizeof(buf), "got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer);
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = 0;
    mmio.pchBuffer = buf;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 0, "expected 0, got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer);
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = 0;
    mmio.pchBuffer = NULL;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 0, "expected 0, got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer == NULL, "expected NULL\n");
    ok(mmio.pchNext == NULL, "expected NULL\n");
    ok(mmio.pchEndRead == NULL, "expected NULL\n");
    ok(mmio.pchEndWrite == NULL, "expected NULL\n");
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = 256;
    mmio.pchBuffer = NULL;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 256, "expected 256, got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer != NULL, "expected not NULL\n");
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = sizeof(buf);
    mmio.pchBuffer = buf;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == sizeof(buf), "got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer);
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = 0;
    mmio.pchBuffer = NULL;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == MMIO_DEFAULTBUFFER, "expected MMIO_DEFAULTBUFFER, got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer != NULL, "expected not NULL\n");
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = 256;
    mmio.pchBuffer = NULL;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF);
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 256, "expected 256, got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer != NULL, "expected not NULL\n");
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    mmioClose(hmmio, 0);

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = 0;
    mmio.pchBuffer = buf;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF);
    if (!hmmio && mmio.wErrorRet == ERROR_BAD_FORMAT)
    {
        /* Seen on Win9x, WinMe but also XP-SP1 */
        skip("Some Windows versions don't like a 0 size and a given buffer\n");
        return;
    }
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == MMIO_DEFAULTBUFFER, "expected MMIO_DEFAULTBUFFER, got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer);
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);

    mmioClose(hmmio, 0);
}
示例#23
0
int SoundEvent::PlaySound(char *filenames,int newbuffer, double offset)
{
    HMMIO m_hmmio;
    HRESULT hr;

    TRACESETUP("PLAYSOUND");

	if(newbuffer)
	{

	m_hmmio = mmioOpen( filenames, NULL, MMIO_ALLOCBUF | MMIO_READ );

	if( NULL == m_hmmio )
	{
		TRACE ("DIRECT SOUND ERROR MMIOOPEN");
		return (false);
	}

    MMCKINFO        ckIn;           // chunk info. for general use.
    PCMWAVEFORMAT   pcmWaveFormat;  // Temp PCM structure to load in.

	WAVEFORMATEX* m_pwfx;        // Pointer to WAVEFORMATEX structure
    MMCKINFO      m_ck;          // Multimedia RIFF chunk
    MMCKINFO      m_ckRiff;      // Use in opening a WAVE file
    DWORD         m_dwSize;      // The size of the wave file
    MMIOINFO      m_mmioinfoOut;
    DWORD         m_dwFlags;

#define WAVEFILE_READ   1
#define WAVEFILE_WRITE  2
	
	
	   m_pwfx = NULL;

    if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) )
	{
        TRACE ("DIRECT SOUND ERROR MMIODESCEND");
		return (false);
	}

    // Check to make sure this is a valid wave file
    if( (m_ckRiff.ckid != FOURCC_RIFF) ||
        (m_ckRiff.fccType != mmioFOURCC('W', 'A', 'V', 'E') ) )
	{
		return(false);
        TRACE ("DIRECT SOUND ERROR MMIOFOURCC");
	}

    // Search the input file for for the 'fmt ' chunk.
    ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) )
	{
        TRACE("DIRECT SOUND ERROR MMIDESCENT FIND CHUNK");
		return(false);
	}

    // Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
    // if there are extra parameters at the end, we'll ignore them
    if( ckIn.cksize < (LONG) sizeof(PCMWAVEFORMAT) )
	{
        TRACE ("DIRECT SOUND ERROR CHUNKSIZE");
		return(false);
	}

    // Read the 'fmt ' chunk into <pcmWaveFormat>.
    if( mmioRead( m_hmmio, (HPSTR) &pcmWaveFormat,
                  sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat) )
	{
        TRACE ("DIRECT SOUND ERROR MMIOREAD");
		return(false);
	}

    // Allocate the waveformatex, but if its not pcm format, read the next
    // word, and thats how many extra bytes to allocate.
    if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
    {
        m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) ];
        if( NULL == m_pwfx )
		{
            TRACE("DIRECT SOUND ERROR ALLOC");
			return(false);
		}

        // Copy the bytes from the pcm structure to the waveformatex structure
        memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
        m_pwfx->cbSize = 0;
    }
    else
    {
        // Read in length of extra bytes.
        WORD cbExtraBytes = 0L;
        if( mmioRead( m_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD) )
		{
            TRACE ("DIRECT SOUND ERROR M_HMMIO");
			return(false);
		}

        m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) + cbExtraBytes ];
        if( NULL == m_pwfx )
		{
            TRACE("DIRECT SOUND ERREOR ALLOC 2");
			return(false);
		}

        // Copy the bytes from the pcm structure to the waveformatex structure
        memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
        m_pwfx->cbSize = cbExtraBytes;

        // Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
        if( mmioRead( m_hmmio, (CHAR*)(((BYTE*)&(m_pwfx->cbSize))+sizeof(WORD)),
                      cbExtraBytes ) != cbExtraBytes )
        {
            //SAFE_DELETE( m_pwfx );
            TRACE("DIRECT SOUND ERROR MMIOREAD2");
			return(false);
        }
    }

    // Ascend the input file out of the 'fmt ' chunk.
    if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) )
    {
        //SAFE_DELETE( m_pwfx );
        TRACE("DIRECT SOUND ERROR MMIOASCEND");
		return(false);
    }

	TRACE("DIRECTSOUND READMMIO OK");



    m_dwFlags = WAVEFILE_READ;

        if( m_dwFlags == WAVEFILE_READ )
        {
            // Seek to the data
            if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC),
                            SEEK_SET ) )
			{
                TRACE ("DIRECT SOUND ERROR MMIOSEEK");
				return(false);
			}

            // Search the input file for the 'data' chunk.
            m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a');
            if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
			{
                 TRACE ("DIRECT SOUND ERROR MMIODESCEND");
				 return(false);
			}
        }
        else
        {
            // Create the 'data' chunk that holds the waveform samples.
            m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a');
            m_ck.cksize = 0;

            if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
			{
                TRACE("DIRECT SOUND ERROR MMIOCREATECHUNK");
				return(false);
			}

            if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
			{
                TRACE ("DIRECT SOUND ERROR MMMIOGETINFO");
				return(false);
			}
		}
  

	TRACE("DIRECTSOUND RESETFILE OK");

 
    // After the reset, the size of the wav file is m_ck.cksize so store it now
    m_dwSize = m_ck.cksize;


    char buffers[80];

	TRACE ("DIRECTSOUND TAILLE BUFFER");
	sprintf(buffers,"%d", m_dwSize);
	TRACE (buffers);


    DWORD                dwDSBufferSize = NULL;



    apDSBuffer = new LPDIRECTSOUNDBUFFER[1];
    if( apDSBuffer == NULL )
    {
        TRACE("ERROR DIRECTSOUND NEW BUFFER");
		return(false);
    }

    // Make the DirectSound buffer the same size as the wav file
    dwDSBufferSize = m_dwSize;

    // Create the direct sound buffer, and only request the flags needed
    // since each requires some overhead and limits if the buffer can
    // be hardware accelerated
    DSBUFFERDESC dsbd2;
    ZeroMemory( &dsbd2, sizeof(DSBUFFERDESC) );
    dsbd2.dwSize          = sizeof(DSBUFFERDESC);
    dsbd2.dwFlags         = 0;
    dsbd2.dwBufferBytes   = dwDSBufferSize;
    dsbd2.guid3DAlgorithm = GUID_NULL;
    dsbd2.lpwfxFormat     = m_pwfx;

TRACE ("APPEL CREATE SOUND BUFFER");

    // DirectSound is only guarenteed to play PCM data.  Other
    // formats may or may not work depending the sound card driver.
    hr = m_pDS->CreateSoundBuffer( &dsbd2, &apDSBuffer[0], NULL );
    if (hr != DS_OK)
	    TRACE ("ERROR DIRECTSOUND CREATE SOUND BUFFER")
	else TRACE("DIRECTSOUND CREATE SOUND BUFFER OK");


	

    // Make sure we have focus, and we didn't just switch in from
    // an app which had a DirectSound device

//    hr = RestoreBuffer( &apDSBuffer[0], NULL );
//    if (hr != DS_OK)
//	    TRACE ("ERROR DIRECTSOUND RESTORE SOUND BUFFER")
//	else TRACE("DIRECTSOUND RESTORE SOUND BUFFER OK");



    // Lock the buffer down
    hr = apDSBuffer[0]->Lock( 0, m_dwSize,
                     &pDSLockedBuffer, &dwDSLockedBufferSize,
                     NULL, NULL, 0L );
    if (hr != DS_OK)
		 TRACE ("ERROR DIRECTSOUND LOCK")
	else TRACE ("DIRECTSOUND LOCK OK");

    // Reset the wave file to the beginning


    // Seek to the data
    if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC),
                            SEEK_SET ) )
         TRACE ("ERROR DIRECTSOUND MMIOSEEK")
	else TRACE ("DIRECTSOUND MMIOSSEEK OK");

    // Search the input file for the 'data' chunk.
    m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a');
    if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
         TRACE ("ERROR DIRECTSOUND MMIODESCEND")
	else TRACE ("DIRECTSOUND MMIODESCEND OK");



    MMIOINFO mmioinfoIn; // current status of m_hmmio
    DWORD   dwWavDataRead        = 0;    // Amount of data read from the wav file


    dwWavDataRead = 0;

    if( 0 != mmioGetInfo( m_hmmio, &mmioinfoIn, 0 ) )
         TRACE ("ERROR DIRECTSOUND MMIOGETINFO")
	else TRACE ("DIRECTSOUND MMIOGETINFO OK");
        

    UINT cbDataIn = m_dwSize;
    if( cbDataIn > m_ck.cksize )
        cbDataIn = m_ck.cksize;

    m_ck.cksize -= cbDataIn;

    for( DWORD cT = 0; cT < cbDataIn; cT++ )
    {
            // Copy the bytes from the io to the buffer.
            if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
            {
                if( 0 != mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ ) )
                         TRACE ("ERROR DIRECTSOUND MMIOADVANCE")
                  	else /* TRACE ("DIRECTSOUND MMIOADVANCE OK")*/;


                if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
                     TRACE ("ERROR DIRECTSOUND READ FIC")
	            else /* TRACE ("DIRECTSOUND READ FIC OK") */;
            }

            // Actual copy.
            *((BYTE*)pDSLockedBuffer+cT) = *((BYTE*)mmioinfoIn.pchNext);
            mmioinfoIn.pchNext++;
    }

    if( 0 != mmioSetInfo( m_hmmio, &mmioinfoIn, 0 ) )
           TRACE ("ERROR DIRECTSOUND MMIOSETINFO")
	  else TRACE ("DIRECTSOUND MMIOSETINFO OK");

    mmioClose( m_hmmio, 0 );

    dwWavDataRead = cbDataIn;
    } // end of newbuffer part


//  Unlock the buffer, we don't need it anymore.
//  apDSBuffer[0]->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );


    if (offset > 0.)
    {
         DWORD curplay,curwrite;
		 char buffers[80];

         apDSBuffer[0]->GetCurrentPosition(&curplay,&curwrite);
         sprintf(buffers, "POS CURPLAY AVT %d", curplay);
         TRACE(buffers);

         curplay = DWORD (offset * 8000.);
	     hr = apDSBuffer[0]->SetCurrentPosition(curplay);
         if (hr != DS_OK)
		     TRACE ("ERROR DIRECTSOUND SETCURRENT")
	     else TRACE ("DIRECTSOUND SETCURRENT OK");

         apDSBuffer[0]->GetCurrentPosition(&curplay,&curwrite);
         sprintf(buffers, "POS CURPLAY APS %d", curplay);
         TRACE(buffers);
	}
示例#24
0
static void test_mmioSetBuffer(char *fname)
{
    char buf[256];
    MMRESULT ret;
    HMMIO hmmio;
    MMIOINFO mmio;

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = sizeof(buf);
    mmio.pchBuffer = buf;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ);
    if (fname && !hmmio)
    {
        skip("%s file is missing, skipping the test\n", fname);
        return;
    }
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == sizeof(buf), "got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer);
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    if (mmio.fccIOProc == FOURCC_DOS)
        ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    else
        ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);

    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = mmioSetBuffer(hmmio, NULL, 0, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 0, "got not 0\n");
    ok(mmio.pchBuffer == NULL, "got not NULL buf\n");
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite);
#if 0 /* remove once passes under Wine */
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);
#endif

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    ret = mmioSetBuffer(hmmio, NULL, 0, MMIO_ALLOCBUF);
    ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 0, "got not 0\n");
    ok(mmio.pchBuffer == NULL, "got not NULL buf\n");
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite);
#if 0 /* remove once passes under Wine */
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);
#endif

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    ret = mmioSetBuffer(hmmio, buf, 0, MMIO_ALLOCBUF);
    ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 0, "got not 0\n");
    ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer);
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite);
#if 0 /* remove once passes under Wine */
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);
#endif

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    ret = mmioSetBuffer(hmmio, NULL, 256, MMIO_WRITE|MMIO_ALLOCBUF);
    ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret);

    memset(&mmio, 0, sizeof(mmio));
    ret = mmioGetInfo(hmmio, &mmio, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret);
    ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags);
    ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet);
    ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc);
    ok(mmio.cchBuffer == 256, "got %u\n", mmio.cchBuffer);
    ok(mmio.pchBuffer != NULL, "expected not NULL\n");
    ok(mmio.pchBuffer != buf, "expected != buf\n");
    ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext);
    ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", buf, mmio.pchEndRead);
    ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite);
#if 0 /* remove once passes under Wine */
    ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset);
    ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset);
#endif

#if 0 /* remove once passes under Wine */
    ret = mmioSeek(hmmio, 0, SEEK_CUR);
    ok(ret == 0, "expected 0, got %d\n", ret);
#endif

    mmioClose(hmmio, 0);
}
示例#25
0
文件: mmio16.c 项目: bilboed/wine
/**************************************************************************
 * 				mmioSeek       		[MMSYSTEM.1214]
 */
LONG WINAPI mmioSeek16(HMMIO16 hmmio, LONG lOffset, INT16 iOrigin)
{
    return mmioSeek(HMMIO_32(hmmio), lOffset, iOrigin);
}
示例#26
0
static void test_mmioDescend(char *fname)
{
    MMRESULT ret;
    HMMIO hmmio;
    MMIOINFO mmio;
    MMCKINFO ckRiff, ckList, ck, ckList2;

    memset(&mmio, 0, sizeof(mmio));
    mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM;
    mmio.cchBuffer = sizeof(RIFF_buf);
    mmio.pchBuffer = (char *)RIFF_buf;
    hmmio = mmioOpen(fname, &mmio, MMIO_READ);
    if (fname && !hmmio)
    {
        skip("%s file is missing, skipping the test\n", fname);
        return;
    }
    ok(hmmio != 0, "mmioOpen error %u\n", mmio.wErrorRet);

    expect_buf_offset(hmmio, 0);

    /* first normal RIFF AVI parsing */
    ret = mmioDescend(hmmio, &ckRiff, NULL, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckRiff.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ckRiff.ckid);
    ok(ckRiff.fccType == formtypeAVI, "wrong fccType: %04x\n", ckRiff.fccType);
    ok(ckRiff.dwDataOffset == 8, "expected 8 got %u\n", ckRiff.dwDataOffset);
    trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n",
          (LPCSTR)&ckRiff.ckid, ckRiff.cksize, (LPCSTR)&ckRiff.fccType,
          ckRiff.dwDataOffset, ckRiff.dwFlags);

    expect_buf_offset(hmmio, 12);

    ret = mmioDescend(hmmio, &ckList, &ckRiff, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ckList.ckid);
    ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ckList.fccType);
    ok(ckList.dwDataOffset == 20, "expected 20 got %u\n", ckList.dwDataOffset);
    trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n",
          (LPCSTR)&ckList.ckid, ckList.cksize, (LPCSTR)&ckList.fccType,
          ckList.dwDataOffset, ckList.dwFlags);

    expect_buf_offset(hmmio, 24);

    ret = mmioDescend(hmmio, &ck, &ckList, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == ckidAVIMAINHDR, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == 0, "wrong fccType: %04x\n", ck.fccType);
    trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n",
          (LPCSTR)&ck.ckid, ck.cksize, (LPCSTR)&ck.fccType,
          ck.dwDataOffset, ck.dwFlags);

    expect_buf_offset(hmmio, 32);

    /* Skip chunk data */
    ret = mmioSeek(hmmio, ck.cksize, SEEK_CUR);
    ok(ret == 0x58, "expected 0x58, got %#x\n", ret);

    ret = mmioDescend(hmmio, &ckList2, &ckList, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckList2.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ckList2.ckid);
    ok(ckList2.fccType == listtypeSTREAMHEADER, "wrong fccType: %04x\n", ckList2.fccType);
    trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n",
          (LPCSTR)&ckList2.ckid, ckList2.cksize, (LPCSTR)&ckList2.fccType,
          ckList2.dwDataOffset, ckList2.dwFlags);

    expect_buf_offset(hmmio, 100);

    ret = mmioDescend(hmmio, &ck, &ckList2, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == ckidSTREAMHEADER, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == 0, "wrong fccType: %04x\n", ck.fccType);
    trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n",
          (LPCSTR)&ck.ckid, ck.cksize, (LPCSTR)&ck.fccType,
          ck.dwDataOffset, ck.dwFlags);

    expect_buf_offset(hmmio, 108);

    /* test various mmioDescend flags */

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ck.ckid = 0;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ck.fccType = 0;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, 0);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType);

    /* do NOT seek, use current file position */
    memset(&ck, 0x66, sizeof(ck));
    ck.fccType = 0;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDLIST);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ck.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ck.ckid = 0;
    ck.fccType = listtypeAVIHEADER;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType);

    /* do NOT seek, use current file position */
    memset(&ck, 0x66, sizeof(ck));
    ck.ckid = FOURCC_LIST;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ck.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ck.ckid = FOURCC_RIFF;
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType);

    /* do NOT seek, use current file position */
    memset(&ckList, 0x66, sizeof(ckList));
    ckList.ckid = 0;
    ret = mmioDescend(hmmio, &ckList, &ck, MMIO_FINDCHUNK);
    ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret);
    ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ckList.ckid);
    ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ckList.fccType);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);
    ok(ck.ckid != 0x66666666, "wrong ckid: %04x\n", ck.ckid);
    ok(ck.fccType != 0x66666666, "wrong fccType: %04x\n", ck.fccType);
    ok(ck.dwDataOffset != 0x66666666, "wrong dwDataOffset: %04x\n", ck.dwDataOffset);

    mmioSeek(hmmio, 0, SEEK_SET);
    memset(&ck, 0x66, sizeof(ck));
    ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF);
    ok(ret == MMIOERR_CHUNKNOTFOUND ||
       ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret);

    mmioClose(hmmio, 0);
}
示例#27
0
文件: wavfile.c 项目: UIKit0/wine-1
static HRESULT AVIFILE_LoadSunFile(IAVIFileImpl *This)
{
  SUNAUDIOHEADER auhdr;

  mmioSeek(This->hmmio, 0, SEEK_SET);
  if (mmioRead(This->hmmio, (HPSTR)&auhdr, sizeof(auhdr)) != sizeof(auhdr))
    return AVIERR_FILEREAD;

  if (auhdr.fccType == 0x0064732E) {
    /* header in little endian */
    This->ckData.dwDataOffset = LE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = LE2H_DWORD(auhdr.size);

    auhdr.encoding   = LE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = LE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = LE2H_DWORD(auhdr.channels);
  } else if (auhdr.fccType == mmioFOURCC('.','s','n','d')) {
    /* header in big endian */
    This->ckData.dwDataOffset = BE2H_DWORD(auhdr.offset);
    This->ckData.cksize       = BE2H_DWORD(auhdr.size);

    auhdr.encoding   = BE2H_DWORD(auhdr.encoding);
    auhdr.sampleRate = BE2H_DWORD(auhdr.sampleRate);
    auhdr.channels   = BE2H_DWORD(auhdr.channels);
  } else
    return AVIERR_FILEREAD;

  if (auhdr.channels < 1)
    return AVIERR_BADFORMAT;

  /* get size of header */
  switch(auhdr.encoding) {
  case AU_ENCODING_ADPCM_G721_32:
    This->cbFormat = sizeof(G721_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G723_24:
    This->cbFormat = sizeof(G723_ADPCMWAVEFORMAT); break;
  case AU_ENCODING_ADPCM_G722:
  case AU_ENCODING_ADPCM_G723_5:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED; /* FIXME */
  default:
    This->cbFormat = sizeof(WAVEFORMATEX); break;
  };

  This->lpFormat = HeapAlloc(GetProcessHeap(), 0, This->cbFormat);
  if (This->lpFormat == NULL)
    return AVIERR_MEMORY;

  This->lpFormat->nChannels      = auhdr.channels;
  This->lpFormat->nSamplesPerSec = auhdr.sampleRate;
  switch(auhdr.encoding) {
  case AU_ENCODING_ULAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_MULAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_PCM_16:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 16;
    break;
  case AU_ENCODING_PCM_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 24;
    break;
  case AU_ENCODING_PCM_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_PCM;
    This->lpFormat->wBitsPerSample = 32;
    break;
  case AU_ENCODING_ALAW_8:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_ALAW;
    This->lpFormat->wBitsPerSample = 8;
    break;
  case AU_ENCODING_ADPCM_G721_32:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G721_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = sizeof(WORD);
    ((LPG721_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  case AU_ENCODING_ADPCM_G723_24:
    This->lpFormat->wFormatTag     = WAVE_FORMAT_G723_ADPCM;
    This->lpFormat->wBitsPerSample = (3*5*8);
    This->lpFormat->nBlockAlign    = 15*15*8;
    This->lpFormat->cbSize         = 2*sizeof(WORD);
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->cbExtraSize   = 0;
    ((LPG723_ADPCMWAVEFORMAT)This->lpFormat)->nAuxBlockSize = 0;
    break;
  default:
    WARN("unsupported Sun audio format %d\n", auhdr.encoding);
    return AVIERR_UNSUPPORTED;
  };

  This->lpFormat->nBlockAlign =
    (This->lpFormat->nChannels * This->lpFormat->wBitsPerSample) / 8;
  if (This->lpFormat->nBlockAlign == 0 && This->lpFormat->wBitsPerSample < 8)
    This->lpFormat->nBlockAlign++;
  This->lpFormat->nAvgBytesPerSec =
    This->lpFormat->nBlockAlign * This->lpFormat->nSamplesPerSec;

  This->fDirty = FALSE;

  This->sInfo.fccType               = streamtypeAUDIO;
  This->sInfo.fccHandler            = 0;
  This->sInfo.dwFlags               = 0;
  This->sInfo.wPriority             = 0;
  This->sInfo.wLanguage             = 0;
  This->sInfo.dwInitialFrames       = 0;
  This->sInfo.dwScale               = This->lpFormat->nBlockAlign;
  This->sInfo.dwRate                = This->lpFormat->nAvgBytesPerSec;
  This->sInfo.dwStart               = 0;
  This->sInfo.dwLength              =
    This->ckData.cksize / This->lpFormat->nBlockAlign;
  This->sInfo.dwSuggestedBufferSize = This->sInfo.dwLength;
  This->sInfo.dwSampleSize          = This->lpFormat->nBlockAlign;

  This->fInfo.dwStreams = 1;
  This->fInfo.dwScale   = 1;
  This->fInfo.dwRate    = This->lpFormat->nSamplesPerSec;
  This->fInfo.dwLength  =
    MulDiv(This->ckData.cksize, This->lpFormat->nSamplesPerSec,
	   This->lpFormat->nAvgBytesPerSec);

  return AVIERR_OK;
}
示例#28
0
// Open
BOOL WaveFile::Open (LPSTR pszFilename)
{
	int done = FALSE;
	WORD cbExtra = 0;
	BOOL fRtn = SUCCESS;    // assume success
	PCMWAVEFORMAT pcmwf;
	char fullpath[_MAX_PATH];

	m_total_uncompressed_bytes_read = 0;
	m_max_uncompressed_bytes_to_read = AS_HIGHEST_MAX;

	int FileSize, FileOffset;

	if ( !cf_find_file_location(pszFilename, CF_TYPE_ANY, fullpath, &FileSize, &FileOffset ))	{
		goto OPEN_ERROR;
	}

	cfp = mmioOpen(fullpath, NULL, MMIO_ALLOCBUF | MMIO_READ);
	if ( cfp == NULL ) {
		goto OPEN_ERROR;
	}

	// Skip the "RIFF" tag and file size (8 bytes)
	// Skip the "WAVE" tag (4 bytes)
	mmioSeek( cfp, 12+FileOffset, SEEK_SET );

	// Now read RIFF tags until the end of file
	uint tag, size, next_chunk;

	while(done == FALSE)	{
		if ( mmioRead(cfp, (char *)&tag, sizeof(uint)) != sizeof(uint) )
			break;

		if ( mmioRead(cfp, (char *)&size, sizeof(uint)) != sizeof(uint) )
			break;

		next_chunk = mmioSeek( cfp, 0, SEEK_CUR );
		next_chunk += size;

		switch( tag )	{
		case 0x20746d66:		// The 'fmt ' tag
			mmioRead( cfp, (char *)&pcmwf, sizeof(PCMWAVEFORMAT) );
			if ( pcmwf.wf.wFormatTag != WAVE_FORMAT_PCM ) {
				mmioRead( cfp, (char *)&cbExtra, sizeof(short) );
			}

			// Allocate memory for WAVEFORMATEX structure + extra bytes
			if ( (m_pwfmt_original = (WAVEFORMATEX *) malloc ( sizeof(WAVEFORMATEX)+cbExtra )) != NULL ){
				Assert(m_pwfmt_original != NULL);
				// Copy bytes from temporary format structure
				memcpy (m_pwfmt_original, &pcmwf, sizeof(pcmwf));
				m_pwfmt_original->cbSize = cbExtra;

				// Read those extra bytes, append to WAVEFORMATEX structure
				if (cbExtra != 0) {
					mmioRead( cfp, (char *)((ubyte *)(m_pwfmt_original) + sizeof(WAVEFORMATEX)), cbExtra );
				}
			}
			else {
				Int3();		// malloc failed
				goto OPEN_ERROR;
			}	
			break;

		case 0x61746164:		// the 'data' tag
			m_nDataSize = size;	// This is size of data chunk.  Compressed if ADPCM.
			m_data_bytes_left = size;
			m_data_offset = mmioSeek( cfp, 0, SEEK_CUR);
			done = TRUE;
			break;

		default:	// unknown, skip it
			break;
		}	// end switch

		mmioSeek( cfp, next_chunk, SEEK_SET );
	}

  	// At this stage, examine source format, and set up WAVEFORATEX structure for DirectSound.
	// Since DirectSound only supports PCM, force this structure to be PCM compliant.  We will
	// need to convert data on the fly later if our souce is not PCM
	switch ( m_pwfmt_original->wFormatTag ) {
		case WAVE_FORMAT_PCM:
			m_wave_format = WAVE_FORMAT_PCM;
			m_wfmt.wBitsPerSample = m_pwfmt_original->wBitsPerSample;
			break;

		case WAVE_FORMAT_ADPCM:
			m_wave_format = WAVE_FORMAT_ADPCM;
			m_wfmt.wBitsPerSample = 16;
			break;

		default:
			nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n"));
			//Int3();
			goto OPEN_ERROR;
			break;

	} // end switch
            
	// Set up the WAVEFORMATEX structure to have the right PCM characteristics
	m_wfmt.wFormatTag = WAVE_FORMAT_PCM;
	m_wfmt.nChannels = m_pwfmt_original->nChannels;
	m_wfmt.nSamplesPerSec = m_pwfmt_original->nSamplesPerSec;
	m_wfmt.cbSize = 0;
	m_wfmt.nBlockAlign = (unsigned short)(( m_wfmt.nChannels * m_wfmt.wBitsPerSample ) / 8);
	m_wfmt.nAvgBytesPerSec = m_wfmt.nBlockAlign * m_wfmt.nSamplesPerSec;

	// Init some member data from format chunk
	m_nBlockAlign = m_pwfmt_original->nBlockAlign;
	m_nUncompressedAvgDataRate = m_wfmt.nAvgBytesPerSec;

	// Cue for streaming
	Cue ();
 
	// Successful open
	goto OPEN_DONE;
    
OPEN_ERROR:
	// Handle all errors here
	nprintf(("SOUND","SOUND ==> Could not open wave file %s for streaming\n",pszFilename));

	fRtn = FAILURE;
	if (cfp != NULL) {
		// Close file
		mmioClose( cfp, 0 );
		cfp = NULL;
	}
	if (m_pwfmt_original)
	{
		free(m_pwfmt_original);
		m_pwfmt_original = NULL;
	}

OPEN_DONE:
	return (fRtn);
}
示例#29
0
文件: wavfile.c 项目: UIKit0/wine-1
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start, LONG samples, void *buffer,
        LONG buffersize, LONG *bytesread, LONG *samplesread)
{
  IAVIFileImpl *This = impl_from_IAVIStream(iface);

  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? */
  if ((DWORD)buffersize < This->sInfo.dwSampleSize)
    return AVIERR_BUFFERTOOSMALL;

  buffersize = samples * This->sInfo.dwSampleSize;

  if (mmioSeek(This->hmmio, This->ckData.dwDataOffset
	       + start * This->sInfo.dwSampleSize, SEEK_SET) == -1)
    return AVIERR_FILEREAD;
  if (mmioRead(This->hmmio, buffer, buffersize) != buffersize)
    return AVIERR_FILEREAD;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = buffersize;
  if (samplesread != NULL)
    *samplesread = samples;  

  return AVIERR_OK;
}
示例#30
0
// Read
//
// Returns number of bytes actually read.
// 
//	Returns -1 if there is nothing more to be read.  This function can return 0, since
// sometimes the amount of bytes requested is too small for the ACM decompression to 
// locate a suitable block
int WaveFile::Read(BYTE *pbDest, UINT cbSize, int service)
{
	unsigned char	*dest_buf=NULL, *uncompressed_wave_data;
	int				rc, uncompressed_bytes_written;
	unsigned int	src_bytes_used, convert_len, num_bytes_desired=0, num_bytes_read;

//	nprintf(("Alan","Reqeusted: %d\n", cbSize));


	if ( service ) {
		uncompressed_wave_data = Wavedata_service_buffer;
	} else {
		uncompressed_wave_data = Wavedata_load_buffer;
	}

	switch ( m_wave_format ) {
		case WAVE_FORMAT_PCM:
			num_bytes_desired = cbSize;
			dest_buf = pbDest;
			break;

		case WAVE_FORMAT_ADPCM:
			if ( !m_hStream_open ) {
				if ( !ACM_stream_open(m_pwfmt_original, &m_wfxDest, (void**)&m_hStream), m_bits_per_sample_uncompressed  ) {
					m_hStream_open = 1;
				} else {
					Int3();
				}
			}

			num_bytes_desired = cbSize;
	
			if ( service ) {
				dest_buf = Compressed_service_buffer;
			} else {
				dest_buf = Compressed_buffer;
			}

			if ( num_bytes_desired <= 0 ) {
				num_bytes_desired = 0;
//				nprintf(("Alan","No bytes required for ADPCM time interval\n"));
			} else {
				num_bytes_desired = ACM_query_source_size((void*)m_hStream, cbSize);
//				nprintf(("Alan","Num bytes desired: %d\n", num_bytes_desired));
			}
			break;

		default:
			nprintf(("SOUND", "SOUND => Not supporting %d format for playing wave files\n"));
			Int3();
			break;

	} // end switch
                
	num_bytes_read = 0;
	convert_len = 0;
	src_bytes_used = 0;

	// read data from disk
	if ( m_data_bytes_left <= 0 ) {
		num_bytes_read = 0;
		uncompressed_bytes_written = 0;
		return -1;
	}

	if ( m_data_bytes_left > 0 && num_bytes_desired > 0 ) {
		int actual_read;

		if ( num_bytes_desired <= (unsigned int)m_data_bytes_left ) {
			num_bytes_read = num_bytes_desired;
		}
		else {
			num_bytes_read = m_data_bytes_left;
		}

		actual_read = mmioRead( cfp, (char *)dest_buf, num_bytes_read );
		if ( (actual_read <= 0) || (m_abort_next_read) ) {
			num_bytes_read = 0;
			uncompressed_bytes_written = 0;
			return -1;
		}

		if ( num_bytes_desired >= (unsigned int)m_data_bytes_left ) {
			m_abort_next_read = 1;			
		}

		num_bytes_read = actual_read;
	}

	// convert data if necessary, to PCM
	if ( m_wave_format == WAVE_FORMAT_ADPCM ) {
		if ( num_bytes_read > 0 ) {
				rc = ACM_convert((void*)m_hStream, dest_buf, num_bytes_read, uncompressed_wave_data, BIGBUF_SIZE, &convert_len, &src_bytes_used);
				if ( rc == -1 ) {
					goto READ_ERROR;
				}
				if ( convert_len == 0 ) {
					Int3();
				}
		}

		Assert(src_bytes_used <= num_bytes_read);
		if ( src_bytes_used < num_bytes_read ) {
			// seek back file pointer to reposition before unused source data
			mmioSeek(cfp, src_bytes_used - num_bytes_read, SEEK_CUR);
		}

		// Adjust number of bytes left
		m_data_bytes_left -= src_bytes_used;
		m_nBytesPlayed += src_bytes_used;
		uncompressed_bytes_written = convert_len;

		// Successful read, keep running total of number of data bytes read
		goto READ_DONE;
	}
	else {
		// Successful read, keep running total of number of data bytes read
		// Adjust number of bytes left
		m_data_bytes_left -= num_bytes_read;
		m_nBytesPlayed += num_bytes_read;
		uncompressed_bytes_written = num_bytes_read;
		goto READ_DONE;
	}
    
READ_ERROR:
	num_bytes_read = 0;
	uncompressed_bytes_written = 0;

READ_DONE:
	m_total_uncompressed_bytes_read += uncompressed_bytes_written;
//	nprintf(("Alan","Read: %d\n", uncompressed_bytes_written));
	return (uncompressed_bytes_written);
}