// Save a palette to an open MMIO handle BOOL CDIBPal::Save(HMMIO hmmio) { // Create a RIFF chunk for a PAL file MMCKINFO ckFile; ckFile.cksize = 0; // corrected later ckFile.fccType = mmioFOURCC('P','A','L',' '); if (mmioCreateChunk(hmmio, &ckFile, MMIO_CREATERIFF) != 0) { TRACE("Failed to create RIFF-PAL chunk"); return FALSE; } // create the LOGPALETTE data which will become // the data chunk int iColors = GetNumColors(); ASSERT(iColors > 0); int iSize = sizeof(LOGPALETTE) + (iColors-1) * sizeof(PALETTEENTRY); LOGPALETTE* plp = (LOGPALETTE*) malloc(iSize); ASSERT(plp); plp->palVersion = 0x300; plp->palNumEntries = iColors; GetPaletteEntries(0, iColors, plp->palPalEntry); // create the data chunk MMCKINFO ckData; ckData.cksize = iSize; ckData.ckid = mmioFOURCC('d','a','t','a'); if (mmioCreateChunk(hmmio, &ckData, 0) != 0) { TRACE("Failed to create data chunk"); return FALSE; } // write the data chunk if (mmioWrite(hmmio, (char*)plp, iSize) != iSize) { TRACE("Failed to write data chunk"); free(plp); return FALSE; } free(plp); // Ascend from the data chunk which will correct the length mmioAscend(hmmio, &ckData, 0); // Ascend from the RIFF/PAL chunk mmioAscend(hmmio, &ckFile, 0); return TRUE; }
static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO *mmckStream) { MMCKINFO mmckInfo; TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccType)), HIBYTE(LOWORD(wma->ash_audio.fccType)), LOBYTE(HIWORD(wma->ash_audio.fccType)), HIBYTE(HIWORD(wma->ash_audio.fccType))); if (wma->ash_audio.fccHandler) /* not all streams specify a handler */ TRACE("ash.fccHandler='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccHandler)), HIBYTE(LOWORD(wma->ash_audio.fccHandler)), LOBYTE(HIWORD(wma->ash_audio.fccHandler)), HIBYTE(HIWORD(wma->ash_audio.fccHandler))); else TRACE("ash.fccHandler=0, no handler specified\n"); TRACE("ash.dwFlags=%d\n", wma->ash_audio.dwFlags); TRACE("ash.wPriority=%d\n", wma->ash_audio.wPriority); TRACE("ash.wLanguage=%d\n", wma->ash_audio.wLanguage); TRACE("ash.dwInitialFrames=%d\n", wma->ash_audio.dwInitialFrames); TRACE("ash.dwScale=%d\n", wma->ash_audio.dwScale); TRACE("ash.dwRate=%d\n", wma->ash_audio.dwRate); TRACE("ash.dwStart=%d\n", wma->ash_audio.dwStart); TRACE("ash.dwLength=%d\n", wma->ash_audio.dwLength); TRACE("ash.dwSuggestedBufferSize=%d\n", wma->ash_audio.dwSuggestedBufferSize); TRACE("ash.dwQuality=%d\n", wma->ash_audio.dwQuality); TRACE("ash.dwSampleSize=%d\n", wma->ash_audio.dwSampleSize); TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left, wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right); /* rewind to the start of the stream */ mmioAscend(wma->hFile, mmckStream, 0); mmckInfo.ckid = ckidSTREAMFORMAT; if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) { WARN("Can't find 'strf' chunk\n"); return FALSE; } if (mmckInfo.cksize < sizeof(WAVEFORMAT)) { WARN("Size of strf chunk (%d) < audio format struct\n", mmckInfo.cksize); return FALSE; } wma->lpWaveFormat = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize); if (!wma->lpWaveFormat) { WARN("Can't alloc WaveFormat\n"); return FALSE; } mmioRead(wma->hFile, (LPSTR)wma->lpWaveFormat, mmckInfo.cksize); TRACE("waveFormat.wFormatTag=%d\n", wma->lpWaveFormat->wFormatTag); TRACE("waveFormat.nChannels=%d\n", wma->lpWaveFormat->nChannels); TRACE("waveFormat.nSamplesPerSec=%d\n", wma->lpWaveFormat->nSamplesPerSec); TRACE("waveFormat.nAvgBytesPerSec=%d\n", wma->lpWaveFormat->nAvgBytesPerSec); TRACE("waveFormat.nBlockAlign=%d\n", wma->lpWaveFormat->nBlockAlign); TRACE("waveFormat.wBitsPerSample=%d\n", wma->lpWaveFormat->wBitsPerSample); if (mmckInfo.cksize >= sizeof(WAVEFORMATEX)) TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize); return TRUE; }
void CWaveFile::CloseFile() { // Close the file // mmioinfoOut.dwFlags |= MMIO_DIRTY; mmioSetInfo(hmmioOut, &mmioinfoOut, 0); mmioAscend(hmmioOut, &ckOut, 0); mmioAscend(hmmioOut, &ckOutRIFF, 0); mmioSeek(hmmioOut, 0, SEEK_SET); mmioDescend(hmmioOut, &ckOutRIFF, NULL, 0); mmioClose(hmmioOut, 0); }
BOOL riffCopyChunk(HMMIO hmmioSrc, HMMIO hmmioDst, const LPMMCKINFO lpck) { MMCKINFO ck; HPSTR hpBuf; hpBuf = (HPSTR)GlobalAllocPtr(GHND, lpck->cksize); if (!hpBuf) return (FALSE); ck.ckid = lpck->ckid; ck.cksize = lpck->cksize; if (mmioCreateChunk(hmmioDst, &ck, 0)) goto rscc_Error; if (mmioRead(hmmioSrc, hpBuf, lpck->cksize) != (LONG)lpck->cksize) goto rscc_Error; if (mmioWrite(hmmioDst, hpBuf, lpck->cksize) != (LONG)lpck->cksize) goto rscc_Error; if (mmioAscend(hmmioDst, &ck, 0)) goto rscc_Error; if (hpBuf) GlobalFreePtr(hpBuf); return (TRUE); rscc_Error: if (hpBuf) GlobalFreePtr(hpBuf); return (FALSE); } /* RIFFSupCopyChunk() */
/** ストリームを閉じる * * @author SAM (T&GG, Org.)<*****@*****.**> * @date 2004/01/21 3:32:04 * Copyright (C) 2001,2002,2003,2004 SAM (T&GG, Org.). All rights reserved. */ HRslt WavFile::close() { if( !hmmio_ ) return CO_E_NOTINITIALIZED; if( flags_ & READ ) { mmioClose( hmmio_, 0 ); hmmio_ = NULL; } else { write_mmioinfo_.dwFlags |= MMIO_DIRTY; if( 0 != mmioSetInfo( hmmio_, &write_mmioinfo_, 0 ) ) return DXTRACE_ERR( TEXT("mmioSetInfo"), E_FAIL ); // Ascend the output file out of the 'data' chunk -- this will cause // the chunk size of the 'data' chunk to be written. if( 0 != mmioAscend( hmmio_, &ck_, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); // Do this here instead... if( 0 != mmioAscend( hmmio_, &ckriff_, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); mmioSeek( hmmio_, 0, SEEK_SET ); if( 0 != (int)mmioDescend( hmmio_, &ckriff_, NULL, 0 ) ) return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL ); ck_.ckid = mmioFOURCC('f','a','c','t'); if( 0 == mmioDescend( hmmio_, &ck_, &ckriff_, MMIO_FINDCHUNK ) ) { DWORD dwSamples = 0; mmioWrite( hmmio_, (HPSTR)&dwSamples, sizeof(dwSamples) ); mmioAscend( hmmio_, &ck_, 0 ); } // Ascend the output file out of the 'RIFF' chunk -- this will cause // the chunk size of the 'RIFF' chunk to be written. if( 0 != mmioAscend( hmmio_, &ckriff_, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); mmioClose( hmmio_, 0 ); hmmio_ = NULL; } SAFE_FREE( buffer_ ); SAFE_FREE( wfx_ ); return S_OK; }
HRESULT FinishWaveFile(HMMIO hFile, MMCKINFO *pckRIFF, MMCKINFO *pckData) { MMRESULT result; result = mmioAscend(hFile, pckData, 0); if (MMSYSERR_NOERROR != result) { printf("mmioAscend(\"data\" failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } result = mmioAscend(hFile, pckRIFF, 0); if (MMSYSERR_NOERROR != result) { printf("mmioAscend(\"RIFF/WAVE\" failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } return S_OK; }
void CWaveRecord::StopWriteFile(UINT nCh) { if(!m_bCompressMp3) { // Call mmioAscend function to mark the end of the chunk // And mmioAscend will corrects the chunk size if(m_hWaveFile[nCh]) { mmioAscend(m_hWaveFile[nCh], &mmckinfoParent[nCh], 0); mmioAscend(m_hWaveFile[nCh], &mmckinfoSubChunk[nCh], 0); mmioClose(m_hWaveFile[nCh], 0); m_hWaveFile[nCh] = NULL; } } else { EndEncodeMp3(nCh); } }
static LPDIRECTSOUNDBUFFER OpenSoundFile(char *name) { DSBUFFERDESC DSBufDESC; WAVEFORMATEX waveFormat; void* buf; DWORD size; HMMIO hmmio; MMCKINFO cParent, cSub; LPDIRECTSOUNDBUFFER lpDSBuf = NULL; MMIOINFO mem; int fileSize; char *data = LoadFile(name, &fileSize); memset(&mem, 0, sizeof(MMIOINFO)); mem.pchBuffer = data; mem.cchBuffer = fileSize; mem.fccIOProc = FOURCC_MEM; hmmio = mmioOpen(NULL, &mem, MMIO_ALLOCBUF | MMIO_READ); cParent.fccType = mmioFOURCC('W','A','V','E'); if (mmioDescend(hmmio, &cParent, NULL, MMIO_FINDRIFF) != MMSYSERR_NOERROR) { return NULL; } cSub.ckid = mmioFOURCC('f','m','t',' '); if (mmioDescend(hmmio, &cSub, &cParent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR) { goto end; } mmioRead(hmmio, (char*)&waveFormat, cSub.cksize); mmioAscend(hmmio, &cSub, 0); if (waveFormat.wFormatTag != WAVE_FORMAT_PCM) { goto end; } cSub.ckid = mmioFOURCC('d','a','t','a'); if (mmioDescend(hmmio, &cSub, &cParent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR) { goto end; } ZeroMemory(&DSBufDESC, sizeof(DSBUFFERDESC)); DSBufDESC.dwSize = sizeof(DSBUFFERDESC); DSBufDESC.dwFlags = DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|DSBCAPS_GLOBALFOCUS; DSBufDESC.dwBufferBytes = cSub.cksize; DSBufDESC.lpwfxFormat = &waveFormat; lpDS->CreateSoundBuffer(&DSBufDESC, &lpDSBuf, NULL); lpDSBuf->Lock(0, cSub.cksize, &buf, &size, NULL, 0, 0); mmioRead(hmmio, (HPSTR)buf, (LONG)cSub.cksize); lpDSBuf->Unlock(buf, size, NULL, 0); mmioClose(hmmio, MMIO_FHOPEN); return lpDSBuf; end: mmioClose(hmmio, MMIO_FHOPEN); free(data); return NULL; }
//----------------------------------------------------------------------------- // Name: WaveCloseWriteFile() // Desc: This routine will close a wave file used for writing. //----------------------------------------------------------------------------- HRESULT WaveCloseWriteFile( HMMIO hmmioOut, MMCKINFO *pckOut, MMCKINFO *pckOutRIFF, MMIOINFO *pmmioinfoOut, DWORD dwSamples ) { pmmioinfoOut->dwFlags |= MMIO_DIRTY; if( 0 != mmioSetInfo( hmmioOut, pmmioinfoOut, 0 ) ) return E_FAIL; // Ascend the output file out of the 'data' chunk -- this will cause // the chunk size of the 'data' chunk to be written. if( 0 != mmioAscend( hmmioOut, pckOut, 0 ) ) return E_FAIL; // Do this here instead... if( 0 != mmioAscend( hmmioOut, pckOutRIFF, 0 ) ) return E_FAIL; mmioSeek( hmmioOut, 0, SEEK_SET ); if( 0 != (INT)mmioDescend( hmmioOut, pckOutRIFF, NULL, 0 ) ) return E_FAIL; pckOut->ckid = mmioFOURCC('f', 'a', 'c', 't'); if( 0 == mmioDescend( hmmioOut, pckOut, pckOutRIFF, MMIO_FINDCHUNK ) ) { mmioWrite( hmmioOut, (HPSTR)&dwSamples, sizeof(DWORD) ); mmioAscend( hmmioOut, pckOut, 0 ); } // Ascend the output file out of the 'RIFF' chunk -- this will cause // the chunk size of the 'RIFF' chunk to be written. if( 0 != mmioAscend( hmmioOut, pckOutRIFF, 0 ) ) return E_FAIL; mmioClose( hmmioOut, 0 ); return S_OK; }
/* reads all non-junk chunks into the extrachunk-structure until it finds * the given chunk or the optional parent-chunk is at the end */ HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck, MMCKINFO *lpckParent,UINT flags) { FOURCC ckid; FOURCC fccType; HRESULT hr; /* pre-conditions */ assert(extra != NULL); assert(hmmio != NULL); assert(lpck != NULL); TRACE("({%p,%lu},%p,%p,%p,0x%X)\n", extra->lp, extra->cb, hmmio, lpck, lpckParent, flags); /* what chunk id and form/list type should we search? */ if (flags & MMIO_FINDCHUNK) { ckid = lpck->ckid; fccType = 0; } else if (flags & MMIO_FINDLIST) { ckid = FOURCC_LIST; fccType = lpck->fccType; } else if (flags & MMIO_FINDRIFF) { ckid = FOURCC_RIFF; fccType = lpck->fccType; } else ckid = fccType = (FOURCC)-1; /* collect everything into extra! */ TRACE(": find ckid=0x%08lX fccType=0x%08lX\n", ckid, fccType); for (;;) { hr = mmioDescend(hmmio, lpck, lpckParent, 0); if (hr != S_OK) { /* No extra chunks in front of desired chunk? */ if (flags == 0 && hr == MMIOERR_CHUNKNOTFOUND) hr = AVIERR_OK; return hr; } /* Have we found what we search for? */ if ((lpck->ckid == ckid) && (fccType == (FOURCC)0 || lpck->fccType == fccType)) return AVIERR_OK; /* Skip padding chunks, the others put into the extrachunk-structure */ if (lpck->ckid == ckidAVIPADDING || lpck->ckid == mmioFOURCC('p','a','d','d')) hr = mmioAscend(hmmio, lpck, 0); else hr = ReadChunkIntoExtra(extra, hmmio, lpck); if (FAILED(hr)) return hr; } }
void CMmio::AscendChunk () { ASSERT (m_hMmio != NULL); ASSERT_VALID (this); if (mmioAscend (m_hMmio, &m_mckiChunk, 0) != 0) { ThrowError (ERR_MMIO_ASCEND_CHUNK); } }
HRESULT FinishWaveFile(HMMIO file, MMCKINFO* packetRIFF, MMCKINFO* packetData) { MMRESULT result; result = mmioAscend(file, packetData, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioAscend(\"data\" failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } result = mmioAscend(file, packetRIFF, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioAscend(\"RIFF/WAVE\" failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } return S_OK; }
bool WaveFileHelper::Read(HMMIO hio) { assertRetVal(hio && !_format && !_data, false); MMCKINFO ckRiff; ff::ZeroObject(ckRiff); assertRetVal(MMSYSERR_NOERROR == mmioDescend(hio, &ckRiff, nullptr, 0), false); assertRetVal(ckRiff.ckid == FOURCC_RIFF && ckRiff.fccType == mmioFOURCC('W', 'A', 'V', 'E'), false); MMCKINFO ckIn; ff::ZeroObject(ckIn); ckIn.ckid = mmioFOURCC('f', 'm', 't', ' '); assertRetVal(MMSYSERR_NOERROR == mmioDescend(hio, &ckIn, &ckRiff, MMIO_FINDCHUNK), false); assertRetVal(ckIn.cksize >= sizeof(PCMWAVEFORMAT), false); PCMWAVEFORMAT pcmFormat; ff::ZeroObject(pcmFormat); assertRetVal(mmioRead(hio, (HPSTR)&pcmFormat, sizeof(pcmFormat)) == sizeof(pcmFormat), false); if(pcmFormat.wf.wFormatTag == WAVE_FORMAT_PCM) { _format.reset(new WAVEFORMATEX); *_format = *(WAVEFORMATEX*)&pcmFormat; _format->cbSize = 0; } else { // Read in length of extra bytes. WORD cbExtraBytes; assertRetVal(mmioRead(hio, (HPSTR)&cbExtraBytes, sizeof(WORD)) == sizeof(WORD), false); _format.reset((WAVEFORMATEX*)new BYTE[sizeof(WAVEFORMATEX) + cbExtraBytes]); *_format = *(WAVEFORMATEX*)&pcmFormat; _format->cbSize = cbExtraBytes; assertRetVal(mmioRead(hio, (HPSTR)(&_format->cbSize + 1), cbExtraBytes) == cbExtraBytes, false); } assertRetVal(MMSYSERR_NOERROR == mmioAscend(hio, &ckIn, 0), false); // Seek to the data MMCKINFO ckData; ff::ZeroObject(ckData); ckData.ckid = mmioFOURCC('d', 'a', 't', 'a'); assertRetVal(-1 != mmioSeek(hio, ckRiff.dwDataOffset + sizeof(FOURCC), SEEK_SET), false); assertRetVal(MMSYSERR_NOERROR == mmioDescend(hio, &ckData, &ckRiff, MMIO_FINDCHUNK), false); assertRetVal(ff::CreateDataInData(_fullData, ckData.dwDataOffset, ckData.cksize, &_data), false); return true; }
void CMmio::AscendList () { ASSERT (m_hMmio != NULL); ASSERT_VALID (this); ASSERT (m_iListDepth > 0); if (mmioAscend (m_hMmio, &m_mckiList[m_iListDepth-1], 0) != 0) { ThrowError (ERR_MMIO_ASCEND_LIST); } m_iListDepth--; }
VOID CSoundRecDlg::CloseDevice() { MMRESULT mRes=0; if(m_hWaveIn) { UnPrepareBuffers(); mRes=waveInClose(m_hWaveIn); } if(m_hOPFile) { mRes=mmioAscend(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); } mRes=mmioAscend(m_hOPFile, &m_stckOutRIFF, 0); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); } mmioClose(m_hOPFile,0); m_hOPFile=NULL; } m_hWaveIn=NULL; // Close FAAC encoder int nRet = faacEncClose(m_hAACEncoder); m_hAACEncoder = 0; if (m_pbAACBuffer) delete[] m_pbAACBuffer; m_pbAACBuffer = NULL; if (m_fpAACOutput) fclose(m_fpAACOutput); m_fpAACOutput = NULL; }
int WAVBegin(const char* _filename, struct WAVFile* _wav_out) { WAVFile& wav = *_wav_out; LPSTR filename = NULL; int result = 0; do { filename = new char[strlen(_filename)+1]; strcpy(filename, _filename); // open the file if(!(wav.wav_file = mmioOpen(filename, NULL, MMIO_CREATE|MMIO_WRITE))) break; delete filename; // create WAVE chunk wav.waveChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mmioCreateChunk(wav.wav_file, &wav.waveChunk, MMIO_CREATERIFF); // create Format chunk wav.fmtChunk.ckid = mmioFOURCC('f', 'm', 't', ' '); mmioCreateChunk(wav.wav_file, &wav.fmtChunk, 0); // then write header memcpy(&wav.wav_format, &wav.wav_format_master, sizeof(WAVEFORMATEX)); wav.wav_format.cbSize = 0; mmioWrite(wav.wav_file, (HPSTR) &wav.wav_format, sizeof(WAVEFORMATEX)); mmioAscend(wav.wav_file, &wav.fmtChunk, 0); // create Data chunk wav.dataChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmioCreateChunk(wav.wav_file, &wav.dataChunk, 0); // success result = 1; wav.valid = true; } while(false); if(!result) { clean_up(&wav); wav.valid = false; } return result; }
/** * Prepare WAV header chunk */ static void prepare_header_chunk(HMMIO hFile, WAVEFORMATEX* pFormat) { ZeroMemory(&_MMCKInfoParent, sizeof(MMCKINFO)); _MMCKInfoParent.fccType = mmioFOURCC('W','A','V','E'); mmioCreateChunk(hFile, &_MMCKInfoParent, MMIO_CREATERIFF); ZeroMemory(&_MMCKInfoChild, sizeof(MMCKINFO)); _MMCKInfoChild.ckid = mmioFOURCC('f','m','t',' '); _MMCKInfoChild.cksize = sizeof(WAVEFORMATEX) + pFormat->cbSize; mmioCreateChunk(hFile, &_MMCKInfoChild, 0); mmioWrite(hFile, (const char*)pFormat, sizeof(WAVEFORMATEX) + pFormat->cbSize); mmioAscend(hFile, &_MMCKInfoChild, 0); _MMCKInfoChild.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmioCreateChunk(hFile, &_MMCKInfoChild, 0); }
/*------------------------------------------------------------------------------*/ void WaveOpen( char *file_name ) { char FileName[256]; sprintf( FileName, "%s.wav", file_name ); hWaveRec = mmioOpenA( FileName, NULL, MMIO_CREATE|MMIO_WRITE ); WaveRiff.fccType = mmioStringToFOURCC( TEXT("WAVE"), 0 ); mmioCreateChunk( hWaveRec, &WaveRiff, MMIO_CREATERIFF ); WaveFmt.ckid = mmioStringToFOURCC( TEXT("fmt "), 0 ); mmioCreateChunk( hWaveRec, &WaveFmt, 0 ); mmioWrite( hWaveRec, (char *)&WaveFormat, sizeof(WAVEFORMATEX) ); mmioAscend( hWaveRec, &WaveFmt, 0 ); WaveData.ckid = mmioStringToFOURCC( TEXT("data"), 0 ); mmioCreateChunk( hWaveRec, &WaveData, 0 ); WaveOutFlag = 1; }
bool CWaveFile::OpenFile(LPTSTR Filename, int SampleRate, int SampleSize, int Channels) { // Open a wave file for streaming // int nError; WaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM; WaveFormat.wf.nChannels = Channels; WaveFormat.wf.nSamplesPerSec = SampleRate; WaveFormat.wf.nBlockAlign = (SampleSize / 8) * Channels; WaveFormat.wf.nAvgBytesPerSec = SampleRate * (SampleSize / 8) * Channels; WaveFormat.wBitsPerSample = SampleSize; hmmioOut = mmioOpen(Filename, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE); ckOutRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E'); ckOutRIFF.cksize = 0; nError = mmioCreateChunk(hmmioOut, &ckOutRIFF, MMIO_CREATERIFF); if (nError != MMSYSERR_NOERROR) return false; ckOut.ckid = mmioFOURCC('f', 'm', 't', ' '); ckOut.cksize = sizeof(PCMWAVEFORMAT); nError = mmioCreateChunk(hmmioOut, &ckOut, 0); if (nError != MMSYSERR_NOERROR) return false; mmioWrite(hmmioOut, (HPSTR)&WaveFormat, sizeof(PCMWAVEFORMAT)); mmioAscend(hmmioOut, &ckOut, 0); ckOut.ckid = mmioFOURCC('d', 'a', 't', 'a'); ckOut.cksize = 0; nError = mmioCreateChunk(hmmioOut, &ckOut, 0); if (nError != MMSYSERR_NOERROR) return false; mmioGetInfo(hmmioOut, &mmioinfoOut, 0); return true; }
mmio_stream_raii( const std::string & filename, const commandlineflags & flags_ ) : flags(flags_), mmio(NULL) { ZeroMemory( &waveformatex, sizeof( WAVEFORMATEX ) ); waveformatex.cbSize = 0; waveformatex.wFormatTag = flags.use_float ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM; waveformatex.nChannels = flags.channels; waveformatex.nSamplesPerSec = flags.samplerate; waveformatex.wBitsPerSample = flags.use_float ? 32 : 16; waveformatex.nBlockAlign = flags.channels * ( waveformatex.wBitsPerSample / 8 ); waveformatex.nAvgBytesPerSec = waveformatex.nSamplesPerSec * waveformatex.nBlockAlign; #if defined(WIN32) && defined(UNICODE) wchar_t * tmp = wcsdup( utf8_to_wstring( filename ).c_str() ); mmio = mmioOpen( tmp, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE ); free( tmp ); tmp = 0; #else char * tmp = strdup( filename.c_str() ); mmio = mmioOpen( tmp, NULL, MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE ); free( tmp ); tmp = 0; #endif ZeroMemory( &WAVE_chunk, sizeof( MMCKINFO ) ); WAVE_chunk.fccType = mmioFOURCC('W', 'A', 'V', 'E'); CHECKED(mmioCreateChunk( mmio, &WAVE_chunk, MMIO_CREATERIFF )); ZeroMemory( &fmt__chunk, sizeof( MMCKINFO ) ); fmt__chunk.ckid = mmioFOURCC('f', 'm', 't', ' '); fmt__chunk.cksize = sizeof( WAVEFORMATEX ); CHECKED(mmioCreateChunk( mmio, &fmt__chunk, 0 )); mmioWrite( mmio, (const char*)&waveformatex, sizeof( WAVEFORMATEX ) ); CHECKED(mmioAscend( mmio, &fmt__chunk, 0 )); ZeroMemory( &data_chunk, sizeof( MMCKINFO ) ); data_chunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); data_chunk.cksize = 0; CHECKED(mmioCreateChunk( mmio, &data_chunk, 0 )); ZeroMemory( &data_info, sizeof( MMIOINFO ) ); CHECKED(mmioGetInfo( mmio, &data_info, 0 )); }
void RecordStart() { WAVEFORMATEX pcmwf; // setup header in the same format as our directsound stream memset(&pcmwf,0,sizeof(WAVEFORMATEX)); pcmwf.wFormatTag = WAVE_FORMAT_PCM; if(iDisStereo) { pcmwf.nChannels = 1; pcmwf.nBlockAlign = 2; } else { pcmwf.nChannels = 2; pcmwf.nBlockAlign = 4; } pcmwf.nSamplesPerSec = 44100; pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign; pcmwf.wBitsPerSample = 16; // create file hWaveFile=mmioOpen(szFileName,NULL,MMIO_CREATE|MMIO_WRITE|MMIO_EXCLUSIVE | MMIO_ALLOCBUF); if(!hWaveFile) return; // setup WAVE, fmt and data chunks memset(&mmckMain,0,sizeof(MMCKINFO)); mmckMain.fccType = mmioFOURCC('W','A','V','E'); mmioCreateChunk(hWaveFile,&mmckMain,MMIO_CREATERIFF); memset(&mmckData,0,sizeof(MMCKINFO)); mmckData.ckid = mmioFOURCC('f','m','t',' '); mmckData.cksize = sizeof(WAVEFORMATEX); mmioCreateChunk(hWaveFile,&mmckData,0); mmioWrite(hWaveFile,(char*)&pcmwf,sizeof(WAVEFORMATEX)); mmioAscend(hWaveFile,&mmckData,0); mmckData.ckid = mmioFOURCC('d','a','t','a'); mmioCreateChunk(hWaveFile,&mmckData,0); }
// Define: closeWAVEFile(); bool waveCapture::closeWAVEFile() { // close file and re-open it to add the header at the beginning: hFile.close(); DWORD total_buff = getTotalBytesRecorded(); MMCKINFO mmckinfo; MMCKINFO mmckinfoSubchunk; MMCKINFO mmckinfoData; memset(&mmckinfo, 0, sizeof(mmckinfo)); memset(&mmckinfoSubchunk, 0, sizeof(mmckinfoSubchunk)); memset(&mmckinfoData, 0, sizeof(mmckinfoData)); // Open the WAVE file using mmio (no create!) // creating a file using mmio HMMIO hfile; hfile = mmioOpenA((LPSTR)_szFilePath, NULL, MMIO_WRITE); mmioSeek(hfile, 0, SEEK_SET); //step 1 create riff chunk mmckinfo.fccType = mmioFOURCC('W','A','V','E'); mmckinfo.cksize = (36 + total_buff); mmioCreateChunk(hfile, &mmckinfo, MMIO_CREATERIFF); //step 2 create fmt chunk //creating fmt chunk also includes writing formatex to this chunk mmckinfoSubchunk.ckid = mmioFOURCC('f','m','t',' '); mmckinfoSubchunk.cksize = sizeof(WAVEFORMATEX); mmioCreateChunk(hfile, &mmckinfoSubchunk, 0); mmioWrite(hfile, (char*)&wf, sizeof(wf)); mmioAscend(hfile, &mmckinfoSubchunk, 0); //step 3 creating data chunk //creating this chunk includes writing actual voice data mmckinfoData.ckid=mmioFOURCC('d','a','t','a'); mmckinfoData.cksize = total_buff; mmioCreateChunk(hfile, &mmckinfoData, 0); mmioClose( MMIO_READ, MMIO_FHOPEN ); return true; }
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); }
//----------------------------------------------------------------------------- // Name: CWaveFile::WriteMMIO() // Desc: Support function for reading from a multimedia I/O stream // pwfxDest is the WAVEFORMATEX for this new wave file. // m_hmmio must be valid before calling. This function uses it to // update m_ckRiff, and m_ck. //----------------------------------------------------------------------------- HRESULT CWaveFile::WriteMMIO( WAVEFORMATEX *pwfxDest ) { DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile. MMCKINFO ckOut1; dwFactChunk = (DWORD)-1; // Create the output file RIFF chunk of form type 'WAVE'. m_ckRiff.fccType = mmioFOURCC('W', 'A', 'V', 'E'); m_ckRiff.cksize = 0; if( 0 != mmioCreateChunk( m_hmmio, &m_ckRiff, MMIO_CREATERIFF ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); // 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. m_ck.ckid = mmioFOURCC('f', 'm', 't', ' '); m_ck.cksize = sizeof(PCMWAVEFORMAT); if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); // Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type. if( pwfxDest->wFormatTag == WAVE_FORMAT_PCM ) { if( mmioWrite( m_hmmio, (HPSTR) pwfxDest, sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT)) return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL ); } else { // Write the variable length size. if( (UINT)mmioWrite( m_hmmio, (HPSTR) pwfxDest, sizeof(*pwfxDest) + pwfxDest->cbSize ) != ( sizeof(*pwfxDest) + pwfxDest->cbSize ) ) return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL ); } // Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk. if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); // 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( 0 != mmioCreateChunk( m_hmmio, &ckOut1, 0 ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); if( mmioWrite( m_hmmio, (HPSTR)&dwFactChunk, sizeof(dwFactChunk)) != sizeof(dwFactChunk) ) return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL ); // Now ascend out of the fact chunk... if( 0 != mmioAscend( m_hmmio, &ckOut1, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); return S_OK; }
//----------------------------------------------------------------------------- // Name: CWaveFile::ReadMMIO() // Desc: Support function for reading from a multimedia I/O stream. // m_hmmio must be valid before calling. This function uses it to // update m_ckRiff, and m_pwfx. //----------------------------------------------------------------------------- HRESULT CWaveFile::ReadMMIO() { MMCKINFO ckIn; // chunk info. for general use. PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in. m_pwfx = NULL; if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) ) return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL ); // 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 DXTRACE_ERR( TEXT("mmioFOURCC"), E_FAIL ); // 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 ) ) return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL ); // 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) ) return DXTRACE_ERR( TEXT("sizeof(PCMWAVEFORMAT)"), E_FAIL ); // Read the 'fmt ' chunk into <pcmWaveFormat>. if( mmioRead( m_hmmio, (HPSTR) &pcmWaveFormat, sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat) ) return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL ); // 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 ) return DXTRACE_ERR( TEXT("m_pwfx"), E_FAIL ); // 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) ) return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL ); m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) + cbExtraBytes ]; if( NULL == m_pwfx ) return DXTRACE_ERR( TEXT("new"), E_FAIL ); // 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 ); return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL ); } } // Ascend the input file out of the 'fmt ' chunk. if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) ) { SAFE_DELETE( m_pwfx ); return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); } return S_OK; }
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; }
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; }
/************************************************************************** * mmioAscend [MMSYSTEM.1224] */ MMRESULT16 WINAPI mmioAscend16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags) { return mmioAscend(HMMIO_32(hmmio),lpck,uFlags); }
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); }