/* 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 #elif defined(HAVE_SYS_ASOUNDLIB_H) #include #endif #ifdef HAVE_SYS_ERRNO_H #include #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() | | PLAYING | * | PLAYING | write() | HEADER | PLAYING | * | (other) | write() | | | * | (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 wine_snd_pcm_recover(snd_pcm_t *pcm, int err, int silent); 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); /* waveinit.c */ extern void ALSA_WaveInit(void); #endif /* __ALSA_H */