|  | /* Definition for ALSA drivers : wine multimedia system | 
|  | * | 
|  | * Copyright (C) 2002 Erich Pouech | 
|  | * Copyright (C) 2002 Marco Pietrobono | 
|  | * Copyright (C) 2003 Christian Costa | 
|  | * Copyright (C) 2007 Maarten Lankhorst | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
|  | */ | 
|  |  | 
|  | #ifndef __WINE_CONFIG_H | 
|  | # error You must include config.h to use this header | 
|  | #endif | 
|  |  | 
|  | #if defined(HAVE_ALSA) && !defined(__ALSA_H) | 
|  | #define __ALSA_H | 
|  |  | 
|  | #ifdef interface | 
|  | #undef interface | 
|  | #endif | 
|  |  | 
|  | #define ALSA_PCM_NEW_HW_PARAMS_API | 
|  | #define ALSA_PCM_NEW_SW_PARAMS_API | 
|  |  | 
|  | #ifdef HAVE_ALSA_ASOUNDLIB_H | 
|  | #include <alsa/asoundlib.h> | 
|  | #elif defined(HAVE_SYS_ASOUNDLIB_H) | 
|  | #include <sys/asoundlib.h> | 
|  | #endif | 
|  | #ifdef HAVE_SYS_ERRNO_H | 
|  | #include <sys/errno.h> | 
|  | #endif | 
|  |  | 
|  | #include "mmreg.h" | 
|  | #include "dsound.h" | 
|  | #include "dsdriver.h" | 
|  |  | 
|  | #include "ks.h" | 
|  | #include "ksmedia.h" | 
|  | #include "ksguid.h" | 
|  |  | 
|  | /* state diagram for waveOut writing: | 
|  | * | 
|  | * +---------+-------------+---------------+---------------------------------+ | 
|  | * |  state  |  function   |     event     |            new state	     | | 
|  | * +---------+-------------+---------------+---------------------------------+ | 
|  | * |	     | open()	   |		   | STOPPED		       	     | | 
|  | * | PAUSED  | write()	   | 		   | PAUSED		       	     | | 
|  | * | STOPPED | write()	   | <thrd create> | PLAYING		  	     | | 
|  | * | PLAYING | write()	   | HEADER        | PLAYING		  	     | | 
|  | * | (other) | write()	   | <error>       |		       		     | | 
|  | * | (any)   | pause()	   | PAUSING	   | PAUSED		       	     | | 
|  | * | PAUSED  | restart()   | RESTARTING    | PLAYING (if no thrd => STOPPED) | | 
|  | * | (any)   | reset()	   | RESETTING     | STOPPED		      	     | | 
|  | * | (any)   | close()	   | CLOSING	   | CLOSED		      	     | | 
|  | * +---------+-------------+---------------+---------------------------------+ | 
|  | */ | 
|  |  | 
|  | /* states of the playing device */ | 
|  | #define	WINE_WS_PLAYING		0 | 
|  | #define	WINE_WS_PAUSED		1 | 
|  | #define	WINE_WS_STOPPED		2 | 
|  | #define WINE_WS_CLOSED		3 | 
|  |  | 
|  | /* events to be send to device */ | 
|  | enum win_wm_message { | 
|  | WINE_WM_PAUSING = WM_USER + 1, WINE_WM_RESTARTING, WINE_WM_RESETTING, WINE_WM_HEADER, | 
|  | WINE_WM_UPDATE, WINE_WM_BREAKLOOP, WINE_WM_CLOSING, WINE_WM_STARTING, WINE_WM_STOPPING | 
|  | }; | 
|  |  | 
|  | typedef struct { | 
|  | enum win_wm_message msg; /* message identifier */ | 
|  | DWORD_PTR param;         /* parameter for this message */ | 
|  | HANDLE hEvent;           /* if message is synchronous, handle of event for synchro */ | 
|  | } ALSA_MSG; | 
|  |  | 
|  | /* implement an in-process message ring for better performance | 
|  | * (compared to passing thru the server) | 
|  | * this ring will be used by the input (resp output) record (resp playback) routine | 
|  | */ | 
|  | typedef struct { | 
|  | ALSA_MSG			* messages; | 
|  | int                         ring_buffer_size; | 
|  | int				msg_tosave; | 
|  | int				msg_toget; | 
|  | /* Either pipe or event is used, but that is defined in alsa.c, | 
|  | * since this is a global header we define both here */ | 
|  | int                         msg_pipe[2]; | 
|  | HANDLE                      msg_event; | 
|  | CRITICAL_SECTION		msg_crst; | 
|  | } ALSA_MSG_RING; | 
|  |  | 
|  | typedef struct { | 
|  | volatile int		state;			/* one of the WINE_WS_ manifest constants */ | 
|  | WAVEOPENDESC		waveDesc; | 
|  | WORD			wFlags; | 
|  | WAVEFORMATPCMEX		format; | 
|  |  | 
|  | char*                       pcmname;                /* string name of alsa PCM device */ | 
|  | char*                       ctlname;                /* string name of alsa control device */ | 
|  | char                        interface_name[MAXPNAMELEN * 2]; | 
|  |  | 
|  | snd_pcm_t*                  pcm;                    /* handle to ALSA playback device */ | 
|  |  | 
|  | snd_pcm_hw_params_t *       hw_params; | 
|  |  | 
|  | DWORD                       dwBufferSize;           /* size of whole ALSA buffer in bytes */ | 
|  | LPWAVEHDR			lpQueuePtr;		/* start of queued WAVEHDRs (waiting to be notified) */ | 
|  | LPWAVEHDR			lpPlayPtr;		/* start of not yet fully played buffers */ | 
|  |  | 
|  | LPWAVEHDR			lpLoopPtr;              /* pointer of first buffer in loop, if any */ | 
|  | DWORD			dwLoops;		/* private copy of loop counter */ | 
|  |  | 
|  | DWORD			dwPlayedTotal;		/* number of bytes actually played since opening */ | 
|  | DWORD			dwWrittenTotal;		/* number of bytes written to ALSA buffer since opening */ | 
|  |  | 
|  | /* synchronization stuff */ | 
|  | HANDLE			hStartUpEvent; | 
|  | HANDLE			hThread; | 
|  | DWORD			dwThreadID; | 
|  | ALSA_MSG_RING		msgRing; | 
|  |  | 
|  | /* DirectSound stuff */ | 
|  | DSDRIVERDESC                ds_desc; | 
|  | DSDRIVERCAPS                ds_caps; | 
|  |  | 
|  | /* Waveout only fields */ | 
|  | WAVEOUTCAPSW		outcaps; | 
|  |  | 
|  | snd_hctl_t *                hctl;                    /* control handle for the playback volume */ | 
|  |  | 
|  | snd_pcm_sframes_t           (*write)(snd_pcm_t *, const void *, snd_pcm_uframes_t ); | 
|  |  | 
|  | DWORD			dwPartialOffset;	/* Offset of not yet written bytes in lpPlayPtr */ | 
|  |  | 
|  | /* Wavein only fields */ | 
|  |  | 
|  | WAVEINCAPSW                 incaps; | 
|  | DWORD                       dwSupport; | 
|  |  | 
|  | snd_pcm_sframes_t           (*read)(snd_pcm_t *, void *, snd_pcm_uframes_t ); | 
|  |  | 
|  | DWORD			dwPeriodSize;		/* size of OSS buffer period */ | 
|  | DWORD			dwTotalRecorded; | 
|  |  | 
|  | }   WINE_WAVEDEV; | 
|  |  | 
|  | /*---------------------------------------------------------------------------- | 
|  | **  Global array of output and input devices, initialized via ALSA_WaveInit | 
|  | */ | 
|  | #define WAVEDEV_ALLOC_EXTENT_SIZE       10 | 
|  |  | 
|  | /* wavein.c */ | 
|  | extern WINE_WAVEDEV	*WInDev; | 
|  | extern DWORD		ALSA_WidNumMallocedDevs; | 
|  | extern DWORD		ALSA_WidNumDevs; | 
|  |  | 
|  | /* waveout.c */ | 
|  | extern WINE_WAVEDEV	*WOutDev; | 
|  | extern DWORD		ALSA_WodNumMallocedDevs; | 
|  | extern DWORD		ALSA_WodNumDevs; | 
|  |  | 
|  | /* alsa.c */ | 
|  | int	ALSA_InitRingMessage(ALSA_MSG_RING* omr); | 
|  | int	ALSA_DestroyRingMessage(ALSA_MSG_RING* omr); | 
|  | void	ALSA_ResetRingMessage(ALSA_MSG_RING* omr); | 
|  | void	ALSA_WaitRingMessage(ALSA_MSG_RING* omr, DWORD sleep); | 
|  | int	ALSA_AddRingMessage(ALSA_MSG_RING* omr, enum win_wm_message msg, DWORD_PTR param, BOOL wait); | 
|  | int	ALSA_RetrieveRingMessage(ALSA_MSG_RING* omr, enum win_wm_message *msg, DWORD_PTR *param, HANDLE *hEvent); | 
|  | int	ALSA_CheckSetVolume(snd_hctl_t *hctl, int *out_left, int *out_right, int *out_min, int *out_max, int *out_step, int *new_left, int *new_right); | 
|  |  | 
|  | const char * ALSA_getCmdString(enum win_wm_message msg); | 
|  | const char * ALSA_getMessage(UINT msg); | 
|  | const char * ALSA_getFormat(WORD wFormatTag); | 
|  | BOOL	ALSA_NearMatch(int rate1, int rate2); | 
|  | DWORD	ALSA_bytes_to_mmtime(LPMMTIME lpTime, DWORD position, WAVEFORMATPCMEX* format); | 
|  | void	ALSA_TraceParameters(snd_pcm_hw_params_t * hw_params, snd_pcm_sw_params_t * sw, int full); | 
|  | int	ALSA_XRUNRecovery(WINE_WAVEDEV * wwo, int err); | 
|  | void	ALSA_copyFormat(LPWAVEFORMATEX wf1, LPWAVEFORMATPCMEX wf2); | 
|  | BOOL	ALSA_supportedFormat(LPWAVEFORMATEX wf); | 
|  |  | 
|  | /* dscapture.c */ | 
|  | DWORD widDsCreate(UINT wDevID, PIDSCDRIVER* drv); | 
|  | DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc); | 
|  |  | 
|  | /* dsoutput.c */ | 
|  | DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv); | 
|  | DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc); | 
|  |  | 
|  | /* midi.c */ | 
|  | extern LONG ALSA_MidiInit(void); | 
|  |  | 
|  | /* waveinit.c */ | 
|  | extern LONG ALSA_WaveInit(void); | 
|  |  | 
|  | #endif /* __ALSA_H */ |