예제 #1
0
//-----------------------------------------------------------------------------
// 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;
}
예제 #2
0
void CWaveFile::WriteRecData2File(char* pszData, DWORD dwBufSize)
{
	int nRecBytes = dwBufSize;

	if(m_hWaveFileRec)
	{
		int nLength = mmioWrite(m_hWaveFileRec, pszData, dwBufSize);
		if(nRecBytes != nLength)
		{
			StopRecord();
		}
	}
}
예제 #3
0
// 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;
}
예제 #4
0
	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");
		}
	}
예제 #5
0
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;
}
예제 #7
0
파일: mmrecord.c 프로젝트: sfsy1989/j2me
/**
 * 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);
}
예제 #8
0
파일: Wave.cpp 프로젝트: p2world/remotelite
/*------------------------------------------------------------------------------*/
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;
}
예제 #9
0
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;
}
예제 #10
0
	/** ストリームを閉じる
	 *
	 * @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;
	}
예제 #11
0
	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 ));

	}
예제 #12
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);
}
예제 #13
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);
}
예제 #14
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;
}
예제 #15
0
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);
}
예제 #16
0
//-----------------------------------------------------------------------------
// 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;   
}
예제 #17
0
파일: Wave.cpp 프로젝트: mygaldre/mmvari
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;
}
예제 #18
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]);
}
예제 #19
0
파일: Wave.cpp 프로젝트: mygaldre/mmvari
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;
				}
			}
		}
	}
}
예제 #20
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() */
예제 #21
0
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__);

		
	}
}
예제 #22
0
void RecordBuffer(unsigned char* pSound,long lBytes)
{
 // write the samples
 if(hWaveFile)
	 mmioWrite(hWaveFile, (const char *) pSound,lBytes);
}
예제 #23
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;
}
예제 #24
0
파일: wavfile.c 프로젝트: UIKit0/wine-1
static HRESULT AVIFILE_SaveFile(const IAVIFileImpl *This)
{
  MMCKINFO ckRIFF;
  MMCKINFO ck;

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

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

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

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

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

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

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

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

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

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

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

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

  return AVIERR_OK;
}
예제 #25
0
파일: mmio16.c 프로젝트: bilboed/wine
/**************************************************************************
 * 				mmioWrite      		[MMSYSTEM.1213]
 */
LONG WINAPI mmioWrite16(HMMIO16 hmmio, HPCSTR pch, LONG cch)
{
    return mmioWrite(HMMIO_32(hmmio),pch,cch);
}
예제 #26
0
파일: wave.c 프로젝트: Ghosthunt7/feos-tas
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); 
} 
예제 #27
0
파일: wave.c 프로젝트: Ghosthunt7/feos-tas
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;
}
예제 #29
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;
}
예제 #30
0
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;
}