/** MMIOストリームへ書き込み * * @author SAM (T&GG, Org.)<*****@*****.**> * @date 2004/01/21 3:37:12 * Copyright (C) 2001,2002,2003,2004 SAM (T&GG, Org.). All rights reserved. */ HRslt WavFile::writeMMIO( const WAVEFORMATEX * src ) { 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'. ckriff_.fccType = mmioFOURCC('W','A','V','E'); ckriff_.cksize = 0; if( 0 != mmioCreateChunk( hmmio_, &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. ck_.ckid = mmioFOURCC('f','m','t',' '); ck_.cksize = sizeof(PCMWAVEFORMAT); if( 0 != mmioCreateChunk( hmmio_, &ck_, 0 ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); // Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type. if( src->wFormatTag == WAVE_FORMAT_PCM ) { if( mmioWrite( hmmio_, (HPSTR)src, sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT)) return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL ); } else { // Write the variable length size. if( (UINT)mmioWrite( hmmio_, (HPSTR)src, sizeof(*src) + src->cbSize ) != ( sizeof(*src) + src->cbSize ) ) return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL ); } // Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk. if( 0 != mmioAscend( hmmio_, &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( hmmio_, &ckOut1, 0 ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); if( mmioWrite( hmmio_, (HPSTR)&dwFactChunk, sizeof(dwFactChunk)) != sizeof(dwFactChunk) ) return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL ); // Now ascend out of the fact chunk... if( 0 != mmioAscend( hmmio_, &ckOut1, 0 ) ) return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL ); return S_OK; }
// 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; }
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; }
/** カーソルを巻き戻す * * @author SAM (T&GG, Org.)<*****@*****.**> * @date 2004/01/21 3:08:18 * Copyright (C) 2001,2002,2003,2004 SAM (T&GG, Org.). All rights reserved. */ HRslt WavFile::rewind() { if(!hmmio_) return CO_E_NOTINITIALIZED; if( flags_&READ ) { // Seek to the data if( -1 == mmioSeek( hmmio_, ckriff_.dwDataOffset + sizeof(FOURCC), SEEK_SET ) ) return DXTRACE_ERR( TEXT("mmioSeek"), E_FAIL ); // Search the input file for the 'data' chunk. ck_.ckid = mmioFOURCC('d','a','t','a'); if( 0 != mmioDescend( hmmio_, &ck_, &ckriff_, MMIO_FINDCHUNK ) ) return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL ); } else { // Create the 'data' chunk that holds the waveform samples. ck_.ckid = mmioFOURCC('d','a','t','a'); ck_.cksize = 0; if( 0 != mmioCreateChunk( hmmio_, &ck_, 0 ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); if( 0 != mmioGetInfo( hmmio_, &write_mmioinfo_, 0 ) ) return DXTRACE_ERR( TEXT("mmioGetInfo"), E_FAIL ); } return S_OK; }
HRESULT WaveDecoder::ResetFile() { if( m_hmmio == NULL ) return CO_E_NOTINITIALIZED; if( m_dwFlags == WAVEFILE_READ ) { // Seek to the data if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof( FOURCC ), SEEK_SET ) ) return E_FAIL; // 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 ) ) return E_FAIL; } 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 ) ) return E_FAIL; if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) ) return E_FAIL; } return S_OK; }
/** * 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); }
int WaveStartDataWrite( HMMIO *phmmioOut, // (IN) MMCKINFO *pckOut, // (IN) MMIOINFO *pmmioinfoOut // (OUT) ) { int nError; nError = 0; /* Create the 'data' chunk that holds the waveform samples. */ pckOut->ckid = mmioFOURCC('d', 'a', 't', 'a'); pckOut->cksize = 0; if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0) { goto ERROR_CANNOT_WRITE; // cannot write file, probably } if ((nError = mmioGetInfo(*phmmioOut, pmmioinfoOut, 0)) != 0) { goto ERROR_CANNOT_WRITE; } goto CLEANUP; ERROR_CANNOT_WRITE: CLEANUP: return(nError); }
/*------------------------------------------------------------------------------*/ 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 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() */
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; }
//----------------------------------------------------------------------------- // Name: WaveStartDataRead() // Desc: This routine has to be called before any data is written to the wave output file, via wavewritefile. This // sets up the data to write, and creates the data chunk. //----------------------------------------------------------------------------- HRESULT WaveStartDataWrite( HMMIO* phmmioOut, MMCKINFO* pckOut, MMIOINFO* pmmioinfoOut ) { // Create the 'data' chunk that holds the waveform samples. pckOut->ckid = mmioFOURCC('d', 'a', 't', 'a'); pckOut->cksize = 0; if( 0 != mmioCreateChunk( *phmmioOut, pckOut, 0 ) ) return E_FAIL; if( 0 != mmioGetInfo( *phmmioOut, pmmioinfoOut, 0 ) ) return E_FAIL; return S_OK; }
//----------------------------------------------------------------------------- // Name: CWaveFile::ResetFile() // Desc: Resets the internal m_ck pointer so reading starts from the // beginning of the file again //----------------------------------------------------------------------------- HRESULT CPCMFile::ResetFile() { if( m_bIsReadingFromMemory ) { m_pbDataCur = m_pbData; } else { if( m_hmmio == NULL ) return CO_E_NOTINITIALIZED; if( m_dwFlags == WAVEFILE_READ ) { // Seek to the data if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC), SEEK_SET ) ) return DXTRACE_ERR( TEXT("mmioSeek"), E_FAIL ); struct _stat buf; _stat(m_strFileName, &buf); // Search the input file for the 'data' chunk. m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a'); m_ck.cksize = buf.st_size; m_ck.fccType = 0; m_ck.dwDataOffset = 0; m_ck.dwFlags = 0; } 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 ) ) return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) ) return DXTRACE_ERR( TEXT("mmioGetInfo"), E_FAIL ); } } return S_OK; }
//----------------------------------------------------------------------------- // Name: CHMWaveFile::ResetFile() // Desc: Resets the internal m_ck pointer so reading starts from the // beginning of the file again //----------------------------------------------------------------------------- HRESULT CHMWaveFile::ResetFile() { if( m_bIsReadingFromMemory ) { m_pbDataCur = m_pbData; } else { if( m_hmmio == NULL ) return CO_E_NOTINITIALIZED; if( m_dwFlags == WAVEFILE_READ ) { // Seek to the data if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC), SEEK_SET ) ) //return DXTRACE_ERR( TEXT("mmioSeek"), E_FAIL ); return -1; // 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 ) ) //return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL ); return -1; } 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 ) ) //return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL ); return -1; if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) ) //return DXTRACE_ERR( TEXT("mmioGetInfo"), E_FAIL ); return -1; } } return S_OK; }
int WaveStartDataWrite( HMMIO *phmmioOut, // (IN) MMCKINFO *pckOut, // (IN) MMIOINFO *pmmioinfoOut // (OUT) ) { int nError=0; /* Create the 'data' chunk that holds the waveform samples. */ pckOut->ckid = mmioFOURCC('d', 'a', 't', 'a'); pckOut->cksize = 0; if ((nError = mmioCreateChunk(*phmmioOut, pckOut, 0)) != 0) { return nError; } nError = mmioGetInfo(*phmmioOut, pmmioinfoOut, 0); return(nError); }
/************************************************************************** * mmioCreateChunk [MMSYSTEM.1225] */ MMRESULT16 WINAPI mmioCreateChunk16(HMMIO16 hmmio, MMCKINFO* lpck, UINT16 uFlags) { return mmioCreateChunk(HMMIO_32(hmmio), lpck, uFlags); }
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); }
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); }
void OpenDevice() { MMRESULT mRes=0; m_stWFEX.nSamplesPerSec=SAMPLES_PER_SEC; m_stWFEX.nChannels=1; m_stWFEX.wBitsPerSample = 16; m_stWFEX.wFormatTag=WAVE_FORMAT_PCM; m_stWFEX.nBlockAlign=m_stWFEX.nChannels*m_stWFEX.wBitsPerSample/8; m_stWFEX.nAvgBytesPerSec=m_stWFEX.nSamplesPerSec*m_stWFEX.nBlockAlign; m_stWFEX.cbSize=sizeof(WAVEFORMATEX); int device = 0; WAVEINCAPS stWIC={0}; ZeroMemory(&stWIC,sizeof(WAVEINCAPS)); mRes=waveInGetDevCaps(device,&stWIC,sizeof(WAVEINCAPS)); if(mRes==0) LOG->Trace( stWIC.szPname ); else FAIL_M("bad"); mRes=waveInOpen(&m_hWaveIn,device,&m_stWFEX,(DWORD_PTR)waveInProc,(DWORD_PTR)this,CALLBACK_FUNCTION); if(mRes!=MMSYSERR_NOERROR) FAIL_M("bad"); const char *csT1 = "C:\\cvs\\stepmania\\speech-test.wav"; ZeroMemory(&m_stmmIF,sizeof(MMIOINFO)); DeleteFile((PCHAR)(LPCTSTR)csT1); m_hOPFile=mmioOpen((PCHAR)(LPCTSTR)csT1,&m_stmmIF,MMIO_WRITE | MMIO_CREATE); if(m_hOPFile==NULL) FAIL_M("Can not open file..."); ZeroMemory(&m_stckOutRIFF,sizeof(MMCKINFO)); m_stckOutRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mRes=mmioCreateChunk(m_hOPFile, &m_stckOutRIFF, MMIO_CREATERIFF); if(mRes!=MMSYSERR_NOERROR) { FAIL_M("bad"); } ZeroMemory(&m_stckOut,sizeof(MMCKINFO)); m_stckOut.ckid = mmioFOURCC('f', 'm', 't', ' '); m_stckOut.cksize = sizeof(m_stWFEX); mRes=mmioCreateChunk(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { FAIL_M("bad"); } int nT1=mmioWrite(m_hOPFile, (HPSTR) &m_stWFEX, sizeof(m_stWFEX)); if(nT1!=sizeof(m_stWFEX)) { FAIL_M("bad"); } mRes=mmioAscend(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { FAIL_M("bad"); } m_stckOut.ckid = mmioFOURCC('d', 'a', 't', 'a'); mRes=mmioCreateChunk(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { FAIL_M("bad"); } }
//----------------------------------------------------------------------------- // 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 WaveDecoder::WriteMMIO( WAVEFORMATEX* pwfxDest ) { DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile. MMCKINFO ckOut1; memset( &ckOut1, 0, sizeof(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( L"mmioCreateChunk", E_FAIL ); return 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( L"mmioCreateChunk", E_FAIL ); return 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( L"mmioWrite", E_FAIL ); return 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( L"mmioWrite", E_FAIL ); return E_FAIL; } // Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk. if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) ) //return DXTRACE_ERR( L"mmioAscend", E_FAIL ); return 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( L"mmioCreateChunk", E_FAIL ); return E_FAIL; if( mmioWrite( m_hmmio, ( HPSTR )&dwFactChunk, sizeof( dwFactChunk ) ) != sizeof( dwFactChunk ) ) //return DXTRACE_ERR( L"mmioWrite", E_FAIL ); return E_FAIL; // Now ascend out of the fact chunk... if( 0 != mmioAscend( m_hmmio, &ckOut1, 0 ) ) //return DXTRACE_ERR( L"mmioAscend", E_FAIL ); return E_FAIL; return S_OK; }
HRESULT WriteWaveHeader(HMMIO file, LPCWAVEFORMATEX pwfx, MMCKINFO* packetRIFF, MMCKINFO* packetData) { MMRESULT result; // make a RIFF/WAVE chunk packetRIFF->ckid = MAKEFOURCC('R', 'I', 'F', 'F'); packetRIFF->fccType = MAKEFOURCC('W', 'A', 'V', 'E'); result = mmioCreateChunk(file, packetRIFF, MMIO_CREATERIFF); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioCreateChunk(\"RIFF/WAVE\") failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } // make a 'fmt ' chunk (within the RIFF/WAVE chunk) MMCKINFO chunk; chunk.ckid = MAKEFOURCC('f', 'm', 't', ' '); result = mmioCreateChunk(file, &chunk, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioCreateChunk(\"fmt \") failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } // write the WAVEFORMATEX data to it LONG lBytesInWfx = sizeof(WAVEFORMATEX) + pwfx->cbSize; LONG lBytesWritten = mmioWrite(file, reinterpret_cast<PCHAR>(const_cast<LPWAVEFORMATEX>(pwfx)), lBytesInWfx); if (lBytesWritten != lBytesInWfx) { fprintf(stderr, "mmioWrite(fmt data) wrote %u bytes; expected %u bytes\n", lBytesWritten, lBytesInWfx); return E_FAIL; } // ascend from the 'fmt ' chunk result = mmioAscend(file, &chunk, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioAscend(\"fmt \" failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } // make a 'fact' chunk whose data is (DWORD)0 chunk.ckid = MAKEFOURCC('f', 'a', 'c', 't'); result = mmioCreateChunk(file, &chunk, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioCreateChunk(\"fmt \") failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } // write (DWORD)0 to it // this is cleaned up later DWORD frames = 0; lBytesWritten = mmioWrite(file, reinterpret_cast<PCHAR>(&frames), sizeof(frames)); if (lBytesWritten != sizeof(frames)) { fprintf(stderr, "mmioWrite(fact data) wrote %u bytes; expected %u bytes\n", lBytesWritten, (UINT32)sizeof(frames)); return E_FAIL; } // ascend from the 'fact' chunk result = mmioAscend(file, &chunk, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioAscend(\"fact\" failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } // make a 'data' chunk and leave the data pointer there packetData->ckid = MAKEFOURCC('d', 'a', 't', 'a'); result = mmioCreateChunk(file, packetData, 0); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "mmioCreateChunk(\"data\") failed: MMRESULT = 0x%08x\n", result); return E_FAIL; } return S_OK; }
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 CWaveFile::StartRecord(LPCTSTR lpszFilePath, WAVEFORMATEX wfx) { CString strErr; MMRESULT mmResult = 0; if(m_hWaveFileRec) { return TRUE; } // Truncate file first mmioOpen((LPTSTR)lpszFilePath, NULL, MMIO_DELETE); m_hWaveFileRec = mmioOpen((LPTSTR)lpszFilePath, NULL, MMIO_CREATE | MMIO_WRITE | MMIO_EXCLUSIVE | MMIO_ALLOCBUF); if(!m_hWaveFileRec) { MyMessageBox(_T("mmioOpen failed"), eERR_ERROR); return FALSE; } // Create 'WAVE' chunk ZeroMemory(&m_mmckinfoParent, sizeof(MMCKINFO)); m_mmckinfoParent.fccType = mmioFOURCC('W','A','V','E'); mmResult = mmioCreateChunk(m_hWaveFileRec, &m_mmckinfoParent, MMIO_CREATERIFF); if(mmResult) { MyMessageBox(_T("Create 'WAVE' chunk failed"), eERR_ERROR); return FALSE; } // Create 'fmt ' chunk ZeroMemory(&m_mmckinfoSubChunk, sizeof(MMCKINFO)); m_mmckinfoSubChunk.ckid = mmioFOURCC('f','m','t',' '); m_mmckinfoSubChunk.cksize = sizeof(WAVEFORMATEX) + wfx.cbSize; mmResult = mmioCreateChunk(m_hWaveFileRec, &m_mmckinfoSubChunk, 0); if(mmResult) { MyMessageBox(_T("Create 'fmt' chunk failed"), eERR_ERROR); return FALSE; } // Write format chunk long lSize = mmioWrite(m_hWaveFileRec, (char*)&wfx, sizeof(WAVEFORMATEX) + wfx.cbSize); if(lSize <= 0) { MyMessageBox(_T("Create format chunk failed"), eERR_ERROR); return FALSE; } mmResult = mmioAscend(m_hWaveFileRec, &m_mmckinfoSubChunk, 0); if(mmResult) { MyMessageBox(_T("mmioAscend failed"), eERR_ERROR); return FALSE; } // Crate 'data' chunk m_mmckinfoSubChunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); mmResult = mmioCreateChunk(m_hWaveFileRec, &m_mmckinfoSubChunk, 0); if(mmResult) { MyMessageBox(_T("Create 'data' chunk failed"), eERR_ERROR); return FALSE; } return TRUE; }
LRESULT WriteSound::OnCreateFile(WPARAM wParam, LPARAM lParam) { int cbsize; MMRESULT mmret; char *filename=(char*)lParam; char str[200]; sprintf(str,"filename is %s ",filename); log.WriteString(str); log.WriteString("\n Creating new file "); m_hwrite=::mmioOpen(filename,NULL,MMIO_CREATE |MMIO_WRITE | MMIO_EXCLUSIVE | MMIO_ALLOCBUF); if(filename) delete filename; if(m_hwrite==NULL) { log.WriteString("Unable to create the specified file"); return FALSE; } //AfxMessageBox("File created "); log.WriteString("\n File created successfully"); ZeroMemory(&riffblock,sizeof(MMCKINFO)); ZeroMemory(&fmtblock,sizeof(MMCKINFO)); ZeroMemory(&datablock,sizeof(MMCKINFO)); riffblock.fccType=mmioFOURCC('W','A','V','E'); mmret=mmioCreateChunk(m_hwrite,&riffblock,MMIO_CREATERIFF); if(mmret!=MMSYSERR_NOERROR) { log.WriteString("\n Riff format writing error"); return FALSE; } fmtblock.ckid=mmioFOURCC('f','m','t',' '); cbsize=sizeof(WAVEFORMATEX)-2; fmtblock.cksize=cbsize; mmret=mmioCreateChunk(m_hwrite,&fmtblock,0); if(mmret!=MMSYSERR_NOERROR) { log.WriteString("\n fmt format writing error"); return FALSE; } ::mmioWrite(m_hwrite,(const char*)&waveformat,cbsize); datablock.ckid=mmioFOURCC('d','a','t','a'); mmret=mmioCreateChunk(m_hwrite,&datablock,0); if(mmret!=MMSYSERR_NOERROR) { log.WriteString("\n data format writing error"); return FALSE; } log.WriteString("\n Format details written successfully"); return TRUE; }
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; }
BOOL CWaveRecord::CreateWaveFile(LPCTSTR lpszWaveFileName, UINT nCh) { CString strErr; CString strFileName = lpszWaveFileName; MMRESULT mmResult = 0; WAVEFORMATEX wfx = m_format; if(nCh < 0 || nCh >= 2) { MyMessageBox(_T("The channel is out of range"), eERR_ERROR); return FALSE; } if(m_hWaveFile[nCh]) { return TRUE; } // Truncate file first mmioOpen((LPTSTR)lpszWaveFileName, NULL, MMIO_DELETE); if(m_nChs == eCH_STEREO) { wfx.nChannels = 2; } else { wfx.nChannels =1; } m_hWaveFile[nCh] = mmioOpen((LPTSTR)lpszWaveFileName, NULL, MMIO_CREATE | MMIO_WRITE | MMIO_EXCLUSIVE | MMIO_ALLOCBUF); if(!m_hWaveFile[nCh]) { MyMessageBox(_T("mmioOpen failed"), eERR_ERROR); return FALSE; } // Create 'wave' format ZeroMemory(&mmckinfoParent[nCh], sizeof(MMCKINFO)); mmckinfoParent[nCh].fccType = mmioFOURCC('W','A','V','E'); mmResult = mmioCreateChunk(m_hWaveFile[nCh], &mmckinfoParent[nCh], MMIO_CREATERIFF); if(mmResult) { MyMessageBox(_T("Create 'WAVE' chunk failed"), eERR_ERROR); return FALSE; } // Create 'fmt ' chunk ZeroMemory(&mmckinfoSubChunk[nCh], sizeof(MMCKINFO)); mmckinfoSubChunk[nCh].ckid = mmioFOURCC('f','m','t',' '); mmckinfoSubChunk[nCh].cksize = sizeof(WAVEFORMATEX) + wfx.cbSize; mmResult = mmioCreateChunk(m_hWaveFile[nCh], &mmckinfoSubChunk[nCh], 0); if(mmResult) { MyMessageBox(_T("Create 'fmt' chunk failed"), eERR_ERROR); return FALSE; } // Create format chunk long lSize = mmioWrite(m_hWaveFile[nCh], (char*)&wfx, sizeof(WAVEFORMATEX) + wfx.cbSize); if(lSize <= 0) { MyMessageBox(_T("Create format chunk failed"), eERR_ERROR); return FALSE; } mmResult = mmioAscend(m_hWaveFile[nCh], &mmckinfoSubChunk[nCh], 0); if(mmResult) { MyMessageBox(_T("mmioAscend failed"), eERR_ERROR); return FALSE; } // Crate 'data' chunk mmckinfoSubChunk[nCh].ckid = mmioFOURCC('d', 'a', 't', 'a'); mmResult = mmioCreateChunk(m_hWaveFile[nCh], &mmckinfoSubChunk[nCh], 0); if(mmResult) { MyMessageBox(_T("Create 'data' chunk failed"), eERR_ERROR); return FALSE; } return TRUE; }
VOID CSoundRecDlg::OpenDevice() { int nT1=0; CString csT1; double dT1=0.0; MMRESULT mRes=0; CComboBox *pDevices=(CComboBox*)GetDlgItem(IDC_DEVICES); CComboBox *pFormats=(CComboBox*)GetDlgItem(IDC_FORMATS); nT1=pFormats->GetCurSel(); if(nT1==-1) throw ""; pFormats->GetLBText(nT1,csT1); sscanf((PCHAR)(LPCTSTR)csT1,"%lf",&dT1); dT1=dT1*1000; m_stWFEX.nSamplesPerSec=(int)dT1; csT1=csT1.Right(csT1.GetLength()-csT1.Find(',')-1); csT1.Trim(); if(csT1.Find("mono")!=-1) m_stWFEX.nChannels=1; if(csT1.Find("stereo")!=-1) m_stWFEX.nChannels=2; csT1=csT1.Right(csT1.GetLength()-csT1.Find(',')-1); csT1.Trim(); sscanf((PCHAR)(LPCTSTR)csT1,"%d",&m_stWFEX.wBitsPerSample); m_stWFEX.wFormatTag=WAVE_FORMAT_PCM; m_stWFEX.nBlockAlign=m_stWFEX.nChannels*m_stWFEX.wBitsPerSample/8; m_stWFEX.nAvgBytesPerSec=m_stWFEX.nSamplesPerSec*m_stWFEX.nBlockAlign; m_stWFEX.cbSize=sizeof(WAVEFORMATEX); mRes=waveInOpen(&m_hWaveIn,pDevices->GetCurSel(),&m_stWFEX,(DWORD_PTR)waveInProc,(DWORD_PTR)this,CALLBACK_FUNCTION); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } GetDlgItem(IDC_FILENAME)->GetWindowText(csT1); ZeroMemory(&m_stmmIF,sizeof(MMIOINFO)); DeleteFile((PCHAR)(LPCTSTR)csT1); m_hOPFile=mmioOpen((PCHAR)(LPCTSTR)csT1,&m_stmmIF,MMIO_WRITE | MMIO_CREATE); if(m_hOPFile==NULL) throw "Can not open file..."; ZeroMemory(&m_stckOutRIFF,sizeof(MMCKINFO)); m_stckOutRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mRes=mmioCreateChunk(m_hOPFile, &m_stckOutRIFF, MMIO_CREATERIFF); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } ZeroMemory(&m_stckOut,sizeof(MMCKINFO)); m_stckOut.ckid = mmioFOURCC('f', 'm', 't', ' '); m_stckOut.cksize = sizeof(m_stWFEX); mRes=mmioCreateChunk(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } nT1=mmioWrite(m_hOPFile, (HPSTR) &m_stWFEX, sizeof(m_stWFEX)); if(nT1!=sizeof(m_stWFEX)) { m_csErrorText.Format("Can not write Wave Header..File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } mRes=mmioAscend(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } m_stckOut.ckid = mmioFOURCC('d', 'a', 't', 'a'); mRes=mmioCreateChunk(m_hOPFile, &m_stckOut, 0); if(mRes!=MMSYSERR_NOERROR) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } // Open FAAC encoder m_hAACEncoder = faacEncOpen(m_stWFEX.nSamplesPerSec, m_stWFEX.nChannels, &m_nMaxInputSamples, &m_nMaxOutputBytes); ShowDebug(_T("CSoundRecDlg::faacEncOpen m_nMaxInputSamples=%d, m_nMaxOutputBytes=%d"), m_nMaxInputSamples, m_nMaxOutputBytes); if (m_hAACEncoder == NULL) { StoreError(mRes,FALSE,"File: %s ,Line Number:%d",__FILE__,__LINE__); throw m_csErrorText; } m_pbAACBuffer = new BYTE[m_nMaxOutputBytes]; if (m_pbAACBuffer == NULL) { return; } // Get current encoding configuration m_pAACConfiguration = faacEncGetCurrentConfiguration(m_hAACEncoder); // switch (m_stWFEX.wBitsPerSample) // { // case 16: // m_pAACConfiguration->inputFormat = FAAC_INPUT_16BIT; // break; // case 24: // m_pAACConfiguration->inputFormat = FAAC_INPUT_24BIT; // break; // case 32: // m_pAACConfiguration->inputFormat = FAAC_INPUT_32BIT; // break; // default: // m_pAACConfiguration->inputFormat = FAAC_INPUT_16BIT; // } m_pAACConfiguration->inputFormat = FAAC_INPUT_16BIT; // Set encoding configuration int nRet = faacEncSetConfiguration(m_hAACEncoder, m_pAACConfiguration); errno_t err = fopen_s(&m_fpAACOutput, "out.aac", "wb"); }