📄 dialogs.c
字号:
/* try and find seconds */
pDelim = strrchr(achTime, ':'); // get last ':'
if (*pDelim) {
p = (pDelim+1);
} else {
// no colon - assume just seconds in string
p = achTime;
}
dwSecs = atoi(p);
if (*pDelim) {
*pDelim = '\0';
/* go and get the minutes part */
pDelim = strrchr(achTime, ':');
if (*pDelim) {
p = (pDelim + 1);
} else {
// no more colons - assume remainder is just minutes
p = achTime;
}
dwMins = atoi(p);
if (*pDelim) {
*pDelim = '\0';
/* get the hours */
p = achTime;
dwHours = atoi(p);
}
}
/* now we've got the hours, minutes, seconds and any */
/* fractional part. Time to build up the total time */
dwSecs += (dwHours * 3600); // add in hours worth of seconds
dwSecs += (dwMins * 60); // add in minutes worth of seconds
dwMSecs = (dwSecs * 1000L);
dwMSecs += (wHundredths * 10L);
/* now we've got the total number of milliseconds */
return dwMSecs;
}
/*
* MCIDeviceClose
* This routine closes the open MCI device.
*/
void MCIDeviceClose (void)
{
mciSendString( "close mciframes", NULL, 0, NULL );
}
/*
* MCIDeviceOpen
* This routine opens the mci device for use, and sets the
* time format to milliseconds.
* Return FALSE on error;
*/
BOOL MCIDeviceOpen (LPSTR lpDevName)
{
char ach[160];
DWORD dwMCIError;
wsprintf( ach, "open %s shareable wait alias mciframes", (LPSTR) lpDevName);
dwMCIError = mciSendString( ach, NULL, 0, NULL );
if( dwMCIError ) {
return(FALSE);
}
dwMCIError = mciSendString( "set mciframes time format milliseconds",
NULL, 0, NULL );
if( dwMCIError ) {
MCIDeviceClose();
return(FALSE);
}
return ( TRUE );
}
/*
* MCIDeviceGetPosition
* Stores the current device position in milliseconds in lpdwPos.
* Returns TRUE on success, FALSE if error.
*/
BOOL FAR PASCAL MCIDeviceGetPosition (LPDWORD lpdwPos)
{
char ach[80];
DWORD dwMCIError;
dwMCIError = mciSendString( "status mciframes position wait",
ach, sizeof(ach), NULL );
if( dwMCIError ) {
*lpdwPos = 0L;
return FALSE;
}
*lpdwPos = atol( ach );
return TRUE;
}
#ifndef USE_ACM
// --- audio streaming ------------------------------------------------
// the ShowLevel dialog streams data in from the input and
// shows the current volume.
// buffers into which sound data is recorded
#define NUM_LEVEL_BUFFERS 2
// the buffer size is calculated to be about 1/20 sec
#define UPDATES_PER_SEC 20
/*
* we save all our data in one of these, and write a pointer to it
* into the dialog DWL_USER field.
*/
typedef struct _LevelStreamData {
LPWAVEHDR alpWave[NUM_LEVEL_BUFFERS];
PCMWAVEFORMAT FAR * pwf;
HWAVEIN hwav;
int buffersize;
} LEVELSTREAMDATA, FAR * PLEVELSTREAMDATA;
//open the wave-device in the given format, queue all the buffers and
//start data streaming. Save the wavein device to the dialog DWL_USER window
//data area so we can close it on dialog dismissal.
BOOL
OpenStream(HWND hDlg, PCMWAVEFORMAT FAR * pwf)
{
PLEVELSTREAMDATA pInfo;
int i;
pInfo = (PLEVELSTREAMDATA) GlobalLock(GlobalAlloc(GHND, sizeof(LEVELSTREAMDATA)));
if (pInfo == NULL) {
return(FALSE);
}
// complete remaining areas of wf
pwf->wf.wFormatTag = WAVE_FORMAT_PCM;
pwf->wf.nBlockAlign = pwf->wf.nChannels * pwf->wBitsPerSample / 8;
pwf->wf.nAvgBytesPerSec = pwf->wf.nSamplesPerSec * pwf->wf.nBlockAlign;
// save for later use
pInfo->pwf = pwf;
// buffer size a fixed fraction of a second
pInfo->buffersize = pwf->wf.nAvgBytesPerSec/UPDATES_PER_SEC;
pInfo->hwav = NULL;
if (waveInOpen(
&pInfo->hwav,
WAVE_MAPPER,
(LPWAVEFORMATEX)pwf,
(DWORD) hDlg, // callback via MM_WIM_ messages to dialogproc
0,
CALLBACK_WINDOW)) {
SetWindowLong(hDlg, DWL_USER, 0);
return(FALSE);
}
// store the info structure in the dialog, so that even if we fail
// on this routine we will clean up correctly
SetWindowLong(hDlg, DWL_USER, (long) pInfo);
// set all the wave headers to null (for cleanup if error)
for (i = 0; i < NUM_LEVEL_BUFFERS; i++) {
pInfo->alpWave[i] = NULL;
}
// alloc, prepare and add all the buffers
for (i = 0; i < NUM_LEVEL_BUFFERS; i++) {
pInfo->alpWave[i] = GlobalLock(GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,
sizeof(WAVEHDR) + pInfo->buffersize));
if (pInfo->alpWave[i] == NULL) {
return(FALSE);
}
pInfo->alpWave[i]->lpData = (LPBYTE) (pInfo->alpWave[i] + 1);
pInfo->alpWave[i]->dwBufferLength = pInfo->buffersize;
pInfo->alpWave[i]->dwBytesRecorded = 0;
pInfo->alpWave[i]->dwUser = 0;
pInfo->alpWave[i]->dwFlags = 0;
pInfo->alpWave[i]->dwLoops = 0;
if (waveInPrepareHeader(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR))) {
return(FALSE);
}
if (waveInAddBuffer(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR))) {
return(FALSE);
}
}
waveInStart(pInfo->hwav);
return(TRUE);
}
// terminate the data streaming on a wavein device associated with a
// dialog, and clean up the buffers allocated
void
CloseStream(HWND hDlg)
{
PLEVELSTREAMDATA pInfo;
int i;
// pick up our info from the dialog
pInfo = (PLEVELSTREAMDATA) GetWindowLong(hDlg, DWL_USER);
if ((pInfo == NULL) || (pInfo->hwav == NULL)) {
return;
}
// stop streaming data
waveInStop(pInfo->hwav);
// release all buffers
waveInReset(pInfo->hwav);
// unlock and free buffers
for (i = 0; i < NUM_LEVEL_BUFFERS; i++) {
if (pInfo->alpWave[i]) {
waveInUnprepareHeader(pInfo->hwav, pInfo->alpWave[i], sizeof(WAVEHDR));
GlobalFree(GlobalHandle(pInfo->alpWave[i]));
pInfo->alpWave[i] = NULL;
}
}
waveInClose(pInfo->hwav);
GlobalFree(GlobalHandle(pInfo));
SetWindowLong(hDlg, DWL_USER, 0);
}
// we have received a block of data. work out the level(s) and send to
// the appropriate control on the dialog, and then requeue the buffer.
// return FALSE if any error occurs, otherwise TRUE
BOOL
StreamData(HWND hDlg, HWAVEIN hwav, LPWAVEHDR pHdr)
{
PLEVELSTREAMDATA pInfo;
int n = 0;
int LevelLeft = 0, LevelRight = 0;
int i, l;
// pick up our info from the dialog
pInfo = (PLEVELSTREAMDATA) GetWindowLong(hDlg, DWL_USER);
if ((pInfo == NULL) || (pInfo->hwav != hwav)) {
return FALSE;
}
// go through all samples in buffer looking for maximum absolute level
while (n < pInfo->buffersize) {
/*
* volumes go above and below the mean level - we are
* interested in the absolute volume
* 8 bit samples are in the range 0..255
* 16-bit samples are in the range -32768..+32767
*/
// skip the first byte if 16-bit
// and adjust to be in range -127..+128
if (pInfo->pwf->wBitsPerSample == 16) {
n++;
i = (int) (signed char) pHdr->lpData[n];
} else {
i = (int) ((unsigned char) pHdr->lpData[n]) - 128;
}
// skip past the byte we've picked up
n++;
// take absolute volume level
if (i < 0) {
i = -i;
}
// convert to percentage
l = (i*100) / 128;
// compare against current max
if (LevelLeft < l) {
LevelLeft = l;
}
// if stereo, repeat for right channel
if (pInfo->pwf->wf.nChannels == 2) {
// skip the first byte if 16-bit
if (pInfo->pwf->wBitsPerSample == 16) {
n++;
i = (int) (signed char) pHdr->lpData[n];
} else {
i = (int) ((unsigned char) pHdr->lpData[n]) - 128;
}
// skip past the byte we've picked up
n++;
// take absolute volume level
if (i < 0) {
i = -i;
}
// convert to percentage
l = (i*100) / 128;
// compare against current max
if (LevelRight < l) {
LevelRight = l;
}
}
}
// put the buffer back on the queue
if (waveInAddBuffer(pInfo->hwav, pHdr, sizeof(WAVEHDR))) {
return(FALSE);
}
// send new level to dialog control
SendDlgItemMessage(hDlg, IDRL_LEVEL1, WMRL_SETLEVEL, 0, LevelLeft);
if (pInfo->pwf->wf.nChannels == 2) {
SendDlgItemMessage(hDlg, IDRL_LEVEL2, WMRL_SETLEVEL, 0, LevelRight);
}
return(TRUE);
}
#endif // ! USE_ACM
// --- dialog procs -----------------------------------------------------
//
// AboutProc: About Dialog Box Procedure
//
int FAR PASCAL AboutProc(HWND hDlg, UINT Message, UINT wParam, LONG lParam)
{
switch (Message) {
case WM_INITDIALOG :
return TRUE ;
case WM_COMMAND :
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK :
EndDialog(hDlg, TRUE) ;
return TRUE ;
case IDCANCEL :
EndDialog(hDlg, FALSE) ;
return TRUE ;
}
break ;
}
return FALSE ;
}
#ifndef USE_ACM
/*
* dialog proc for IDD_RECLVLMONO and IDD_RECLVLSTEREO - show current
* volume level
*/
int FAR PASCAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -