/* SGLUALSA.h Copyright (C) 2012 Stephan Kochen, Paul C. Pratt You can redistribute this file and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. You should have received a copy of the license along with this file; see the file COPYING. This file 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 license for more details.*/ /* Sound GLUe for ALSA ALSA sound support by Stephan Kochen.*/ #ifndef RaspbianWorkAround#define RaspbianWorkAround 0#endif #if 0 #include "alsa/asoundlib.h" /* and link with "-lasound" */ #define My_snd_pcm_t snd_pcm_t#define My_snd_pcm_hw_params_t snd_pcm_hw_params_t#define My_snd_pcm_sw_params_t snd_pcm_sw_params_t#define My_snd_pcm_state_t snd_pcm_state_t#if RaspbianWorkAround#define My_snd_pcm_status_t snd_pcm_status_t#endif #define My_SND_PCM_STATE_OPEN SND_PCM_STATE_OPEN#define My_SND_PCM_STATE_SETUP SND_PCM_STATE_SETUP#define My_SND_PCM_STATE_PREPARED SND_PCM_STATE_PREPARED#define My_SND_PCM_STATE_RUNNING SND_PCM_STATE_RUNNING#define My_SND_PCM_STATE_XRUN SND_PCM_STATE_XRUN#define My_SND_PCM_STATE_DRAINING SND_PCM_STATE_DRAINING#define My_SND_PCM_STATE_PAUSED SND_PCM_STATE_PAUSED#define My_SND_PCM_STATE_SUSPENDED SND_PCM_STATE_SUSPENDED#define My_SND_PCM_STATE_DISCONNECTED SND_PCM_STATE_DISCONNECTED#define My_SND_PCM_STATE_LAST SND_PCM_STATE_LAST #define My_snd_pcm_stream_t snd_pcm_stream_t #define My_SND_PCM_STREAM_PLAYBACK SND_PCM_STREAM_PLAYBACK#define My_SND_PCM_STREAM_CAPTURE SND_PCM_STREAM_CAPTURE#define My_SND_PCM_STREAM_LAST SND_PCM_STREAM_LAST #define My_snd_pcm_access_t snd_pcm_access_t #define My_SND_PCM_ACCESS_MMAP_INTERLEAVED \ SND_PCM_ACCESS_MMAP_INTERLEAVED#define My_SND_PCM_ACCESS_MMAP_NONINTERLEAVED \ SND_PCM_ACCESS_MMAP_NONINTERLEAVED#define My_SND_PCM_ACCESS_MMAP_COMPLEX \ SND_PCM_ACCESS_MMAP_COMPLEX#define My_SND_PCM_ACCESS_RW_INTERLEAVED \ SND_PCM_ACCESS_RW_INTERLEAVED#define My_SND_PCM_ACCESS_RW_NONINTERLEAVED \ SND_PCM_ACCESS_RW_NONINTERLEAVED#define My_SND_PCM_ACCESS_LAST \ SND_PCM_ACCESS_LAST #define My_snd_pcm_format_t snd_pcm_format_t #define My_SND_PCM_FORMAT_UNKNOWN SND_PCM_FORMAT_UNKNOWN#define My_SND_PCM_FORMAT_S8 SND_PCM_FORMAT_S8#define My_SND_PCM_FORMAT_U8 SND_PCM_FORMAT_U8#define My_SND_PCM_FORMAT_S16_LE SND_PCM_FORMAT_S16_LE#define My_SND_PCM_FORMAT_S16_BE SND_PCM_FORMAT_S16_BE#define My_SND_PCM_FORMAT_U16_LE SND_PCM_FORMAT_U16_LE#define My_SND_PCM_FORMAT_U16_BE SND_PCM_FORMAT_U16_BE#define My_SND_PCM_FORMAT_S24_LE SND_PCM_FORMAT_S24_LE#define My_SND_PCM_FORMAT_S24_BE SND_PCM_FORMAT_S24_BE#define My_SND_PCM_FORMAT_U24_LE SND_PCM_FORMAT_U24_LE#define My_SND_PCM_FORMAT_U24_BE SND_PCM_FORMAT_U24_BE#define My_SND_PCM_FORMAT_S32_LE SND_PCM_FORMAT_S32_LE#define My_SND_PCM_FORMAT_S32_BE SND_PCM_FORMAT_S32_BE#define My_SND_PCM_FORMAT_U32_LE SND_PCM_FORMAT_U32_LE#define My_SND_PCM_FORMAT_U32_BE SND_PCM_FORMAT_U32_BE#define My_SND_PCM_FORMAT_FLOAT_LE SND_PCM_FORMAT_FLOAT_LE#define My_SND_PCM_FORMAT_FLOAT_BE SND_PCM_FORMAT_FLOAT_BE#define My_SND_PCM_FORMAT_FLOAT64_LE SND_PCM_FORMAT_FLOAT64_LE#define My_SND_PCM_FORMAT_FLOAT64_BE SND_PCM_FORMAT_FLOAT64_BE#define My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE \ SND_PCM_FORMAT_IEC958_SUBFRAME_LE#define My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE \ SND_PCM_FORMAT_IEC958_SUBFRAME_BE#define My_SND_PCM_FORMAT_MU_LAW SND_PCM_FORMAT_MU_LAW#define My_SND_PCM_FORMAT_A_LAW SND_PCM_FORMAT_A_LAW#define My_SND_PCM_FORMAT_IMA_ADPCM SND_PCM_FORMAT_IMA_ADPCM#define My_SND_PCM_FORMAT_MPEG SND_PCM_FORMAT_MPEG#define My_SND_PCM_FORMAT_GSM SND_PCM_FORMAT_GSM#define My_SND_PCM_FORMAT_SPECIAL SND_PCM_FORMAT_SPECIAL#define My_SND_PCM_FORMAT_S24_3LE SND_PCM_FORMAT_S24_3LE#define My_SND_PCM_FORMAT_S24_3BE SND_PCM_FORMAT_S24_3BE#define My_SND_PCM_FORMAT_U24_3LE SND_PCM_FORMAT_U24_3LE#define My_SND_PCM_FORMAT_U24_3BE SND_PCM_FORMAT_U24_3BE#define My_SND_PCM_FORMAT_S20_3LE SND_PCM_FORMAT_S20_3LE#define My_SND_PCM_FORMAT_S20_3BE SND_PCM_FORMAT_S20_3BE#define My_SND_PCM_FORMAT_U20_3LE SND_PCM_FORMAT_U20_3LE#define My_SND_PCM_FORMAT_U20_3BE SND_PCM_FORMAT_U20_3BE#define My_SND_PCM_FORMAT_S18_3LE SND_PCM_FORMAT_S18_3LE#define My_SND_PCM_FORMAT_S18_3BE SND_PCM_FORMAT_S18_3BE#define My_SND_PCM_FORMAT_U18_3LE SND_PCM_FORMAT_U18_3LE#define My_SND_PCM_FORMAT_U18_3BE SND_PCM_FORMAT_U18_3BE#define My_SND_PCM_FORMAT_LAST SND_PCM_FORMAT_LAST #define My_SND_PCM_FORMAT_S16 SND_PCM_FORMAT_S16#define My_SND_PCM_FORMAT_U16 SND_PCM_FORMAT_U16#define My_SND_PCM_FORMAT_S24 SND_PCM_FORMAT_S24#define My_SND_PCM_FORMAT_U24 SND_PCM_FORMAT_U24#define My_SND_PCM_FORMAT_S32 SND_PCM_FORMAT_S32#define My_SND_PCM_FORMAT_U32 SND_PCM_FORMAT_U32#define My_SND_PCM_FORMAT_FLOAT SND_PCM_FORMAT_FLOAT#define My_SND_PCM_FORMAT_FLOAT64 SND_PCM_FORMAT_FLOAT64#define My_SND_PCM_FORMAT_IEC958_SUBFRAME SND_PCM_FORMAT_FLOAT64 #define My_snd_pcm_uframes_t snd_pcm_uframes_t#define My_snd_pcm_sframes_t snd_pcm_sframes_t #define My_SND_PCM_NONBLOCK SND_PCM_NONBLOCK #define My_snd_pcm_open snd_pcm_open#define HaveMy_snd_pcm_open() (1) #define My_snd_pcm_close snd_pcm_close#define HaveMy_snd_pcm_close() (1) #define My_snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc#define HaveMy_snd_pcm_hw_params_malloc() (1) #define My_snd_pcm_hw_params_free snd_pcm_hw_params_free#define HaveMy_snd_pcm_hw_params_free() (1) #define My_snd_pcm_hw_params_any snd_pcm_hw_params_any#define HaveMy_snd_pcm_hw_params_any() (1) #define My_snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access#define HaveMy_snd_pcm_hw_params_set_access() (1) #define My_snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format#define HaveMy_snd_pcm_hw_params_set_format() (1) #define My_snd_pcm_hw_params_set_rate_near \ snd_pcm_hw_params_set_rate_near#define HaveMy_snd_pcm_hw_params_set_rate_near() (1) #define My_snd_pcm_hw_params_set_channels \ snd_pcm_hw_params_set_channels#define HaveMy_snd_pcm_hw_params_set_channels() (1) #define My_snd_pcm_hw_params_set_buffer_size_near \ snd_pcm_hw_params_set_buffer_size_near#define HaveMy_snd_pcm_hw_params_set_buffer_size_near() (1) #define My_snd_pcm_hw_params_set_period_size_near \ snd_pcm_hw_params_set_period_size_near#define HaveMy_snd_pcm_hw_params_set_period_size_near() (1) #define My_snd_pcm_hw_params snd_pcm_hw_params#define HaveMy_snd_pcm_hw_params() (1) #define My_snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc#define HaveMy_snd_pcm_sw_params_malloc() (1) #define My_snd_pcm_sw_params_free snd_pcm_sw_params_free#define HaveMy_snd_pcm_sw_params_free() (1) #define My_snd_pcm_sw_params_current snd_pcm_sw_params_current#define HaveMy_snd_pcm_sw_params_current() (1) #define My_snd_pcm_sw_params_set_start_threshold \ snd_pcm_sw_params_set_start_threshold#define HaveMy_snd_pcm_sw_params_set_start_threshold() (1) #define My_snd_pcm_sw_params_set_avail_min \ snd_pcm_sw_params_set_avail_min#define HaveMy_snd_pcm_sw_params_set_avail_min() (1) #define My_snd_pcm_sw_params_set_xfer_align \ snd_pcm_sw_params_set_xfer_align#define HaveMy_snd_pcm_sw_params_set_xfer_align() (1) #define My_snd_pcm_sw_params snd_pcm_sw_params#define HaveMy_snd_pcm_sw_params() (1) #define My_snd_pcm_nonblock snd_pcm_nonblock#define HaveMy_snd_pcm_nonblock() (1) #define My_snd_pcm_state snd_pcm_state#define HaveMy_snd_pcm_state() (1) #define My_snd_pcm_prepare snd_pcm_prepare#define HaveMy_snd_pcm_prepare() (1) #define My_snd_pcm_start snd_pcm_start#define HaveMy_snd_pcm_start() (1) #define My_snd_pcm_resume snd_pcm_resume#define HaveMy_snd_pcm_resume() (1) #define My_snd_pcm_avail_update snd_pcm_avail_update#define HaveMy_snd_pcm_avail_update() (1) #define My_snd_pcm_writei snd_pcm_writei#define HaveMy_snd_pcm_writei() (1) #define My_snd_pcm_drop snd_pcm_drop#define HaveMy_snd_pcm_drop() (1) #if RaspbianWorkAround#define My_snd_pcm_status_malloc snd_pcm_status_malloc#define HaveMy_snd_pcm_status_malloc() (1) #define My_snd_pcm_status snd_pcm_status#define HaveMy_snd_pcm_status() (1) #define My_snd_pcm_status_get_avail snd_pcm_status_get_avail#define HaveMy_snd_pcm_status_get_avail() (1)#endif #define My_snd_strerror snd_strerror#define HaveMy_snd_strerror() (1) #define MyCloseAlsaLib() #else static void *alsa_handle = NULL; LOCALVAR blnr DidAlsaLib = falseblnr; LOCALFUNC blnr HaveAlsaLib(void){ if (! DidAlsaLib) { alsa_handle = dlopen("libasound.so.2", RTLD_NOW); if (NULL == alsa_handle) { fprintf(stderr, "dlopen libasound failed\n"); } DidAlsaLib = trueblnr; } return (alsa_handle != NULL);} LOCALPROC MyCloseAlsaLib(void){ if (NULL != alsa_handle) { if (0 != dlclose(alsa_handle)) { fprintf(stderr, "dlclose libasound failed\n"); } alsa_handle = NULL; }} /* PCM handle */typedef struct My__snd_pcm My_snd_pcm_t;/* PCM hardware configuration space container */typedef struct My__snd_pcm_hw_params My_snd_pcm_hw_params_t;/* PCM software configuration container */typedef struct My__snd_pcm_sw_params My_snd_pcm_sw_params_t; #if RaspbianWorkAround/* PCM status container */typedef struct My__snd_pcm_status My_snd_pcm_status_t;#endif /* PCM state */typedef enum My__snd_pcm_state { /* Open */ My_SND_PCM_STATE_OPEN = 0, /* Setup installed */ My_SND_PCM_STATE_SETUP, /* Ready to start */ My_SND_PCM_STATE_PREPARED, /* Running */ My_SND_PCM_STATE_RUNNING, /* Stopped: underrun (playback) or overrun (capture) detected */ My_SND_PCM_STATE_XRUN, /* Draining: running (playback) or stopped (capture) */ My_SND_PCM_STATE_DRAINING, /* Paused */ My_SND_PCM_STATE_PAUSED, /* Hardware is suspended */ My_SND_PCM_STATE_SUSPENDED, /* Hardware is disconnected */ My_SND_PCM_STATE_DISCONNECTED, My_SND_PCM_STATE_LAST = My_SND_PCM_STATE_DISCONNECTED} My_snd_pcm_state_t; /* PCM stream (direction) */typedef enum My__snd_pcm_stream { /* Playback stream */ My_SND_PCM_STREAM_PLAYBACK = 0, /* Capture stream */ My_SND_PCM_STREAM_CAPTURE, My_SND_PCM_STREAM_LAST = My_SND_PCM_STREAM_CAPTURE} My_snd_pcm_stream_t; /* PCM access type */typedef enum My__snd_pcm_access { /* mmap access with simple interleaved channels */ My_SND_PCM_ACCESS_MMAP_INTERLEAVED = 0, /* mmap access with simple non interleaved channels */ My_SND_PCM_ACCESS_MMAP_NONINTERLEAVED, /* mmap access with complex placement */ My_SND_PCM_ACCESS_MMAP_COMPLEX, /* snd_pcm_readi/snd_pcm_writei access */ My_SND_PCM_ACCESS_RW_INTERLEAVED, /* snd_pcm_readn/snd_pcm_writen access */ My_SND_PCM_ACCESS_RW_NONINTERLEAVED, My_SND_PCM_ACCESS_LAST = My_SND_PCM_ACCESS_RW_NONINTERLEAVED} My_snd_pcm_access_t; /* PCM sample format */typedef enum My__snd_pcm_format { /* Unknown */ My_SND_PCM_FORMAT_UNKNOWN = -1, /* Signed 8 bit */ My_SND_PCM_FORMAT_S8 = 0, /* Unsigned 8 bit */ My_SND_PCM_FORMAT_U8, /* Signed 16 bit Little Endian */ My_SND_PCM_FORMAT_S16_LE, /* Signed 16 bit Big Endian */ My_SND_PCM_FORMAT_S16_BE, /* Unsigned 16 bit Little Endian */ My_SND_PCM_FORMAT_U16_LE, /* Unsigned 16 bit Big Endian */ My_SND_PCM_FORMAT_U16_BE, /* Signed 24 bit Little Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_S24_LE, /* Signed 24 bit Big Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_S24_BE, /* Unsigned 24 bit Little Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_U24_LE, /* Unsigned 24 bit Big Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_U24_BE, /* Signed 32 bit Little Endian */ My_SND_PCM_FORMAT_S32_LE, /* Signed 32 bit Big Endian */ My_SND_PCM_FORMAT_S32_BE, /* Unsigned 32 bit Little Endian */ My_SND_PCM_FORMAT_U32_LE, /* Unsigned 32 bit Big Endian */ My_SND_PCM_FORMAT_U32_BE, /* Float 32 bit Little Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT_LE, /* Float 32 bit Big Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT_BE, /* Float 64 bit Little Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT64_LE, /* Float 64 bit Big Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT64_BE, /* IEC-958 Little Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE, /* IEC-958 Big Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE, /* Mu-Law */ My_SND_PCM_FORMAT_MU_LAW, /* A-Law */ My_SND_PCM_FORMAT_A_LAW, /* Ima-ADPCM */ My_SND_PCM_FORMAT_IMA_ADPCM, /* MPEG */ My_SND_PCM_FORMAT_MPEG, /* GSM */ My_SND_PCM_FORMAT_GSM, /* Special */ My_SND_PCM_FORMAT_SPECIAL = 31, /* Signed 24bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_S24_3LE = 32, /* Signed 24bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_S24_3BE, /* Unsigned 24bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_U24_3LE, /* Unsigned 24bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_U24_3BE, /* Signed 20bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_S20_3LE, /* Signed 20bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_S20_3BE, /* Unsigned 20bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_U20_3LE, /* Unsigned 20bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_U20_3BE, /* Signed 18bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_S18_3LE, /* Signed 18bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_S18_3BE, /* Unsigned 18bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_U18_3LE, /* Unsigned 18bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_U18_3BE, My_SND_PCM_FORMAT_LAST = My_SND_PCM_FORMAT_U18_3BE, #if __BYTE_ORDER == __LITTLE_ENDIAN /* Signed 16 bit CPU endian */ My_SND_PCM_FORMAT_S16 = My_SND_PCM_FORMAT_S16_LE, /* Unsigned 16 bit CPU endian */ My_SND_PCM_FORMAT_U16 = My_SND_PCM_FORMAT_U16_LE, /* Signed 24 bit CPU endian */ My_SND_PCM_FORMAT_S24 = My_SND_PCM_FORMAT_S24_LE, /* Unsigned 24 bit CPU endian */ My_SND_PCM_FORMAT_U24 = My_SND_PCM_FORMAT_U24_LE, /* Signed 32 bit CPU endian */ My_SND_PCM_FORMAT_S32 = My_SND_PCM_FORMAT_S32_LE, /* Unsigned 32 bit CPU endian */ My_SND_PCM_FORMAT_U32 = My_SND_PCM_FORMAT_U32_LE, /* Float 32 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT = My_SND_PCM_FORMAT_FLOAT_LE, /* Float 64 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT64 = My_SND_PCM_FORMAT_FLOAT64_LE, /* IEC-958 CPU Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME = My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE#elif __BYTE_ORDER == __BIG_ENDIAN /* Signed 16 bit CPU endian */ My_SND_PCM_FORMAT_S16 = My_SND_PCM_FORMAT_S16_BE, /* Unsigned 16 bit CPU endian */ My_SND_PCM_FORMAT_U16 = My_SND_PCM_FORMAT_U16_BE, /* Signed 24 bit CPU endian */ My_SND_PCM_FORMAT_S24 = My_SND_PCM_FORMAT_S24_BE, /* Unsigned 24 bit CPU endian */ My_SND_PCM_FORMAT_U24 = My_SND_PCM_FORMAT_U24_BE, /* Signed 32 bit CPU endian */ My_SND_PCM_FORMAT_S32 = My_SND_PCM_FORMAT_S32_BE, /* Unsigned 32 bit CPU endian */ My_SND_PCM_FORMAT_U32 = My_SND_PCM_FORMAT_U32_BE, /* Float 32 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT = My_SND_PCM_FORMAT_FLOAT_BE, /* Float 64 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT64 = My_SND_PCM_FORMAT_FLOAT64_BE, /* IEC-958 CPU Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME = My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE#else#error "Unknown endian"#endif} My_snd_pcm_format_t; /* Unsigned frames quantity */typedef unsigned long My_snd_pcm_uframes_t;/* Signed frames quantity */typedef long My_snd_pcm_sframes_t; /* Non blocking mode (flag for open mode) \hideinitializer */#define My_SND_PCM_NONBLOCK 0x00000001 typedef int (*snd_pcm_open_ProcPtr) (My_snd_pcm_t **pcm, const char *name, My_snd_pcm_stream_t stream, int mode);LOCALVAR snd_pcm_open_ProcPtr My_snd_pcm_open = NULL;LOCALVAR blnr Did_snd_pcm_open = falseblnr; LOCALFUNC blnr HaveMy_snd_pcm_open(void){ if (! Did_snd_pcm_open) { if (HaveAlsaLib()) { My_snd_pcm_open = (snd_pcm_open_ProcPtr)dlsym(alsa_handle, "snd_pcm_open"); if (NULL == My_snd_pcm_open) { fprintf(stderr, "dlsym snd_pcm_open failed\n"); } } Did_snd_pcm_open = trueblnr; } return (My_snd_pcm_open != NULL);} typedef int (*snd_pcm_close_ProcPtr)(My_snd_pcm_t *pcm);LOCALVAR snd_pcm_close_ProcPtr My_snd_pcm_close = NULL;LOCALVAR blnr Did_snd_pcm_close = falseblnr; LOCALFUNC blnr HaveMy_snd_pcm_close(void){ if (! Did_snd_pcm_close) { if (HaveAlsaLib()) { My_snd_pcm_close = (snd_pcm_close_ProcPtr)dlsym(alsa_handle, "snd_pcm_close"); if (NULL == My_snd_pcm_close) { fprintf(stderr, "dlsym snd_pcm_close failed\n"); } } Did_snd_pcm_close = trueblnr;Lines 1–500 of 1618. Load more
/* SGLUALSA.h Copyright (C) 2012 Stephan Kochen, Paul C. Pratt You can redistribute this file and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. You should have received a copy of the license along with this file; see the file COPYING. This file 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 license for more details. */ /* Sound GLUe for ALSA ALSA sound support by Stephan Kochen. */ #ifndef RaspbianWorkAround #define RaspbianWorkAround 0 #endif #if 0 #include "alsa/asoundlib.h" /* and link with "-lasound" */ #define My_snd_pcm_t snd_pcm_t #define My_snd_pcm_hw_params_t snd_pcm_hw_params_t #define My_snd_pcm_sw_params_t snd_pcm_sw_params_t #define My_snd_pcm_state_t snd_pcm_state_t #if RaspbianWorkAround #define My_snd_pcm_status_t snd_pcm_status_t #endif #define My_SND_PCM_STATE_OPEN SND_PCM_STATE_OPEN #define My_SND_PCM_STATE_SETUP SND_PCM_STATE_SETUP #define My_SND_PCM_STATE_PREPARED SND_PCM_STATE_PREPARED #define My_SND_PCM_STATE_RUNNING SND_PCM_STATE_RUNNING #define My_SND_PCM_STATE_XRUN SND_PCM_STATE_XRUN #define My_SND_PCM_STATE_DRAINING SND_PCM_STATE_DRAINING #define My_SND_PCM_STATE_PAUSED SND_PCM_STATE_PAUSED #define My_SND_PCM_STATE_SUSPENDED SND_PCM_STATE_SUSPENDED #define My_SND_PCM_STATE_DISCONNECTED SND_PCM_STATE_DISCONNECTED #define My_SND_PCM_STATE_LAST SND_PCM_STATE_LAST #define My_snd_pcm_stream_t snd_pcm_stream_t #define My_SND_PCM_STREAM_PLAYBACK SND_PCM_STREAM_PLAYBACK #define My_SND_PCM_STREAM_CAPTURE SND_PCM_STREAM_CAPTURE #define My_SND_PCM_STREAM_LAST SND_PCM_STREAM_LAST #define My_snd_pcm_access_t snd_pcm_access_t #define My_SND_PCM_ACCESS_MMAP_INTERLEAVED \ SND_PCM_ACCESS_MMAP_INTERLEAVED #define My_SND_PCM_ACCESS_MMAP_NONINTERLEAVED \ SND_PCM_ACCESS_MMAP_NONINTERLEAVED #define My_SND_PCM_ACCESS_MMAP_COMPLEX \ SND_PCM_ACCESS_MMAP_COMPLEX #define My_SND_PCM_ACCESS_RW_INTERLEAVED \ SND_PCM_ACCESS_RW_INTERLEAVED #define My_SND_PCM_ACCESS_RW_NONINTERLEAVED \ SND_PCM_ACCESS_RW_NONINTERLEAVED #define My_SND_PCM_ACCESS_LAST \ SND_PCM_ACCESS_LAST #define My_snd_pcm_format_t snd_pcm_format_t #define My_SND_PCM_FORMAT_UNKNOWN SND_PCM_FORMAT_UNKNOWN #define My_SND_PCM_FORMAT_S8 SND_PCM_FORMAT_S8 #define My_SND_PCM_FORMAT_U8 SND_PCM_FORMAT_U8 #define My_SND_PCM_FORMAT_S16_LE SND_PCM_FORMAT_S16_LE #define My_SND_PCM_FORMAT_S16_BE SND_PCM_FORMAT_S16_BE #define My_SND_PCM_FORMAT_U16_LE SND_PCM_FORMAT_U16_LE #define My_SND_PCM_FORMAT_U16_BE SND_PCM_FORMAT_U16_BE #define My_SND_PCM_FORMAT_S24_LE SND_PCM_FORMAT_S24_LE #define My_SND_PCM_FORMAT_S24_BE SND_PCM_FORMAT_S24_BE #define My_SND_PCM_FORMAT_U24_LE SND_PCM_FORMAT_U24_LE #define My_SND_PCM_FORMAT_U24_BE SND_PCM_FORMAT_U24_BE #define My_SND_PCM_FORMAT_S32_LE SND_PCM_FORMAT_S32_LE #define My_SND_PCM_FORMAT_S32_BE SND_PCM_FORMAT_S32_BE #define My_SND_PCM_FORMAT_U32_LE SND_PCM_FORMAT_U32_LE #define My_SND_PCM_FORMAT_U32_BE SND_PCM_FORMAT_U32_BE #define My_SND_PCM_FORMAT_FLOAT_LE SND_PCM_FORMAT_FLOAT_LE #define My_SND_PCM_FORMAT_FLOAT_BE SND_PCM_FORMAT_FLOAT_BE #define My_SND_PCM_FORMAT_FLOAT64_LE SND_PCM_FORMAT_FLOAT64_LE #define My_SND_PCM_FORMAT_FLOAT64_BE SND_PCM_FORMAT_FLOAT64_BE #define My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE \ SND_PCM_FORMAT_IEC958_SUBFRAME_LE #define My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE \ SND_PCM_FORMAT_IEC958_SUBFRAME_BE #define My_SND_PCM_FORMAT_MU_LAW SND_PCM_FORMAT_MU_LAW #define My_SND_PCM_FORMAT_A_LAW SND_PCM_FORMAT_A_LAW #define My_SND_PCM_FORMAT_IMA_ADPCM SND_PCM_FORMAT_IMA_ADPCM #define My_SND_PCM_FORMAT_MPEG SND_PCM_FORMAT_MPEG #define My_SND_PCM_FORMAT_GSM SND_PCM_FORMAT_GSM #define My_SND_PCM_FORMAT_SPECIAL SND_PCM_FORMAT_SPECIAL #define My_SND_PCM_FORMAT_S24_3LE SND_PCM_FORMAT_S24_3LE #define My_SND_PCM_FORMAT_S24_3BE SND_PCM_FORMAT_S24_3BE #define My_SND_PCM_FORMAT_U24_3LE SND_PCM_FORMAT_U24_3LE #define My_SND_PCM_FORMAT_U24_3BE SND_PCM_FORMAT_U24_3BE #define My_SND_PCM_FORMAT_S20_3LE SND_PCM_FORMAT_S20_3LE #define My_SND_PCM_FORMAT_S20_3BE SND_PCM_FORMAT_S20_3BE #define My_SND_PCM_FORMAT_U20_3LE SND_PCM_FORMAT_U20_3LE #define My_SND_PCM_FORMAT_U20_3BE SND_PCM_FORMAT_U20_3BE #define My_SND_PCM_FORMAT_S18_3LE SND_PCM_FORMAT_S18_3LE #define My_SND_PCM_FORMAT_S18_3BE SND_PCM_FORMAT_S18_3BE #define My_SND_PCM_FORMAT_U18_3LE SND_PCM_FORMAT_U18_3LE #define My_SND_PCM_FORMAT_U18_3BE SND_PCM_FORMAT_U18_3BE #define My_SND_PCM_FORMAT_LAST SND_PCM_FORMAT_LAST #define My_SND_PCM_FORMAT_S16 SND_PCM_FORMAT_S16 #define My_SND_PCM_FORMAT_U16 SND_PCM_FORMAT_U16 #define My_SND_PCM_FORMAT_S24 SND_PCM_FORMAT_S24 #define My_SND_PCM_FORMAT_U24 SND_PCM_FORMAT_U24 #define My_SND_PCM_FORMAT_S32 SND_PCM_FORMAT_S32 #define My_SND_PCM_FORMAT_U32 SND_PCM_FORMAT_U32 #define My_SND_PCM_FORMAT_FLOAT SND_PCM_FORMAT_FLOAT #define My_SND_PCM_FORMAT_FLOAT64 SND_PCM_FORMAT_FLOAT64 #define My_SND_PCM_FORMAT_IEC958_SUBFRAME SND_PCM_FORMAT_FLOAT64 #define My_snd_pcm_uframes_t snd_pcm_uframes_t #define My_snd_pcm_sframes_t snd_pcm_sframes_t #define My_SND_PCM_NONBLOCK SND_PCM_NONBLOCK #define My_snd_pcm_open snd_pcm_open #define HaveMy_snd_pcm_open() (1) #define My_snd_pcm_close snd_pcm_close #define HaveMy_snd_pcm_close() (1) #define My_snd_pcm_hw_params_malloc snd_pcm_hw_params_malloc #define HaveMy_snd_pcm_hw_params_malloc() (1) #define My_snd_pcm_hw_params_free snd_pcm_hw_params_free #define HaveMy_snd_pcm_hw_params_free() (1) #define My_snd_pcm_hw_params_any snd_pcm_hw_params_any #define HaveMy_snd_pcm_hw_params_any() (1) #define My_snd_pcm_hw_params_set_access snd_pcm_hw_params_set_access #define HaveMy_snd_pcm_hw_params_set_access() (1) #define My_snd_pcm_hw_params_set_format snd_pcm_hw_params_set_format #define HaveMy_snd_pcm_hw_params_set_format() (1) #define My_snd_pcm_hw_params_set_rate_near \ snd_pcm_hw_params_set_rate_near #define HaveMy_snd_pcm_hw_params_set_rate_near() (1) #define My_snd_pcm_hw_params_set_channels \ snd_pcm_hw_params_set_channels #define HaveMy_snd_pcm_hw_params_set_channels() (1) #define My_snd_pcm_hw_params_set_buffer_size_near \ snd_pcm_hw_params_set_buffer_size_near #define HaveMy_snd_pcm_hw_params_set_buffer_size_near() (1) #define My_snd_pcm_hw_params_set_period_size_near \ snd_pcm_hw_params_set_period_size_near #define HaveMy_snd_pcm_hw_params_set_period_size_near() (1) #define My_snd_pcm_hw_params snd_pcm_hw_params #define HaveMy_snd_pcm_hw_params() (1) #define My_snd_pcm_sw_params_malloc snd_pcm_sw_params_malloc #define HaveMy_snd_pcm_sw_params_malloc() (1) #define My_snd_pcm_sw_params_free snd_pcm_sw_params_free #define HaveMy_snd_pcm_sw_params_free() (1) #define My_snd_pcm_sw_params_current snd_pcm_sw_params_current #define HaveMy_snd_pcm_sw_params_current() (1) #define My_snd_pcm_sw_params_set_start_threshold \ snd_pcm_sw_params_set_start_threshold #define HaveMy_snd_pcm_sw_params_set_start_threshold() (1) #define My_snd_pcm_sw_params_set_avail_min \ snd_pcm_sw_params_set_avail_min #define HaveMy_snd_pcm_sw_params_set_avail_min() (1) #define My_snd_pcm_sw_params_set_xfer_align \ snd_pcm_sw_params_set_xfer_align #define HaveMy_snd_pcm_sw_params_set_xfer_align() (1) #define My_snd_pcm_sw_params snd_pcm_sw_params #define HaveMy_snd_pcm_sw_params() (1) #define My_snd_pcm_nonblock snd_pcm_nonblock #define HaveMy_snd_pcm_nonblock() (1) #define My_snd_pcm_state snd_pcm_state #define HaveMy_snd_pcm_state() (1) #define My_snd_pcm_prepare snd_pcm_prepare #define HaveMy_snd_pcm_prepare() (1) #define My_snd_pcm_start snd_pcm_start #define HaveMy_snd_pcm_start() (1) #define My_snd_pcm_resume snd_pcm_resume #define HaveMy_snd_pcm_resume() (1) #define My_snd_pcm_avail_update snd_pcm_avail_update #define HaveMy_snd_pcm_avail_update() (1) #define My_snd_pcm_writei snd_pcm_writei #define HaveMy_snd_pcm_writei() (1) #define My_snd_pcm_drop snd_pcm_drop #define HaveMy_snd_pcm_drop() (1) #if RaspbianWorkAround #define My_snd_pcm_status_malloc snd_pcm_status_malloc #define HaveMy_snd_pcm_status_malloc() (1) #define My_snd_pcm_status snd_pcm_status #define HaveMy_snd_pcm_status() (1) #define My_snd_pcm_status_get_avail snd_pcm_status_get_avail #define HaveMy_snd_pcm_status_get_avail() (1) #endif #define My_snd_strerror snd_strerror #define HaveMy_snd_strerror() (1) #define MyCloseAlsaLib() #else static void *alsa_handle = NULL; LOCALVAR blnr DidAlsaLib = falseblnr; LOCALFUNC blnr HaveAlsaLib(void) { if (! DidAlsaLib) { alsa_handle = dlopen("libasound.so.2", RTLD_NOW); if (NULL == alsa_handle) { fprintf(stderr, "dlopen libasound failed\n"); } DidAlsaLib = trueblnr; } return (alsa_handle != NULL); } LOCALPROC MyCloseAlsaLib(void) { if (NULL != alsa_handle) { if (0 != dlclose(alsa_handle)) { fprintf(stderr, "dlclose libasound failed\n"); } alsa_handle = NULL; } } /* PCM handle */ typedef struct My__snd_pcm My_snd_pcm_t; /* PCM hardware configuration space container */ typedef struct My__snd_pcm_hw_params My_snd_pcm_hw_params_t; /* PCM software configuration container */ typedef struct My__snd_pcm_sw_params My_snd_pcm_sw_params_t; #if RaspbianWorkAround /* PCM status container */ typedef struct My__snd_pcm_status My_snd_pcm_status_t; #endif /* PCM state */ typedef enum My__snd_pcm_state { /* Open */ My_SND_PCM_STATE_OPEN = 0, /* Setup installed */ My_SND_PCM_STATE_SETUP, /* Ready to start */ My_SND_PCM_STATE_PREPARED, /* Running */ My_SND_PCM_STATE_RUNNING, /* Stopped: underrun (playback) or overrun (capture) detected */ My_SND_PCM_STATE_XRUN, /* Draining: running (playback) or stopped (capture) */ My_SND_PCM_STATE_DRAINING, /* Paused */ My_SND_PCM_STATE_PAUSED, /* Hardware is suspended */ My_SND_PCM_STATE_SUSPENDED, /* Hardware is disconnected */ My_SND_PCM_STATE_DISCONNECTED, My_SND_PCM_STATE_LAST = My_SND_PCM_STATE_DISCONNECTED } My_snd_pcm_state_t; /* PCM stream (direction) */ typedef enum My__snd_pcm_stream { /* Playback stream */ My_SND_PCM_STREAM_PLAYBACK = 0, /* Capture stream */ My_SND_PCM_STREAM_CAPTURE, My_SND_PCM_STREAM_LAST = My_SND_PCM_STREAM_CAPTURE } My_snd_pcm_stream_t; /* PCM access type */ typedef enum My__snd_pcm_access { /* mmap access with simple interleaved channels */ My_SND_PCM_ACCESS_MMAP_INTERLEAVED = 0, /* mmap access with simple non interleaved channels */ My_SND_PCM_ACCESS_MMAP_NONINTERLEAVED, /* mmap access with complex placement */ My_SND_PCM_ACCESS_MMAP_COMPLEX, /* snd_pcm_readi/snd_pcm_writei access */ My_SND_PCM_ACCESS_RW_INTERLEAVED, /* snd_pcm_readn/snd_pcm_writen access */ My_SND_PCM_ACCESS_RW_NONINTERLEAVED, My_SND_PCM_ACCESS_LAST = My_SND_PCM_ACCESS_RW_NONINTERLEAVED } My_snd_pcm_access_t; /* PCM sample format */ typedef enum My__snd_pcm_format { /* Unknown */ My_SND_PCM_FORMAT_UNKNOWN = -1, /* Signed 8 bit */ My_SND_PCM_FORMAT_S8 = 0, /* Unsigned 8 bit */ My_SND_PCM_FORMAT_U8, /* Signed 16 bit Little Endian */ My_SND_PCM_FORMAT_S16_LE, /* Signed 16 bit Big Endian */ My_SND_PCM_FORMAT_S16_BE, /* Unsigned 16 bit Little Endian */ My_SND_PCM_FORMAT_U16_LE, /* Unsigned 16 bit Big Endian */ My_SND_PCM_FORMAT_U16_BE, /* Signed 24 bit Little Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_S24_LE, /* Signed 24 bit Big Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_S24_BE, /* Unsigned 24 bit Little Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_U24_LE, /* Unsigned 24 bit Big Endian using low three bytes in 32-bit word */ My_SND_PCM_FORMAT_U24_BE, /* Signed 32 bit Little Endian */ My_SND_PCM_FORMAT_S32_LE, /* Signed 32 bit Big Endian */ My_SND_PCM_FORMAT_S32_BE, /* Unsigned 32 bit Little Endian */ My_SND_PCM_FORMAT_U32_LE, /* Unsigned 32 bit Big Endian */ My_SND_PCM_FORMAT_U32_BE, /* Float 32 bit Little Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT_LE, /* Float 32 bit Big Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT_BE, /* Float 64 bit Little Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT64_LE, /* Float 64 bit Big Endian, Range -1.0 to 1.0 */ My_SND_PCM_FORMAT_FLOAT64_BE, /* IEC-958 Little Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE, /* IEC-958 Big Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE, /* Mu-Law */ My_SND_PCM_FORMAT_MU_LAW, /* A-Law */ My_SND_PCM_FORMAT_A_LAW, /* Ima-ADPCM */ My_SND_PCM_FORMAT_IMA_ADPCM, /* MPEG */ My_SND_PCM_FORMAT_MPEG, /* GSM */ My_SND_PCM_FORMAT_GSM, /* Special */ My_SND_PCM_FORMAT_SPECIAL = 31, /* Signed 24bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_S24_3LE = 32, /* Signed 24bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_S24_3BE, /* Unsigned 24bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_U24_3LE, /* Unsigned 24bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_U24_3BE, /* Signed 20bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_S20_3LE, /* Signed 20bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_S20_3BE, /* Unsigned 20bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_U20_3LE, /* Unsigned 20bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_U20_3BE, /* Signed 18bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_S18_3LE, /* Signed 18bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_S18_3BE, /* Unsigned 18bit Little Endian in 3bytes format */ My_SND_PCM_FORMAT_U18_3LE, /* Unsigned 18bit Big Endian in 3bytes format */ My_SND_PCM_FORMAT_U18_3BE, My_SND_PCM_FORMAT_LAST = My_SND_PCM_FORMAT_U18_3BE, #if __BYTE_ORDER == __LITTLE_ENDIAN /* Signed 16 bit CPU endian */ My_SND_PCM_FORMAT_S16 = My_SND_PCM_FORMAT_S16_LE, /* Unsigned 16 bit CPU endian */ My_SND_PCM_FORMAT_U16 = My_SND_PCM_FORMAT_U16_LE, /* Signed 24 bit CPU endian */ My_SND_PCM_FORMAT_S24 = My_SND_PCM_FORMAT_S24_LE, /* Unsigned 24 bit CPU endian */ My_SND_PCM_FORMAT_U24 = My_SND_PCM_FORMAT_U24_LE, /* Signed 32 bit CPU endian */ My_SND_PCM_FORMAT_S32 = My_SND_PCM_FORMAT_S32_LE, /* Unsigned 32 bit CPU endian */ My_SND_PCM_FORMAT_U32 = My_SND_PCM_FORMAT_U32_LE, /* Float 32 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT = My_SND_PCM_FORMAT_FLOAT_LE, /* Float 64 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT64 = My_SND_PCM_FORMAT_FLOAT64_LE, /* IEC-958 CPU Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME = My_SND_PCM_FORMAT_IEC958_SUBFRAME_LE #elif __BYTE_ORDER == __BIG_ENDIAN /* Signed 16 bit CPU endian */ My_SND_PCM_FORMAT_S16 = My_SND_PCM_FORMAT_S16_BE, /* Unsigned 16 bit CPU endian */ My_SND_PCM_FORMAT_U16 = My_SND_PCM_FORMAT_U16_BE, /* Signed 24 bit CPU endian */ My_SND_PCM_FORMAT_S24 = My_SND_PCM_FORMAT_S24_BE, /* Unsigned 24 bit CPU endian */ My_SND_PCM_FORMAT_U24 = My_SND_PCM_FORMAT_U24_BE, /* Signed 32 bit CPU endian */ My_SND_PCM_FORMAT_S32 = My_SND_PCM_FORMAT_S32_BE, /* Unsigned 32 bit CPU endian */ My_SND_PCM_FORMAT_U32 = My_SND_PCM_FORMAT_U32_BE, /* Float 32 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT = My_SND_PCM_FORMAT_FLOAT_BE, /* Float 64 bit CPU endian */ My_SND_PCM_FORMAT_FLOAT64 = My_SND_PCM_FORMAT_FLOAT64_BE, /* IEC-958 CPU Endian */ My_SND_PCM_FORMAT_IEC958_SUBFRAME = My_SND_PCM_FORMAT_IEC958_SUBFRAME_BE #else #error "Unknown endian" #endif } My_snd_pcm_format_t; /* Unsigned frames quantity */ typedef unsigned long My_snd_pcm_uframes_t; /* Signed frames quantity */ typedef long My_snd_pcm_sframes_t; /* Non blocking mode (flag for open mode) \hideinitializer */ #define My_SND_PCM_NONBLOCK 0x00000001 typedef int (*snd_pcm_open_ProcPtr) (My_snd_pcm_t **pcm, const char *name, My_snd_pcm_stream_t stream, int mode); LOCALVAR snd_pcm_open_ProcPtr My_snd_pcm_open = NULL; LOCALVAR blnr Did_snd_pcm_open = falseblnr; LOCALFUNC blnr HaveMy_snd_pcm_open(void) { if (! Did_snd_pcm_open) { if (HaveAlsaLib()) { My_snd_pcm_open = (snd_pcm_open_ProcPtr)dlsym(alsa_handle, "snd_pcm_open"); if (NULL == My_snd_pcm_open) { fprintf(stderr, "dlsym snd_pcm_open failed\n"); } } Did_snd_pcm_open = trueblnr; } return (My_snd_pcm_open != NULL); } typedef int (*snd_pcm_close_ProcPtr)(My_snd_pcm_t *pcm); LOCALVAR snd_pcm_close_ProcPtr My_snd_pcm_close = NULL; LOCALVAR blnr Did_snd_pcm_close = falseblnr; LOCALFUNC blnr HaveMy_snd_pcm_close(void) { if (! Did_snd_pcm_close) { if (HaveAlsaLib()) { My_snd_pcm_close = (snd_pcm_close_ProcPtr)dlsym(alsa_handle, "snd_pcm_close"); if (NULL == My_snd_pcm_close) { fprintf(stderr, "dlsym snd_pcm_close failed\n"); } } Did_snd_pcm_close = trueblnr;