File:  [WindowsNT SDKs] / ntddk / src / mmedia / soundlib / inc / wave.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

/*++ BUILD Version: 0001    // Increment this if a change has global effects


Copyright (c) 1990  Microsoft Corporation

Module Name:

    wave.h

Abstract:

    This include file defines common structures for wave drivers

Author:

    Robin Speed (RobinSp) 17-Oct-92

Revision History:

--*/

//
// Minimum buffer size for DMA (in case we couldn't get what we asked for).
// 4K
//
#define SOUND_MINIMUM_WAVE_BUFFER_SIZE (4096)

//
// Common DMA buffer for auto-initialize DMA and structures
// for using double-buffered DMA
//


typedef struct {
    PADAPTER_OBJECT      AdapterObject[2]; // The adapter object(s) -
                                         // We may use 2 channels
    ULONG                BufferSize;     // Size of the buffer
    PVOID                VirtualAddress; // Address of buffer
    PHYSICAL_ADDRESS     LogicalAddress; // Where is it really?
    PMDL                 Mdl;            // Mdl we are using for the buffer
} SOUND_DMA_BUFFER, *PSOUND_DMA_BUFFER;


typedef struct {
    //
    // Values for NextHalf field.  This is the half of the DMA buffer
    // to fill next.  If wave data is being played or recorded this is
    // also the 'live' part of the buffer (the part DMA is running on)
    // and hence the next part to become free.
    //
    enum {LowerHalf = 0,
          UpperHalf}
                         NextHalf;       // Where we are now
    ULONG                BufferSize;     // Size of the buffer
    struct SOUND_DMABUF {
        ULONG  Size;
        ULONG  nBytes;                   // Our 2 half buffers
        PUCHAR Buf;
    }                    Buffer[2];
    UCHAR           Pad;                 // Padding byte to use

                                        // reprogramming (SB versions < 2.0)
} SOUND_DOUBLE_BUFFER, *PSOUND_DOUBLE_BUFFER;

//
// Control processing of device queue
//

typedef struct {
    LIST_ENTRY      QueueHead;          // head of the queue if Irps
                                        // for writing to / reading from
                                        // device.
                                        // Entries are cancellable Irps.
    ULONG           BytesProcessed;     // Bytes put into or copied from buffers
    ULONG           UserBufferSize;     // Size of user buffer
    ULONG           UserBufferPosition; // Position in buffer and
    PUCHAR          UserBuffer;         // buffer corresponding to next user
    PIRP            pIrp;               // pointer to the current request

    //
    // Variables for controlling wave output sequencing of Irps
    // to ensure that wave output is not signalled as finished until
    // the data has actually played
    //

    LIST_ENTRY      ProgressQueue;      // Wave output buffers in progress
                                        // Entries on this queue are not
                                        // cancellable

} SOUND_BUFFER_QUEUE, *PSOUND_BUFFER_QUEUE;

//
// Hardware interface routine type for Wave processing
//


struct _WAVE_INFO;
typedef BOOLEAN WAVE_INTERFACE_ROUTINE(struct _WAVE_INFO *);
typedef WAVE_INTERFACE_ROUTINE *PWAVE_INTERFACE_ROUTINE;
typedef NTSTATUS SOUND_QUERY_FORMAT_ROUTINE (PLOCAL_DEVICE_INFO, PPCMWAVEFORMAT);
typedef SOUND_QUERY_FORMAT_ROUTINE *PSOUND_QUERY_FORMAT_ROUTINE;

enum {
    SoundNoDMA,
    SoundAutoInitDMA,             // Use autoinitialize
    SoundReprogramOnInterruptDMA, // Reprogram on interrupt
    Sound2ChannelDMA              // Keep 2 channels going
};

