//----------------------------------------------------------------------------- // Name: CWaveFile::Close() // Desc: Closes the wave file //----------------------------------------------------------------------------- HRESULT CWaveFile::Close() { if( m_dwFlags == WAVEFILE_READ ) { mmioClose( m_hmmio, 0 ); m_hmmio = NULL; SAFE_DELETE_ARRAY( m_pResourceBuffer ); } else { m_mmioinfoOut.dwFlags |= MMIO_DIRTY; if( m_hmmio == NULL ) return CO_E_NOTINITIALIZED; if( 0 != mmioSetInfo( m_hmmio, &m_mmioinfoOut, 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( m_hmmio, &m_ck, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); // Do this here instead... if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); mmioSeek( m_hmmio, 0, SEEK_SET ); if( 0 != (INT)mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL ); m_ck.ckid = mmioFOURCC('f', 'a', 'c', 't'); if( 0 == mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) ) { DWORD dwSamples = 0; mmioWrite( m_hmmio, (HPSTR)&dwSamples, sizeof(DWORD) ); mmioAscend( m_hmmio, &m_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( m_hmmio, &m_ckRiff, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); mmioClose( m_hmmio, 0 ); m_hmmio = NULL; } return S_OK; }
void CWaveFile::WriteRecData2File(char* pszData, DWORD dwBufSize) { int nRecBytes = dwBufSize; if(m_hWaveFileRec) { int nLength = mmioWrite(m_hWaveFileRec, pszData, dwBufSize); if(nRecBytes != nLength) { StopRecord(); } } }
// 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; }
void ProcessHeader(WAVEHDR * pHdr) { //LOG->Trace("%d",pHdr->dwUser); if(WHDR_DONE==(WHDR_DONE &pHdr->dwFlags)) { //LOG->Trace("Got %d bytes of data", pHdr->dwBytesRecorded ); int iSampleCount = pHdr->dwBytesRecorded / sizeof(short); m_dp.ReadOne( (short*)pHdr->lpData, iSampleCount ); mmioWrite(m_hOPFile,pHdr->lpData,pHdr->dwBytesRecorded); MMRESULT mRes = waveInAddBuffer(m_hWaveIn,pHdr,sizeof(WAVEHDR)); if(mRes!=0) FAIL_M("bad"); } }
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; }
LRESULT WriteSound::OnWriteData(WPARAM wParam, LPARAM lParam) { LPWAVEHDR lphdr=(LPWAVEHDR)lParam; int length=lphdr->dwBufferLength; if(m_hwrite==NULL) return FALSE; log.WriteString("\n Writing the data"); if(lphdr->lpData && length>0) mmioWrite(m_hwrite,lphdr->lpData,length); return TRUE; }
/** * 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; }
/** ストリームを閉じる * * @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; }
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 )); }
int bwrite(int n,void *adr,long len) { HMMIO fp; int r= -1; if (n) { fp=ftab[n-1]; if (fp) { if (len==mmioWrite(fp,adr,len)) r=0; else r= -1; } } return(r); }
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; }
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: 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; }
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; }
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]); }
void __fastcall CWaveFile::ReadWrite(short *s, int size) { int csize = size * sizeof(short); if( m_Handle != NULL ){ if( m_mode == 2 ){ // 書きこみ if( !m_pause ){ if( mmioWrite(m_Handle, (const char*)s, csize) != csize ){ mmioClose(m_Handle, 0); m_Handle = 0; m_mode = 0; } else { m_pos += csize; } } } else { // 読み出し if( m_pause || m_dis ){ memset(s, 0, csize); } else { if( mmioRead(m_Handle, (char *)s, csize) == csize ){ m_pos += csize; } else if( m_autopause ){ // Rewind(); m_pause = 1; } else { mmioClose(m_Handle, 0); m_Handle = 0; m_mode = 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() */
VOID CSoundRecDlg::ProcessHeader(WAVEHDR * pHdr) { MMRESULT mRes=0; TRACE("%d",pHdr->dwUser); if(WHDR_DONE==(WHDR_DONE &pHdr->dwFlags)) { ShowDebug(_T("CSoundRecDlg::ProcessHeader, pHdr->dwBytesRecorded=%d"), pHdr->dwBytesRecorded); unsigned long nInputSamples = pHdr->dwBytesRecorded / (m_stWFEX.wBitsPerSample / 8); ShowDebug(_T("CSoundRecDlg::ProcessHeader faacEncEncode nInputSamples=%d"), nInputSamples); long nLeftSamples = nInputSamples; BYTE* pData = (BYTE*)pHdr->lpData; while (nLeftSamples > 0) { int nBytesEncoded = faacEncEncode(m_hAACEncoder, (int*)pData, m_nMaxInputSamples, m_pbAACBuffer, m_nMaxOutputBytes); ShowDebug(_T("CSoundRecDlg::ProcessHeader faacEncEncode nBytesEncoded=%d"), nBytesEncoded); int nBytesWritten = fwrite(m_pbAACBuffer, 1, nBytesEncoded, m_fpAACOutput); ShowDebug(_T("CSoundRecDlg::ProcessHeader fwrite nBytesWritten=%d"), nBytesWritten); nLeftSamples -= m_nMaxInputSamples; pData += m_nMaxInputSamples; } mmioWrite(m_hOPFile,pHdr->lpData,pHdr->dwBytesRecorded); mRes=waveInAddBuffer(m_hWaveIn,pHdr,sizeof(WAVEHDR)); if(mRes!=0) StoreError(mRes,TRUE,"File: %s ,Line Number:%d",__FILE__,__LINE__); } }
void RecordBuffer(unsigned char* pSound,long lBytes) { // write the samples if(hWaveFile) mmioWrite(hWaveFile, (const char *) pSound,lBytes); }
//----------------------------------------------------------------------------- // 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; }
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; }
/************************************************************************** * mmioWrite [MMSYSTEM.1213] */ LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch) { return mmioWrite(HMMIO_32(hmmio),pch,cch); }
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); }
int WaveCloseWriteFile( HMMIO *phmmioOut, // (IN) MMCKINFO *pckOut, // (IN) MMCKINFO *pckOutRIFF, // (IN) MMIOINFO *pmmioinfoOut, // (IN) DWORD cSamples // (IN) ) { int nError; nError = 0; if (*phmmioOut == NULL) return(0); pmmioinfoOut->dwFlags |= MMIO_DIRTY; if ((nError = mmioSetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0) { // cannot flush, probably... goto ERROR_CANNOT_WRITE; } /* Ascend the output file out of the 'data' chunk -- this will cause * the chunk size of the 'data' chunk to be written. */ if ((nError = mmioAscend(*phmmioOut, pckOut, 0)) != 0) goto ERROR_CANNOT_WRITE; // cannot write file, probably // Do this here instead... if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0) goto ERROR_CANNOT_WRITE; // cannot write file, probably nError = mmioSeek(*phmmioOut, 0, SEEK_SET); if ((nError = (int)mmioDescend(*phmmioOut, pckOutRIFF, NULL, 0)) != 0) goto ERROR_CANNOT_WRITE; nError = 0; pckOut->ckid = mmioFOURCC('f', 'a', 'c', 't'); if ((nError = mmioDescend(*phmmioOut, pckOut, pckOutRIFF, MMIO_FINDCHUNK)) == 0) { // If it didn't fail, write the fact chunk out, if it failed, not critical, just // assert (below). nError = mmioWrite(*phmmioOut, (HPSTR)&cSamples, sizeof(DWORD)); nError = mmioAscend(*phmmioOut, pckOut, 0); nError = 0; } else { nError = 0; // ASSERT(FALSE); } /* Ascend the output file out of the 'RIFF' chunk -- this will cause * the chunk size of the 'RIFF' chunk to be written. */ if ((nError = mmioAscend(*phmmioOut, pckOutRIFF, 0)) != 0) goto ERROR_CANNOT_WRITE; // cannot write file, probably ERROR_CANNOT_WRITE: if (*phmmioOut != NULL) { mmioClose(*phmmioOut, 0); *phmmioOut = NULL; } return(nError); }
int do_everything(int argc, LPCWSTR argv[]) { HRESULT hr = S_OK; // parse command line CPrefs prefs(argc, argv, hr); if (FAILED(hr)) { ERR(L"CPrefs::CPrefs constructor failed: hr = 0x%08x", hr); return -__LINE__; } if (S_FALSE == hr) { // nothing to do return 0; } // create a "loopback capture has started" event HANDLE hStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hStartedEvent) { ERR(L"CreateEvent failed: last error is %u", GetLastError()); return -__LINE__; } CloseHandleOnExit closeStartedEvent(hStartedEvent); // create a "stop capturing now" event HANDLE hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL == hStopEvent) { ERR(L"CreateEvent failed: last error is %u", GetLastError()); return -__LINE__; } CloseHandleOnExit closeStopEvent(hStopEvent); // create arguments for loopback capture thread LoopbackCaptureThreadFunctionArguments threadArgs; threadArgs.hr = E_UNEXPECTED; // thread will overwrite this threadArgs.pMMDevice = prefs.m_pMMDevice; threadArgs.bInt16 = prefs.m_bInt16; threadArgs.hFile = prefs.m_hFile; threadArgs.hStartedEvent = hStartedEvent; threadArgs.hStopEvent = hStopEvent; threadArgs.nFrames = 0; HANDLE hThread = CreateThread( NULL, 0, LoopbackCaptureThreadFunction, &threadArgs, 0, NULL ); if (NULL == hThread) { ERR(L"CreateThread failed: last error is %u", GetLastError()); return -__LINE__; } CloseHandleOnExit closeThread(hThread); // wait for either capture to start or the thread to end HANDLE waitArray[2] = { hStartedEvent, hThread }; DWORD dwWaitResult; dwWaitResult = WaitForMultipleObjects( _countof(waitArray), waitArray, FALSE, INFINITE ); if (WAIT_OBJECT_0 + 1 == dwWaitResult) { ERR(L"Thread aborted before starting to loopback capture: hr = 0x%08x", threadArgs.hr); return -__LINE__; } if (WAIT_OBJECT_0 != dwWaitResult) { ERR(L"Unexpected WaitForMultipleObjects return value %u", dwWaitResult); return -__LINE__; } // at this point capture is running // wait for the user to press a key or for capture to error out { WaitForSingleObjectOnExit waitForThread(hThread); SetEventOnExit setStopEvent(hStopEvent); HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (INVALID_HANDLE_VALUE == hStdIn) { ERR(L"GetStdHandle returned INVALID_HANDLE_VALUE: last error is %u", GetLastError()); return -__LINE__; } LOG(L"%s", L"Press Enter to quit..."); HANDLE rhHandles[2] = { hThread, hStdIn }; bool bKeepWaiting = true; while (bKeepWaiting) { dwWaitResult = WaitForMultipleObjects(2, rhHandles, FALSE, INFINITE); switch (dwWaitResult) { case WAIT_OBJECT_0: // hThread ERR(L"%s", L"The thread terminated early - something bad happened"); bKeepWaiting = false; break; case WAIT_OBJECT_0 + 1: // hStdIn // see if any of them was an Enter key-up event INPUT_RECORD rInput[128]; DWORD nEvents; if (!ReadConsoleInput(hStdIn, rInput, _countof(rInput), &nEvents)) { ERR(L"ReadConsoleInput failed: last error is %u", GetLastError()); bKeepWaiting = false; } else { for (DWORD i = 0; i < nEvents; i++) { if ( KEY_EVENT == rInput[i].EventType && VK_RETURN == rInput[i].Event.KeyEvent.wVirtualKeyCode && !rInput[i].Event.KeyEvent.bKeyDown ) { LOG(L"%s", L"Stopping capture..."); bKeepWaiting = false; break; } } // if none of them were Enter key-up events, // continue waiting } break; default: ERR(L"WaitForMultipleObjects returned unexpected value 0x%08x", dwWaitResult); bKeepWaiting = false; break; } // switch } // while } // naked scope // at this point the thread is definitely finished DWORD exitCode; if (!GetExitCodeThread(hThread, &exitCode)) { ERR(L"GetExitCodeThread failed: last error is %u", GetLastError()); return -__LINE__; } if (0 != exitCode) { ERR(L"Loopback capture thread exit code is %u; expected 0", exitCode); return -__LINE__; } if (S_OK != threadArgs.hr) { ERR(L"Thread HRESULT is 0x%08x", threadArgs.hr); return -__LINE__; } // everything went well... fixup the fact chunk in the file MMRESULT result = mmioClose(prefs.m_hFile, 0); prefs.m_hFile = NULL; if (MMSYSERR_NOERROR != result) { ERR(L"mmioClose failed: MMSYSERR = %u", result); return -__LINE__; } // reopen the file in read/write mode MMIOINFO mi = {0}; prefs.m_hFile = mmioOpen(const_cast<LPWSTR>(prefs.m_szFilename), &mi, MMIO_READWRITE); if (NULL == prefs.m_hFile) { ERR(L"mmioOpen(\"%ls\", ...) failed. wErrorRet == %u", prefs.m_szFilename, mi.wErrorRet); return -__LINE__; } // descend into the RIFF/WAVE chunk MMCKINFO ckRIFF = {0}; ckRIFF.ckid = MAKEFOURCC('W', 'A', 'V', 'E'); // this is right for mmioDescend result = mmioDescend(prefs.m_hFile, &ckRIFF, NULL, MMIO_FINDRIFF); if (MMSYSERR_NOERROR != result) { ERR(L"mmioDescend(\"WAVE\") failed: MMSYSERR = %u", result); return -__LINE__; } // descend into the fact chunk MMCKINFO ckFact = {0}; ckFact.ckid = MAKEFOURCC('f', 'a', 'c', 't'); result = mmioDescend(prefs.m_hFile, &ckFact, &ckRIFF, MMIO_FINDCHUNK); if (MMSYSERR_NOERROR != result) { ERR(L"mmioDescend(\"fact\") failed: MMSYSERR = %u", result); return -__LINE__; } // write the correct data to the fact chunk LONG lBytesWritten = mmioWrite( prefs.m_hFile, reinterpret_cast<PCHAR>(&threadArgs.nFrames), sizeof(threadArgs.nFrames) ); if (lBytesWritten != sizeof(threadArgs.nFrames)) { ERR(L"Updating the fact chunk wrote %u bytes; expected %u", lBytesWritten, (UINT32)sizeof(threadArgs.nFrames)); return -__LINE__; } // ascend out of the fact chunk result = mmioAscend(prefs.m_hFile, &ckFact, 0); if (MMSYSERR_NOERROR != result) { ERR(L"mmioAscend(\"fact\") failed: MMSYSERR = %u", result); return -__LINE__; } // let prefs' destructor call mmioClose return 0; }
BOOL CWavFile::CreateWaveFile(HMMIO& hWaveFile, LPCTSTR lpszFilePath, WAVEFORMATEX wfx) { CString strErr; CString strFilePath = lpszFilePath; MMRESULT mmResult = 0; if(hWaveFile) { return TRUE; } mmioOpen((LPTSTR)lpszFilePath, NULL, MMIO_DELETE); if(hWaveFile) { return TRUE; } hWaveFile = mmioOpen((LPTSTR)lpszFilePath, NULL, MMIO_CREATE | MMIO_WRITE | MMIO_EXCLUSIVE | MMIO_ALLOCBUF); if(!hWaveFile) { MyMessageBox(_T("mmioOpen failed"), eERR_ERROR); return FALSE; } ZeroMemory(&m_mmckinfoParent, sizeof(MMCKINFO)); m_mmckinfoParent.fccType = mmioFOURCC('W','A','V','E'); mmResult = mmioCreateChunk(hWaveFile, &m_mmckinfoParent, MMIO_CREATERIFF); if(mmResult) { MyMessageBox(_T("Create 'WAVE' chunk failed"), eERR_ERROR); return FALSE; } ZeroMemory(&m_mmckinfoSubChunk, sizeof(MMCKINFO)); m_mmckinfoSubChunk.ckid = mmioFOURCC('f','m','t',' '); m_mmckinfoSubChunk.cksize = sizeof(WAVEFORMATEX) + wfx.cbSize; mmResult = mmioCreateChunk(hWaveFile, &m_mmckinfoSubChunk, 0); if(mmResult) { MyMessageBox(_T("Create 'fmt' chunk failed"), eERR_ERROR); return FALSE; } long lSize = mmioWrite(hWaveFile, (char*)&wfx, sizeof(WAVEFORMATEX) + wfx.cbSize); if(lSize <= 0) { MyMessageBox(_T("mmioWrite failed"), eERR_ERROR); return FALSE; } mmResult = mmioAscend(hWaveFile, &m_mmckinfoSubChunk, 0); if(mmResult) { MyMessageBox(_T("mmioAscend failed"), eERR_ERROR); return FALSE; } m_mmckinfoSubChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmResult = mmioCreateChunk (hWaveFile, &m_mmckinfoSubChunk, 0); if(mmResult) { MyMessageBox(_T("Create 'data' chunk failed"), eERR_ERROR); return FALSE; } return TRUE; }
BOOL CWavFile::Combine(CString strPathL, CString strPathR, CString strPathObj) { int nPackNo = 0; int nPackSize = 0; int nDataSize = 0; const int nLen = 65536; BYTE byDataL[nLen * 2] = {0}; BYTE byDataR[nLen * 2] = {0}; BYTE byDataC[nLen * 4] = {0}; HMMIO hWaveFile = NULL; LPTSTR pszFilePath = strdup(strPathObj); if(!m_hWaveFileL || !m_hWaveFileR) { return FALSE; } // They can combine or not nDataSize = IsCanCombine(strPathL, strPathR); if(nDataSize == -1) { return FALSE; } // Create an object wave file m_formatL.nChannels = 2; m_formatL.nBlockAlign *= 2; m_formatL.nAvgBytesPerSec *= 2; if(!CreateWaveFile(hWaveFile, pszFilePath, m_formatL)) { MyMessageBox(_T("Create object file failed: ") + strPathObj, eERR_ERROR); return FALSE; } // Combine them one packet by one nPackSize = nLen; nPackNo = (nDataSize + nLen - 1) / nLen; for(int i = 0; i < nPackNo; i++) { // Case of the last packet if(i == (nPackNo - 1)) { nPackSize = nDataSize - i * nLen; } // Read data from left channel int nSizeL = nPackSize; if(ReadDataFromFile(m_hWaveFileL, byDataL, nSizeL)) { if(nSizeL != nPackSize) { memset(byDataL + nSizeL, 0, nPackSize - nSizeL); } } else { MyMessageBox(_T("Read sound data from L file failed"), eERR_ERROR); } // Read data from right channel int nSizeR = nPackSize; if(ReadDataFromFile(m_hWaveFileR, byDataR, nSizeR)) { if(nSizeR != nPackSize) { memset(byDataR + nSizeR, 0, nPackSize - nSizeR); } } else { MyMessageBox(_T("Read sound data from R file failed"), eERR_ERROR); } // Re-combine left channel data and right channel data int nCoef = m_formatL.wBitsPerSample / 8; for(int i = 0; i < (nPackSize / nCoef); i++) { if(nCoef == 1) { byDataC[2 * i + 0] = byDataL[i]; byDataC[2 * i + 1] = byDataR[i]; } else { byDataC[4 * i + 0] = byDataL[2 * i]; byDataC[4 * i + 2] = byDataR[2 * i]; byDataC[4 * i + 1] = byDataL[2 * i + 1]; byDataC[4 * i + 3] = byDataR[2 * i + 1]; } } // Write to object file if(mmioWrite(hWaveFile, (char*)byDataC, nPackSize * 2) != nPackSize * 2) { MyMessageBox(_T("Write object file failed"), eERR_ERROR); return FALSE; } } // Call mmioAscend function to mark the end of the chunk // And mmioAscend will corrects the chunk size mmioAscend(hWaveFile, &m_mmckinfoParent, 0); mmioAscend(hWaveFile, &m_mmckinfoSubChunk, 0); mmioClose(hWaveFile, 0); mmioClose(m_hWaveFileL, 0); mmioClose(m_hWaveFileR, 0); return TRUE; }