HMMIO PmmioOpen(LPSTR szFilename, LPMMIOINFO lpmmioinfo, DWORD dwOpenFlags) { HMMIO hmmio; // CHAR err[MAX_PATH]; hmmio = mmioOpen( szFilename, lpmmioinfo, dwOpenFlags); if (hmmio==NULL) { TRACE("%s open error!", szFilename ); //sprintf( err, "%s open error!", szFilename ); //AfxMessageBox(err); return NULL; } FILE *tp = fopen( szFilename, "rb" ); mmioSeek(hmmio, 0, SEEK_SET); fclose(tp); return hmmio; }
inAudioCapture(WAVEFORMATEX *pwfx=NULL,int samplingRate=44100) : timeElapsed(1),samplingRate(samplingRate),byteReady(false) { if(!pwfx) { waveFormatInit(); } else { this->pwfx = *pwfx; } data_size = this->samplingRate*timeElapsed; dataIn = new int[data_size]; initializeBuffer(); #if WRITEWAVE handle = mmioOpen("test.wav", 0, MMIO_CREATE | MMIO_WRITE); #endif }
int bmake(char *nom,void *adr,long len) { HMMIO fp; int r= -1; char nom2[200]; verifnom(nom,nom2); fp = mmioOpen(nom2,NULL,MMIO_WRITE|MMIO_CREATE); if (fp) { if (len==mmioWrite(fp,adr,len)) r=0; else r= -1; mmioClose(fp,NULL); } return(r); }
//----------------------------------------------------------------------------- // Name: WaveOpenFile() // Desc: This function will open a wave input file and prepare it for reading, // so the data can be easily read with WaveReadFile. Returns 0 if // successful, the error code if not. //----------------------------------------------------------------------------- HRESULT WaveOpenFile( CHAR* strFileName, HMMIO* phmmioIn, WAVEFORMATEX** ppwfxInfo, MMCKINFO* pckInRIFF ) { HRESULT hr; HMMIO hmmioIn = NULL; if( NULL == ( hmmioIn = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF|MMIO_READ ) ) ) return E_FAIL; if( FAILED( hr = ReadMMIO( hmmioIn, pckInRIFF, ppwfxInfo ) ) ) { mmioClose( hmmioIn, 0 ); return hr; } *phmmioIn = hmmioIn; return S_OK; }
void __fastcall CWaveFile::Rec(LPCSTR pName) { FileClose(); m_FileName = pName; GetFileName(m_Name, pName); m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_CREATE|MMIO_WRITE|MMIO_ALLOCBUF); if( m_Handle == NULL ){ ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'を作成できません.", pName); return; } m_Head[0] = 0x55; m_Head[1] = 0xaa; m_Head[2] = char(SAMPTYPE); m_Head[3] = 0; mmioWrite(m_Handle, (const char *)m_Head, 4); m_pos = 4; m_mode = 2; m_pause = 0; m_dis = 0; }
int bload(char *nom,void *adr,long offset,long len) { HMMIO fp; int r= -1; char nom2[200]; verifnom(nom,nom2); fp = mmioOpen(nom2,NULL,MMIO_READ); if (fp) { mmioSeek(fp, offset, SEEK_SET); if (len==mmioRead(fp,adr,len)) r=0; else r= -1; mmioClose(fp,NULL); } return(r); }
WaveFileHelper::WaveFileHelper(ff::IData *fullData) : _fullData(fullData) { if (_fullData && _fullData->GetSize()) { MMIOINFO info; ff::ZeroObject(info); info.fccIOProc = FOURCC_MEM; info.pchBuffer = (HPSTR)_fullData->GetMem(); info.cchBuffer = (LONG)_fullData->GetSize(); HMMIO hio = mmioOpen(nullptr, &info, MMIO_ALLOCBUF | MMIO_READ); assert(hio); if (hio) { verify(Read(hio)); mmioClose(hio, 0); } } }
//----------------------------------------------------------------------------- // Name: WaveOpenFile() // Desc: This routine will create a wave file for writing. This will // automatically overwrite any existing file with the same name //----------------------------------------------------------------------------- HRESULT WaveOpenFile( CHAR* strFileName, HMMIO* phmmioOut, WAVEFORMATEX* pwfxDest, MMCKINFO *pckOut, MMCKINFO *pckOutRIFF ) { HRESULT hr; HMMIO hmmioOut = NULL; if( NULL == ( hmmioOut = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE ) ) ) return E_FAIL; if( FAILED( hr = WriteMMIO( hmmioOut, pckOut, pckOutRIFF, pwfxDest ) ) ) { mmioClose( hmmioOut, 0 ); return hr; } *phmmioOut = hmmioOut; return S_OK; }
void CMmioEmbeddedFile::Open( UINT hFile, const char * pFileName ) { ASSERT_VALID( this ); if( m_hMmio != NULL ) Close(); MMIOINFO info; ( void )memset( &info, 0, sizeof( info ) ); info.fccIOProc = FOURCC_DOS; info.pchBuffer = NULL; info.adwInfo[ 0 ] = hFile; m_hMmio = mmioOpen( NULL, &info, MMIO_READ | MMIO_DENYWRITE | MMIO_ALLOCBUF ); m_sFileName = pFileName; // ThrowError exception if the open was // unsuccessful. if ( m_hMmio == NULL ) ThrowError( ERR_MMIO_OPEN ); }
void QFObjectRenderer::captureFrame(IString saveAsFileName, FOURCC ioProc) { HMMIO frameFile; MMIOINFO info = {0}; LONG bytesWritten; MMIMAGEHEADER header = {0}; PBYTE frameBuffer; ULONG scanLineBytes, scanLines; LONG errorCode; info.fccIOProc = ioProc; info.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA; errorCode = DiveBeginImageBufferAccess(dive, frame[currentColumn][currentRow], &frameBuffer, &scanLineBytes, &scanLines); header.ulHeaderLength = sizeof(MMIMAGEHEADER); header.ulContentType = MMIO_IMAGE_PHOTO; header.ulMediaType = MMIO_MEDIATYPE_IMAGE; header.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize = scanLineBytes * scanLines; /* Length of bitmap. */ header.mmXDIBHeader.XDIBHeaderPrefix.ulPelFormat = FOURCC_BGR3; /* FOURCC code defining the pel format. */ header.mmXDIBHeader.BMPInfoHeader2.cbFix = sizeof (BITMAPINFOHEADER2); header.mmXDIBHeader.BMPInfoHeader2.cx = movieSize().width(); header.mmXDIBHeader.BMPInfoHeader2.cy = movieSize().height(); header.mmXDIBHeader.BMPInfoHeader2.cPlanes = 1; /* Number of planes. */ header.mmXDIBHeader.BMPInfoHeader2.cBitCount = 24; /* Bits per pel. */ header.mmXDIBHeader.BMPInfoHeader2.ulCompression = BCA_UNCOMP; header.mmXDIBHeader.BMPInfoHeader2.cbImage = header.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize; header.mmXDIBHeader.BMPInfoHeader2.usRecording = BRA_BOTTOMUP; /* Must be BRA_BOTTOMUP. */ header.mmXDIBHeader.BMPInfoHeader2.usRendering = BRH_NOTHALFTONED; /* Not used. */ frameFile = mmioOpen(saveAsFileName, &info, MMIO_CREATE | MMIO_WRITE); mmioSetHeader(frameFile, &header, sizeof(MMIMAGEHEADER), &bytesWritten, 0, 0); mmioWrite(frameFile, frameBuffer, header.mmXDIBHeader.XDIBHeaderPrefix.ulMemSize); mmioClose(frameFile, 0); errorCode = DiveEndImageBufferAccess(dive, frame[currentColumn][currentRow]); }
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); }
/** メモリからの読み込み用にオープン * * @author SAM (T&GG, Org.)<*****@*****.**> * @date 2004/01/21 2:32:45 * Copyright (C) 2001,2002,2003,2004 SAM (T&GG, Org.). All rights reserved. */ HRslt WavFile::open(const void * const src, std::size_t size) { if(isOpen()) close(); flags_ = READ; HRslt hr; MMIOINFO mmioinfo; memset(&mmioinfo, 0, sizeof(mmioinfo)); mmioinfo.fccIOProc = FOURCC_MEM; mmioinfo.cchBuffer = (DWORD)size; mmioinfo.pchBuffer = const_cast<char *>(reinterpret_cast<const char *>(src)); hmmio_ = mmioOpen(NULL, &mmioinfo, MMIO_ALLOCBUF | MMIO_READ | MMIO_COMPAT); if(!( hr = readMMIO() )) { // ReadMMIO will fail if its an not a wave file mmioClose(hmmio_, 0); return DXTRACE_ERR(TEXT("readMMIO"), hr.i); } if(!( hr = rewind() )) return DXTRACE_ERR( TEXT("ResetFile"), hr.i ); // After the rewind, the size of the wav file is m_ck.cksize so store it now size_ = ck_.cksize; return S_OK; }
SoundBuffer::SoundBuffer(std::string filePath) { HMMIO hMmio = NULL; MMIOINFO mmioInfo = {}; hMmio = mmioOpen(const_cast<LPSTR>(filePath.c_str()), &mmioInfo, MMIO_READ); if (!hMmio) throw std::runtime_error("Failed open " + filePath); MMRESULT mmResult; MMCKINFO riffChunk; riffChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mmResult = mmioDescend(hMmio, &riffChunk, NULL, MMIO_FINDRIFF); //TODO:error check MMCKINFO formatChunk; formatChunk.ckid = mmioFOURCC('f', 'm', 't', ' '); mmResult = mmioDescend(hMmio, &formatChunk, &riffChunk, MMIO_FINDCHUNK); //TODO:error check mmioRead(hMmio, (HPSTR)&waveFormatEx, formatChunk.cksize); //TODO:error check mmioAscend(hMmio, &formatChunk, 0); MMCKINFO dataChunk; dataChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmResult = mmioDescend(hMmio, &dataChunk, &riffChunk, MMIO_FINDCHUNK); //TODO:error check buffer.resize(dataChunk.cksize); size = mmioRead(hMmio, (HPSTR)buffer.data(), dataChunk.cksize); //TODO:error check mmioClose(hMmio, 0); }
/** 抽象ファイルからの読み込み用にオープン * * @author SAM (T&GG, Org.)<*****@*****.**> * @date 2004/01/21 2:32:45 * Copyright (C) 2001,2002,2003,2004 SAM (T&GG, Org.). All rights reserved. */ HRslt WavFile::open(AbstractFilePtr fileptr) { if(isOpen()) close(); flags_ = READ; HRslt hr; MMIOINFO mmioinfo; memset(&mmioinfo, 0, sizeof(mmioinfo)); AbstractFilePtr *__self = (AbstractFilePtr *)mmioinfo.adwInfo; (*__self) = fileptr; installIOProc(); mmioinfo.fccIOProc = mmioFOURCC('g', 'c', 't', 'p'); hmmio_ = mmioOpen(NULL, &mmioinfo, MMIO_ALLOCBUF | MMIO_READ | MMIO_COMPAT); if(!( hr = readMMIO() )) { // ReadMMIO will fail if its an not a wave file mmioClose(hmmio_, 0); return DXTRACE_ERR(TEXT("readMMIO"), hr.i); } if(!( hr = rewind() )) return DXTRACE_ERR( TEXT("ResetFile"), hr.i ); // After the rewind, the size of the wav file is m_ck.cksize so store it now size_ = ck_.cksize; return S_OK; }
//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; }
void playThread( void *arg ) { char *name = arg; HMMIO hmmio; MMIOINFO mmioInfo; MMAUDIOHEADER mmAudioHeader; LONG lBytesRead; KAISPEC ksWanted, ksObtained; HKAI hkai; CBDATA cd; /* Open the audio file. */ memset( &mmioInfo, '\0', sizeof( MMIOINFO )); mmioInfo.fccIOProc = mmioFOURCC('W', 'A', 'V', 'E'); hmmio = mmioOpen( name, &mmioInfo, MMIO_READ | MMIO_DENYNONE ); if( !hmmio ) { fprintf( stderr, "[%s] Failed to open a wave file!!!\n", name ); goto exit_discount_threads; } /* Get the audio file header. */ mmioGetHeader( hmmio, &mmAudioHeader, sizeof( MMAUDIOHEADER ), &lBytesRead, 0, 0); memset( &cd, 0, sizeof( CBDATA )); cd.hmmio = hmmio; ksWanted.usDeviceIndex = 0; ksWanted.ulType = KAIT_PLAY; ksWanted.ulBitsPerSample = mmAudioHeader.mmXWAVHeader.WAVEHeader.usBitsPerSample; ksWanted.ulSamplingRate = mmAudioHeader.mmXWAVHeader.WAVEHeader.ulSamplesPerSec; ksWanted.ulDataFormat = 0; ksWanted.ulChannels = mmAudioHeader.mmXWAVHeader.WAVEHeader.usChannels; ksWanted.ulNumBuffers = 2; ksWanted.ulBufferSize = 0; ksWanted.fShareable = TRUE; ksWanted.pfnCallBack = kaiCallback; ksWanted.pCallBackData = &cd; if( kaiOpen( &ksWanted, &ksObtained, &hkai )) { fprintf( stderr, "[%s] Failed to open audio device!!!\n", name ); goto exit_mmio_close; } printf("[%s] hkai = %lx\n", name, hkai ); kaiSetVolume( hkai, MCI_SET_AUDIO_ALL, 50 ); kaiSetSoundState( hkai, MCI_SET_AUDIO_ALL, TRUE ); printf("[%s] Trying to play...\n", name ); //DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0 ); while( 1 ) { switch( kaiPlay( hkai )) { case KAIE_NO_ERROR : break; #if 0 // Wait for instance to be active case KAIE_NOT_READY : DosSleep( 1 ); continue; #endif default : fprintf( stderr, "[%s] Failed to play!!!\n", name ); goto exit_kai_close; } break; } //DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, 0, 0 ); printf("[%s] Playing...\n", name ); while( !m_fQuit && !( kaiStatus( hkai ) & KAIS_COMPLETED )) DosSleep( 1 ); printf("[%s] Completed\n", name ); exit_kai_close : kaiClose( hkai ); exit_mmio_close : mmioClose( hmmio, 0 ); exit_discount_threads : m_nThreads--; }
int GYMCreateFile( TCHAR *pszFileName, // (IN) HMMIO *phmmioOut, // (OUT) WAVEFORMATEX *pwfxDest, // (IN) MMCKINFO *pckOut, // (OUT) MMCKINFO *pckOutRIFF // (OUT) ) { int nError; // Return value. DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile. MMCKINFO ckOut1; char Name[128] = ""; char ext[12] = "_000.wav"; int num = -1, i, j; do { if (num++ > 99999) return(20); ext[0] = '_'; i = 1; j = num / 10000; if (j) ext[i++] = '0' + j; j = (num / 1000) % 10; if (j) ext[i++] = '0' + j; j = (num / 100) % 10; ext[i++] = '0' + j; j = (num / 10) % 10; ext[i++] = '0' + j; j = num % 10; ext[i++] = '0' + j; ext[i++] = '.'; ext[i++] = 'w'; ext[i++] = 'a'; ext[i++] = 'v'; ext[i] = 0; if ((strlen(pszFileName) + strlen(ext)) > 127) return(21); strcpy(Name, pszFileName); strcat(Name, ext); } while(mmioOpen(Name, NULL, MMIO_EXIST) == (HMMIO) TRUE); dwFactChunk = (DWORD)-1; nError = 0; *phmmioOut = mmioOpen(Name, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE); if (*phmmioOut == NULL) { nError = ER_CANNOTWRITE; goto ERROR_CANNOT_WRITE; // cannot save WAVE file } /* Create the output file RIFF chunk of form type 'WAVE'. */ pckOutRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E'); pckOutRIFF->cksize = 0; if ((nError = mmioCreateChunk(*phmmioOut, pckOutRIFF, MMIO_CREATERIFF)) != 0) { goto ERROR_CANNOT_WRITE; // cannot write file, probably } /* We are now descended into the 'RIFF' chunk we just created. * Now create the 'fmt ' chunk. Since we know the size of this chunk, * specify it in the MMCKINFO structure so MMIO doesn't have to seek * back and set the chunk size after ascending from the chunk. */ pckOut->ckid = mmioFOURCC('f', 'm', 't', ' '); pckOut->cksize = sizeof(PCMWAVEFORMAT); // we know the size of this ck. if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0) { goto ERROR_CANNOT_WRITE; // cannot write file, probably } /* Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type. */ if (pwfxDest->wFormatTag == WAVE_FORMAT_PCM) { if (mmioWrite(*phmmioOut, (HPSTR) pwfxDest, sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT)) { nError = ER_CANNOTWRITE; goto ERROR_CANNOT_WRITE; // cannot write file, probably } } else { // Write the variable length size. if ((UINT)mmioWrite(*phmmioOut, (HPSTR) pwfxDest, sizeof(*pwfxDest)+pwfxDest->cbSize) != (sizeof(*pwfxDest)+pwfxDest->cbSize)) { nError = ER_CANNOTWRITE; goto ERROR_CANNOT_WRITE; // cannot write file, probably } } /* Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk. */ if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0) { goto ERROR_CANNOT_WRITE; // cannot write file, probably } // Now create the fact chunk, not required for PCM but nice to have. This is filled // in when the close routine is called. ckOut1.ckid = mmioFOURCC('f', 'a', 'c', 't'); ckOut1.cksize = 0; if ((nError = mmioCreateChunk(*phmmioOut, &ckOut1, 0)) != 0) { goto ERROR_CANNOT_WRITE; // cannot write file, probably } if (mmioWrite(*phmmioOut, (HPSTR)&dwFactChunk, sizeof(dwFactChunk)) != sizeof(dwFactChunk)) { nError = ER_CANNOTWRITE; goto ERROR_CANNOT_WRITE; } // Now ascend out of the fact chunk... if ((nError = mmioAscend(*phmmioOut, &ckOut1, 0)) != 0) { nError = ER_CANNOTWRITE; // cannot write file, probably goto ERROR_CANNOT_WRITE; } goto DONE_CREATE; ERROR_CANNOT_WRITE: // Maybe delete the half-written file? Ah forget it for now, its good to leave the // file there for debugging... DONE_CREATE: return(nError); }
bool CSoundFile::OpenWaveFile() { // code taken from Visual C++ Multimedia -- Aitken and Jarol p 122 // check if file is already open if(m_hFile) return FALSE; m_hFile = mmioOpen(m_szFileName,NULL,MMIO_READ); if(m_hFile == NULL) { m_Mode = FILE_ERROR; return FALSE; } m_MMCKInfoParent.fccType = mmioFOURCC('W','A','V','E'); MMRESULT mmResult = ::mmioDescend(m_hFile, &m_MMCKInfoParent,NULL,MMIO_FINDRIFF); if(mmResult) { //CString tstr; //tstr.LoadString(IDS_STRING_ERRDESCENT); //AfxMessageBox(tstr); AfxMessageBox("Error descending into file"); mmioClose(m_hFile,0); m_hFile = NULL; m_Mode = FILE_ERROR; return FALSE; } m_MMCKInfoChild.ckid = mmioFOURCC('f','m','t',' '); mmResult = mmioDescend(m_hFile,&m_MMCKInfoChild,&m_MMCKInfoParent,MMIO_FINDCHUNK); if(mmResult) { AfxMessageBox("Error descending in wave file"); mmioClose(m_hFile,0); m_Mode = FILE_ERROR; m_hFile = NULL; return FALSE; } DWORD bytesRead = mmioRead(m_hFile,(LPSTR)&m_Format,m_MMCKInfoChild.cksize); if(bytesRead < 0) { AfxMessageBox("Error reading PCM wave format record"); mmioClose(m_hFile,0); m_Mode = FILE_ERROR; return FALSE; } // open output sound file mmResult = mmioAscend(m_hFile,&m_MMCKInfoChild,0); if(mmResult) { AfxMessageBox("Error ascending in File"); mmioClose(m_hFile,0); m_hFile = NULL; m_Mode = FILE_ERROR; return FALSE; } m_MMCKInfoChild.ckid = mmioFOURCC('d','a','t','a'); mmResult = mmioDescend(m_hFile,&m_MMCKInfoChild, &m_MMCKInfoParent,MMIO_FINDCHUNK); if(mmResult) { AfxMessageBox("error reading data chunk"); mmioClose(m_hFile,0); m_hFile = NULL; m_Mode = FILE_ERROR; return FALSE; } return TRUE; }
/* This function will open a wave input file and prepare it for reading, * so the data can be easily * read with WaveReadFile. Returns 0 if successful, the error code if not. * pszFileName - Input filename to load. * phmmioIn - Pointer to handle which will be used * for further mmio routines. * ppwfxInfo - Ptr to ptr to WaveFormatEx structure * with all info about the file. * */ int WaveOpenFile( TCHAR*pszFileName, // (IN) HMMIO *phmmioIn, // (OUT) WAVEFORMATEX **ppwfxInfo, // (OUT) MMCKINFO *pckInRIFF // (OUT) ) { HMMIO hmmioIn; MMCKINFO ckIn; // chunk info. for general use. PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in. WORD cbExtraAlloc; // Extra bytes for waveformatex int nError; // Return value. // Initialization... *ppwfxInfo = NULL; nError = 0; hmmioIn = NULL; if ((hmmioIn = mmioOpen(pszFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)) == NULL) { nError = ER_CANNOTOPEN; goto ERROR_READING_WAVE; } if ((nError = (int)mmioDescend(hmmioIn, pckInRIFF, NULL, 0)) != 0) { goto ERROR_READING_WAVE; } if ((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E'))) { nError = ER_NOTWAVEFILE; goto ERROR_READING_WAVE; } /* Search the input file for for the 'fmt ' chunk. */ ckIn.ckid = mmioFOURCC('f', 'm', 't', ' '); if ((nError = (int)mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK)) != 0) { goto ERROR_READING_WAVE; } /* 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)) { nError = ER_NOTWAVEFILE; goto ERROR_READING_WAVE; } /* Read the 'fmt ' chunk into <pcmWaveFormat>.*/ if (mmioRead(hmmioIn, (HPSTR) &pcmWaveFormat, (long) sizeof(pcmWaveFormat)) != (long) sizeof(pcmWaveFormat)) { nError = ER_CANNOTREAD; goto ERROR_READING_WAVE; } // Ok, 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) cbExtraAlloc = 0; else { // Read in length of extra bytes. if (mmioRead(hmmioIn, (LPTSTR) &cbExtraAlloc, (long) sizeof(cbExtraAlloc)) != (long) sizeof(cbExtraAlloc)) { nError = ER_CANNOTREAD; goto ERROR_READING_WAVE; } } // Ok, now allocate that waveformatex structure. if ((*ppwfxInfo = GlobalAlloc(GMEM_FIXED, sizeof(WAVEFORMATEX)+cbExtraAlloc)) == NULL) { nError = ER_MEM; goto ERROR_READING_WAVE; } // Copy the bytes from the pcm structure to the waveformatex structure memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat)); (*ppwfxInfo)->cbSize = cbExtraAlloc; // Now, read those extra bytes into the structure, if cbExtraAlloc != 0. if (cbExtraAlloc != 0) { if (mmioRead(hmmioIn, (LPTSTR) (((BYTE*)&((*ppwfxInfo)->cbSize))+sizeof(cbExtraAlloc)), (long) (cbExtraAlloc)) != (long) (cbExtraAlloc)) { nError = ER_NOTWAVEFILE; goto ERROR_READING_WAVE; } } /* Ascend the input file out of the 'fmt ' chunk. */ if ((nError = mmioAscend(hmmioIn, &ckIn, 0)) != 0) { goto ERROR_READING_WAVE; } goto TEMPCLEANUP; ERROR_READING_WAVE: if (*ppwfxInfo != NULL) { GlobalFree(*ppwfxInfo); *ppwfxInfo = NULL; } if (hmmioIn != NULL) { mmioClose(hmmioIn, 0); hmmioIn = NULL; } TEMPCLEANUP: *phmmioIn = hmmioIn; return(nError); }
int main (int argc, char *argv[]) { HAB hab; HMQ hmq; QMSG qmsg; char text[CCHMAXPATH]; char title[CCHMAXPATH]; short a; HWND hwndClient; HMMIO hmmio; ULONG result; LONG lBytesRead=0; ULONG rc; /* Create a copy of the args */ /* argv[0]: progname argv[1]: installdir argv[2]: 0: query wave, 1: query mp3 argv[3]: wavefile */ numArgs=argc; sprintf(text,""); for(a=0;a<argc;a++) { params[a]=argv[a]; } hab=WinInitialize(0); if(hab) { hmq=WinCreateMsgQueue(hab,0); if(hmq) { /* Check if user started prog by hand */ if(argc!=4) { pmUsage();} else { /* Save installation directory */ strcpy(chrInstallDir,params[1]); /* Get our ressource dll */ RESSOURCEHANDLE=queryResModuleHandle2(chrInstallDir); iMp3=atoi(params[2]); removeLog2(chrInstallDir, logName); readIni2(chrInstallDir); if(readWindowPosFromIni(chrInstallDir, "pmwvinfo")) bHaveWindowPos=TRUE; rc=-1; if(!iMp3 || (iMp3 && iMp3Decoder==IDKEY_USEMMIOMP3)) { // open the wave file do { MMIOINFO mmioinfo; memset(&mmioinfo,0, sizeof(mmioinfo)); mmioinfo.ulTranslate = MMIO_TRANSLATEHEADER | MMIO_TRANSLATEDATA; mmioinfo.ulFlags=MMIO_READ|MMIO_DENYNONE; hmmio = mmioOpen(params[3], &mmioinfo, MMIO_READ); if(!hmmio) { /* Text: "Can't open file %s" Title: "Wavefile Information" */ getMessage(title, IDSTR_PMWAVEINFOFILEERROR, sizeof(title), RESSOURCEHANDLE, HWND_DESKTOP); sprintf(text, title, params[2]); getMessage(title, IDSTR_PMWAVEINFOTITLE, sizeof(title), RESSOURCEHANDLE, HWND_DESKTOP); WinMessageBox( HWND_DESKTOP, HWND_DESKTOP, text, title, 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE ); break; } memset(&mmAudioHeader,0,sizeof(MMAUDIOHEADER)); result = mmioGetHeader(hmmio, &mmAudioHeader,sizeof(MMAUDIOHEADER), &lBytesRead, 0, 0); if(result!=MMIO_SUCCESS) { mmioClose(hmmio, 0); /* Text: "Can't get MMAUDIOHEADER" Title: "Wavefile Information" */ messageBox( text, IDSTR_PMWAVEINFOMMAUDIOERROR , sizeof(text), title, IDSTR_PMWAVEINFOTITLE , sizeof(title), RESSOURCEHANDLE, HWND_DESKTOP, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE); break; } mmioClose(hmmio, 0); rc=0; break; }while (FALSE); } else { rc=0; } if(!rc) { if( WinDlgBox( HWND_DESKTOP, NULLHANDLE, waveinfoStatusDialogProc, RESSOURCEHANDLE, IDDLG_WAVEINFO, 0) == DID_ERROR ) { DosBeep(100,600); errorResource2("Problem with Audio/Data-CD-Creator installation"); WinDestroyMsgQueue( hmq ); WinTerminate( hab ); return( 1 ); } writeWindowPosToIni(chrInstallDir, "pmwvinfo"); } freeResHandle(); } WinDestroyMsgQueue(hmq); } WinTerminate(hab); } return 0; }
void CSoundMgr::Play (int iChannel, int iVolume, int iPan) // Play // // Plays a channel. // // iVolume = 0 for maximum volume. // iVolume = -10,000 for minimum volume. { if (m_pDS == NULL || m_iSoundVolume == 0) return; SChannel *pChannel = GetChannel(iChannel); if (pChannel->pBuffer == NULL) return; // If the buffer is lost, then we need to restore it DWORD dwStatus; pChannel->pBuffer->GetStatus(&dwStatus); if (dwStatus & DSBSTATUS_BUFFERLOST) { if (FAILED(pChannel->pBuffer->Restore())) return; if (pChannel->sFilename.IsBlank()) return; // Open the file MMCKINFO parent, child; ::ZeroMemory(&parent, sizeof(parent)); ::ZeroMemory(&child, sizeof(child)); HMMIO hFile = mmioOpen(pChannel->sFilename.GetASCIIZPointer(), NULL, MMIO_READ | MMIO_ALLOCBUF); if (hFile == NULL) return; // Descend into the RIFF parent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if (mmioDescend(hFile, &parent, NULL, MMIO_FINDRIFF)) { mmioClose(hFile, 0); return; } child.ckid = mmioFOURCC('d', 'a', 't', 'a'); if (mmioDescend(hFile, &child, &parent, MMIO_FINDCHUNK)) { mmioClose(hFile, 0); return; } DWORD dwDataSize = child.cksize; // Now read into the buffer LPVOID pDest; DWORD dwDestSize; if (FAILED(pChannel->pBuffer->Lock(0, 0, &pDest, &dwDestSize, NULL, NULL, DSBLOCK_ENTIREBUFFER))) { mmioClose(hFile, 0); return; } if (mmioRead(hFile, (char *)pDest, dwDestSize) != (LONG)dwDataSize) { mmioClose(hFile, 0); return; } // Done with the wave file mmioClose(hFile, 0); } // Check to see if the channel is busy. If it is, then we may need to create // a second buffer. else if (dwStatus & DSBSTATUS_PLAYING) { SChannel *pLastChannel = pChannel; pChannel = pChannel->pNext; while (pChannel) { pChannel->pBuffer->GetStatus(&dwStatus); if (!(dwStatus & DSBSTATUS_BUFFERLOST) && !(dwStatus & DSBSTATUS_PLAYING)) break; pLastChannel = pChannel; pChannel = pChannel->pNext; } // If we couldn't find another channel, then duplicate the original if (pChannel == NULL) { pChannel = GetChannel(iChannel); LPDIRECTSOUNDBUFFER pNewBuffer = NULL; if (FAILED(m_pDS->DuplicateSoundBuffer(pChannel->pBuffer, &pNewBuffer))) return; SChannel *pNewChannel = new SChannel; pLastChannel->pNext = pNewChannel; pNewChannel->pBuffer = pNewBuffer; pNewChannel->pNext = NULL; pChannel = pNewChannel; } } // Adjust volume int iVolumeAdj = MAX_VOLUME_LEVEL - m_iSoundVolume; int iMaxVolume = -(iVolumeAdj * VOLUME_STEP); int iVolumeRange = iMaxVolume - MIN_VOLUME; iVolume = iMaxVolume - ((iVolumeRange * iVolume) / MIN_VOLUME); // pChannel now points to a valid buffer. Play it! pChannel->pBuffer->SetVolume(iVolume); pChannel->pBuffer->SetPan(iPan); pChannel->pBuffer->Play(0, 0, 0); // Clean-up any channels after us that are done playing SChannel *pLastChannel = pChannel; pChannel = pChannel->pNext; while (pChannel) { pChannel->pBuffer->GetStatus(&dwStatus); if (!(dwStatus & DSBSTATUS_PLAYING)) { pChannel->pBuffer->Release(); pLastChannel->pNext = pChannel->pNext; delete pChannel; pChannel = pLastChannel->pNext; } else { pLastChannel = pChannel; pChannel = pChannel->pNext; } } }
int Sound::LoadWAV(char *filename, int control_flags) { // this function loads a .wav file, sets up the directsound // buffer and loads the data into memory, the function returns // the id number of the sound HMMIO hwav; // handle to wave file MMCKINFO parent, // parent chunk child; // child chunk WAVEFORMATEX wfmtx; // wave format structure int sound_id = -1, // id of sound to be loaded index; // looping variable unsigned char *snd_buffer, // temporary sound buffer to hold voc data *audio_ptr_1=NULL, // data ptr to first write buffer *audio_ptr_2=NULL; // data ptr to second write buffer DWORD audio_length_1=0, // length of first write buffer audio_length_2=0; // length of second write buffer // step one: are there any open id's ? for (index=0; index < MAX_SOUNDS; index++) { // make sure this sound is unused if (sound_fx[index].state==SOUND_NULL) { sound_id = index; break; } } // did we get a free id? if (sound_id==-1) return(-1); // set up chunk info structure parent.ckid = (FOURCC)0; parent.cksize = 0; parent.fccType = (FOURCC)0; parent.dwDataOffset = 0; parent.dwFlags = 0; // copy data child = parent; // open the WAV file if ((hwav = mmioOpen(filename, NULL, MMIO_READ | MMIO_ALLOCBUF))==NULL) return(-1); // descend into the RIFF parent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if (mmioDescend(hwav, &parent, NULL, MMIO_FINDRIFF)) { // close the file mmioClose(hwav, 0); // return error, no wave section return(-1); } // descend to the WAVEfmt child.ckid = mmioFOURCC('f', 'm', 't', ' '); if (mmioDescend(hwav, &child, &parent, 0)) { // close the file mmioClose(hwav, 0); // return error, no format section return(-1); } // now read the wave format information from file if (mmioRead(hwav, (char *)&wfmtx, sizeof(wfmtx)) != sizeof(wfmtx)) { // close file mmioClose(hwav, 0); // return error, no wave format data return(-1); } // make sure that the data format is PCM if (wfmtx.wFormatTag != WAVE_FORMAT_PCM) { // close the file mmioClose(hwav, 0); // return error, not the right data format return(-1); } // now ascend up one level, so we can access data chunk if (mmioAscend(hwav, &child, 0)) { // close file mmioClose(hwav, 0); // return error, couldn't ascend return(-1); } // descend to the data chunk child.ckid = mmioFOURCC('d', 'a', 't', 'a'); if (mmioDescend(hwav, &child, &parent, MMIO_FINDCHUNK)) { // close file mmioClose(hwav, 0); // return error, no data return(-1); } // finally!!!! now all we have to do is read the data in and // set up the directsound buffer // allocate the memory to load sound data snd_buffer = (unsigned char *)malloc(child.cksize); // read the wave data mmioRead(hwav, (char *)snd_buffer, child.cksize); // close the file mmioClose(hwav, 0); // set rate and size in data structure sound_fx[sound_id].rate = wfmtx.nSamplesPerSec; sound_fx[sound_id].size = child.cksize; sound_fx[sound_id].state = SOUND_LOADED; // set up the format data structure memset(&pcmwf, 0, sizeof(WAVEFORMATEX)); pcmwf.wFormatTag = WAVE_FORMAT_PCM; // pulse code modulation pcmwf.nChannels = 1; // mono pcmwf.nSamplesPerSec = 11025; // always this rate pcmwf.nBlockAlign = 1; pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign; pcmwf.wBitsPerSample = 8; pcmwf.cbSize = 0; // prepare to create sounds buffer dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = control_flags | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE; dsbd.dwBufferBytes = child.cksize; dsbd.lpwfxFormat = &pcmwf; // create the sound buffer if (FAILED(lpds->CreateSoundBuffer(&dsbd,&sound_fx[sound_id].dsbuffer,NULL))) { // release memory free(snd_buffer); // return error return(-1); } // copy data into sound buffer if (FAILED(sound_fx[sound_id].dsbuffer->Lock(0, child.cksize, (void **) &audio_ptr_1, &audio_length_1, (void **)&audio_ptr_2, &audio_length_2, DSBLOCK_FROMWRITECURSOR))) return(0); // copy first section of circular buffer memcpy(audio_ptr_1, snd_buffer, audio_length_1); // copy last section of circular buffer memcpy(audio_ptr_2, (snd_buffer+audio_length_1),audio_length_2); // unlock the buffer if (FAILED(sound_fx[sound_id].dsbuffer->Unlock(audio_ptr_1, audio_length_1, audio_ptr_2, audio_length_2))) return(0); // release the temp buffer free(snd_buffer); return(sound_id); }
WIOERR WIOAPI wioFileOpen ( LPWAVEIOCB pwio, LPCTSTR pszFilePath, DWORD fdwOpen ) { UINT u; TCHAR ach[255]; WIOERR werr; HMMIO hmmio; MMCKINFO ckRIFF; MMCKINFO ck; DWORD dw; // // validate a couple of things... // if (NULL == pwio) return (WIOERR_BADPARAM); // // default our error return (assume the worst) // _fmemset(pwio, 0, sizeof(*pwio)); werr = WIOERR_FILEERROR; pwio->dwFlags = fdwOpen; // // first try to open the file, etc.. open the given file for reading // using buffered I/O // hmmio = mmioOpen((LPTSTR)pszFilePath, NULL, MMIO_READ | MMIO_ALLOCBUF); if (NULL == hmmio) goto wio_Open_Error; pwio->hmmio = hmmio; // // locate a 'WAVE' form type... // ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if (mmioDescend(hmmio, &ckRIFF, NULL, MMIO_FINDRIFF)) goto wio_Open_Error; // // we found a WAVE chunk--now go through and get all subchunks that // we know how to deal with... // pwio->dwDataSamples = (DWORD)-1L; #if 0 if (lrt=riffInitINFO(&wio.pInfo)) { lr=lrt; goto wio_Open_Error; } #endif // // // while (MMSYSERR_NOERROR == mmioDescend(hmmio, &ck, &ckRIFF, 0)) { // // quickly check for corrupt RIFF file--don't ascend past end! // if ((ck.dwDataOffset + ck.cksize) > (ckRIFF.dwDataOffset + ckRIFF.cksize)) { DPF(1, "wioFileOpen() FILE MIGHT BE CORRUPT!"); DPF(1, " ckRIFF.dwDataOffset: %lu", ckRIFF.dwDataOffset); DPF(1, " ckRIFF.cksize: %lu", ckRIFF.cksize); DPF(1, " ck.dwDataOffset: %lu", ck.dwDataOffset); DPF(1, " ck.cksize: %lu", ck.cksize); wsprintf(ach, TEXT("This wave file might be corrupt. The RIFF chunk.ckid '%.08lX' (data offset at %lu) specifies a cksize of %lu that extends beyond what the RIFF header cksize of %lu allows. Attempt to load?"), ck.ckid, ck.dwDataOffset, ck.cksize, ckRIFF.cksize); u = MessageBox(NULL, ach, TEXT("wioFileOpen"), MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL); if (IDNO == u) { werr = WIOERR_BADFILE; goto wio_Open_Error; } } switch (ck.ckid) { case mmioFOURCC('L', 'I', 'S', 'T'): if (ck.fccType == mmioFOURCC('I', 'N', 'F', 'O')) { #if 0 if(lrt=riffReadINFO(hmmio, &ck, wio.pInfo)) { lr=lrt; goto wio_Open_Error; } #endif } break; case mmioFOURCC('D', 'I', 'S', 'P'): #if 0 riffReadDISP(hmmio, &ck, &(wio.pDisp)); #endif break; case mmioFOURCC('f', 'm', 't', ' '): // // !?! another format chunk !?! // if (NULL != pwio->pwfx) break; // // get size of the format chunk, allocate and lock memory // for it. we always alloc a complete extended format header // (even for PCM headers that do not have the cbSize field // defined--we just set it to zero). // dw = ck.cksize; if (dw < sizeof(WAVEFORMATEX)) dw = sizeof(WAVEFORMATEX); pwio->pwfx = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, dw); if (NULL == pwio->pwfx) { werr = WIOERR_NOMEM; goto wio_Open_Error; } // // read the format chunk // werr = WIOERR_FILEERROR; dw = ck.cksize; if (mmioRead(hmmio, (HPSTR)pwio->pwfx, dw) != (LONG)dw) goto wio_Open_Error; break; case mmioFOURCC('d', 'a', 't', 'a'): // // !?! multiple data chunks !?! // if (0L != pwio->dwDataBytes) break; // // just hang on to the total length in bytes of this data // chunk.. and the offset to the start of the data // pwio->dwDataBytes = ck.cksize; pwio->dwDataOffset = ck.dwDataOffset; break; case mmioFOURCC('f', 'a', 'c', 't'): // // !?! multiple fact chunks !?! // if (-1L != pwio->dwDataSamples) break; // // read the first dword in the fact chunk--it's the only // info we need (and is currently the only info defined for // the fact chunk...) // // if this fails, dwDataSamples will remain -1 so we will // deal with it later... // mmioRead(hmmio, (HPSTR)&pwio->dwDataSamples, sizeof(DWORD)); break; } // // step up to prepare for next chunk.. // mmioAscend(hmmio, &ck, 0); } // // if no fmt chunk was found, then die! // if (NULL == pwio->pwfx) { werr = WIOERR_ERROR; goto wio_Open_Error; } // // all wave files other than PCM are _REQUIRED_ to have a fact chunk // telling the number of samples that are contained in the file. it // is optional for PCM (and if not present, we compute it here). // // if the file is not PCM and the fact chunk is not found, then fail! // if (-1L == pwio->dwDataSamples) { if (WAVE_FORMAT_PCM == pwio->pwfx->wFormatTag) { pwio->dwDataSamples = pwio->dwDataBytes / pwio->pwfx->nBlockAlign; } else { // // !!! HACK HACK HACK !!! // // although this should be considered an invalid wave file, we // will bring up a message box describing the error--hopefully // people will start realizing that something is missing??? // //CamStudio v2.24 //By pass this message since some of the converted .wav files are like this /* u = MessageBox(NULL, TEXT("This wave file does not have a 'fact' chunk and requires one! This is completely invalid and MUST be fixed! Attempt to load it anyway?"), TEXT("wioFileOpen"), MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL); if (IDNO == u) { werr = WIOERR_BADFILE; goto wio_Open_Error; } */ // // !!! need to hack stuff in here !!! // pwio->dwDataSamples = 0L; } } // // cool! no problems.. // return (WIOERR_NOERROR); // // return error (after minor cleanup) // wio_Open_Error: wioFileClose(pwio, 0L); return (werr); } // wioFileOpen()
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; }
int load_wave_file(const char* fname, LPWAVEHDR hdr, LPWAVEFORMATEX format) { HMMIO hmmio; /* file handle for open file */ MMCKINFO mmckinfoParent; /* parent chunk information structure */ MMCKINFO mmckinfoSubchunk; /* subchunk information structure */ DWORD dwFmtSize; /* size of "fmt" chunk */ DWORD dwDataSize; /* size of "data" chunk */ /* * Open the given file for reading with buffered I/O * using the default internal buffer. */ hmmio = mmioOpen((LPSTR) fname, NULL, MMIO_READ | MMIO_ALLOCBUF); if (hmmio == NULL) { Print("load_wave_file(): '%s' - Failed to open file.\n", fname); return 0; } /* * Locate a "RIFF" chunk with a "WAVE" form type * to make sure the file is a WAVE file. */ mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF)) { Print("load_wave_file(): '%s' - This is not a WAVE file.\n", fname); mmioClose(hmmio, 0); return 0; } /* * Find the "fmt " chunk (form type "fmt "); it must be * a subchunk of the "RIFF" parent chunk. */ mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)) { Print("load_wave_file(): '%s' - WAVE file has no \"fmt\" chunk\n", fname); mmioClose(hmmio, 0); return 0; } /* * Get the size of the "fmt " chunk--allocate and lock memory for it. */ dwFmtSize = mmckinfoSubchunk.cksize; /* Read the "fmt " chunk. */ if (mmioRead(hmmio, (HPSTR) format, dwFmtSize) != (LRESULT)dwFmtSize) { Print("load_wave_file(): '%s' - Failed to read format chunk.\n", fname); mmioClose(hmmio, 0); return 0; } /* Ascend out of the "fmt " subchunk. */ mmioAscend(hmmio, &mmckinfoSubchunk, 0); /* * Find the data subchunk. The current file position * should be at the beginning of the data chunk. */ mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)) { Print("load_wave_file(): '%s' - WAVE file has no data chunk.\n", fname); mmioClose(hmmio, 0); return 0; } /* Get the size of the data subchunk. */ dwDataSize = mmckinfoSubchunk.cksize; if (dwDataSize == 0L) { Print("load_wave_file(): '%s' - The data chunk contains no data.\n", fname); mmioClose(hmmio, 0); return 0; } // allocate the data block: hdr->lpData = (LPSTR) new(__FILE__,__LINE__) BYTE[dwDataSize]; hdr->dwBufferLength = dwDataSize; /* Read the waveform data subchunk. */ if (mmioRead(hmmio, (HPSTR) hdr->lpData, dwDataSize) != (LRESULT)dwDataSize) { Print("load_wave_file(): '%s' - Failed to read data chunk.\n", fname); mmioClose(hmmio, 0); return 0; } /* Close the file. */ mmioClose(hmmio, 0); return 1; }
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); }
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; } }
/* ------------------------------------------------------------------------------------ */ int StreamingAudio::WaveOpen(char *szFileName, HMMIO *pFileID, WAVEFORMATEX **ppwfxInfo, MMCKINFO *pckInRIFF) { HMMIO hmmioIn = NULL; MMCKINFO ckIn; // chunk info. for general use. PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in. WORD cbExtraAlloc = 0; // Extra bytes for waveformatex int nError = 0; // Return value. // Set up for the job *ppwfxInfo = NULL; if((hmmioIn = mmioOpen(szFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)) == NULL) return -1; if(mmioDescend(hmmioIn, pckInRIFF, NULL, 0) != 0) { mmioClose(hmmioIn, 0); // Clean up return -1; } // Check to make sure we're really opening a WAVE file if((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E'))) { mmioClose(hmmioIn, 0); // Clean up return -2; } // Search the input file for for the 'fmt ' chunk. ckIn.ckid = mmioFOURCC('f', 'm', 't', ' '); if(mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK) != 0) { mmioClose(hmmioIn, 0); // Clean up return -3; } // 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)) { mmioClose(hmmioIn, 0); // Clean up return -4; } // Read the 'fmt ' chunk into <pcmWaveFormat> if(mmioRead(hmmioIn, (HPSTR) &pcmWaveFormat, (long) sizeof(pcmWaveFormat)) != (long) sizeof(pcmWaveFormat)) { mmioClose(hmmioIn, 0); // Clean up return -5; } // Ok, 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) cbExtraAlloc = 0; else { // Read in length of extra bytes. if (mmioRead(hmmioIn, (LPSTR) &cbExtraAlloc, (long) sizeof(cbExtraAlloc)) != (long) sizeof(cbExtraAlloc)) { mmioClose(hmmioIn, 0); // Clean up return -6; } } // Ok, now allocate that waveformatex structure. if((*ppwfxInfo = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)+cbExtraAlloc)) == NULL) { mmioClose(hmmioIn, 0); // Clean up return -7; } // Copy the bytes from the pcm structure to the waveformatex structure memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat)); (*ppwfxInfo)->cbSize = cbExtraAlloc; // Now, read those extra bytes into the structure, if cbExtraAlloc != 0. if(cbExtraAlloc != 0) { if(mmioRead(hmmioIn, (LPSTR) (((BYTE*)&((*ppwfxInfo)->cbSize))+sizeof(cbExtraAlloc)), (long) (cbExtraAlloc)) != (long) (cbExtraAlloc)) { mmioClose(hmmioIn, 0); // Clean up return -8; } } // Ascend the input file out of the 'fmt ' chunk if(mmioAscend(hmmioIn, &ckIn, 0) != 0) { mmioClose(hmmioIn, 0); // Clean up return -9; } // Search the input file for for the 'data' chunk. ckIn.ckid = mmioFOURCC('d', 'a', 't', 'a'); if(mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK) != 0) { mmioClose(hmmioIn, 0); // Clean up return -10; } memcpy(pckInRIFF, &ckIn, sizeof(MMCKINFO)); // Set up for later use. // Ok, return the handle to the file for later use... *pFileID = hmmioIn; return RGF_SUCCESS; // Ok, it worked! }
//----------------------------------------------------------------------------- // Name: CWaveFile::Open() // Desc: Opens a wave file for reading //----------------------------------------------------------------------------- HRESULT CWaveFile::Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags ) { HRESULT hr; m_dwFlags = dwFlags; m_bIsReadingFromMemory = FALSE; if( m_dwFlags == WAVEFILE_READ ) { if( strFileName == NULL ) return E_INVALIDARG; SAFE_DELETE_ARRAY( m_pwfx ); m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ ); if( NULL == m_hmmio ) { HRSRC hResInfo; HGLOBAL hResData; DWORD dwSize; VOID* pvRes; // Loading it as a file failed, so try it as a resource if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT("WAVE") ) ) ) { if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT("WAV") ) ) ) return DXTRACE_ERR( TEXT("FindResource"), E_FAIL ); } if( NULL == ( hResData = LoadResource( NULL, hResInfo ) ) ) return DXTRACE_ERR( TEXT("LoadResource"), E_FAIL ); if( 0 == ( dwSize = SizeofResource( NULL, hResInfo ) ) ) return DXTRACE_ERR( TEXT("SizeofResource"), E_FAIL ); if( NULL == ( pvRes = LockResource( hResData ) ) ) return DXTRACE_ERR( TEXT("LockResource"), E_FAIL ); m_pResourceBuffer = new CHAR[ dwSize ]; memcpy( m_pResourceBuffer, pvRes, dwSize ); MMIOINFO mmioInfo; ZeroMemory( &mmioInfo, sizeof(mmioInfo) ); mmioInfo.fccIOProc = FOURCC_MEM; mmioInfo.cchBuffer = dwSize; mmioInfo.pchBuffer = (CHAR*) m_pResourceBuffer; m_hmmio = mmioOpen( NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ ); } if( FAILED( hr = ReadMMIO() ) ) { // ReadMMIO will fail if its an not a wave file mmioClose( m_hmmio, 0 ); return DXTRACE_ERR( TEXT("ReadMMIO"), hr ); } if( FAILED( hr = ResetFile() ) ) return DXTRACE_ERR( TEXT("ResetFile"), hr ); // After the reset, the size of the wav file is m_ck.cksize so store it now m_dwSize = m_ck.cksize; } else { m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE ); if( NULL == m_hmmio ) return DXTRACE_ERR( TEXT("mmioOpen"), E_FAIL ); if( FAILED( hr = WriteMMIO( pwfx ) ) ) { mmioClose( m_hmmio, 0 ); return DXTRACE_ERR( TEXT("WriteMMIO"), hr ); } if( FAILED( hr = ResetFile() ) ) return DXTRACE_ERR( TEXT("ResetFile"), hr ); } return hr; }
bool Wave::Open(const LPTSTR strFileName, const WAVEFORMATEX* wavFmt, const DWORD dwFlags) { HMMIO hWav; // WAVE's handle MMCKINFO child, parent; LPDIRECTSOUNDBUFFER wavFileBuffer; // temporary buffer LPDIRECTSOUNDBUFFER *p_wavFileBuffer; p_wavFileBuffer = &wavFileBuffer; hWav = mmioOpen(strFileName, NULL, MMIO_READ | MMIO_ALLOCBUF); if (hWav==NULL) { //ErrorBox("Could not find / load file at mmioOpen()"); return false; } parent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); // descend to riff if (mmioDescend(hWav, &parent, NULL, MMIO_FINDRIFF)) { //ErrorBox("Could not descend to RIFF, file is corrupt or not a WAVE file."); mmioClose(hWav, 0); return false; } // descend to WAVEfmt child.ckid = mmioFOURCC('f', 'm', 't', ' '); if (mmioDescend(hWav, &child, &parent, 0)) { //ErrorBox("Could not descend to WAVEfmt, file is corrupt or not a WAVE file."); mmioClose(hWav, 0); return false; } // open <strong class="highlight">WAV</strong> file for reading, check to make sure format is correct if (mmioRead(hWav, (char*)&wfmex, sizeof(WAVEFORMATEX)) != sizeof(WAVEFORMATEX)) { //ErrorBox("Error reading <strong class="highlight">WAV</strong> format, file is corrupt or not a WAVE file."); mmioClose(hWav, 0); return false; } if (wfmex.wFormatTag != WAVE_FORMAT_PCM) { //ErrorBox("WAVE file is not of PCM format."); mmioClose(hWav, 0); return false; } if (mmioAscend(hWav, &child, 0)) { //ErrorBox("Error ascending to WAVE data."); mmioClose(hWav, 0); return false; } // descend to data child.ckid = mmioFOURCC('d', 'a', 't', 'a'); if (mmioDescend(hWav, &child, &parent, MMIO_FINDCHUNK)) { //ErrorBox("Error descending to the WAVE data level."); mmioClose(hWav, 0); return false; } // verification complete, now <strong class="highlight">read</strong> information // allocate memory and load pointer if (!(pData = new UCHAR [child.cksize])) { //ErrorBox("Insufficient memory to load WAVE file."); mmioClose(hWav, 0); return false; } // <strong class="highlight">read</strong> WAVE data long lBytesRead; lBytesRead = mmioRead(hWav, (char*)pData, child.cksize); if (lBytesRead<0) { //ErrorBox("Unable to <strong class="highlight">read</strong> WAVE file data."); mmioClose(hWav, 0); return false; } mmioClose(hWav, 0); // place our information on our buffer, prepare our description for direct sound dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwBufferBytes = child.cksize; // size of buffer is equal to the wave's size dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE | // Force loading in software so we can't loose it. DSBCAPS_GLOBALFOCUS | // Don't mute on 'lostfocus' DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsbd.lpwfxFormat = &wfmex; dsbd.dwReserved = NULL; dsbd.guid3DAlgorithm = DS3DALG_DEFAULT; return true; }