1311 lines
31 KiB
C
1311 lines
31 KiB
C
//==========================================================================;
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
|
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
|
// PURPOSE.
|
|
//
|
|
// Copyright (c) 1992 - 1994 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// aaplyrec.c
|
|
//
|
|
// Description:
|
|
// An play/record dialog based on MCI Wave.
|
|
//
|
|
//
|
|
// Known Bugs In MCIWAVE for Windows 3.1:
|
|
// ======================================
|
|
//
|
|
// o If you are running SHARE (or the equivelant) and attempt to open
|
|
// a file that is open by another application, you will receive the
|
|
// following error:
|
|
//
|
|
// "Cannot find the specified file. Make sure the path and
|
|
// filename are correct..."
|
|
//
|
|
// This is of course wrong. The problem is the file cannot be opened
|
|
// read/write by multiple applications.
|
|
//
|
|
// o Opening a wave file that is more than about three seconds long and
|
|
// issueing the following commands will hang Windows:
|
|
//
|
|
// open xxx.wav alias zyz ; open > 3 second file
|
|
// delete zyz from 1000 to 2000 ; remove some data
|
|
// delete zyz from 1000 to 2000 ; do it again and you hang
|
|
//
|
|
// I think this will also happen with the following commands:
|
|
//
|
|
// open c:\win31\ding.wav alias zyz
|
|
// delete zyz to 100
|
|
//
|
|
// o You cannot play or record data with a synchronous wave device. This
|
|
// is due to MCIWAVE relying on the ability to 'stream' data. This is
|
|
// not really a bug, just a limitation.
|
|
//
|
|
// o Block alignment is not correctly handled for non-PCM wave files
|
|
// when editing (includes recording). It is illegal to start recording
|
|
// in the middle of a block. The result if this happens is garbage
|
|
// data. This occurs if you insert data with a partial block at the
|
|
// end also...
|
|
//
|
|
// o It is possible to kill Windows by issueing the following commands
|
|
// without yielding between sending the commands:
|
|
//
|
|
// capability <file> inputs
|
|
// close <file>
|
|
// open <file>
|
|
//
|
|
// Should be able to fix the problem by Yield'ing.
|
|
//
|
|
// o Saving to the same wave file twice without closing the device deletes
|
|
// the existing file. Don't save twice.
|
|
//
|
|
// o Saving an 'empty' wave file does not work. Issueing the following
|
|
// commands demonstrates the problem:
|
|
//
|
|
// open new type waveaudio alias zyz
|
|
// save zyz as c:\zyz.wav
|
|
//
|
|
// You will receive an 'out of memory error' which is completely bogus.
|
|
// Just don't save empty files.
|
|
//
|
|
// o Setting the time format to bytes doesn't work with compressed files.
|
|
// Sigh...
|
|
//
|
|
// o And there are others with less frequently used commands.
|
|
//
|
|
//==========================================================================;
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <mmsystem.h>
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
#include <mmreg.h>
|
|
#include <msacm.h>
|
|
|
|
#include "muldiv32.h"
|
|
#include "appport.h"
|
|
#include "acmapp.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
#ifndef _MCIERROR_
|
|
#define _MCIERROR_
|
|
typedef DWORD MCIERROR; // error return code, 0 means no error
|
|
#endif
|
|
|
|
|
|
TCHAR gszAlias[] = TEXT("zyzthing");
|
|
|
|
BOOL gfFileOpen;
|
|
BOOL gfDirty;
|
|
BOOL gfTimerGoing;
|
|
|
|
UINT guPlayRecordStatus;
|
|
|
|
|
|
#define AAPLAYRECORD_TIMER_RESOLUTION 54
|
|
|
|
#define AAPLAYRECORD_MAX_MCI_COMMAND_CHARS 255
|
|
|
|
#define AAPLAYRECORD_STATUS_NOT_READY 0
|
|
#define AAPLAYRECORD_STATUS_PAUSED 1
|
|
#define AAPLAYRECORD_STATUS_PLAYING 2
|
|
#define AAPLAYRECORD_STATUS_STOPPED 3
|
|
#define AAPLAYRECORD_STATUS_RECORDING 4
|
|
#define AAPLAYRECORD_STATUS_SEEKING 5
|
|
|
|
#define AAPLAYRECORD_STATUS_NOT_OPEN (UINT)-1
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// MCIERROR AcmPlayRecordSendCommand
|
|
//
|
|
// Description:
|
|
// The string is of the form "verb params" our device name is inserted
|
|
// after the verb and send to the device.
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PSTR pszCommand:
|
|
//
|
|
// PSTR pszReturn:
|
|
//
|
|
// UINT cbReturn:
|
|
//
|
|
// BOOL fErrorBox:
|
|
//
|
|
// Return (MCIERROR):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
MCIERROR FNLOCAL AcmPlayRecordSendCommand
|
|
(
|
|
HWND hwnd,
|
|
PTSTR pszCommand,
|
|
PTSTR pszReturn,
|
|
UINT cbReturn,
|
|
BOOL fErrorBox
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
TCHAR ach[AAPLAYRECORD_MAX_MCI_COMMAND_CHARS * 2];
|
|
TCHAR *pch;
|
|
PTSTR psz;
|
|
|
|
pch = pszCommand;
|
|
|
|
while (('\t' == *pch) || (' ' == *pch))
|
|
{
|
|
pch++;
|
|
}
|
|
|
|
if (0 == lstrlen(pch))
|
|
{
|
|
return (MMSYSERR_NOERROR);
|
|
}
|
|
|
|
pch = ach;
|
|
psz = pszCommand;
|
|
while (('\0' != *psz) && (' ' != *psz))
|
|
{
|
|
*pch++ = *psz++;
|
|
}
|
|
|
|
*pch++ = ' ';
|
|
|
|
lstrcpy(pch, gszAlias);
|
|
lstrcat(pch, psz);
|
|
|
|
mcierr = mciSendString(ach, pszReturn, cbReturn, hwnd);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
if (fErrorBox)
|
|
{
|
|
int n;
|
|
|
|
n = wsprintf(ach, TEXT("Command: '%s'\n\nMCI Wave Error (%lu): "),
|
|
(LPTSTR)pszCommand, mcierr);
|
|
|
|
mciGetErrorString(mcierr, &ach[n], SIZEOF(ach) - n);
|
|
MessageBox(hwnd, ach, TEXT("MCI Wave Error"), MB_ICONEXCLAMATION | MB_OK);
|
|
}
|
|
}
|
|
|
|
return (mcierr);
|
|
} // AcmPlayRecordSendCommand()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordCommand
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordCommand
|
|
(
|
|
HWND hwnd
|
|
)
|
|
{
|
|
TCHAR ach[AAPLAYRECORD_MAX_MCI_COMMAND_CHARS * 2];
|
|
HWND hedit;
|
|
MCIERROR mcierr;
|
|
|
|
//
|
|
//
|
|
//
|
|
hedit = GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_COMMAND);
|
|
Edit_SetSel(hedit, 0, -1);
|
|
|
|
Edit_GetText(hedit, ach, SIZEOF(ach));
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, ach, ach, SIZEOF(ach), FALSE);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
mciGetErrorString(mcierr, ach, SIZEOF(ach));
|
|
}
|
|
|
|
hedit = GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_RESULT);
|
|
Edit_SetText(hedit, ach);
|
|
|
|
return (TRUE);
|
|
} // AcmAppPlayRecordCommand()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordSetPosition
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// HWND hsb:
|
|
//
|
|
// UINT uCode:
|
|
//
|
|
// int nPos:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordSetPosition
|
|
(
|
|
HWND hwnd,
|
|
HWND hsb,
|
|
UINT uCode,
|
|
int nPos
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
TCHAR szPosition[40];
|
|
TCHAR szLength[40];
|
|
LONG lLength;
|
|
LONG lPosition;
|
|
LONG lPageInc;
|
|
int nRange;
|
|
int nMinPos;
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
if (AAPLAYRECORD_STATUS_NOT_OPEN == guPlayRecordStatus)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status length"), szLength, SIZEOF(szLength), FALSE);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
lLength = _tcstol(szLength, NULL, 10);
|
|
if (0L == lLength)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status position"), szPosition, SIZEOF(szPosition), FALSE);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
lPosition = _tcstol(szPosition, NULL, 10);
|
|
|
|
lPageInc = (lLength / 10);
|
|
if (0L == lPageInc)
|
|
{
|
|
lPageInc = 1;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
switch (uCode)
|
|
{
|
|
case SB_PAGEDOWN:
|
|
lPosition = min(lLength, lPosition + lPageInc);
|
|
break;
|
|
|
|
case SB_LINEDOWN:
|
|
lPosition = min(lLength, lPosition + 1);
|
|
break;
|
|
|
|
case SB_PAGEUP:
|
|
lPosition -= lPageInc;
|
|
|
|
//-- fall through --//
|
|
|
|
case SB_LINEUP:
|
|
lPosition = (lPosition < 1) ? 0 : (lPosition - 1);
|
|
break;
|
|
|
|
|
|
case SB_TOP:
|
|
lPosition = 0;
|
|
break;
|
|
|
|
case SB_BOTTOM:
|
|
lPosition = lLength;
|
|
break;
|
|
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
GetScrollRange(hsb, SB_CTL, &nMinPos, &nRange);
|
|
lPosition = (DWORD)MulDivRN((DWORD)nPos, (DWORD)lLength, (DWORD)nRange);
|
|
break;
|
|
|
|
default:
|
|
return (FALSE);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
wsprintf(szPosition, TEXT("seek to %lu"), lPosition);
|
|
AcmPlayRecordSendCommand(hwnd, szPosition, NULL, 0, FALSE);
|
|
|
|
return (TRUE);
|
|
} // AcmAppPlayRecordSetPosition()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordStatus
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordStatus
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
TCHAR ach[AAPLAYRECORD_MAX_MCI_COMMAND_CHARS];
|
|
TCHAR szMode[40];
|
|
TCHAR szPosition[40];
|
|
TCHAR szLength[40];
|
|
TCHAR szFormat[40];
|
|
MCIERROR mcierr;
|
|
UINT uStatus;
|
|
BOOL fStartTimer;
|
|
BOOL fPlay;
|
|
BOOL fPause;
|
|
BOOL fStop;
|
|
BOOL fStart;
|
|
BOOL fEnd;
|
|
BOOL fRecord;
|
|
BOOL fCommand;
|
|
UINT uIdFocus;
|
|
DWORD dwLength;
|
|
DWORD dwPosition;
|
|
HWND hsb;
|
|
|
|
//
|
|
//
|
|
//
|
|
if (AAPLAYRECORD_STATUS_NOT_OPEN != guPlayRecordStatus)
|
|
{
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status mode"), szMode, SIZEOF(szMode), FALSE);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
guPlayRecordStatus = AAPLAYRECORD_STATUS_NOT_OPEN;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// assume all buttons disabled
|
|
//
|
|
fStartTimer = FALSE;
|
|
fPlay = FALSE;
|
|
fPause = FALSE;
|
|
fStop = FALSE;
|
|
fStart = FALSE;
|
|
fEnd = FALSE;
|
|
fRecord = FALSE;
|
|
fCommand = TRUE;
|
|
uIdFocus = IDOK;
|
|
dwPosition = 0L;
|
|
dwLength = 0L;
|
|
lstrcpy(szFormat, TEXT("???"));
|
|
|
|
hsb = GetDlgItem(hwnd, IDD_AAPLAYRECORD_SCROLL_POSITION);
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
if (AAPLAYRECORD_STATUS_NOT_OPEN == guPlayRecordStatus)
|
|
{
|
|
lstrcpy(szMode, TEXT("not open"));
|
|
}
|
|
else if (0 == lstrcmpi(TEXT("not ready"), szMode))
|
|
{
|
|
uStatus = AAPLAYRECORD_STATUS_NOT_READY;
|
|
|
|
fStartTimer = TRUE;
|
|
}
|
|
else if (0 == lstrcmpi(TEXT("paused"), szMode))
|
|
{
|
|
uStatus = AAPLAYRECORD_STATUS_PAUSED;
|
|
|
|
fPause = TRUE;
|
|
fStop = TRUE;
|
|
}
|
|
else if (0 == lstrcmpi(TEXT("playing"), szMode))
|
|
{
|
|
uStatus = AAPLAYRECORD_STATUS_PLAYING;
|
|
|
|
fStartTimer = TRUE;
|
|
fPause = TRUE;
|
|
fStop = TRUE;
|
|
}
|
|
else if (0 == lstrcmpi(TEXT("stopped"), szMode))
|
|
{
|
|
uStatus = AAPLAYRECORD_STATUS_STOPPED;
|
|
|
|
fPlay = TRUE;
|
|
fStart = TRUE;
|
|
fEnd = TRUE;
|
|
fRecord = TRUE;
|
|
}
|
|
else if (0 == lstrcmpi(TEXT("recording"), szMode))
|
|
{
|
|
uStatus = AAPLAYRECORD_STATUS_RECORDING;
|
|
|
|
fStartTimer = TRUE;
|
|
fPause = TRUE;
|
|
fStop = TRUE;
|
|
}
|
|
else if (0 == lstrcmpi(TEXT("seeking"), szMode))
|
|
{
|
|
uStatus = AAPLAYRECORD_STATUS_SEEKING;
|
|
|
|
fStartTimer = TRUE;
|
|
fStop = TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
if (fStartTimer)
|
|
{
|
|
if (!gfTimerGoing)
|
|
{
|
|
SetTimer(hwnd, 1, AAPLAYRECORD_TIMER_RESOLUTION, NULL);
|
|
gfTimerGoing = TRUE;
|
|
}
|
|
}
|
|
else if (gfTimerGoing)
|
|
{
|
|
KillTimer(hwnd, 1);
|
|
gfTimerGoing = FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
if (AAPLAYRECORD_STATUS_NOT_OPEN != guPlayRecordStatus)
|
|
{
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status position"), szPosition, SIZEOF(szPosition), FALSE);
|
|
if (MMSYSERR_NOERROR == mcierr)
|
|
{
|
|
dwPosition = _tcstoul(szPosition, NULL, 10);
|
|
}
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status length"), szLength, SIZEOF(szLength), FALSE);
|
|
if (MMSYSERR_NOERROR == mcierr)
|
|
{
|
|
dwLength = _tcstoul(szLength, NULL, 10);
|
|
}
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status time format"), szFormat, SIZEOF(szFormat), FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
if (uStatus != guPlayRecordStatus)
|
|
{
|
|
if (GetFocus() != hsb)
|
|
{
|
|
LRESULT lr;
|
|
|
|
lr = SendMessage(hwnd, DM_GETDEFID, 0, 0L);
|
|
if (DC_HASDEFID == HIWORD(lr))
|
|
{
|
|
UINT uIdDefId;
|
|
|
|
uIdDefId = LOWORD(lr);
|
|
if (IDOK != uIdDefId)
|
|
{
|
|
HWND hwndDefId;
|
|
|
|
hwndDefId = GetDlgItem(hwnd, uIdDefId);
|
|
|
|
Button_SetStyle(hwndDefId, BS_PUSHBUTTON, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
SendMessage(hwnd, DM_SETDEFID, IDOK, 0L);
|
|
|
|
SetFocus(GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_COMMAND));
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_BTN_PLAY), fPlay );
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_BTN_PAUSE), fPause );
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_BTN_STOP), fStop );
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_BTN_START), fStart );
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_BTN_END), fEnd );
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_BTN_RECORD), fRecord);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_COMMAND), fCommand);
|
|
EnableWindow(GetDlgItem(hwnd, IDOK), fCommand);
|
|
|
|
if (AAPLAYRECORD_STATUS_PAUSED == uStatus)
|
|
SetDlgItemText(hwnd, IDD_AAPLAYRECORD_BTN_PAUSE, TEXT("Resum&e"));
|
|
else
|
|
SetDlgItemText(hwnd, IDD_AAPLAYRECORD_BTN_PAUSE, TEXT("Paus&e"));
|
|
|
|
guPlayRecordStatus = uStatus;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
AppFormatBigNumber(szPosition, dwPosition);
|
|
AppFormatBigNumber(szLength, dwLength);
|
|
|
|
wsprintf(ach, TEXT("%s: %14s (%s) %s"),
|
|
(LPSTR)szMode,
|
|
(LPSTR)szPosition,
|
|
(LPSTR)szLength,
|
|
(LPSTR)szFormat);
|
|
|
|
SetDlgItemText(hwnd, IDD_AAPLAYRECORD_TXT_POSITION, ach);
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
{
|
|
int nRange;
|
|
int nValue;
|
|
int nMinPos;
|
|
int nMaxPos;
|
|
|
|
GetScrollRange(hsb, SB_CTL, &nMinPos, &nMaxPos);
|
|
|
|
nRange = (int)min(dwLength, 32767L);
|
|
|
|
if (nMaxPos != nRange)
|
|
{
|
|
SetScrollRange(hsb, SB_CTL, 0, nRange, FALSE);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
nValue = 0;
|
|
if (0L != dwLength)
|
|
{
|
|
nValue = (int)MulDivRN(dwPosition, nRange, dwLength);
|
|
}
|
|
|
|
if (nValue != GetScrollPos(hsb, SB_CTL))
|
|
{
|
|
SetScrollPos(hsb, SB_CTL, nValue, TRUE);
|
|
}
|
|
}
|
|
|
|
return (TRUE);
|
|
} // AcmAppPlayRecordStatus()
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordRecord
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordRecord
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("record insert"), NULL, 0, TRUE);
|
|
if (MMSYSERR_NOERROR == mcierr)
|
|
{
|
|
gfDirty = TRUE;
|
|
}
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordRecord()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordStart
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordStart
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("seek to start"), NULL, 0, TRUE);
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordStart()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordEnd
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordEnd
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("seek to end"), NULL, 0, TRUE);
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordEnd()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordStop
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordStop
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("stop"), NULL, 0, TRUE);
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordStop()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordPause
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordPause
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
PTSTR psz;
|
|
|
|
//
|
|
//
|
|
//
|
|
if (AAPLAYRECORD_STATUS_PAUSED == guPlayRecordStatus)
|
|
psz = TEXT("resume");
|
|
else
|
|
psz = TEXT("pause");
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, psz, NULL, 0, TRUE);
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordPause()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordPlay
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordPlay
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
TCHAR szPosition[40];
|
|
TCHAR szLength[40];
|
|
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status position"), szPosition, SIZEOF(szPosition), TRUE);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("status length"), szLength, SIZEOF(szLength), TRUE);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
if (0 == lstrcmp(szPosition, szLength))
|
|
{
|
|
AcmPlayRecordSendCommand(hwnd, TEXT("seek to start"), NULL, 0, TRUE);
|
|
}
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("play"), NULL, 0, TRUE);
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordPlay()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordClose
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordClose
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
MCIERROR mcierr;
|
|
|
|
if (gfDirty)
|
|
{
|
|
UINT u;
|
|
|
|
u = MessageBox(hwnd, TEXT("Save newly recorded data?"), TEXT("Save"),
|
|
MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
|
|
if (IDYES == u)
|
|
{
|
|
AppHourGlass(TRUE);
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("save"), NULL, 0, TRUE);
|
|
AppHourGlass(FALSE);
|
|
}
|
|
else
|
|
{
|
|
gfDirty = FALSE;
|
|
}
|
|
}
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("close"), NULL, 0, TRUE);
|
|
|
|
return (MMSYSERR_NOERROR == mcierr);
|
|
} // AcmAppPlayRecordClose()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordOpen
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordOpen
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd,
|
|
UINT uWaveInId,
|
|
UINT uWaveOutId
|
|
)
|
|
{
|
|
TCHAR ach[AAPLAYRECORD_MAX_MCI_COMMAND_CHARS];
|
|
MCIERROR mcierr;
|
|
|
|
guPlayRecordStatus = AAPLAYRECORD_STATUS_NOT_OPEN;
|
|
|
|
gfTimerGoing = FALSE;
|
|
gfFileOpen = FALSE;
|
|
|
|
gfDirty = FALSE;
|
|
|
|
if (NULL == paafd->pwfx)
|
|
{
|
|
MessageBox(hwnd, TEXT("No wave file currently selected."),
|
|
TEXT("Open Error"), MB_ICONEXCLAMATION | MB_OK);
|
|
return (FALSE);
|
|
}
|
|
|
|
wsprintf(ach, TEXT("open %s alias %s"), (LPSTR)paafd->szFilePath, (LPSTR)gszAlias);
|
|
|
|
mcierr = mciSendString(ach, NULL, 0, NULL);
|
|
if (MMSYSERR_NOERROR != mcierr)
|
|
{
|
|
mciGetErrorString(mcierr, ach, SIZEOF(ach));
|
|
MessageBox(hwnd, ach, TEXT("Open Error"), MB_ICONEXCLAMATION | MB_OK);
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
gfFileOpen = TRUE;
|
|
guPlayRecordStatus = AAPLAYRECORD_STATUS_NOT_READY;
|
|
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, TEXT("set time format samples"), NULL, 0, TRUE);
|
|
|
|
if (WAVE_MAPPER != uWaveInId)
|
|
{
|
|
wsprintf(ach, TEXT("set input %u"), uWaveInId);
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, ach, NULL, 0, TRUE);
|
|
}
|
|
|
|
if (WAVE_MAPPER != uWaveOutId)
|
|
{
|
|
wsprintf(ach, TEXT("set output %u"), uWaveOutId);
|
|
mcierr = AcmPlayRecordSendCommand(hwnd, ach, NULL, 0, TRUE);
|
|
}
|
|
|
|
return (TRUE);
|
|
} // AcmAppPlayRecordOpen()
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecordInitCommands
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd:
|
|
//
|
|
// PACMAPPFILEDESC paafd:
|
|
//
|
|
// Return (BOOL):
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNLOCAL AcmAppPlayRecordInitCommands
|
|
(
|
|
HWND hwnd,
|
|
PACMAPPFILEDESC paafd
|
|
)
|
|
{
|
|
static PTSTR pszCommands[] =
|
|
{
|
|
TEXT("play"),
|
|
TEXT("play to Y"),
|
|
TEXT("play from X to Y"),
|
|
|
|
TEXT(""),
|
|
TEXT("capability can eject"),
|
|
TEXT("capability can play"),
|
|
TEXT("capability can record"),
|
|
TEXT("capability can save"),
|
|
TEXT("capability compound device"),
|
|
TEXT("capability device type"),
|
|
TEXT("capability has audio"),
|
|
TEXT("capability has video"),
|
|
TEXT("capability inputs"),
|
|
TEXT("capability outputs"),
|
|
TEXT("capability uses files"),
|
|
|
|
TEXT(""),
|
|
TEXT("cue input !"),
|
|
TEXT("cue output !"),
|
|
|
|
TEXT(""),
|
|
TEXT("delete to Y !"),
|
|
TEXT("delete from X to Y !"),
|
|
|
|
TEXT(""),
|
|
TEXT("info input"),
|
|
TEXT("info file"),
|
|
TEXT("info output"),
|
|
TEXT("info product"),
|
|
|
|
TEXT(""),
|
|
TEXT("pause"),
|
|
|
|
TEXT(""),
|
|
TEXT("record insert !"),
|
|
TEXT("record overwrite !"),
|
|
TEXT("record to Y !"),
|
|
TEXT("record from X to Y !"),
|
|
|
|
TEXT(""),
|
|
TEXT("resume"),
|
|
|
|
TEXT(""),
|
|
TEXT("save"),
|
|
TEXT("save FILENAME"),
|
|
|
|
TEXT(""),
|
|
TEXT("seek to Y"),
|
|
TEXT("seek to start"),
|
|
TEXT("seek to end"),
|
|
|
|
TEXT(""),
|
|
TEXT("set alignment X"),
|
|
TEXT("set any input"),
|
|
TEXT("set any output"),
|
|
TEXT("set audio all off"),
|
|
TEXT("set audio all on"),
|
|
TEXT("set audio left off"),
|
|
TEXT("set audio left on"),
|
|
TEXT("set audio right off"),
|
|
TEXT("set audio right on"),
|
|
TEXT("set bitspersample X"),
|
|
TEXT("set bytespersec X"),
|
|
TEXT("set channels X"),
|
|
TEXT("set format tag X"),
|
|
TEXT("set format tag pcm"),
|
|
TEXT("set input X"),
|
|
TEXT("set output X"),
|
|
TEXT("set samplespersec X"),
|
|
TEXT("set time format bytes"),
|
|
TEXT("set time format milliseconds"),
|
|
TEXT("set time format samples"),
|
|
|
|
TEXT(""),
|
|
TEXT("status alignment"),
|
|
TEXT("status bitspersample"),
|
|
TEXT("status bytespersec"),
|
|
TEXT("status channels"),
|
|
TEXT("status current track"),
|
|
TEXT("status format tag"),
|
|
TEXT("status input"),
|
|
TEXT("status length"),
|
|
TEXT("status length track X"),
|
|
TEXT("status level"),
|
|
TEXT("status media present"),
|
|
TEXT("status mode"),
|
|
TEXT("status number of tracks"),
|
|
TEXT("status output"),
|
|
TEXT("status position"),
|
|
TEXT("status position track X"),
|
|
TEXT("status ready"),
|
|
TEXT("status samplespersec"),
|
|
TEXT("status start position"),
|
|
TEXT("status time format"),
|
|
|
|
TEXT(""),
|
|
TEXT("stop"),
|
|
NULL
|
|
};
|
|
|
|
HWND hcb;
|
|
UINT u;
|
|
PTSTR psz;
|
|
|
|
//
|
|
//
|
|
//
|
|
hcb = GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_COMMAND);
|
|
|
|
for (u = 0; psz = pszCommands[u]; u++)
|
|
{
|
|
ComboBox_AddString(hcb, psz);
|
|
}
|
|
|
|
ComboBox_SetCurSel(hcb, 0);
|
|
|
|
return (TRUE);
|
|
} // AcmAppPlayRecordInitCommands()
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// BOOL AcmAppPlayRecord
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Arguments:
|
|
// HWND hwnd: Handle to window.
|
|
//
|
|
// UINT uMsg: Message being sent to the window.
|
|
//
|
|
// WPARAM wParam: Specific argument to message.
|
|
//
|
|
// LPARAM lParam: Specific argument to message.
|
|
//
|
|
// Return (BOOL):
|
|
// The return value is specific to the message that was received. For
|
|
// the most part, it is FALSE if this dialog procedure does not handle
|
|
// a message.
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
|
|
BOOL FNEXPORT AcmAppPlayRecord
|
|
(
|
|
HWND hwnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
PACMAPPFILEDESC paafd;
|
|
UINT uId;
|
|
HWND hedit;
|
|
HFONT hfont;
|
|
|
|
paafd = (PACMAPPFILEDESC)(UINT)GetWindowLong(hwnd, DWL_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
paafd = (PACMAPPFILEDESC)(UINT)lParam;
|
|
|
|
SetWindowLong(hwnd, DWL_USER, lParam);
|
|
|
|
// hfont = GetStockFont(ANSI_FIXED_FONT);
|
|
hfont = ghfontApp;
|
|
|
|
hedit = GetDlgItem(hwnd, IDD_AAPLAYRECORD_TXT_POSITION);
|
|
SetWindowFont(hedit, hfont, FALSE);
|
|
|
|
hedit = GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_COMMAND);
|
|
SetWindowFont(hedit, hfont, FALSE);
|
|
|
|
hedit = GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_RESULT);
|
|
SetWindowFont(hedit, hfont, FALSE);
|
|
|
|
AcmAppPlayRecordInitCommands(hwnd, paafd);
|
|
|
|
AcmAppPlayRecordOpen(hwnd, paafd, guWaveInId, guWaveOutId);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
|
|
|
|
//
|
|
// if the format is non-PCM, display a little warning so the
|
|
// user knows that not everything may work correctly when
|
|
// dealing working with MCI Wave..
|
|
//
|
|
if ((NULL != paafd->pwfx) &&
|
|
(WAVE_FORMAT_PCM != paafd->pwfx->wFormatTag))
|
|
{
|
|
hedit = GetDlgItem(hwnd, IDD_AAPLAYRECORD_EDIT_RESULT);
|
|
Edit_SetText(hedit, TEXT("WARNING! There are known bugs with MCI Wave EDITING operations on non-PCM formats--see the README.TXT with this application. (end)\r\n\r\nRemember, DON'T PANIC!\r\n\r\n\r\n\r\n\r\n\r\n- zYz -"));
|
|
}
|
|
return (TRUE);
|
|
|
|
case WM_TIMER:
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
HANDLE_WM_HSCROLL(hwnd, wParam, lParam, AcmAppPlayRecordSetPosition);
|
|
|
|
guPlayRecordStatus = AAPLAYRECORD_STATUS_SEEKING;
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
return (TRUE);
|
|
|
|
case WM_COMMAND:
|
|
uId = GET_WM_COMMAND_ID(wParam, lParam);
|
|
switch (uId)
|
|
{
|
|
case IDD_AAPLAYRECORD_BTN_PLAY:
|
|
AcmAppPlayRecordPlay(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case IDD_AAPLAYRECORD_BTN_PAUSE:
|
|
AcmAppPlayRecordPause(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case IDD_AAPLAYRECORD_BTN_STOP:
|
|
AcmAppPlayRecordStop(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case IDD_AAPLAYRECORD_BTN_START:
|
|
AcmAppPlayRecordStart(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case IDD_AAPLAYRECORD_BTN_END:
|
|
AcmAppPlayRecordEnd(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case IDD_AAPLAYRECORD_BTN_RECORD:
|
|
AcmAppPlayRecordRecord(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
case IDOK:
|
|
AcmAppPlayRecordCommand(hwnd);
|
|
|
|
guPlayRecordStatus = AAPLAYRECORD_STATUS_SEEKING;
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
break;
|
|
|
|
|
|
case IDCANCEL:
|
|
if (gfFileOpen)
|
|
{
|
|
AcmAppPlayRecordStop(hwnd, paafd);
|
|
AcmAppPlayRecordStatus(hwnd, paafd);
|
|
|
|
AcmAppPlayRecordClose(hwnd, paafd);
|
|
}
|
|
|
|
EndDialog(hwnd, gfDirty);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return (FALSE);
|
|
} // AcmAppPlayRecord()
|