]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/sys/linux/sound.h
hello world
[icculus/iodoom3.git] / neo / sys / linux / sound.h
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28 #ifndef ID_SND_BACKENDS
29 #define ID_SND_BACKENDS
30
31 class idAudioHardwareOSS : public idAudioHardware {
32         // if you can't write MIXBUFFER_SAMPLES all at once to the audio device, split in MIXBUFFER_CHUNKS
33         static const int MIXBUFFER_CHUNKS = 4;
34
35         int                             m_audio_fd;
36         int                             m_sample_format;
37         unsigned int    m_channels;
38         unsigned int    m_speed;
39         void                    *m_buffer;
40         int                             m_buffer_size;
41         
42                                         // counting the loops through the dma buffer
43         int                             m_loops;
44         
45                                         // how many chunks we have left to write in cases where we need to split
46         int                             m_writeChunks;
47                                         // how many chunks we can write to the audio device without blocking
48         int                             m_freeWriteChunks;
49         
50 public:
51         idAudioHardwareOSS() { 
52                 m_audio_fd = 0;
53                 m_sample_format = 0;
54                 m_channels = 0;
55                 m_speed = 0;
56                 m_buffer = NULL;
57                 m_buffer_size = 0;
58                 m_loops = 0;
59                 m_writeChunks           = 0;
60                 m_freeWriteChunks       = 0;
61         }
62         virtual         ~idAudioHardwareOSS();
63
64         bool            Initialize( void );
65
66         // Linux driver doesn't support memory map API
67         bool            Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; }
68         bool            Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
69         bool            GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; }
70         
71         bool            Flush();
72         void            Write( bool flushing );
73
74         int                     GetNumberOfSpeakers() { return m_channels; }
75         int                     GetMixBufferSize();
76         short*          GetMixBuffer();
77                 
78 private:
79         void            Release( bool bSilent = false );
80         void            InitFailed();
81         void            ExtractOSSVersion( int version, idStr &str ) const;
82 };
83
84 #ifndef NO_ALSA
85
86 // libasound2-dev
87 // the new/old API may be a problem if we are going to dynamically load the asound lib?
88 #define ALSA_PCM_NEW_HW_PARAMS_API
89 #define ALSA_PCM_NEW_SW_PARAMS_API
90 #include <alsa/asoundlib.h>
91
92 #define id_snd_pcm_hw_params_alloca(ptr) do { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(id_snd_pcm_hw_params_sizeof()); memset(*ptr, 0, id_snd_pcm_hw_params_sizeof()); } while (0)
93
94 typedef const char * ( *pfn_snd_asoundlib_version )( void );
95 typedef snd_pcm_sframes_t ( *pfn_snd_pcm_avail_update )( snd_pcm_t *pcm );
96 typedef int ( *pfn_snd_pcm_close )( snd_pcm_t *pcm );
97 typedef const char * ( *pfn_snd_strerror )( int errnum );
98 typedef int ( *pfn_snd_pcm_hw_params )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params );
99 typedef int ( *pfn_snd_pcm_hw_params_any )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params );
100 typedef int ( *pfn_snd_pcm_hw_params_get_buffer_size )( const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val );
101 typedef int ( *pfn_snd_pcm_hw_params_set_access )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access );
102 typedef int ( *pfn_snd_pcm_hw_params_set_buffer_size_min )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val );
103 typedef int ( *pfn_snd_pcm_hw_params_set_channels )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val );
104 typedef int ( *pfn_snd_pcm_hw_params_set_format )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t format );
105 typedef int ( *pfn_snd_pcm_hw_params_set_rate )( snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir );
106 typedef size_t ( *pfn_snd_pcm_hw_params_sizeof )( void );
107 typedef int ( *pfn_snd_pcm_open )( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode );
108 typedef int ( *pfn_snd_pcm_prepare )( snd_pcm_t *pcm );
109 typedef snd_pcm_state_t ( *pfn_snd_pcm_state )( snd_pcm_t *pcm );
110 typedef snd_pcm_sframes_t ( *pfn_snd_pcm_writei )( snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size );
111
112 #define ALSA_DLSYM(SYM) id_##SYM = ( pfn_##SYM )dlvsym( m_handle, #SYM, "ALSA_0.9" ); if ( !id_##SYM ) { common->Printf( "dlsym "#SYM" failed: %s\n", dlerror() ); Release(); return false; }
113
114 class idAudioHardwareALSA : public idAudioHardware {
115 private:
116         // if you can't write MIXBUFFER_SAMPLES all at once to the audio device, split in MIXBUFFER_CHUNKS
117         static const int        MIXBUFFER_CHUNKS = 4;
118
119         snd_pcm_t                       *m_pcm_handle;
120         unsigned int            m_channels;
121         void                            *m_buffer;
122         int                                     m_buffer_size;
123
124         // how many frames remaining to be written to the device
125         int                                     m_remainingFrames;
126
127         void                            *m_handle;
128         
129 public:
130                                                 idAudioHardwareALSA() {
131                                                         m_pcm_handle            = NULL;
132                                                         m_channels                      = 0;
133                                                         m_buffer                        = NULL;
134                                                         m_buffer_size           = 0;
135                                                         m_remainingFrames       = 0;
136                                                         m_handle                        = NULL;
137                                                 }
138                                                 virtual                         ~idAudioHardwareALSA();
139
140                                                 // dlopen the lib ( check minimum version )
141         bool                            DLOpen();
142
143     bool                                Initialize( void );
144
145
146         // Linux driver doesn't support memory map API
147         bool                            Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) { return false; }
148         bool                            Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
149         bool                            GetCurrentPosition( ulong *pdwCurrentWriteCursor ) { return false; }
150         
151         bool                            Flush();
152         void                            Write( bool flushing );
153
154         int                                     GetNumberOfSpeakers( void ) { return m_channels; }
155         int                                     GetMixBufferSize( void );
156         short*                          GetMixBuffer( void );
157
158 private:
159         void                            Release();
160         void                            InitFailed();
161         void                            PlayTestPattern();
162
163         // may be NULL, outdated alsa versions are missing it and we just ignore
164         pfn_snd_asoundlib_version id_snd_asoundlib_version;
165
166         pfn_snd_pcm_avail_update id_snd_pcm_avail_update;
167         pfn_snd_pcm_close id_snd_pcm_close;
168         pfn_snd_strerror id_snd_strerror;
169         pfn_snd_pcm_hw_params id_snd_pcm_hw_params;
170         pfn_snd_pcm_hw_params_any id_snd_pcm_hw_params_any;
171         pfn_snd_pcm_hw_params_get_buffer_size id_snd_pcm_hw_params_get_buffer_size;
172         pfn_snd_pcm_hw_params_set_access id_snd_pcm_hw_params_set_access;
173         pfn_snd_pcm_hw_params_set_buffer_size_min id_snd_pcm_hw_params_set_buffer_size_min;
174         pfn_snd_pcm_hw_params_set_channels id_snd_pcm_hw_params_set_channels;
175         pfn_snd_pcm_hw_params_set_format id_snd_pcm_hw_params_set_format;
176         pfn_snd_pcm_hw_params_set_rate id_snd_pcm_hw_params_set_rate;
177         pfn_snd_pcm_hw_params_sizeof id_snd_pcm_hw_params_sizeof;
178         pfn_snd_pcm_open id_snd_pcm_open;
179         pfn_snd_pcm_prepare id_snd_pcm_prepare;
180         pfn_snd_pcm_state id_snd_pcm_state;
181         pfn_snd_pcm_writei id_snd_pcm_writei;
182
183 };
184
185 #endif // NO_ALSA
186
187 #endif