typedef struct _WAVE_INFO {
    ULONG           Key;               // Debugging

#define WAVE_INFO_KEY       (*(ULONG *)"Wave")

    PDEVICE_OBJECT  DeviceObject;      // Current real device (back pointer)

    //
    // Information input to this component about our DMA buffer
    //

    SOUND_DMA_BUFFER
                    DMABuf;

    //
    // Data for manipulation of the buffer, INTERNAL to this component
    //

    SOUND_DOUBLE_BUFFER
                    DoubleBuffer;

    //
    // Data for maninpulation of input queue of data INTERNAL to this
    // component
    //

    SOUND_BUFFER_QUEUE
                    BufferQueue;
    //
    // Current wave format data - created by this component - INPUT to
    // hardware interface routines
    //

    ULONG           SamplesPerSec;
    UCHAR           BitsPerSample;
    UCHAR           Channels;
    BOOLEAN         FormatChanged;             // New format has been set
                                                                                   // Initially TRUE
    PVOID           MRB[2];                // Info about adapter for DMA

    //
    // Event to wait for Dma channel to be allocated
    //

    KEVENT          DmaSetupEvent;

    //
    // The following events are reset by SoundStopDMA and waited on
    // if DpcQueued is set after resetting it.  The Dpc routine sets
    // this event when it has finished.
    //

    KEVENT          DpcEvent;
    KEVENT          TimerDpcEvent;
    KSPIN_LOCK      DeviceSpinLock;     // spin lock for synchrnonizing with
                                        // Dpc routine
#if DBG
    BOOLEAN         LockHeld;           // Get spin locks right
#endif

    PKINTERRUPT     Interrupt;          // interrupt object

    BOOLEAN         Direction;          // TRUE = out, FALSE = in
    UCHAR           DMAType;            // Type of DMA :
                                        //     SoundAutoInitDMA
                                        //     SoundReprogramOnInterruptDMA
                                        //     Sound2DMAChannelDMA
    UCHAR           InterruptHalf;      // Used with SoundReprogramOnInterruptDMA
                                        // as next half to use.

    volatile BOOLEAN
                    DMABusy;            // set if dma in progress
                                        // Dpc routine can turn it off
                                        // so make it volatile

    volatile BOOLEAN
                    DpcQueued;          // Set by Isr, cleared by Dpc routine
                                        // tested by SoundStopDMA
    ULONG           Overrun;            // Interrupts overran Dpcs
                                        // Managed at DEVICE level

    PVOID           HwContext;          // Context for hardware interface
                                        // routines

    //
    // Callouts back to device specific code
    //


    //
    // This routine returns TRUE if a wave format passed to it can be
    // handled by the device.
    //

    PSOUND_QUERY_FORMAT_ROUTINE
                    QueryFormat;        // Format query and set routine


    PWAVE_INTERFACE_ROUTINE
                    HwSetupDMA,         // Outside spin lock - sets up parms
                                        // for DMA
                    HwStopDMA,          // Outside spin lock - stop device
                                        // gracefully
                    HwSetWaveFormat;    // Set the format to use

    KDPC            TimerDpc;           // Check if the device keeps
    KTIMER          DeviceCheckTimer;   // going
    BOOLEAN         GotWaveDpc;         // This flag is set if we are
                                        // still going
    BOOLEAN         DeviceBad;          // Failed timer test
    BOOLEAN         TimerActive;        // Need to synch timer routine
    UCHAR           FailureCount;       // If we fail 30 times in a row give up
} WAVE_INFO, *PWAVE_INFO;

//
// Macros to assist in safely using our spin lock
//

#if DBG
#define DMAEnter(pWave)                    \
    {                                      \
       KIRQL OldIrql;                      \
       KeAcquireSpinLock(&(pWave)->DeviceSpinLock, &OldIrql);\
       ASSERT((pWave)->LockHeld == FALSE); \
       (pWave)->LockHeld = TRUE;

#define DMALeave(pWave)                    \
       ASSERT((pWave)->LockHeld == TRUE);  \
       (pWave)->LockHeld = FALSE;          \
       KeReleaseSpinLock(&(pWave)->DeviceSpinLock, OldIrql);\
    }
#else
#define DMAEnter(pWave)                    \
    {                                      \
       KIRQL OldIrql;                      \
       ASSERT((pWave)->LockHeld == FALSE); \
       KeAcquireSpinLock(&(pWave)->DeviceSpinLock, &OldIrql);

#define DMALeave(pWave)                    \
       ASSERT((pWave)->LockHeld == TRUE);  \
       KeReleaseSpinLock(&(pWave)->DeviceSpinLock, OldIrql);\
    }
#endif

//
// Exported routines
//

VOID
SoundInitializeWaveInfo(
    PWAVE_INFO WaveInfo,
    UCHAR DMAType,
    PSOUND_QUERY_FORMAT_ROUTINE QueryFormat,
    PVOID HwContext
);

NTSTATUS
SoundGetCommonBuffer(
    IN  PDEVICE_DESCRIPTION DeviceDescription,
    IN  OUT PSOUND_DMA_BUFFER SoundAutoData
);

VOID
SoundFreeCommonBuffer(
    IN OUT PSOUND_DMA_BUFFER SoundAutoData
);

//
// New Routine used by WAVE.C
//
ULONG    SoundGetDMABufferSize( IN OUT PWAVE_INFO WaveInfo );

int
SoundTestWaveDevice(
    IN PDEVICE_OBJECT pDO
);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.