841 lines
25 KiB
C
841 lines
25 KiB
C
/*
|
|
** Copyright (c) 1985-1998 Microsoft Corporation
|
|
**
|
|
** Title: mciwave.h - Multimedia Systems Media Control Interface
|
|
** streaming digital audio driver internal header file.
|
|
*/
|
|
|
|
|
|
/*
|
|
** Change log:
|
|
**
|
|
** DATE REV DESCRIPTION
|
|
** ----------- ----- ------------------------------------------
|
|
** 18-APR-1990 ROBWI Original
|
|
** 10-Jan-1992 MikeTri Ported to NT
|
|
** Aug 1994 Lauriegr Tried to add some explanation
|
|
*/
|
|
|
|
|
|
/********************* The OVERALL SCHEME OF THINGS ************************\
|
|
|
|
There are normally one or two files on the go. One is the original wave file,
|
|
the other is a temporary file. The data in these files is described by a
|
|
WAVEDESC which contains a pointer to an array of WAVEDATANODEs.
|
|
Each WAVEDATANODE identifies some part of one of the files.
|
|
The high order bit of the length field identifies which file (totally naff,
|
|
if you ask me, but I didn't invent it). Concatenate all the sections that
|
|
the WAVEDATANODEs identify and that's the wave data.
|
|
|
|
The WAVEDATANODEs actually form a linked list (linked by array indices not
|
|
pointers) and it is the concatenation of that list which defines the file.
|
|
There may also be some WAVEDATANODEs that define free space.
|
|
|
|
I'm confused about what exactly the dDataStart in the NODEs means. Is it the
|
|
position in the logical file or in one or other of the physical files? Either
|
|
way it probably gets messed up if you try deleting anything (KNOWN BUG).
|
|
|
|
LaurieGr
|
|
|
|
\***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef MCIWAVE_H
|
|
#define MCIWAVE_H
|
|
|
|
#include <stdio.h>
|
|
#include <mmsystem.h>
|
|
|
|
#define WAIT_FOREVER ((DWORD)(-1))
|
|
|
|
#if DBG
|
|
#define PUBLIC extern /* Public label. SO DEBUGGER CAN */
|
|
#define PRIVATE extern /* Private label. SEE THE SYMBOLS */
|
|
#else
|
|
#define PUBLIC extern /* Public label. */
|
|
#define PRIVATE extern /* Private label. */
|
|
#endif
|
|
#define REALLYPRIVATE static
|
|
|
|
#define EXPORT /* Export function. */
|
|
|
|
|
|
#ifndef RC_INVOKED /* These are defined to RC */
|
|
#define STATICDT
|
|
#define STATICFN
|
|
#define STATIC
|
|
#endif /* RC_INVOKED */
|
|
|
|
/*
|
|
** This constant defines the maximum length of strings containing
|
|
** file paths. This number is the same as the string in OFSTRUCT.
|
|
*/
|
|
|
|
#define _MAX_PATH MAX_PATH
|
|
|
|
/*
|
|
** These two constants define extended commands that are use within the
|
|
** wave handler. The first can be sent to the MCI entry point, and the
|
|
** second is used entirely internally.
|
|
*/
|
|
|
|
#define MCI_MCIWAVE_PLAY_HOLD 0x01000000L
|
|
#define MCI_MCIWAVE_CUE 0x02000000L
|
|
|
|
/*
|
|
** The first two constants represent the maximum and minimum number of
|
|
** seconds of buffering that can be specified either on the SYSTEM.INI
|
|
** device driver entry, or in the MCI_OPEN command.
|
|
** The third constant defines the default number of seconds to use when
|
|
** calculating the number of seconds of buffering to allocate.
|
|
*/
|
|
|
|
#define MaxAudioSeconds 9
|
|
#define MinAudioSeconds 2
|
|
#define AudioSecondsDefault 4
|
|
|
|
/*
|
|
** This constant is used for recording when no record stopping point
|
|
** is specified.
|
|
*/
|
|
|
|
#define INFINITEFILESIZE 0X7FFFFFFFL
|
|
|
|
/*
|
|
** These constants represent the various RIFF components of the file.
|
|
*/
|
|
|
|
#define mmioWAVE mmioFOURCC('W','A','V','E')
|
|
#define mmioFMT mmioFOURCC('f','m','t',' ')
|
|
#define mmioDATA mmioFOURCC('d','a','t','a')
|
|
|
|
/*
|
|
** The following represent identifiers for string resources.
|
|
*/
|
|
|
|
#define IDS_PRODUCTNAME 0
|
|
#define IDS_MAPPER 1
|
|
#define IDS_COMMANDS 2
|
|
|
|
/*
|
|
** The following constant is used to specify the sample size when
|
|
** determing the input level during a Cued record. This number must
|
|
** be divisible by 4.
|
|
*/
|
|
|
|
#define NUM_LEVEL_SAMPLES 64L
|
|
|
|
/*
|
|
** The following constants represent specific task modes and task
|
|
** commands.
|
|
*/
|
|
|
|
#define MODE_PLAYING 0x0001
|
|
#define MODE_INSERT 0x0002
|
|
#define MODE_OVERWRITE 0x0004
|
|
#define MODE_PAUSED 0x0008
|
|
#define MODE_CUED 0x0010
|
|
#define MODE_HOLDING 0x0020
|
|
#define MODE_CLEANUP 0x0040
|
|
#define MODE_WAIT 0x0080
|
|
#define COMMAND_NEW 0x0100
|
|
#define COMMAND_PLAY 0x0200
|
|
#define COMMAND_INSERT 0x0400
|
|
#define COMMAND_OVERWRITE 0x0800
|
|
#define COMMAND_STOP 0x1000
|
|
#define COMMAND_CUE 0x2000
|
|
#define COMMAND_HOLD 0x4000
|
|
|
|
/*
|
|
** The following macros allow modes and commands to be added, removed,
|
|
** queried, set, and get.
|
|
*/
|
|
|
|
#define ADDMODE(pwd, m) ((pwd)->wMode |= (m))
|
|
#define REMOVEMODE(pwd, m) ((pwd)->wMode &= ~(m))
|
|
#define ISMODE(pwd, m) ((pwd)->wMode & (m))
|
|
#define SETMODE(pwd, m) ((pwd)->wMode = (m))
|
|
#define GETMODE(pwd) ((pwd)->wMode)
|
|
|
|
/*
|
|
** The following macros allow testing and setting of the current task
|
|
** state.
|
|
*/
|
|
|
|
#define ISTASKSTATE(pwd, s) ((pwd)->wTaskState == (s))
|
|
#define SETTASKSTATE(pwd, s) ((pwd)->wTaskState = (s))
|
|
#define TASKSTATE(pwd) ((pwd)->wTaskState)
|
|
|
|
/*
|
|
** Define message for state changes for device tasks
|
|
*/
|
|
|
|
#define WTM_STATECHANGE (WM_USER + 1)
|
|
|
|
/*
|
|
@doc INTERNAL MCIWAVE
|
|
|
|
@types DIRECTION |
|
|
The Direction enumeration is used internally in the MCI wave handler
|
|
to indicate the current direction of data flow. This is either input
|
|
(record), or output (play).
|
|
|
|
@flag input |
|
|
Indicates the direction is record.
|
|
|
|
@flag output |
|
|
Indicates the direction is playback.
|
|
|
|
@tagname tagDirection
|
|
*/
|
|
|
|
typedef enum tagDirection {
|
|
input,
|
|
output
|
|
} DIRECTION;
|
|
|
|
/*
|
|
** The following constants represent specific task states.
|
|
*/
|
|
|
|
#define TASKNONE 0
|
|
#define TASKINIT 1
|
|
#define TASKIDLE 2
|
|
#define TASKBUSY 3
|
|
#define TASKCLOSE 4
|
|
#define TASKSAVE 5
|
|
#define TASKDELETE 6
|
|
#define TASKCUT 7
|
|
|
|
/*
|
|
** The following constants and macros are used in dealing with data nodes,
|
|
** which are pointers to blocks of data. The first constant is used
|
|
** within these macros as a mask for block pointers which refer to data
|
|
** located in the temporary file, and not in the original read-only file.
|
|
*/
|
|
|
|
#define TEMPDATAMASK (0x80000000)
|
|
#define ENDOFNODES (-1)
|
|
#define ISTEMPDATA(lpwdn) (((lpwdn)->dDataStart & TEMPDATAMASK) != 0)
|
|
#define MASKDATASTART(d) ((d) | TEMPDATAMASK)
|
|
#define UNMASKDATASTART(lpwdn) ((lpwdn)->dDataStart & ~TEMPDATAMASK)
|
|
#define LPWDN(pwd, d) ((pwd)->lpWaveDataNode + (d))
|
|
#define RELEASEBLOCKNODE(lpwdn) ((lpwdn)->dDataLength = (DWORD)-1)
|
|
#define ISFREEBLOCKNODE(lpwdn) ((lpwdn)->dDataLength == (DWORD)-1)
|
|
|
|
/*
|
|
** The following constant is used to determine the allocation increments
|
|
** for data pointers
|
|
*/
|
|
|
|
#define DATANODEALLOCSIZE 32
|
|
|
|
/*
|
|
** The following macro is used to round a data offset to the next nearest
|
|
** buffer size increment.
|
|
*/
|
|
|
|
#define ROUNDDATA(pwd, d) ((((DWORD)(d) + (pwd)->dAudioBufferLen - 1) / (pwd)->dAudioBufferLen) * (pwd)->dAudioBufferLen)
|
|
#define BLOCKALIGN(pwd, d) ((((DWORD)(d) + (pwd)->pwavefmt->nBlockAlign - 1) / (pwd)->pwavefmt->nBlockAlign) * (pwd)->pwavefmt->nBlockAlign)
|
|
|
|
/************************************************************************/
|
|
|
|
/*
|
|
@doc INTERNAL MCIWAVE
|
|
|
|
@types WAVEDATANODE |
|
|
The Wave Data Node structure is used internally in the MCI wave
|
|
handler to store information about a block of wave data, located either
|
|
in the original file, or in the temporary data file. These structures
|
|
are used to form a linked list of wave data nodes that describe the
|
|
data in the entire file as it currently exists.
|
|
|
|
The headers themselves are allocated as an expandable array of global
|
|
memory, using <e>WAVEDATANODE.dDataLength<d> as an in-use flag when
|
|
searching the list for free entries to use. Note that a free entry
|
|
can also have free temporary data attached to it, as in the case of
|
|
performing a delete in which all the data for a specific node is
|
|
removed.
|
|
|
|
@field DWORD | dDataStart |
|
|
Indicates the absolute position at which the data for this node begins.
|
|
This element is also used in determining if the data pointed to by this
|
|
node is original data, or newly created temporary data. This is done
|
|
by masking the length with <f>TEMPDATAMASK<d>. The length can be
|
|
accessed by using <f>UNMASKDATASTART<d>.
|
|
|
|
@field DWORD | dDataLength |
|
|
Indicates the length of active data pointed to by the node. This
|
|
could be zero if say, a write failed. This contains -1 if the node
|
|
is not part of the linked list of active nodes.
|
|
|
|
@field DWORD | dTotalLength |
|
|
Indicates the actual total length of data available to this node. For
|
|
original data, this will always be the same as the
|
|
<e>WAVEDATANODE.dDataLength<d> element, but for temporary data, this
|
|
may be longer, as it is a block aligned number, the block lengths being
|
|
based on the size of wave data buffers. If the node is not in use, it
|
|
still may have data associated with it. If there is no data associated
|
|
with a free node, the total length is set to zero.
|
|
|
|
@field DWORD | dNextWaveDataNode |
|
|
This element is used for active nodes, and contains an index into the
|
|
array of nodes indicating the location of the next active node, or
|
|
<f>ENDOFNODES<d> to indicate the end of the list of active nodes.
|
|
|
|
@othertype WAVEDATANODE NEAR * | LPWAVEDATANODE |
|
|
A far pointer to the structure.
|
|
|
|
@tagname tagWaveDataNode
|
|
*/
|
|
|
|
typedef struct tagWaveDataNode {
|
|
DWORD dDataStart;
|
|
DWORD dDataLength;
|
|
DWORD dTotalLength;
|
|
DWORD dNextWaveDataNode;
|
|
} WAVEDATANODE,
|
|
FAR * LPWAVEDATANODE;
|
|
|
|
/*
|
|
@doc INTERNAL MCIWAVE
|
|
|
|
@types WAVEDESC |
|
|
The Wave Description structure is used internally in the MCI wave
|
|
handler to store details for each device, along with any state information.
|
|
|
|
@field MCIDEVICEID | wDeviceID |
|
|
MCI device identifier passed to the driver during driver open.
|
|
|
|
@field UINT | wMode |
|
|
Contains the current mode of the background task, if there is a task.
|
|
|
|
@flag MODE_PLAYING |
|
|
This mode is set when the task is actually doing playback. It is reset
|
|
before Cleanup mode is entered.
|
|
|
|
@flag MODE_INSERT |
|
|
This mode is set when the task is actually doing insert recording. It
|
|
is reset before Cleanup mode is entered.
|
|
|
|
@flag MODE_OVERWRITE |
|
|
This mode is set when the task is actually doing overwrite recording.
|
|
It is reset before Cleanup mode is entered.
|
|
|
|
@flag MODE_PAUSED |
|
|
This mode is set if playback or recording has been paused by an
|
|
MCI_PAUSE command.
|
|
|
|
@flag MODE_CUED |
|
|
This mode is entered when playback or recording has actually been cued.
|
|
|
|
@flag MODE_HOLDING |
|
|
This mode is entered when playback is about to block itself and hold
|
|
after doing playback.
|
|
|
|
@flag MODE_CLEANUP |
|
|
This mode is entered after playback or recording has finished, but
|
|
before the task has entered idle state, and new commands are being
|
|
ignored.
|
|
|
|
@flag MODE_WAIT |
|
|
This mode flag is used by both the calling task and the background
|
|
task. If the calling task received a Record or Play command with the
|
|
Wait flag, then this mode is set, so that if an error occurs during
|
|
playback or recording, the background task does not perform
|
|
notification, but just clears the notification callback handle. Just
|
|
before it performs notification, the background task clears this
|
|
flag so that the calling task will know that it should not return an
|
|
error condition. If the calling task is broken out of the wait loop,
|
|
it checks this flag to determine if it should report an error
|
|
condition.
|
|
|
|
@flag COMMAND_NEW |
|
|
This command specifies that a new command has been set.
|
|
|
|
@flag COMMAND_PLAY |
|
|
This command indicates that playback should be performed on the preset
|
|
parameters.
|
|
|
|
@flag COMMAND_INSERT |
|
|
This command indicates that insert recording should be performed on
|
|
the preset parameters.
|
|
|
|
@flag COMMAND_OVERWRITE |
|
|
This command indicates that overwrite recording should be performed on
|
|
the preset parameters.
|
|
|
|
@flag COMMAND_STOP |
|
|
This command indicates that playback or recording should stop.
|
|
|
|
@flag COMMAND_CUE |
|
|
This command indicates that playback should initially pause itself
|
|
before writing then enter Cue mode when all buffers have been written.
|
|
For recording, it should enter a level checking loop and wait for
|
|
further commands.
|
|
|
|
@flag COMMAND_HOLD |
|
|
This command specifies that playback should enter a hold state after
|
|
completing playback.
|
|
|
|
@field DWORD | dTimeFormat |
|
|
Indicates the current format of position values used in messages.
|
|
|
|
@flag MCI_FORMAT_MILLISECONDS |
|
|
Milliseconds.
|
|
|
|
@flag MCI_FORMAT_SAMPLES |
|
|
Samples.
|
|
|
|
@flag MCI_FORMAT_BYTES |
|
|
Bytes.
|
|
|
|
@field UINT | wSeconds |
|
|
Contains the desired amount of buffering in terms of seconds. This
|
|
is then converted to actual buffers, and limited by the predefined
|
|
min and max values.
|
|
|
|
@field HWND | hwndCallback |
|
|
If a message has specified notification, this contains the window
|
|
handle to where notification is to be sent. The handle is stored
|
|
here for delayed notification, and can be checked when the function
|
|
has finished or was interrupted.
|
|
|
|
@field HTASK | hTask |
|
|
If the MCI wave device instance was opened with an element attached,
|
|
this element contains the handle to the background task used for
|
|
playback and recording.
|
|
|
|
@field <t>DIRECTION<d> | Direction |
|
|
Indicates the current direction of data flow.
|
|
|
|
@flag input |
|
|
Indicates the direction is inwards, i.e. recording.
|
|
|
|
@flag output |
|
|
Indicates the direction is outwards, i.e. playback.
|
|
|
|
@field UINT | wTaskState |
|
|
MCIWAVE has a separate background task for every open instance of
|
|
mciwave. The task handle and task state are stored in the
|
|
per-instance data structure. The task can be in one of four states.
|
|
|
|
@flag TASKNONE |
|
|
This state is only set if the requested file cannot be opened during
|
|
task initialization. It is used so that the task create loop is able
|
|
to abort on an initialization failure.
|
|
|
|
@flag TASKINIT |
|
|
This is the initial task state set when the instance data structure is
|
|
initialized in <f>mwOpenDevice<d> before the actual task is created by
|
|
<f>mmTaskCreate<d>. After the task is created, <f>mwOpenDevice<d>
|
|
waits until the task state changes to TASKIDLE before returning success
|
|
so that the background task is definitely initialized after an open
|
|
call.
|
|
|
|
@flag TASKIDLE |
|
|
The task sets the state to TASKIDLE and blocks whenever there is
|
|
nothing to do. When the task wakes, the state is either TASKCLOSE if
|
|
the instance is being closed or else TASKBUSY if the task is to begin
|
|
recording or playback of the file.
|
|
|
|
@flag TASKCLOSE |
|
|
<f>mwCloseDevice<d> stops playback or recording which forces the task
|
|
state to TASKIDLE and then sets the state to TASKCLOSE and wakes the
|
|
task so that the task will destroy itself.
|
|
|
|
@flag TASKBUSY |
|
|
The task is in this state during playback and recording.
|
|
|
|
@flag TASKCLOSE |
|
|
The task is closing and about to terminate.
|
|
|
|
@flag TASKSAVE |
|
|
The task saving the current data to the specified file.
|
|
|
|
@flag TASKDELETE |
|
|
The task deleting the specified data.
|
|
|
|
@flag TASKCUT |
|
|
The task cutting the specified data (Not implemented).
|
|
|
|
@field UINT | idOut |
|
|
Wave device id of output device to use, or WAVE_MAPPER for any.
|
|
|
|
@field UINT | idIn |
|
|
Wave device id of input device to use, or WAVE_MAPPER for any.
|
|
|
|
@field HWAVEOUT | hWaveOut |
|
|
Output wave device handle when in use.
|
|
|
|
@field HWAVEIN | hWaveIn |
|
|
Input wave device handle when in use.
|
|
|
|
@field <t>LPWAVEHDR<d> | rglpWaveHdr |
|
|
Pointer to array of audio buffers for wave buffering.
|
|
|
|
@field DWORD | dCur |
|
|
Current position in file in bytes.
|
|
|
|
@field DWORD | dFrom |
|
|
Position in bytes at which playback or recording should begin.
|
|
|
|
@field DWORD | dTo |
|
|
Position in bytes at which playback or recording should terminate,
|
|
or <f>INFINITEFILESIZE<d> if recording should continue until stopped.
|
|
|
|
@field DWORD | dSize |
|
|
Actual wave data size in bytes.
|
|
|
|
@field char | aszFile |
|
|
Contains the name of the element attached to the MCI wave device
|
|
instance, if any. This might be a zero length string if the file is
|
|
new and has not been named yet.
|
|
|
|
@field char | aszTempFile |
|
|
Contains the name of the temporary data file, if any.
|
|
|
|
@field <t>HMMIO<d> | hmmio |
|
|
MMIO identifier of the element attached to the MCI wave device
|
|
instance, if any.
|
|
|
|
@field HFILE | hfTempBuffers |
|
|
Contains the temporary data DOS file handle, if any, else HFILE_ERROR.
|
|
|
|
@field <t>LPMMIOPROC<d> | pIOProc |
|
|
Contains a pointer to the alternate MMIO IO procedure, if any, else
|
|
NULL.
|
|
|
|
@field <t>LPWAVEDATANODE<d> | lpWaveDataNode |
|
|
Points to the array of wave data nodes. This is allocated when the
|
|
file opens, so it is always valid. The array is expanded as needed.
|
|
|
|
@field DWORD | dRiffData |
|
|
This contains an offset into the original file, if any, indicating
|
|
the actual starting point of the wave data, which in a RIFF file will
|
|
not be zero.
|
|
|
|
@field DWORD | dWaveDataStartNode |
|
|
This contains an index to the first active data pointer in the linked
|
|
list of data pointer nodes.
|
|
|
|
@field DWORD | dWaveDataCurrentNode |
|
|
This contains an index to the current active data pointer in the
|
|
linked list of data pointer nodes.
|
|
|
|
@field DWORD | dVirtualWaveDataStart |
|
|
This contains a virtual starting point representing logically where in
|
|
the file the data for the current node begins.
|
|
|
|
@field DWORD | dWaveDataNodes |
|
|
This indicates the total number of data pointer nodes available.
|
|
|
|
@field DWORD | dWaveTempDataLength |
|
|
This contains the current length of the temporary data file, if any.
|
|
|
|
@field DWORD | dLevel |
|
|
Current input level if it is being scanned.
|
|
|
|
@field UINT | wTaskError |
|
|
Task error return.
|
|
|
|
@field UINT | wAudioBuffers |
|
|
Number of audio buffers actually allocated during playback or recording.
|
|
|
|
@field DWORD | wAudioBufferLen |
|
|
Length of each audio buffer.
|
|
|
|
@field PSTR | szSaveFile |
|
|
During a save command, this optionally contains the name of the file
|
|
to save to, unless data is being saved to the original file.
|
|
|
|
@field UINT | wFormatSize |
|
|
This contains the size of the wave header, which is used when saving
|
|
data to a new file.
|
|
|
|
@field <t>WAVEFORMAT<d> | pwavefmt |
|
|
Pointer to the wave format header.
|
|
|
|
@field HANDLE | hTaskHandle |
|
|
Handle to the thread that started this request
|
|
|
|
@field CRITCAL_SECTION | CritSec |
|
|
Serialisation object for threads accessing this <t>WAVEDESC<d> structure
|
|
|
|
@othertype WAVEDESC NEAR * | PWAVEDESC |
|
|
A near pointer to the structure.
|
|
|
|
@tagname tagWaveDesc
|
|
*/
|
|
|
|
#ifndef MMNOMMIO
|
|
#ifndef MMNOWAVE
|
|
|
|
typedef struct tagWaveDesc {
|
|
MCIDEVICEID wDeviceID;
|
|
UINT wMode;
|
|
DWORD dTimeFormat;
|
|
UINT wSeconds;
|
|
HWND hwndCallback;
|
|
DWORD hTask;
|
|
//HANDLE hTask;
|
|
DIRECTION Direction;
|
|
UINT wTaskState;
|
|
UINT idOut;
|
|
UINT idIn;
|
|
HWAVEOUT hWaveOut;
|
|
HWAVEIN hWaveIn;
|
|
DWORD dCur;
|
|
DWORD dFrom;
|
|
DWORD dTo;
|
|
DWORD dSize;
|
|
HMMIO hmmio;
|
|
HANDLE hTempBuffers;
|
|
LPMMIOPROC pIOProc;
|
|
LPWAVEDATANODE lpWaveDataNode;
|
|
DWORD dRiffData;
|
|
DWORD dWaveDataStartNode;
|
|
DWORD dWaveDataCurrentNode;
|
|
DWORD dVirtualWaveDataStart;
|
|
DWORD dWaveDataNodes;
|
|
DWORD dWaveTempDataLength;
|
|
DWORD dLevel;
|
|
UINT wTaskError;
|
|
UINT wAudioBuffers;
|
|
DWORD dAudioBufferLen;
|
|
LPWSTR szSaveFile;
|
|
UINT wFormatSize;
|
|
WAVEFORMAT NEAR * pwavefmt;
|
|
HANDLE hTaskHandle; // Handle of the thread running this job
|
|
LPWAVEHDR rglpWaveHdr[MaxAudioSeconds];
|
|
WCHAR aszFile[_MAX_PATH];
|
|
WCHAR aszTempFile[_MAX_PATH];
|
|
} WAVEDESC;
|
|
typedef WAVEDESC * PWAVEDESC;
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
//PRIVATE DWORD PASCAL FAR time2bytes(
|
|
// PWAVEDESC pwd,
|
|
// DWORD dTime,
|
|
// DWORD dFormat);
|
|
//
|
|
//PRIVATE DWORD PASCAL FAR bytes2time(
|
|
// PWAVEDESC pwd,
|
|
// DWORD dBytes,
|
|
// DWORD dFormat);
|
|
|
|
PUBLIC VOID PASCAL FAR mwDelayedNotify(
|
|
PWAVEDESC pwd,
|
|
UINT uStatus);
|
|
|
|
PUBLIC LPWAVEHDR * PASCAL FAR NextWaveHdr(
|
|
PWAVEDESC pwd,
|
|
LPWAVEHDR * lplpWaveHdr);
|
|
|
|
PUBLIC UINT PASCAL FAR PlayFile(
|
|
register PWAVEDESC pwd);
|
|
|
|
PUBLIC UINT PASCAL FAR RecordFile(
|
|
register PWAVEDESC pwd);
|
|
|
|
PUBLIC DWORD PASCAL FAR mwInfo(
|
|
PWAVEDESC pwd,
|
|
DWORD dFlags,
|
|
LPMCI_INFO_PARMS lpInfo);
|
|
|
|
PUBLIC DWORD PASCAL FAR mwGetDevCaps(
|
|
PWAVEDESC pwd,
|
|
DWORD dFlags,
|
|
LPMCI_GETDEVCAPS_PARMS lpCaps);
|
|
|
|
PUBLIC DWORD PASCAL FAR mwAllocMoreBlockNodes(
|
|
PWAVEDESC pwd);
|
|
|
|
PUBLIC DWORD PASCAL FAR mwFindAnyFreeDataNode(
|
|
PWAVEDESC pwd,
|
|
DWORD dMinDataLength);
|
|
|
|
PUBLIC VOID PASCAL FAR mwDeleteData(
|
|
PWAVEDESC pwd);
|
|
|
|
PUBLIC VOID PASCAL FAR mwSaveData(
|
|
PWAVEDESC pwd);
|
|
|
|
PUBLIC VOID PASCAL FAR InitMMIOOpen(
|
|
PWAVEDESC pwd,
|
|
LPMMIOINFO lpmmioInfo);
|
|
|
|
#endif // MMNOWAVE
|
|
#endif // MMNOMMIO
|
|
|
|
PUBLIC LRESULT PASCAL FAR mciDriverEntry(
|
|
MCIDEVICEID wDeviceID,
|
|
UINT uMessage,
|
|
DWORD dFlags,
|
|
LPMCI_GENERIC_PARMS lpParms);
|
|
|
|
PUBLIC INT_PTR PASCAL FAR Config(
|
|
HWND hWnd,
|
|
LPDRVCONFIGINFO lpdci,
|
|
HINSTANCE hInstance);
|
|
|
|
PUBLIC UINT PASCAL FAR GetAudioSeconds(
|
|
LPCWSTR pch);
|
|
|
|
__inline BOOL MySeekFile(HANDLE hFile, LONG Position)
|
|
{
|
|
return 0xFFFFFFFF != SetFilePointer(hFile, Position, NULL, FILE_BEGIN);
|
|
}
|
|
|
|
__inline BOOL MyReadFile(HANDLE hFile, LPVOID pBuffer, ULONG cBytesToRead, PULONG pcBytesRead)
|
|
{
|
|
BOOL fReturn;
|
|
ULONG cBytesRead;
|
|
if (!pcBytesRead) pcBytesRead = &cBytesRead;
|
|
fReturn = ReadFile(hFile, pBuffer, cBytesToRead, pcBytesRead, NULL);
|
|
if (fReturn && (*pcBytesRead == cBytesToRead))
|
|
{
|
|
return TRUE;
|
|
}
|
|
*pcBytesRead = -1;
|
|
return FALSE;
|
|
}
|
|
|
|
__inline BOOL MyWriteFile(HANDLE hFile, LPCVOID pBuffer, ULONG cBytesToWrite, PULONG pcBytesWritten)
|
|
{
|
|
BOOL fReturn;
|
|
ULONG cBytesWritten;
|
|
if (!pcBytesWritten) pcBytesWritten = &cBytesWritten;
|
|
fReturn = WriteFile(hFile, pBuffer, cBytesToWrite, pcBytesWritten, NULL);
|
|
if (fReturn && (*pcBytesWritten == cBytesToWrite))
|
|
{
|
|
return TRUE;
|
|
}
|
|
*pcBytesWritten = -1;
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
|
|
/*
|
|
** This defines a stack and code based pointer types.
|
|
*/
|
|
|
|
//#define STACK _based(_segname("_STACK"))
|
|
//#define SZCODE char _based(_segname("_CODE"))
|
|
//typedef char STACK * SSZ;
|
|
|
|
#define SZCODE WCHAR // Should be sufficient,
|
|
typedef WCHAR *SSZ; // as segments no longer matter in Win32
|
|
|
|
/************************************************************************/
|
|
|
|
PUBLIC HINSTANCE hModuleInstance;
|
|
PUBLIC UINT cWaveOutMax;
|
|
PUBLIC UINT cWaveInMax;
|
|
PUBLIC UINT wAudioSeconds;
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
Synchronisation support
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
VOID InitCrit(VOID);
|
|
|
|
VOID DeleteCrit(VOID);
|
|
|
|
#if DBG
|
|
extern VOID DbgEnterCrit(UINT ln, LPCSTR lpszFile);
|
|
#define EnterCrit() DbgEnterCrit(__LINE__, __FILE__)
|
|
#else
|
|
VOID EnterCrit(VOID);
|
|
#endif
|
|
|
|
|
|
VOID LeaveCrit(VOID);
|
|
|
|
VOID TaskWaitComplete(HANDLE h);
|
|
|
|
UINT TaskBlock(VOID);
|
|
|
|
BOOL TaskSignal(DWORD h, UINT Msg);
|
|
|
|
#ifndef MMNOMMIO
|
|
#ifndef MMNOWAVE
|
|
|
|
#if DBG
|
|
extern DWORD dwCritSecOwner;
|
|
#define mmYield(pwd) mmDbgYield(pwd, __LINE__, __FILE__)
|
|
|
|
extern VOID mmDbgYield(PWAVEDESC pwd, UINT ln, LPCSTR lpszFile);
|
|
|
|
#define CheckIn() WinAssert((GetCurrentThreadId() == dwCritSecOwner))
|
|
#define CheckOut() WinAssert((GetCurrentThreadId() != dwCritSecOwner))
|
|
|
|
#else
|
|
|
|
#define CheckIn()
|
|
#define CheckOut()
|
|
#define mmYield(pwd) \
|
|
{ \
|
|
LeaveCrit(); \
|
|
Sleep(10); \
|
|
EnterCrit(); \
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
DEBUGGING SUPPORT
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
#if DBG
|
|
|
|
extern void mciwaveDbgOut(LPSTR lpszFormat, ...);
|
|
extern void mciwaveInitDebugLevel(void);
|
|
extern void dDbgAssert(LPSTR exp, LPSTR file, int line);
|
|
|
|
#define WinAssert(exp) \
|
|
((exp) ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__))
|
|
|
|
#define WinEval(exp) \
|
|
((__dwEval=(DWORD)(exp)), \
|
|
__dwEval ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__), __dwEval)
|
|
|
|
int mciwaveDebugLevel;
|
|
|
|
#define dprintf( _x_ ) mciwaveDbgOut _x_
|
|
#define dprintf1( _x_ ) if (mciwaveDebugLevel >= 1) mciwaveDbgOut _x_
|
|
#define dprintf2( _x_ ) if (mciwaveDebugLevel >= 2) mciwaveDbgOut _x_
|
|
#define dprintf3( _x_ ) if (mciwaveDebugLevel >= 3) mciwaveDbgOut _x_
|
|
#define dprintf4( _x_ ) if (mciwaveDebugLevel >= 4) mciwaveDbgOut _x_
|
|
|
|
#else // DBG
|
|
|
|
#define mciwaveInitDebugLevel() 0
|
|
|
|
#define WinAssert(exp) 0
|
|
#define WinEval(exp) (exp)
|
|
|
|
#define dprintf(x)
|
|
#define dprintf1(x)
|
|
#define dprintf2(x)
|
|
#define dprintf3(x)
|
|
#define dprintf4(x)
|
|
|
|
#endif
|
|
|
|
#endif // MCIWAVE_H
|