⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavrec.cpp

📁 WinCE5.0BSP for Renesas SH7770
💻 CPP
字号:
//
//  Copyright(C) Renesas Technology Corp. 2004-2005. All rights reserved.
//
// OAL Test for ITS-DS7
//
// FILE     : WAVREC.CPP
// CREATED  : 2004.09.01
// MODIFIED : 2005.03.04
// AUTHOR   : Renesas Technology Corp.
// HARDWARE : RENESAS ITS-DS7
// HISTORY  : 
//            2004.09.01
//            - Created release code.
//              (based on SDK for WCE5.0)
//            2005.03.04
//            - Modified use a blank for a file name.
//            - Modified IOCTL_MIX_MESSAGE corresponded to WAV1:.
//

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <dsound.h>
#include <wavedev.h>
#include <wavemdd.h>
#include "wavefile.h"

#define NELEMS(a) (sizeof(a)/sizeof((a)[0]))

#define MRCHECK(mr,str)\
    if ((mr != MMSYSERR_NOERROR)) { RETAILMSG(1, (TEXT(#str) TEXT(" failed. mr=%08x\r\n"), mr)); goto ERROR_DONE;}

MMRESULT
RecordWaveBuffer (PWAVEHDR pwh, DWORD dwDeviceId, PWAVEFORMATEX pwfx, DWORD dwDuration)
{ const DWORD dwTolerance = 1000;
  DWORD dwWait;
  HANDLE hevDone;
  HWAVEIN hwi;

    // create an event so we know when capture is completed
    hevDone = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (hevDone == NULL) {
        RETAILMSG (1, (TEXT("Unable to create completion event\r\n")));
        return MMSYSERR_NOMEM;
    }

    // open the wave capture device
    MMRESULT mr = waveInOpen(&hwi, dwDeviceId, pwfx, (DWORD) hevDone, NULL, CALLBACK_EVENT);
    if (mr != MMSYSERR_NOERROR) {
        RETAILMSG(1, (TEXT("waveInOpen failed. mr=%08x\r\n"), mr));
        return mr;
    }

    // set up the WAVEHDR structure that describes the capture buffer

    // prepare the buffer for capture
    mr = waveInPrepareHeader(hwi, pwh, sizeof(WAVEHDR));
    MRCHECK(mr, waveInPrepareHeader);

    // submit the buffer for capture
    mr = waveInAddBuffer(hwi, pwh, sizeof(WAVEHDR));
    MRCHECK(mr, waveInAddBuffer);



    // start capturing
    RETAILMSG(1, (TEXT("Starting capture...\r\n")));
    mr = waveInStart(hwi);
    MRCHECK(mr, waveInStart);

    // wait for completion + 1 second tolerance
    dwWait= WaitForSingleObject(hevDone, dwDuration + dwTolerance); 
    if (dwWait != WAIT_OBJECT_0) {
        RETAILMSG(1, (TEXT("Timeout waiting for capture to complete, writing partialy file.\r\n")));
        mr = waveInReset(hwi);
        if (mr != MMSYSERR_NOERROR) {
            RETAILMSG(1, (TEXT("warning: waveInReset failed. mr=%08x\r\n"), mr));
        }
    }

    // now clean up: unprepare the buffer
    mr = waveInUnprepareHeader(hwi, pwh, sizeof(WAVEHDR));
    MRCHECK(mr, waveInUnprepareHeader);

ERROR_DONE:
    // close the capture device & free the event handle
    mr = waveInClose(hwi);
    if (mr != MMSYSERR_NOERROR) {
        RETAILMSG(1, (TEXT("warning: waveInClose failed. mr=%08x\r\n"), mr));
    }

    CloseHandle(hevDone);

    return mr;
}

MMRESULT
RecordWaveFile (PCTSTR pszFilename, DWORD dwDeviceId, PWAVEFORMATEX pwfx, DWORD dwDuration)
{ MMRESULT mr;
  PBYTE pBufferBits;
  DWORD dwBufferSize;

    // compute the size of the capture buffer
    // compute total # of samples & multiply by blocksize to get sample-aligned buffer size
    dwBufferSize = (dwDuration * pwfx->nSamplesPerSec / 1000) * pwfx->nBlockAlign;

    // let user know what's going on
    RETAILMSG(1, (TEXT("Recording %5d ms to \"%s\": %c%02d %5dHz (%8d bytes)\r\n")
        , dwDuration
        , pszFilename
        , pwfx->nChannels == 2 ? L'S' : L'M' 
        , pwfx->wBitsPerSample
        , pwfx->nSamplesPerSec
        , dwBufferSize
        ));
    
    // try to allocate the capture buffer
    pBufferBits = new BYTE [dwBufferSize];
    if (pBufferBits == NULL) {
        RETAILMSG (1, (TEXT("Unable to allocate %d bytes for %d ms of audio data\r\n"), dwBufferSize, dwDuration));
        return MMSYSERR_NOMEM;
    }
    WAVEHDR hdr;
    memset(&hdr, 0, sizeof(WAVEHDR));
    hdr.dwBufferLength = dwBufferSize;
    hdr.lpData = (char *) pBufferBits;

    mr = RecordWaveBuffer(&hdr, dwDeviceId, pwfx, dwDuration);
    MRCHECK(mr, RecordWaveBuffer);

    // finally, write the captured buffer to the file
    // note that we use hdr.dwBytesRecorded, not dwBuffersize.
    RETAILMSG(1, (TEXT("Capture completed. Writing %s\r\n"), pszFilename));
    mr = WriteWaveFile(pszFilename, pwfx, hdr.dwBytesRecorded, pBufferBits);
    MRCHECK(mr, WriteWaveFile);

ERROR_DONE:
    // free up the capture buffer and release the done event
    delete [] pBufferBits;

    // and we're done
    return mr;
}


PTSTR usage_text[] =
{
    TEXT("usage:\r\n"),
    TEXT("       -f <filename>    output filename\r\n"),
    TEXT("       -r <rate>        sample rate\r\n"),
    TEXT("       -b <8|16>        sample size in bits\r\n"),
    TEXT("       -c <1|2>         channels (mono/stereo)\r\n"),
    TEXT("       -t <duration>	  recording time in milliseconds\r\n"),
    TEXT("       -d <device>      device index\r\n"),
    TEXT("       -i <Mic|LineIn>  InputSelect (0:Mic / 1:LineIN)\r\n"),
    TEXT("       -?               help\r\n"),
};

void
Usage(void)
{ int i;

    for (i = 0; i < NELEMS(usage_text); i++) {
        RETAILMSG(1, (usage_text[i]));
    }
}

int 
WINAPI WinMain 
    ( HINSTANCE hInstance
    , HINSTANCE hPrevInstance
    , PTSTR pCmdLine
    , int nCmdShow
    )
{ PTSTR pOption;
  TCHAR ws[] = TEXT(" \t");
  int errors = 0;
    MMDRV_MESSAGE_PARAMS	Param;
    MIXERCONTROLDETAILS		mix;
    DWORD					details[2];
    HANDLE					h;
	TCHAR szWavDev[16];
	UINT cmdlen;
	PTSTR pNext;

    // The run parameters
    // Set up defaults to be overridden by command line
    PTSTR pszFilename = TEXT("wavrec.wav");
    DWORD dwDuration = 5 * 1000;    // record for 5 seconds
    DWORD dwChannels = 1;           // default to mono
    DWORD dwBitsPerSample = 16;     // default to 16-bit samples
    DWORD dwSampleRate = 11025;     // default to 11.025KHz sample rate
    DWORD dwDeviceId = 0;           // capture from device 0
    DWORD dwInputSelect = 0;        // Input Select
	BOOL bIsSelected=FALSE;

	cmdlen = _tcslen(pCmdLine);
    // parse the command line
    for (pOption = _tcstok(pCmdLine, ws); pOption != NULL; pOption = _tcstok(NULL, ws)) {
        if (pOption[0] != '/' && pOption[0] != '-') {
            RETAILMSG(1, (TEXT("Unrecognized argument %s\r\n"), pOption));
            errors++;
            continue;
        }
        PTSTR pParameter = _tcstok(NULL, ws);
        if (pParameter == NULL) {
            RETAILMSG(1, (TEXT("Missing parameter to option %s\r\n"), pOption));
        }
        switch (pOption[1]) {
        case 'f':
			pszFilename = pParameter;
			for(pNext=&pParameter[_tcslen(pParameter)+1];*pNext==' ' || *pNext=='\t';pNext++) ;

			// case:space in filename
			// "\CD-ROM Drive\xxx.wav"
			while(cmdlen > (UINT)(pParameter-pCmdLine+_tcslen(pParameter)) && *pNext != '-'){
				//skip(also filename)
				pParameter[_tcslen(pParameter)] = ' ';
				pParameter = _tcstok(NULL, ws);
				for(pNext=&pParameter[_tcslen(pParameter)+1];*pNext==' ' || *pNext=='\t';pNext++) ;
			}
            break;

        case 't':
            dwDuration = _ttoi(pParameter);
            break;

        case 'c':
            dwChannels = _ttoi(pParameter);
            break;

        case 'r':
            dwSampleRate = _ttoi(pParameter);
            break;

        case 'b':
            dwBitsPerSample = _ttoi(pParameter);
            break;

	case 'd':
	    dwDeviceId = _ttoi(pParameter);
	    break;

	case 'i':
	    dwInputSelect = _ttoi(pParameter);
		bIsSelected = TRUE;
	    break;

        case '?':
        case 'h':
            Usage();
            errors++;
            break;

        default:
            RETAILMSG(1, (TEXT("Unrecognized option %s\r\n"), pOption));
            errors++;
            break;
        }
    }

    if (errors > 0) {
        // we've already issued complaint, now just exit
        return -1;
    }

	if(bIsSelected){
	    _stprintf( szWavDev, TEXT("WAV%d:"), dwDeviceId );
		// Input Select (Mic / LineIN)
		h = CreateFile (
						szWavDev,
						GENERIC_READ | GENERIC_WRITE,
		               	0,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL,
						NULL
						);
		if( dwInputSelect == 0 ){
			details[0] = 0;		// Line IN
			details[1] = 1;		// Mic
		}
		else{
			details[0] = 1;		// Line IN
			details[1] = 0;		// Mic
		}
		mix.dwControlID  = 2;
		mix.cMultipleItems = 2;
		mix.paDetails = details;
		Param.uDeviceId  = dwDeviceId;
		Param.uMsg       = MXDM_SETCONTROLDETAILS;
		Param.dwUser     = 0;
		Param.dwParam1   = (DWORD)&mix;
		Param.dwParam2   = 0;

		DeviceIoControl( h, IOCTL_MIX_MESSAGE, (PBYTE)&Param, (DWORD)sizeof(Param), 0, 0, 0, 0 );

		CloseHandle ( h );
	}

    // set up the wave format structure
    WAVEFORMATEX wfx;
    wfx.cbSize = 0;
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.wBitsPerSample = (WORD) dwBitsPerSample;
    wfx.nSamplesPerSec = dwSampleRate;
    wfx.nChannels = (WORD) dwChannels;
    wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
    wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;

    // we're all set: go do the real work
    RecordWaveFile(pszFilename, dwDeviceId, &wfx, dwDuration);

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -