Various headers needed to compile the sound support libraries.

svn path=/trunk/; revision=39253
This commit is contained in:
Andrew Greenwood 2009-01-31 22:13:30 +00:00
parent 5bc7ecd049
commit 5fa9003095
9 changed files with 1882 additions and 0 deletions

View file

@ -0,0 +1,396 @@
/*
ReactOS Sound System
NT4 Multimedia Audio Support (ntddsnd.h)
Author:
Andrew Greenwood (andrew.greenwood@silverblade.co.uk)
History:
24 May 2008 - Created
2 July 2008 - Added device names as seen from user-mode
5 July 2008 - Added macros for checking device type
This file contains definitions and structures for Windows NT4 style
multimedia drivers. The NT4 DDK has these split across multiple header
files: NTDDSND.H, NTDDWAVE.H, NTDDMIDI.H, NTDDMIX.H and NTDDAUX.H
Should you have an unstoppable urge to build an NT4 multimedia driver
against these headers, just create the other files listed above and make
them #include this one.
There are also a number of additional enhancements within this file
not found in the originals (such as DOS device name strings and device
type IDs).
*/
#ifndef NTDDWAVE
#define NTDDWAVE
#define SOUND_MAX_DEVICES 100
/*
Device types
Not part of the original DDK header, but based on the values stored in
registry by sndblst
*/
#define WAVE_IN_DEVICE_TYPE 1
#define WAVE_OUT_DEVICE_TYPE 2
#define MIDI_IN_DEVICE_TYPE 3
#define MIDI_OUT_DEVICE_TYPE 4
#define AUX_DEVICE_TYPE 5
#define MIXER_DEVICE_TYPE 6
#define MIN_SOUND_DEVICE_TYPE WAVE_IN_DEVICE_TYPE
#define MAX_SOUND_DEVICE_TYPE MIXER_DEVICE_TYPE
#define SOUND_DEVICE_TYPES 6
#define IS_VALID_SOUND_DEVICE_TYPE(x) \
( ( x >= MIN_SOUND_DEVICE_TYPE ) && ( x <= MAX_SOUND_DEVICE_TYPE ) )
#define IS_WAVE_DEVICE_TYPE(x) \
( ( x == WAVE_IN_DEVICE_TYPE ) || ( x == WAVE_OUT_DEVICE_TYPE ) )
#define IS_MIDI_DEVICE_TYPE(x) \
( ( x == MIDI_IN_DEVICE_TYPE ) || ( x == MIDI_OUT_DEVICE_TYPE ) )
#define IS_AUX_DEVICE_TYPE(x) \
( x == AUX_DEVICE_TYPE )
#define IS_MIXER_DEVICE_TYPE(x) \
( x == MIXER_DEVICE_TYPE )
/*
Base device names
Each device name should be given a numerical suffix identifying that
unique device, eg:
\Device\WaveOut0 - First wave output device
\Device\WaveOut1 - Second wave output device
*/
#define SOUND_MAX_DEVICE_NAME 80
#define DD_WAVE_IN_DEVICE_NAME "\\Device\\WaveIn"
#define DD_WAVE_IN_DEVICE_NAME_U L"\\Device\\WaveIn"
#define DD_WAVE_IN_DOS_DEVICE_NAME "\\DosDevices\\WaveIn"
#define DD_WAVE_IN_DOS_DEVICE_NAME_U L"\\DosDevices\\WaveIn"
#define DD_WAVE_IN_WIN32_DEVICE_NAME "\\\\.\\WaveIn"
#define DD_WAVE_IN_WIN32_DEVICE_NAME_U L"\\\\.\\WaveIn"
#define DD_WAVE_OUT_DEVICE_NAME "\\Device\\WaveOut"
#define DD_WAVE_OUT_DEVICE_NAME_U L"\\Device\\WaveOut"
#define DD_WAVE_OUT_DOS_DEVICE_NAME "\\DosDevices\\WaveOut"
#define DD_WAVE_OUT_DOS_DEVICE_NAME_U L"\\DosDevices\\WaveOut"
#define DD_WAVE_OUT_WIN32_DEVICE_NAME "\\\\.\\WaveOut"
#define DD_WAVE_OUT_WIN32_DEVICE_NAME_U L"\\\\.\\WaveOut"
#define DD_MIDI_IN_DEVICE_NAME "\\Device\\MidiIn"
#define DD_MIDI_IN_DEVICE_NAME_U L"\\Device\\MidiIn"
#define DD_MIDI_IN_DOS_DEVICE_NAME "\\DosDevices\\MidiIn"
#define DD_MIDI_IN_DOS_DEVICE_NAME_U L"\\DosDevices\\MidiIn"
#define DD_MIDI_IN_WIN32_DEVICE_NAME "\\\\.\\MidiIn"
#define DD_MIDI_IN_WIN32_DEVICE_NAME_U L"\\\\.\\MidiIn"
#define DD_MIDI_OUT_DEVICE_NAME "\\Device\\MidiOut"
#define DD_MIDI_OUT_DEVICE_NAME_U L"\\Device\\MidiOut"
#define DD_MIDI_OUT_DOS_DEVICE_NAME "\\DosDevices\\MidiOut"
#define DD_MIDI_OUT_DOS_DEVICE_NAME_U L"\\DosDevices\\MidiOut"
#define DD_MIDI_OUT_WIN32_DEVICE_NAME "\\\\.\\MidiOut"
#define DD_MIDI_OUT_WIN32_DEVICE_NAME_U L"\\\\.\\MidiOut"
#define DD_MIX_DEVICE_NAME "\\Device\\MMMix"
#define DD_MIX_DEVICE_NAME_U L"\\Device\\MMMix"
#define DD_MIX_DOS_DEVICE_NAME "\\DosDevices\\MMMix"
#define DD_MIX_DOS_DEVICE_NAME_U L"\\DosDevices\\MMMix"
#define DD_MIX_WIN32_DEVICE_NAME "\\\\.\\MMMix"
#define DD_MIX_WIN32_DEVICE_NAME_U L"\\\\.\\MMMix"
#define DD_AUX_DEVICE_NAME "\\Device\\MMAux"
#define DD_AUX_DEVICE_NAME_U L"\\Device\\MMAux"
#define DD_AUX_DOS_DEVICE_NAME "\\DosDevices\\MMAux"
#define DD_AUX_DOS_DEVICE_NAME_U L"\\DosDevices\\MMAux"
#define DD_AUX_WIN32_DEVICE_NAME "\\\\.\\MMAux"
#define DD_AUX_WIN32_DEVICE_NAME_U L"\\\\.\\MMAux"
/*
Registry keys
*/
#define REG_SERVICES_KEY_NAME_U L"System\\CurrentControlSet\\Services"
#define REG_PARAMETERS_KEY_NAME_U L"Parameters"
#define REG_DEVICE_KEY_NAME_U L"Device"
#define REG_DEVICES_KEY_NAME_U L"Devices"
/*
Base control codes
*/
#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
#define IOCTL_WAVE_BASE 0x0000
#define IOCTL_MIDI_BASE 0x0080
#define IOCTL_AUX_BASE 0x0100
#define IOCTL_MIX_BASE 0x0180
/*
Helper macros for defining control codes
*/
#define WAVE_CTL_CODE(subcode, iomethod, access) \
CTL_CODE(FILE_DEVICE_SOUND, IOCTL_WAVE_BASE + subcode, iomethod, access)
#define MIDI_CTL_CODE(subcode, iomethod, access) \
CTL_CODE(FILE_DEVICE_SOUND, IOCTL_MIDI_BASE + subcode, iomethod, access)
#define MIX_CTL_CODE(subcode, iomethod, access) \
CTL_CODE(FILE_DEVICE_SOUND, IOCTL_MIX_BASE + subcode, iomethod, access)
#define AUX_CTL_CODE(subcode, iomethod, access) \
CTL_CODE(FILE_DEVICE_SOUND, IOCTL_AUX_BASE + subcode, iomethod, access)
/*
Wave device control codes
*/
#define IOCTL_WAVE_QUERY_FORMAT \
WAVE_CTL_CODE(0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_WAVE_SET_FORMAT \
WAVE_CTL_CODE(0x0002, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_GET_CAPABILITIES \
WAVE_CTL_CODE(0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_WAVE_SET_STATE \
WAVE_CTL_CODE(0x0004, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_GET_STATE \
WAVE_CTL_CODE(0x0005, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_GET_POSITION \
WAVE_CTL_CODE(0x0006, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_SET_VOLUME \
WAVE_CTL_CODE(0x0007, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_WAVE_GET_VOLUME \
WAVE_CTL_CODE(0x0008, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_WAVE_SET_PITCH \
WAVE_CTL_CODE(0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_GET_PITCH \
WAVE_CTL_CODE(0x000A, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_SET_PLAYBACK_RATE \
WAVE_CTL_CODE(0x000B, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_GET_PLAYBACK_RATE \
WAVE_CTL_CODE(0x000C, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_PLAY \
WAVE_CTL_CODE(0x000D, METHOD_IN_DIRECT, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_RECORD \
WAVE_CTL_CODE(0x000E, METHOD_OUT_DIRECT, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_BREAK_LOOP \
WAVE_CTL_CODE(0x000F, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_WAVE_SET_LOW_PRIORITY \
WAVE_CTL_CODE(0x0010, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#if DBG
/* Debug-only control code */
#define IOCTL_WAVE_SET_DEBUG_LEVEL \
WAVE_CTL_CODE(0x0040, METHOD_BUFFERED, FILE_READ_ACCESS)
#endif
/*
MIDI device control codes
*/
#define IOCTL_MIDI_GET_CAPABILITIES \
MIDI_CTL_CODE(0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MIDI_SET_STATE \
MIDI_CTL_CODE(0x0002, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_MIDI_GET_STATE \
MIDI_CTL_CODE(0x0003, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_MIDI_SET_VOLUME \
MIDI_CTL_CODE(0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MIDI_GET_VOLUME \
MIDI_CTL_CODE(0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MIDI_PLAY \
MIDI_CTL_CODE(0x0006, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_MIDI_RECORD \
MIDI_CTL_CODE(0x0007, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_MIDI_CACHE_PATCHES \
MIDI_CTL_CODE(0x0008, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_MIDI_CACHE_DRUM_PATCHES \
MIDI_CTL_CODE(0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#if DBG
/* Debug-only control code */
#define IOCTL_MIDI_SET_DEBUG_LEVEL \
WAVE_CTL_CODE(0x0040, METHOD_BUFFERED, FILE_READ_ACCESS)
#endif
/*
Mixer device control codes
*/
#define IOCTL_MIX_GET_CONFIGURATION \
MIX_CTL_CODE(0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MIX_GET_CONTROL_DATA \
MIX_CTL_CODE(0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MIX_GET_LINE_DATA \
MIX_CTL_CODE(0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_MIX_REQUEST_NOTIFY \
MIX_CTL_CODE(0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
/*
Auxiliary device control codes
*/
#define IOCTL_AUX_GET_CAPABILITIES \
AUX_CTL_CODE(0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_AUX_SET_VOLUME \
AUX_CTL_CODE(0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_AUX_GET_VOLUME \
AUX_CTL_CODE(0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
#define IOCTL_SOUND_GET_CHANGED_VOLUME \
AUX_CTL_CODE(0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
/*
Wave structures & states
*/
#define WAVE_DD_MAX_VOLUME 0xFFFFFFFF
typedef struct _WAVE_DD_VOLUME
{
ULONG Left;
ULONG Right;
} WAVE_DD_VOLUME, *PWAVE_DD_VOLUME;
typedef struct _WAVE_DD_PITCH
{
ULONG Pitch;
} WAVE_DD_PITCH, *PWAVE_DD_PITCH;
typedef struct _WAVE_DD_PLAYBACK_RATE
{
ULONG Rate;
} WAVE_DD_PLAYBACK_RATE, *PWAVE_DD_PLAYBACK_RATE;
/* IOCTL_WAVE_SET_STATE commands */
#define WAVE_DD_STOP 0x0001
#define WAVE_DD_PLAY 0x0002
#define WAVE_DD_RECORD 0x0003
#define WAVE_DD_RESET 0x0004
/* IOCTL_WAVE_GET_STATE responses */
#define WAVE_DD_IDLE 0x0000
#define WAVE_DD_STOPPED 0x0001
#define WAVE_DD_PLAYING 0x0002
#define WAVE_DD_RECORDING 0x0003
/*
MIDI structures & states
*/
typedef struct _MIDI_DD_INPUT_DATA
{
LARGE_INTEGER Time;
UCHAR Data[sizeof(ULONG)];
} MIDI_DD_INPUT_DATA, *PMIDI_DD_INPUT_DATA;
typedef struct _MIDI_DD_VOLUME
{
ULONG Left;
ULONG Right;
} MIDI_DD_VOLUME, *PMIDI_DD_VOLUME;
typedef struct _MIDI_DD_CACHE_PATCHES
{
ULONG Bank;
ULONG Flags;
ULONG Patches[128];
} MIDI_DD_CACHE_PATCHES, *PMIDI_DD_CACHE_PATCHES;
typedef struct _MIDI_DD_CACHE_DRUM_PATCHES
{
ULONG Patch;
ULONG Flags;
ULONG DrumPatches[128];
} MIDI_DD_CACHE_DRUM_PATCHES, *PMIDI_DD_CACHE_DRUM_PATCHES;
/* IOCTL_MIDI_SET_STATE commands */
#define MIDI_DD_STOP 0x0001
#define MIDI_DD_PLAY 0x0002
#define MIDI_DD_RECORD 0x0003
#define MIDI_DD_RESET 0x0004
/* IOCTL_MIDI_GET_STATE responses */
#define MIDI_DD_IDLE 0x0000
#define MIDI_DD_STOPPED 0x0001
#define MIDI_DD_PLAYING 0x0002
#define MIDI_DD_RECORDING 0x0003
/*
Mixer structures
TODO: This is incomplete (see NTDDMIX.H in NT4 DDK)
*/
typedef struct _MIXER_DD_READ_DATA
{
ULONG Id;
} MIXER_DD_READ_DATA, *PMIXER_DD_READ_DATA;
typedef struct _MIXER_DD_LINE_DATA
{
ULONG fdwLine;
} MIXER_DD_LINE_DATA, *PMIXER_DD_LINE_DATA;
/*
Auxiliary structures
*/
#define AUX_DD_MAX_VOLUME 0xFFFFFFFF
typedef struct _AUX_DD_VOLUME
{
ULONG Left;
ULONG Right;
} AUX_DD_VOLUME, *PAUX_DD_VOLUME;
#endif

View file

@ -0,0 +1,138 @@
/*
ReactOS Sound System
Device naming & creation helper routines
Author:
Andrew Greenwood (silverblade@reactos.org)
History:
25 May 2008 - Created
*/
#ifndef ROS_DEVNAME
#define ROS_DEVNAME
/*
ConstructDeviceName
This takes a wide-character string containing the device name body (for
example, "\\Device\\WaveOut") and appends the device index, forming a
string like "\\Device\\WaveOut0", and so on.
The resulting device name is a unicode string.
*/
NTSTATUS
ConstructDeviceName(
IN PCWSTR Path,
IN UCHAR Index,
OUT PUNICODE_STRING DeviceName);
/*
FreeUnicodeStringBuffer
A small helper routine to free a unicode string buffer, nullify the
buffer and reset the lengths to zero.
*/
VOID
FreeUnicodeStringBuffer(IN PUNICODE_STRING String);
/*
GetDefaultSoundDeviceNameBodies
Simply accesses the SoundDeviceNameBodies struct defined earlier and
fills the DeviceNameBody and DosDeviceNameBody parameters accordingly.
Basically a "safe" way to access the array and perform two assignments
with one call, as this will assign the name and DOS name if a valid
DeviceType is passed, otherwise it will fail with STATUS_INVALID_PARAMETER.
*/
NTSTATUS
GetDefaultSoundDeviceNameBodies(
IN UCHAR DeviceType,
OUT PCWSTR* DeviceNameBody,
OUT PCWSTR* DosDeviceNameBody);
/*
ConstructSoundDeviceNames
Given two wide-character strings and a device index, convert these into
two unicode strings with the index appended to the end.
This is intended for converting a device name and a DOS device name at
the same time.
*/
NTSTATUS
ConstructSoundDeviceNames(
IN PCWSTR DeviceNameBody,
IN PCWSTR DosDeviceNameBody,
IN UCHAR Index,
OUT PUNICODE_STRING FullDeviceName,
OUT PUNICODE_STRING FullDosDeviceName);
/*
CreateSoundDevice
Creates a device and symbolically-links a DOS device to this. Use this
when you want to specify alternative device names to the defaults
(eg: "\\Device\\MySoundDev" rather than "\\Device\\WaveOut")
*/
NTSTATUS
CreateSoundDevice(
IN PDRIVER_OBJECT DriverObject,
IN PCWSTR WideDeviceName,
IN PCWSTR WideDosDeviceName,
IN UCHAR Index,
IN ULONG ExtensionSize,
OUT PDEVICE_OBJECT* DeviceObject);
/*
CreateSoundDeviceWithDefaultName
Similar to CreateSoundDevice, except this uses the default device names
("\\Device\\WaveOut" etc.) based on the DeviceType parameter.
*/
NTSTATUS
CreateSoundDeviceWithDefaultName(
IN PDRIVER_OBJECT DriverObject,
IN UCHAR DeviceType,
IN UCHAR Index,
IN ULONG ExtensionSize,
OUT PDEVICE_OBJECT* DeviceObject);
/*
DestroySoundDevice
Destroy a device and its symbolic link
*/
NTSTATUS
DestroySoundDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PCWSTR WideDosDeviceName,
IN UCHAR Index);
/*
DestroySoundDeviceWithDefaultName
Similar to DestroySoundDevice, but operating on one of the
default device names.
*/
NTSTATUS
DestroySoundDeviceWithDefaultName(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR DeviceType,
IN UCHAR Index);
#endif

View file

@ -0,0 +1,23 @@
/*
ReactOS Sound System
Legacy support
Hardware interaction helper
Author:
Andrew Greenwood (silverblade@reactos.org)
History:
2 July 2008 - Created
*/
#ifndef ROS_AUDIOLEG_HARDWARE_H
#define ROS_AUDIOLEG_HARDWARE_H
NTSTATUS
LegacyAttachInterrupt(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR Irq,
IN PKSERVICE_ROUTINE ServiceRoutine,
OUT PKINTERRUPT* InterruptObject);
#endif

View file

@ -0,0 +1,39 @@
/*
ReactOS Sound System
MIDI constants
Author:
Andrew Greenwood (silverblade@reactos.org)
History:
26 May 2008 - Created
*/
#ifndef ROS_MIDI
#define ROS_MIDI
/* Channel-based MIDI status bytes */
#define MIDI_NOTE_OFF 0x80
#define MIDI_NOTE_ON 0x90
#define MIDI_KEY_PRESSURE 0xA0
#define MIDI_CONTROL_CHANGE 0xB0
#define MIDI_PROGRAM_CHANGE 0xC0
#define MIDI_CHANNEL_PRESSURE 0xD0
#define MIDI_PITCH_BEND 0xE0
/* System MIDI status bytes */
#define MIDI_SYSEX_START 0xF0
#define MIDI_QUARTER_FRAME 0xF1
#define MIDI_SONG_POSITION 0xF2
#define MIDI_SONG_SELECT 0xF3
#define MIDI_TUNE_REQUEST 0xF6
#define MIDI_SYSEX_END 0xF7
#define MIDI_CLOCK 0xF8
#define MIDI_TICK 0xF9
#define MIDI_START 0xFA
#define MIDI_CONTINUE 0xFB
#define MIDI_STOP 0xFC
#define MIDI_ACTIVE_SENSE 0xFE
#define MIDI_RESET 0xFF
#endif

View file

@ -0,0 +1,111 @@
/*
ReactOS Sound System
MIDI UART support
Author:
Andrew Greenwood (silverblade@reactos.org)
History:
26 May 2008 - Created
Notes:
MIDI UART is fairly simple. There are two ports - one is a data
port and is read/write, the other is a command/status port where
you can write commands, and read status.
We use a subset of the functionality offered by the original MPU-401
hardware, which is pretty much the only part implemented in sound
cards these days, known as "MIDI UART" mode.
*/
#ifndef ROS_MIDIUART
#define ROS_MIDIUART
/* Port read/write abstraction (no wait) */
#define WRITE_MIDIUART_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp, x)
#define READ_MIDIUART_DATA(bp) READ_PORT_UCHAR((PUCHAR) bp)
#define WRITE_MIDIUART_COMMAND(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+1, x)
#define READ_MIDIUART_STATUS(bp) READ_PORT_UCHAR((PUCHAR) bp+1)
/* Status flags */
#define MIDIUART_STATUS_DTR 0x40
#define MIDIUART_STATUS_CTS 0x80
/*
WaitForMidiUartStatus
A universal routine for waiting for one or more bits to be set on the
MIDI UART command/status port. (Not a particularly efficient wait as
this polls the port until it's ready!)
If the timeout is reached, the function returns FALSE. Otherwise, when
the specified flag(s) become set, the function returns TRUE.
*/
BOOLEAN
WaitForMidiUartStatus(
IN PUCHAR UartBasePort,
IN UCHAR StatusFlags,
IN ULONG Timeout);
/* Waits for the CTS status bit to be set */
#define WaitForMidiUartCTS(UartBasePort, Timeout) \
WaitForMidiUartStatus(UartBasePort, MIDIUART_STATUS_CTS, Timeout)
/* Waits for the DTR status bit to be set */
#define WaitForMidiUartDTR(UartBasePort, Timeout) \
WaitForMidiUartStatus(UartBasePort, MIDIUART_STATUS_DTR, Timeout)
/*
WriteMidiUartByte
Wait for the CTS bit to be set on the command/status port, before
writing to the data port. If CTS does not get set within the timeout
period, returns FALSE. Otherwise, returns TRUE.
*/
BOOLEAN
WriteMidiUartByte(
IN PUCHAR UartBasePort,
IN UCHAR Data,
IN ULONG Timeout);
/*
WriteMidiUartMulti
Write multiple bytes to the MIDI UART data port. The timeout applies on a
per-byte basis. If it is reached for any byte, the function will return
FALSE.
All data is written "as-is" - there are no checks made as to the validity
of the data.
*/
BOOLEAN
WriteMidiUartMulti(
IN PUCHAR UartBasePort,
IN PUCHAR Data,
IN ULONG DataLength,
IN ULONG Timeout);
/*
ReadMidiUartByte
Wait for the DTR bit to be set on the command/status port, before
reading from the data port. If DTR does not get set within the
timeout period, returns FALSE. Otherwise, returns TRUE.
On success, the read data is stored in the location specified by
the Data parameter.
*/
BOOLEAN
ReadMidiUartByte(
IN PUCHAR UartBasePort,
OUT UCHAR* Data,
IN ULONG Timeout);
#endif

View file

@ -0,0 +1,741 @@
/*
* PROJECT: ReactOS Sound System "MME Buddy" Library
* LICENSE: GPL - See COPYING in the top level directory
* FILE: include/reactos/libs/sound/mmebuddy.h
*
* PURPOSE: Header for the "MME Buddy" helper library (located in
* lib/drivers/sound/mmebuddy)
*
* PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
*
* HISTORY: 4 July 2008 - Created
* 31 Dec 2008 - Split off NT4-specific code into a separate library
*
* NOTES: MME Buddy was the best name I could come up with...
* The structures etc. here should be treated as internal to the
* library so should not be directly accessed elsewhere.
*/
#ifndef ROS_AUDIO_MMEBUDDY_H
#define ROS_AUDIO_MMEBUDDY_H
/*
Hacky debug macro
*/
#define POPUP(...) \
{ \
WCHAR dbg_popup_msg[1024], dbg_popup_title[256]; \
wsprintf(dbg_popup_title, L"%hS(%d)", __FILE__, __LINE__); \
wsprintf(dbg_popup_msg, __VA_ARGS__); \
MessageBox(0, dbg_popup_msg, dbg_popup_title, MB_OK | MB_TASKMODAL); \
}
#ifdef DEBUG_NT4
#define SND_ERR(...) \
{ \
WCHAR dbg_popup_msg[1024]; \
wsprintf(dbg_popup_msg, __VA_ARGS__); \
OutputDebugString(dbg_popup_msg); \
}
#define SND_WARN(...) \
{ \
WCHAR dbg_popup_msg[1024]; \
wsprintf(dbg_popup_msg, __VA_ARGS__); \
OutputDebugString(dbg_popup_msg); \
}
#define SND_TRACE(...) \
{ \
WCHAR dbg_popup_msg[1024]; \
wsprintf(dbg_popup_msg, __VA_ARGS__); \
OutputDebugString(dbg_popup_msg); \
}
#define SND_ASSERT(condition) \
{ \
if ( ! ( condition ) ) \
{ \
SND_ERR(L"ASSERT FAILED: %hS\n", #condition); \
POPUP(L"ASSERT FAILED: %hS\n", #condition); \
ExitProcess(1); \
} \
}
#else
#define SND_ERR(...) while ( 0 ) do {}
#define SND_WARN(...) while ( 0 ) do {}
#define SND_TRACE(...) while ( 0 ) do {}
#define SND_ASSERT(condition) while ( 0 ) do {}
#endif
/*
Some memory allocation helper macros
*/
#define AllocateStruct(thing) \
(thing*) AllocateMemory(sizeof(thing))
#define StringLengthToBytes(chartype, string_length) \
( ( string_length + 1 ) * sizeof(chartype) )
#define AllocateWideString(string_length) \
(PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
#define ZeroWideString(string) \
ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
#define CopyWideString(dest, source) \
CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
/*
Helps find the minimum/maximum of two values
*/
#define MinimumOf(value_a, value_b) \
( value_a < value_b ? value_a : value_b )
#define MaximumOf(value_a, value_b) \
( value_a > value_b ? value_a : value_b )
/*
Convert a device type into a zero-based array index
*/
#define SOUND_DEVICE_TYPE_TO_INDEX(x) \
( x - MIN_SOUND_DEVICE_TYPE )
#define INDEX_TO_SOUND_DEVICE_TYPE(x) \
( x + MIN_SOUND_DEVICE_TYPE )
/*
Validation
*/
#define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
#define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
{ \
if ( ! (parameter_condition) ) \
{ \
SND_ERR(L"FAILED parameter check: %hS\n", #parameter_condition); \
return MMSYSERR_INVALPARAM; \
} \
}
#define MMSUCCESS(result) \
( result == MMSYSERR_NOERROR )
/*
Types and Structures
*/
typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
struct _SOUND_DEVICE;
struct _SOUND_DEVICE_INSTANCE;
#define DEFINE_GETCAPS_FUNCTYPE(func_typename, caps_type) \
typedef MMRESULT (*func_typename)( \
IN struct _SOUND_DEVICE* SoundDevice, \
OUT caps_type Capabilities, \
IN DWORD CapabilitiesSize);
/* This one is for those of us who don't care */
DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC, PVOID);
/* These are for those of us that do */
DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC, LPWAVEOUTCAPS);
DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC, LPWAVEINCAPS );
DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC, LPMIDIOUTCAPS);
DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC, LPMIDIINCAPS );
struct _SOUND_DEVICE;
struct _SOUND_DEVICE_INSTANCE;
typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC)(
IN struct _SOUND_DEVICE* Device,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize);
typedef MMRESULT (*MMWAVESETFORMAT_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* Instance,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize);
typedef MMRESULT (*MMOPEN_FUNC)(
IN struct _SOUND_DEVICE* SoundDevice,
OUT PVOID* Handle);
typedef MMRESULT (*MMCLOSE_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN PVOID Handle); /* not sure about this */
typedef MMRESULT (*MMWAVEHEADER_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN PWAVEHDR WaveHeader);
typedef struct _MMFUNCTION_TABLE
{
union
{
MMGETCAPS_FUNC GetCapabilities;
MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities;
MMGETWAVEINCAPS_FUNC GetWaveInCapabilities;
MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities;
MMGETMIDIINCAPS_FUNC GetMidiInCapabilities;
};
MMOPEN_FUNC Open;
MMCLOSE_FUNC Close;
MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport;
MMWAVESETFORMAT_FUNC SetWaveFormat;
MMWAVEHEADER_FUNC PrepareWaveHeader;
MMWAVEHEADER_FUNC UnprepareWaveHeader;
MMWAVEHEADER_FUNC SubmitWaveHeader;
} MMFUNCTION_TABLE, *PMMFUNCTION_TABLE;
typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN PVOID Parameter);
typedef struct _SOUND_THREAD
{
HANDLE Handle;
BOOL Running;
struct
{
HANDLE Ready;
HANDLE Request;
HANDLE Done;
} Events;
struct
{
SOUND_THREAD_REQUEST_HANDLER Handler;
struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
PVOID Parameter;
MMRESULT Result;
} Request;
} SOUND_THREAD, *PSOUND_THREAD;
typedef struct _SOUND_DEVICE
{
struct _SOUND_DEVICE* Next;
struct _SOUND_DEVICE_INSTANCE* HeadInstance;
struct _SOUND_DEVICE_INSTANCE* TailInstance;
MMDEVICE_TYPE Type;
PVOID Identifier; /* Path for NT4 drivers */
/*PWSTR Path;*/
MMFUNCTION_TABLE FunctionTable;
} SOUND_DEVICE, *PSOUND_DEVICE;
typedef struct _SOUND_DEVICE_INSTANCE
{
struct _SOUND_DEVICE_INSTANCE* Next;
struct _SOUND_DEVICE* Device;
PVOID Handle;
struct _SOUND_THREAD* Thread;
/* Stuff generously donated to us from WinMM */
struct
{
HDRVR Handle;
DWORD Flags;
DWORD ClientCallback;
DWORD ClientCallbackInstanceData;
} WinMM;
} SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
/*
reentrancy.c
*/
MMRESULT
InitEntrypointMutexes();
VOID
CleanupEntrypointMutexes();
VOID
AcquireEntrypointMutex(
IN MMDEVICE_TYPE DeviceType);
VOID
ReleaseEntrypointMutex(
IN MMDEVICE_TYPE DeviceType);
/*
mme.c
*/
VOID
NotifyMmeClient(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN DWORD Message,
IN DWORD Parameter);
MMRESULT
MmeGetSoundDeviceCapabilities(
IN MMDEVICE_TYPE DeviceType,
IN DWORD DeviceId,
IN PVOID Capabilities,
IN DWORD CapabilitiesSize);
MMRESULT
MmeOpenWaveDevice(
IN MMDEVICE_TYPE DeviceType,
IN DWORD DeviceId,
IN LPWAVEOPENDESC OpenParameters,
IN DWORD Flags,
OUT DWORD* PrivateHandle);
MMRESULT
MmeCloseDevice(
IN DWORD PrivateHandle);
#define MmePrepareWaveHeader(private_handle, header) \
PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
#define MmeUnprepareWaveHeader(private_handle, header) \
UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
#define MmeSubmitWaveHeader(private_handle, header) \
SubmitWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
/*
capabilities.c
*/
MMRESULT
GetSoundDeviceCapabilities(
IN PSOUND_DEVICE SoundDevice,
OUT PVOID Capabilities,
IN DWORD CapabilitiesSize);
/*
devicelist.c
*/
ULONG
GetSoundDeviceCount(
IN MMDEVICE_TYPE DeviceType);
BOOLEAN
IsValidSoundDevice(
IN PSOUND_DEVICE SoundDevice);
MMRESULT
ListSoundDevice(
IN MMDEVICE_TYPE DeviceType,
IN PVOID Identifier OPTIONAL,
OUT PSOUND_DEVICE* SoundDevice OPTIONAL);
MMRESULT
UnlistSoundDevice(
IN MMDEVICE_TYPE DeviceType,
IN PSOUND_DEVICE SoundDevice);
MMRESULT
UnlistSoundDevices(
IN MMDEVICE_TYPE DeviceType);
VOID
UnlistAllSoundDevices();
MMRESULT
GetSoundDevice(
IN MMDEVICE_TYPE DeviceType,
IN DWORD DeviceIndex,
OUT PSOUND_DEVICE* Device);
MMRESULT
GetSoundDeviceIdentifier(
IN PSOUND_DEVICE SoundDevice,
OUT PVOID* Identifier);
MMRESULT
GetSoundDeviceType(
IN PSOUND_DEVICE SoundDevice,
OUT PMMDEVICE_TYPE DeviceType);
/*
functiontable.c
*/
MMRESULT
SetSoundDeviceFunctionTable(
IN PSOUND_DEVICE SoundDevice,
IN PMMFUNCTION_TABLE FunctionTable OPTIONAL);
MMRESULT
GetSoundDeviceFunctionTable(
IN PSOUND_DEVICE SoundDevice,
OUT PMMFUNCTION_TABLE* FunctionTable);
/*
deviceinstance.c
*/
BOOLEAN
IsValidSoundDeviceInstance(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
MMRESULT
CreateSoundDeviceInstance(
IN PSOUND_DEVICE SoundDevice,
OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance);
MMRESULT
DestroySoundDeviceInstance(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
MMRESULT
DestroyAllSoundDeviceInstances(
IN PSOUND_DEVICE SoundDevice);
MMRESULT
GetSoundDeviceFromInstance(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
OUT PSOUND_DEVICE* SoundDevice);
MMRESULT
GetSoundDeviceInstanceHandle(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
OUT PVOID* Handle);
MMRESULT
SetSoundDeviceInstanceMmeData(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN HDRVR MmeHandle,
IN DWORD ClientCallback,
IN DWORD ClientCallbackData,
IN DWORD Flags);
/*
thread.c
*/
MMRESULT
CreateSoundThread(
OUT PSOUND_THREAD* Thread);
MMRESULT
DestroySoundThread(
IN PSOUND_THREAD Thread);
MMRESULT
CallSoundThread(
IN PSOUND_THREAD Thread,
IN SOUND_THREAD_REQUEST_HANDLER RequestHandler,
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance OPTIONAL,
IN PVOID Parameter OPTIONAL);
/*
utility.c
*/
PVOID
AllocateMemory(
IN UINT Size);
VOID
FreeMemory(
IN PVOID Pointer);
UINT
GetMemoryAllocationCount();
UINT
GetDigitCount(
IN UINT Number);
MMRESULT
Win32ErrorToMmResult(
IN UINT ErrorCode);
MMRESULT
TranslateInternalMmResult(
IN MMRESULT Result);
/*
wave/format.c
*/
MMRESULT
QueryWaveDeviceFormatSupport(
IN PSOUND_DEVICE SoundDevice,
IN LPWAVEFORMATEX Format,
IN DWORD FormatSize);
MMRESULT
SetWaveDeviceFormat(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN LPWAVEFORMATEX Format,
IN DWORD FormatSize);
/*
wave/header.c
*/
MMRESULT
PrepareWaveHeader(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN PWAVEHDR Header);
MMRESULT
UnprepareWaveHeader(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN PWAVEHDR Header);
MMRESULT
SubmitWaveHeader(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN PWAVEHDR Header);
/*
kernel.c
*/
#if 0
#define QueryDevice(h, ctl, o, o_size, xfer, ovl) \
Win32ErrorToMmResult( \
DeviceIoControl(h, ctl, NULL, 0, o, o_size, xfer, ovl) != 0 \
? ERROR_SUCCESS : GetLastError() \
)
#define ControlDevice(h, ctl, i, i_size, xfer, ovl) \
Win32ErrorToMmResult( \
DeviceIoControl(h, ctl, i, i_size, NULL, 0, xfer, ovl) != 0 \
? ERROR_SUCCESS : GetLastError() \
)
#define QuerySoundDevice(sd, ctl, o, o_size, xfer) \
SoundDeviceIoControl(sd, ctl, NULL, 0, o, o_size, xfer)
#define ControlSoundDevice(sd, ctl, i, i_size, xfer) \
SoundDeviceIoControl(sd, ctl, i, i_size, NULL, 0, xfer)
#endif
MMRESULT
OpenKernelSoundDeviceByName(
IN PWSTR DevicePath,
IN BOOLEAN ReadOnly,
OUT PHANDLE Handle);
MMRESULT
OpenKernelSoundDevice(
IN PSOUND_DEVICE SoundDevice,
IN BOOLEAN ReadOnly,
OUT PHANDLE Handle);
MMRESULT
CloseKernelSoundDevice(
IN HANDLE Handle);
MMRESULT
SyncOverlappedDeviceIoControl(
IN HANDLE SoundDeviceInstance,
IN DWORD IoControlCode,
IN LPVOID InBuffer,
IN DWORD InBufferSize,
OUT LPVOID OutBuffer,
IN DWORD OutBufferSize,
OUT LPDWORD BytesTransferred OPTIONAL);
#if 0
typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
struct _SOUND_DEVICE;
struct _SOUND_DEVICE_INSTANCE;
/*
Rather than pass caps structures around as a PVOID, this can be
used instead.
*/
typedef union _UNIVERSAL_CAPS
{
WAVEOUTCAPS WaveOut;
WAVEINCAPS WaveIn;
MIDIOUTCAPS MidiOut;
MIDIINCAPS MidiIn;
} UNIVERSAL_CAPS, *PUNIVERSAL_CAPS;
/* New sound thread code */
typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN OPTIONAL PVOID Parameter);
typedef struct _SOUND_THREAD_REQUEST
{
/* The sound device instance this request relates to */
struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
/* What function to call */
SOUND_THREAD_REQUEST_HANDLER RequestHandler;
/* Caller-defined parameter */
PVOID Parameter;
/* This will contain the return code of the request function */
MMRESULT ReturnValue;
} SOUND_THREAD_REQUEST, *PSOUND_THREAD_REQUEST;
typedef VOID (*SOUND_THREAD_IO_COMPLETION_HANDLER)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
IN PVOID Parameter OPTIONAL,
IN DWORD BytesWritten);
typedef struct _SOUND_THREAD_COMPLETED_IO
{
struct _SOUND_THREAD_COMPLETED_IO* Previous;
struct _SOUND_THREAD_COMPLETED_IO* Next;
struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
SOUND_THREAD_IO_COMPLETION_HANDLER CompletionHandler;
PVOID Parameter;
DWORD BytesTransferred;
} SOUND_THREAD_COMPLETED_IO, *PSOUND_THREAD_COMPLETED_IO;
typedef struct _SOUND_THREAD_OVERLAPPED
{
OVERLAPPED General;
/* Pointer to structure to fill with completion data */
PSOUND_THREAD_COMPLETED_IO CompletionData;
} SOUND_THREAD_OVERLAPPED, *PSOUND_THREAD_OVERLAPPED;
/*
Audio device function table
*/
typedef MMRESULT (*MMCREATEINSTANCE_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance);
typedef VOID (*MMDESTROYINSTANCE_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance);
typedef MMRESULT (*MMGETCAPS_FUNC)(
IN struct _SOUND_DEVICE* Device,
OUT PUNIVERSAL_CAPS Capabilities);
typedef MMRESULT (*MMWAVEQUERYFORMAT_FUNC)(
IN struct _SOUND_DEVICE* Device,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize);
typedef MMRESULT (*MMWAVESETFORMAT_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* Instance,
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize);
typedef MMRESULT (*MMWAVEQUEUEBUFFER_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* Instance,
IN PWAVEHDR WaveHeader);
typedef MMRESULT (*MMGETWAVESTATE_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* Instance,
OUT PULONG State);
typedef MMRESULT (*MMSETWAVESTATE_FUNC)(
IN struct _SOUND_DEVICE_INSTANCE* Instance);
typedef struct _MMFUNCTION_TABLE
{
MMCREATEINSTANCE_FUNC Constructor;
MMDESTROYINSTANCE_FUNC Destructor;
MMGETCAPS_FUNC GetCapabilities;
MMWAVEQUERYFORMAT_FUNC QueryWaveFormat;
MMWAVESETFORMAT_FUNC SetWaveFormat;
MMWAVEQUEUEBUFFER_FUNC QueueWaveBuffer;
MMGETWAVESTATE_FUNC GetWaveDeviceState;
MMSETWAVESTATE_FUNC PauseWaveDevice;
MMSETWAVESTATE_FUNC RestartWaveDevice;
MMSETWAVESTATE_FUNC ResetWaveDevice;
MMSETWAVESTATE_FUNC BreakWaveDeviceLoop;
} MMFUNCTION_TABLE, *PMMFUNCTION_TABLE;
/*
Represents an audio device
*/
#define SOUND_DEVICE_TAG "SndD"
typedef struct _SOUND_DEVICE
{
struct _SOUND_DEVICE* Next;
struct _SOUND_DEVICE_INSTANCE* FirstInstance;
UCHAR DeviceType;
LPWSTR DevicePath;
MMFUNCTION_TABLE Functions;
} SOUND_DEVICE, *PSOUND_DEVICE;
/*
Represents an individual instance of an audio device
*/
#define WAVE_STREAM_INFO_TAG "WavS"
typedef struct _WAVE_STREAM_INFO
{
/* Buffer queue head and tail */
PWAVEHDR BufferQueueHead;
PWAVEHDR BufferQueueTail;
/* The buffer currently being processed */
PWAVEHDR CurrentBuffer;
/* How far into the current buffer we've gone */
DWORD BufferOffset;
/* How many I/O operations have been submitted */
DWORD BuffersOutstanding;
/* Looping */
PWAVEHDR LoopHead;
DWORD LoopsRemaining;
} WAVE_STREAM_INFO, *PWAVE_STREAM_INFO;
#define SOUND_DEVICE_INSTANCE_TAG "SndI"
typedef struct _SOUND_DEVICE_INSTANCE
{
struct _SOUND_DEVICE_INSTANCE* Next;
PSOUND_DEVICE Device;
/* The currently opened handle to the device */
HANDLE Handle;
/* PSOUND_THREAD Thread;*/
/* Device-specific parameters */
union
{
WAVE_STREAM_INFO Wave;
} Streaming;
} SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
#endif
#endif

View file

@ -0,0 +1,89 @@
/*
* PROJECT: ReactOS Sound System "MME Buddy" Library (NT4 Helpers)
* LICENSE: GPL - See COPYING in the top level directory
* FILE: include/reactos/libs/sound/mment4.h
*
* PURPOSE: Header for the NT4 part of the "MME Buddy" helper library
* (located in lib/drivers/sound/mment4)
*
* PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
*
* 31 Dec 2008 - Created
*
* NOTES: This is intended for use in building NT4 compatible audio device
* drivers. Include mmebuddy.h first.
*/
#ifndef ROS_AUDIO_MMENT4_H
#define ROS_AUDIO_MMENT4_H
/*
detect.c
*/
typedef BOOLEAN (*SOUND_DEVICE_DETECTED_PROC)(
UCHAR DeviceType,
PWSTR DevicePath);
MMRESULT
EnumerateNt4ServiceSoundDevices(
IN LPWSTR ServiceName,
IN MMDEVICE_TYPE DeviceType,
IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc);
MMRESULT
DetectNt4SoundDevices(
IN MMDEVICE_TYPE DeviceType,
IN PWSTR BaseDeviceName,
IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc);
/*
registry.c
*/
MMRESULT
OpenSoundDriverParametersRegKey(
IN LPWSTR ServiceName,
OUT PHKEY KeyHandle);
MMRESULT
OpenSoundDeviceRegKey(
IN LPWSTR ServiceName,
IN DWORD DeviceIndex,
OUT PHKEY KeyHandle);
/*
general.c - UNSORTED
*/
MMRESULT
GetNt4SoundDeviceCapabilities(
IN PSOUND_DEVICE SoundDevice,
OUT PVOID Capabilities,
IN DWORD CapabilitiesSize);
MMRESULT
QueryNt4WaveDeviceFormatSupport(
IN PSOUND_DEVICE SoundDevice,
IN LPWAVEFORMATEX Format,
IN DWORD FormatSize);
MMRESULT
SetNt4WaveDeviceFormat(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN LPWAVEFORMATEX Format,
IN DWORD FormatSize);
MMRESULT
OpenNt4SoundDevice(
IN PSOUND_DEVICE SoundDevice,
OUT PVOID* Handle);
MMRESULT
CloseNt4SoundDevice(
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
IN PVOID Handle);
#endif

View file

@ -0,0 +1,324 @@
/*
ReactOS Sound System
Sound Blaster DSP support
Author:
Andrew Greenwood (silverblade@reactos.org)
History:
26 May 2008 - Created
Notes:
Where timeouts are concerned, a value of 0 is interpreted as "forever".
*/
#ifndef ROS_SOUND_SBDSP_H
#define ROS_SOUND_SBDSP_H
/*
Product versions
DSP 1.0, 1.5, 2.0, 2.01 correspond with respective Sound Blaster versions.
DSP 3.xx is Sound Blaster Pro
DSP 4.xx is Sound Blaster 16
*/
#define SOUND_BLASTER_1_0 L"Sound Blaster 1.0"
#define SOUND_BLASTER_1_5 L"Sound Blaster 1.5"
#define SOUND_BLASTER_2_0 L"Sound Blaster 2.0"
#define SOUND_BLASTER_PRO L"Sound Blaster Pro"
#define SOUND_BLASTER_16 L"Sound Blaster 16"
/*
Sound Blaster ports I/O
*/
#define READ_SB_FM1_STATUS(bp) READ_PORT_UCHAR((PUCHAR) bp)
#define WRITE_SB_FM1_REGISTER(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp, x)
#define WRITE_SB_FM1_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x01, x)
#define READ_SB_AFM_STATUS(bp) READ_PORT_UCHAR((PUCHAR) bp+0x02)
#define WRITE_SB_AFM_REGISTER(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x02, x)
#define WRITE_SB_AFM_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x03, x)
#define WRITE_SB_MIXER_REGISTER(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x04, x)
#define READ_SB_MIXER_DATA(bp) READ_PORT_UCHAR((PUCHAR) bp+0x05)
#define WRITE_SB_MIXER_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x05, x)
#define WRITE_SB_DSP_RESET(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x06, x)
#define READ_SB_FM2_STATUS(bp) READ_PORT_UCHAR((PUCHAR) bp+0x08)
#define WRITE_SB_FM2_REGISTER(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x08, x)
#define WRITE_SB_FM2_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x09, x)
#define READ_SB_DSP_DATA(bp) READ_PORT_UCHAR((PUCHAR) bp+0x0A)
#define WRITE_SB_DSP_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x0C, x)
#define WRITE_SB_DSP_COMMAND(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x0C, x)
/* Clear to send */
#define SB_DSP_CLEAR_TO_SEND(bp) \
( ! (READ_PORT_UCHAR((PUCHAR) bp+0x0C) & 0x80 ) )
/* Data available for reading */
#define SB_DSP_DATA_AVAILABLE(bp) \
( READ_PORT_UCHAR((PUCHAR) bp+0x0E) & 0x80 )
#define SB_DSP_READY 0xAA
/*
Sound Blaster DSP commands
(partial list)
*/
#define SB_DSP_OUTPUT_RATE 0x41
#define SB_DSP_INPUT_RATE 0x42
#define SB_DSP_BLOCK_SIZE 0x48
#define SB_DSP_SPEAKER_ON 0xD1
#define SB_DSP_SPEAKER_OFF 0xD3
#define SB_DSP_SPEAKER_STATUS 0xD8
#define SB_DSP_VERSION 0xE1
/*
Mixer lines (legacy)
*/
#define SB_MIX_VOC_LEVEL 0x04
#define SB_MIX_LEGACY_MIC_LEVEL 0x0A
#define SB_MIX_MASTER_LEVEL 0x22
#define SB_MIX_FM_LEVEL 0x26
#define SB_MIX_CD_LEVEL 0x28
#define SB_MIX_LINE_LEVEL 0x2E
/*
Mixer lines
*/
#define SB_MIX_RESET 0x00
#define SB_MIX_MASTER_LEFT_LEVEL 0x30
#define SB_MIX_MASTER_RIGHT_LEVEL 0x31
#define SB_MIX_VOC_LEFT_LEVEL 0x32
#define SB_MIX_VOC_RIGHT_LEVEL 0x33
#define SB_MIX_MIDI_LEFT_LEVEL 0x34
#define SB_MIX_MIDI_RIGHT_LEVEL 0x35
#define SB_MIX_CD_LEFT_LEVEL 0x36
#define SB_MIX_CD_RIGHT_LEVEL 0x37
#define SB_MIX_LINE_LEFT_LEVEL 0x38
#define SB_MIX_LINE_RIGHT_LEVEL 0x39
#define SB_MIX_MIC_LEVEL 0x3A
#define SB_MIX_PC_SPEAKER_LEVEL 0x3B
#define SB_MIX_OUTPUT_SWITCHES 0x3C
#define SB_MIX_INPUT_LEFT_SWITCHES 0x3D
#define SB_MIX_INPUT_RIGHT_SWITCHES 0x3E
#define SB_MIX_INPUT_LEFT_GAIN 0x3F
#define SB_MIX_INPUT_RIGHT_GAIN 0x40
#define SB_MIX_OUTPUT_LEFT_GAIN 0x41
#define SB_MIX_OUTPUT_RIGHT_GAIN 0x42
#define SB_MIX_AGC 0x43
#define SB_MIX_TREBLE_LEFT_LEVEL 0x44
#define SB_MIX_TREBLE_RIGHT_LEVEL 0x45
#define SB_MIX_BASS_LEFT_LEVEL 0x46
#define SB_MIX_BASS_RIGHT_LEVEL 0x47
/*
Mixer switches
(are these correct?)
*/
#define SB_MIX_MIDI_LEFT_SWITCH 0x01
#define SB_MIX_MIDI_RIGHT_SWITCH 0x02
#define SB_MIX_LINE_LEFT_SWITCH 0x04
#define SB_MIX_LINE_RIGHT_SWITCH 0x08
#define SB_MIX_CD_LEFT_SWITCH 0x10
#define SB_MIX_CD_RIGHT_SWITCH 0x20
#define SB_MIX_MIC_SWITCH 0x40
/*
Reset the Sound Blaster DSP.
*/
NTSTATUS
SbDspReset(
IN PUCHAR BasePort,
IN ULONG Timeout);
/*
Wait for the Sound Blaster DSP to be ready for data to be written to it.
*/
NTSTATUS
SbDspWaitToWrite(
IN PUCHAR BasePort,
IN ULONG Timeout);
/*
Wait for data to be ready for reading from the Sound Blaster DSP.
*/
NTSTATUS
SbDspWaitToRead(
IN PUCHAR BasePort,
IN ULONG Timeout);
/*
Wait for the Sound Blaster DSP to be ready for data to be written to it,
then (providing it becomes ready within the timeout period), write the
data to it.
*/
NTSTATUS
SbDspWrite(
IN PUCHAR BasePort,
IN UCHAR DataByte,
IN ULONG Timeout);
/*
Wait for the Sound Blaster DSP to be ready for data to be read from it,
then read the data from it into the pointer supplied as DataByte. If
the timeout is exceeded, DataByte will not be modified.
*/
NTSTATUS
SbDspRead(
IN PUCHAR BasePort,
OUT PUCHAR DataByte,
IN ULONG Timeout);
/*
This can only be called immediately after a reset has been issued. The
major version and minor version are returned in MajorVersion and
MinorVersion, respectively.
The timeout applies to each DSP read/write performed. Note that the
data pointed to by MajorVersion may still fail if the retrieval of
MinorVersion times out.
*/
NTSTATUS
SbDspGetVersion(
IN PUCHAR BasePort,
OUT PUCHAR MajorVersion,
OUT PUCHAR MinorVersion,
IN ULONG Timeout);
/*
Turn the speaker on.
*/
NTSTATUS
SbDspEnableSpeaker(
IN PUCHAR BasePort,
IN ULONG Timeout);
/*
Turn the speaker off.
*/
NTSTATUS
SbDspDisableSpeaker(
IN PUCHAR BasePort,
IN ULONG Timeout);
/*
Obtains the speaker status, storing the result in IsEnabled. This will be
TRUE if the speaker is enabled, otherwise FALSE.
*/
NTSTATUS
SbDspIsSpeakerEnabled(
IN PUCHAR BasePort,
OUT PBOOLEAN IsEnabled,
IN ULONG Timeout);
/*
Validate the input sample rate. The major and minor versions are required
to determine the capabilities of the card.
*/
BOOLEAN
SbDspIsValidInputRate(
IN UCHAR MajorVersion,
IN UCHAR MinorVersion,
IN USHORT Rate,
IN BOOLEAN Stereo);
/*
Validate the output sample rate. The major and minor versions are required
to determine the capabilities of the card.
*/
BOOLEAN
SbDspIsValidOutputRate(
IN UCHAR MajorVersion,
IN UCHAR MinorVersion,
IN USHORT Rate,
IN BOOLEAN Stereo);
/*
Set the output/playback rate
* DSP 4.xx only
*/
NTSTATUS
SbDsp4SetOutputRate(
IN PUCHAR BasePort,
IN USHORT Rate,
IN ULONG Timeout);
/*
Set the input/record rate
* DSP 4.xx only
*/
NTSTATUS
SbDsp4SetInputRate(
IN PUCHAR BasePort,
IN USHORT Rate,
IN ULONG Timeout);
/*
Reset the mixer
*/
VOID
SbMixerReset(IN PUCHAR BasePort);
/*
Pack mixer level data
*/
NTSTATUS
SbMixerPackLevelData(
IN UCHAR Line,
IN UCHAR Level,
OUT PUCHAR PackedLevel);
/*
Unpack mixer level data
*/
NTSTATUS
SbMixerUnpackLevelData(
IN UCHAR Line,
IN UCHAR PackedLevel,
OUT PUCHAR Level);
/*
Set a mixer line level
*/
NTSTATUS
SbMixerSetLevel(
IN PUCHAR BasePort,
IN UCHAR Line,
IN UCHAR Level);
/*
Get a mixer line level
*/
NTSTATUS
SbMixerGetLevel(
IN PUCHAR BasePort,
IN UCHAR Line,
OUT PUCHAR Level);
/*
Enable automatic gain control
*/
VOID
SbMixerEnableAGC(IN PUCHAR BasePort);
/*
Disable automatic gain control
*/
VOID
SbMixerDisableAGC(IN PUCHAR BasePort);
/*
Retrieve the current state of the automatic gain control
*/
BOOLEAN
SbMixerIsAGCEnabled(IN PUCHAR BasePort);
#endif

View file

@ -0,0 +1,21 @@
/*
ReactOS Sound System
Timing helper
Author:
Andrew Greenwood (silverblade@reactos.org)
History:
1 July 2008 - Created
*/
#ifndef ROS_SOUND_TIME_H
#define ROS_SOUND_TIME_H
VOID
SleepMs(ULONG Milliseconds);
ULONG
QuerySystemTimeMs();
#endif