~ubuntu-branches/ubuntu/saucy/sflphone/saucy

« back to all changes in this revision

Viewing changes to sflphone-common/src/audio/alsa/alsalayer.h

  • Committer: Bazaar Package Importer
  • Author(s): Francois Marier
  • Date: 2010-12-24 16:33:55 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20101224163355-tkvvikqxbrbav6up
Tags: 0.9.11-1
* New upstream release
* Add new build dependencies on libwebkit-dev and libyaml-dev

* Bump Standards-Version up to 3.9.1
* Bump debhelper compatibility to 8
* Patch another typo in the upstream code (lintian notice)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc.
3
3
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
 
4
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
4
5
 *
5
6
 *  This program is free software; you can redistribute it and/or modify
6
7
 *  it under the terms of the GNU General Public License as published by
7
8
 *  the Free Software Foundation; either version 3 of the License, or
8
9
 *  (at your option) any later version.
9
 
 *                                                                              
 
10
 *
10
11
 *  This program is distributed in the hope that it will be useful,
11
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
14
 *  GNU General Public License for more details.
14
 
 *                                                                              
 
15
 *
15
16
 *  You should have received a copy of the GNU General Public License
16
17
 *  along with this program; if not, write to the Free Software
17
18
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33
34
 
34
35
#include "audio/audiolayer.h"
35
36
#include "audio/samplerateconverter.h"
36
 
#include "audio/dcblocker.h"
37
37
#include "eventthread.h"
38
38
#include <alsa/asoundlib.h>
39
39
 
 
40
// #include <fstream>
 
41
 
40
42
class RingBuffer;
41
43
class ManagerImpl;
42
44
 
45
47
 
46
48
/**
47
49
 * @file  AlsaLayer.h
48
 
 * @brief Main sound class. Manages the data transfers between the application and the hardware. 
 
50
 * @brief Main sound class. Manages the data transfers between the application and the hardware.
49
51
 */
50
52
 
51
 
class AlsaLayer : public AudioLayer {
52
 
  public:
53
 
    /**
54
 
     * Constructor
55
 
     * @param manager An instance of managerimpl
56
 
     */
57
 
    AlsaLayer( ManagerImpl* manager );  
58
 
 
59
 
    /**
60
 
     * Destructor
61
 
     */
62
 
    ~AlsaLayer(void);
63
 
 
64
 
    bool closeLayer( void );
65
 
 
66
 
    /**
67
 
     * Check if no devices are opened, otherwise close them.
68
 
     * Then open the specified devices by calling the private functions open_device
69
 
     * @param indexIn   The number of the card choosen for capture
70
 
     * @param indexOut  The number of the card choosen for playback
71
 
     * @param sampleRate  The sample rate 
72
 
     * @param frameSize   The frame size
73
 
     * @param stream      To indicate which kind of stream you want to open
74
 
     *                    SFL_PCM_CAPTURE
75
 
     *                    SFL_PCM_PLAYBACK
76
 
     *                    SFL_PCM_BOTH
77
 
     * @param plugin      The alsa plugin ( dmix , default , front , surround , ...)
78
 
     */
79
 
    bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize, int stream, std::string plugin);
80
 
 
81
 
    /**
82
 
     * Start the capture stream and prepare the playback stream. 
83
 
     * The playback starts accordingly to its threshold
84
 
     * ALSA Library API
85
 
     */
86
 
    void startStream(void);
87
 
 
88
 
    /**
89
 
     * Stop the playback and capture streams. 
90
 
     * Drops the pending frames and put the capture and playback handles to PREPARED state
91
 
     * ALSA Library API
92
 
     */
93
 
    void stopStream(void);
94
 
    
95
 
    /**
96
 
     * Query the capture device for number of bytes available in the hardware ring buffer
97
 
     * @return int The number of bytes available
98
 
     */
99
 
    int canGetMic();
100
 
 
101
 
    /**
102
 
     * Get data from the capture device
103
 
     * @param buffer The buffer for data
104
 
     * @param toCopy The number of bytes to get
105
 
     * @return int The number of bytes acquired ( 0 if an error occured)
106
 
     */
107
 
    int getMic(void * buffer, int toCopy);
108
 
    
109
 
    /**
110
 
     * Concatenate two strings. Used to build a valid pcm device name. 
111
 
     * @param plugin the alsa PCM name
112
 
     * @param card the sound card number
113
 
     * @param subdevice the subdevice number
114
 
     * @return std::string the concatenated string
115
 
     */
116
 
    std::string buildDeviceTopo( std::string plugin, int card, int subdevice );
117
 
 
118
 
    /**
119
 
     * Scan the sound card available on the system
120
 
     * @param stream To indicate whether we are looking for capture devices or playback devices
121
 
     *             SFL_PCM_CAPTURE
122
 
     *             SFL_PCM_PLAYBACK
123
 
     *             SFL_PCM_BOTH
124
 
     * @return std::vector<std::string> The vector containing the string description of the card
125
 
     */
126
 
    std::vector<std::string> getSoundCardsInfo( int stream );
127
 
 
128
 
    /**
129
 
     * Check if the given index corresponds to an existing sound card and supports the specified streaming mode
130
 
     * @param card   An index
131
 
     * @param stream  The stream mode
132
 
     *            SFL_PCM_CAPTURE
133
 
     *            SFL_PCM_PLAYBACK
134
 
     *            SFL_PCM_BOTH
135
 
     * @return bool True if it exists and supports the mode
136
 
     *              false otherwise
137
 
     */
138
 
    bool soundCardIndexExist( int card , int stream );
139
 
    
140
 
    /**
141
 
     * An index is associated with its string description
142
 
     * @param description The string description
143
 
     * @return  int       Its index
144
 
     */
145
 
    int soundCardGetIndex( std::string description );
146
 
 
147
 
    /**
148
 
     * Get the current audio plugin.
149
 
     * @return std::string  The name of the audio plugin
150
 
     */
151
 
    std::string getAudioPlugin( void ) { return _audioPlugin; }
152
 
 
153
 
    void audioCallback (void);
154
 
 
155
 
    bool isCaptureActive (void);
156
 
 
157
 
  private:
158
 
  
159
 
    // Copy Constructor
160
 
    AlsaLayer(const AlsaLayer& rh);
161
 
 
162
 
    // Assignment Operator
163
 
    AlsaLayer& operator=( const AlsaLayer& rh);
164
 
 
165
 
    bool is_playback_prepared (void) { return _is_prepared_playback; }
166
 
    bool is_capture_prepared (void) { return _is_prepared_capture; }
167
 
    void prepare_playback (void) { _is_prepared_playback = true; }
168
 
    void prepare_capture (void) { _is_prepared_capture = true; }
169
 
    bool is_capture_running (void) { return _is_running_capture; }
170
 
    bool is_playback_running (void) { return _is_running_playback; }
171
 
    void start_playback (void) { _is_running_playback = true; }
172
 
    void stop_playback (void) { _is_running_playback = false; _is_prepared_playback = false; }
173
 
    void start_capture (void) { _is_running_capture = true; }
174
 
    void stop_capture (void) { _is_running_capture = false; _is_prepared_capture = false; }
175
 
    void close_playback (void) { _is_open_playback = false; }
176
 
    void close_capture (void) { _is_open_capture = false; }
177
 
    void open_playback (void) { _is_open_playback = true; }
178
 
    void open_capture (void) { _is_open_capture = true; }
179
 
    bool is_capture_open (void) { return _is_open_capture; }
180
 
    bool is_playback_open (void) { return _is_open_playback; }
181
 
    
182
 
    /**
183
 
     * Drop the pending frames and close the capture device
184
 
     * ALSA Library API
185
 
     */
186
 
    void closeCaptureStream( void );
187
 
    void stopCaptureStream( void );
188
 
    void startCaptureStream( void );
189
 
    void prepareCaptureStream( void );
190
 
 
191
 
    void closePlaybackStream( void );
192
 
    void stopPlaybackStream( void );
193
 
    void startPlaybackStream( void );
194
 
    void preparePlaybackStream( void );
195
 
 
196
 
    /**
197
 
     * Open the specified device.
198
 
     * ALSA Library API
199
 
     * @param pcm_p The string name for the playback device
200
 
     * @param pcm_c The string name for the capture device
201
 
     * @param flag  To indicate which kind of stream you want to open
202
 
     *              SFL_PCM_CAPTURE
203
 
     *              SFL_PCM_PLAYBACK
204
 
     *              SFL_PCM_BOTH
205
 
     * @return true if successful
206
 
     *         false otherwise
207
 
     */
208
 
    bool open_device( std::string pcm_p, std::string pcm_c, int flag); 
209
 
 
210
 
    bool alsa_set_params( snd_pcm_t *pcm_handle, int type, int rate );
211
 
 
212
 
    /**
213
 
     * Copy a data buffer in the internal ring buffer
214
 
     * ALSA Library API
215
 
     * @param buffer The data to be copied
216
 
     * @param length The size of the buffer
217
 
     * @return int The number of frames actually copied
218
 
     */
219
 
    int write( void* buffer, int length);
220
 
    
221
 
    /**
222
 
     * Read data from the internal ring buffer
223
 
     * ALSA Library API
224
 
     * @param buffer  The buffer to stock the read data
225
 
     * @param toCopy  The number of bytes to get
226
 
     * @return int The number of frames actually read
227
 
     */
228
 
    int read( void* buffer, int toCopy);
229
 
    
230
 
    
231
 
 
232
 
    /**
233
 
     * Recover from XRUN state for capture
234
 
     * ALSA Library API
235
 
     */
236
 
    void handle_xrun_capture( void );
237
 
 
238
 
    /**
239
 
     * Recover from XRUN state for playback
240
 
     * ALSA Library API
241
 
     */
242
 
    void handle_xrun_playback( void );
243
 
    
244
 
    void* adjustVolume( void* buffer , int len, int stream );
245
 
    
246
 
/**
247
 
     * Handles to manipulate playback stream
248
 
     * ALSA Library API
249
 
     */
250
 
    snd_pcm_t* _PlaybackHandle;
251
 
 
252
 
    /**
253
 
     * Handles to manipulate capture stream
254
 
     * ALSA Library API
255
 
     */
256
 
    snd_pcm_t* _CaptureHandle;
257
 
    
258
 
    /**
259
 
     * Alsa parameter - Size of a period in the hardware ring buffer
260
 
     */
261
 
    snd_pcm_uframes_t _periodSize;
262
 
 
263
 
    /**
264
 
     * name of the alsa audio plugin used
265
 
     */
266
 
    std::string _audioPlugin;
267
 
 
268
 
    /** Vector to manage all soundcard index - description association of the system */
269
 
    std::vector<HwIDPair> IDSoundCards;
270
 
 
271
 
        bool _is_prepared_playback;
272
 
    bool _is_prepared_capture;
273
 
    bool _is_running_playback;
274
 
    bool _is_running_capture;
275
 
    bool _is_open_playback;
276
 
    bool _is_open_capture;
277
 
    bool _trigger_request;
278
 
    
279
 
    AudioThread* _audioThread;
280
 
 
281
 
    /** Sample rate converter object */
282
 
    SamplerateConverter* _converter;
283
 
 
284
 
    // Allpass filter to remove DC offset
285
 
    DcBlocker* dcblocker;
 
53
class AlsaLayer : public AudioLayer
 
54
{
 
55
    public:
 
56
        /**
 
57
         * Constructor
 
58
         * @param manager An instance of managerimpl
 
59
         */
 
60
        AlsaLayer (ManagerImpl* manager);
 
61
 
 
62
        /**
 
63
         * Destructor
 
64
         */
 
65
        ~AlsaLayer (void);
 
66
 
 
67
        bool closeLayer (void);
 
68
 
 
69
        /**
 
70
         * Check if no devices are opened, otherwise close them.
 
71
         * Then open the specified devices by calling the private functions open_device
 
72
         * @param indexIn       The number of the card chosen for capture
 
73
         * @param indexOut      The number of the card chosen for playback
 
74
         * @param sampleRate  The sample rate
 
75
         * @param frameSize       The frame size
 
76
         * @param stream          To indicate which kind of stream you want to open
 
77
         *                        SFL_PCM_CAPTURE
 
78
         *                        SFL_PCM_PLAYBACK
 
79
         *                        SFL_PCM_BOTH
 
80
         * @param plugin          The alsa plugin ( dmix , default , front , surround , ...)
 
81
         */
 
82
        bool openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize, int stream, std::string plugin);
 
83
 
 
84
        /**
 
85
         * Start the capture stream and prepare the playback stream.
 
86
         * The playback starts accordingly to its threshold
 
87
         * ALSA Library API
 
88
         */
 
89
        void startStream (void);
 
90
 
 
91
        /**
 
92
         * Stop the playback and capture streams.
 
93
         * Drops the pending frames and put the capture and playback handles to PREPARED state
 
94
         * ALSA Library API
 
95
         */
 
96
        void stopStream (void);
 
97
 
 
98
        /**
 
99
         * Query the capture device for number of bytes available in the hardware ring buffer
 
100
         * @return int The number of bytes available
 
101
         */
 
102
        int canGetMic();
 
103
 
 
104
        /**
 
105
         * Get data from the capture device
 
106
         * @param buffer The buffer for data
 
107
         * @param toCopy The number of bytes to get
 
108
         * @return int The number of bytes acquired ( 0 if an error occured)
 
109
         */
 
110
        int getMic (void * buffer, int toCopy);
 
111
 
 
112
        /**
 
113
         * Concatenate two strings. Used to build a valid pcm device name.
 
114
         * @param plugin the alsa PCM name
 
115
         * @param card the sound card number
 
116
         * @param subdevice the subdevice number
 
117
         * @return std::string the concatenated string
 
118
         */
 
119
        std::string buildDeviceTopo (std::string plugin, int card, int subdevice);
 
120
 
 
121
        /**
 
122
         * Scan the sound card available on the system
 
123
         * @param stream To indicate whether we are looking for capture devices or playback devices
 
124
         *                 SFL_PCM_CAPTURE
 
125
         *                 SFL_PCM_PLAYBACK
 
126
         *                 SFL_PCM_BOTH
 
127
         * @return std::vector<std::string> The vector containing the string description of the card
 
128
         */
 
129
        std::vector<std::string> getSoundCardsInfo (int stream);
 
130
 
 
131
        /**
 
132
         * Check if the given index corresponds to an existing sound card and supports the specified streaming mode
 
133
         * @param card   An index
 
134
         * @param stream  The stream mode
 
135
         *                SFL_PCM_CAPTURE
 
136
         *                SFL_PCM_PLAYBACK
 
137
         *                SFL_PCM_BOTH
 
138
         * @return bool True if it exists and supports the mode
 
139
         *                  false otherwise
 
140
         */
 
141
        bool soundCardIndexExist (int card , int stream);
 
142
 
 
143
        /**
 
144
         * An index is associated with its string description
 
145
         * @param description The string description
 
146
         * @return      int       Its index
 
147
         */
 
148
        int soundCardGetIndex (std::string description);
 
149
 
 
150
        /**
 
151
         * Get the current audio plugin.
 
152
         * @return std::string  The name of the audio plugin
 
153
         */
 
154
        std::string getAudioPlugin (void) {
 
155
            return _audioPlugin;
 
156
        }
 
157
 
 
158
        void audioCallback (void);
 
159
 
 
160
        bool isCaptureActive (void);
 
161
 
 
162
        /**
 
163
         * Get the noise suppressor state
 
164
         * @return true if noise suppressor activated
 
165
         */
 
166
        virtual bool getNoiseSuppressState (void) {
 
167
            return AudioLayer::_noisesuppressstate;
 
168
        }
 
169
 
 
170
        /**
 
171
         * Set the noise suppressor state
 
172
         * @param state true if noise suppressor active, false elsewhere
 
173
         */
 
174
        virtual void setNoiseSuppressState (bool state);
 
175
 
 
176
    private:
 
177
 
 
178
        // Copy Constructor
 
179
        AlsaLayer (const AlsaLayer& rh);
 
180
 
 
181
        // Assignment Operator
 
182
        AlsaLayer& operator= (const AlsaLayer& rh);
 
183
 
 
184
        bool is_playback_prepared (void) {
 
185
            return _is_prepared_playback;
 
186
        }
 
187
        bool is_capture_prepared (void) {
 
188
            return _is_prepared_capture;
 
189
        }
 
190
        void prepare_playback (void) {
 
191
            _is_prepared_playback = true;
 
192
        }
 
193
        void prepare_capture (void) {
 
194
            _is_prepared_capture = true;
 
195
        }
 
196
        bool is_capture_running (void) {
 
197
            return _is_running_capture;
 
198
        }
 
199
        bool is_playback_running (void) {
 
200
            return _is_running_playback;
 
201
        }
 
202
        void start_playback (void) {
 
203
            _is_running_playback = true;
 
204
        }
 
205
        void stop_playback (void) {
 
206
            _is_running_playback = false;
 
207
            _is_prepared_playback = false;
 
208
        }
 
209
        void start_capture (void) {
 
210
            _is_running_capture = true;
 
211
        }
 
212
        void stop_capture (void) {
 
213
            _is_running_capture = false;
 
214
            _is_prepared_capture = false;
 
215
        }
 
216
        void close_playback (void) {
 
217
            _is_open_playback = false;
 
218
        }
 
219
        void close_capture (void) {
 
220
            _is_open_capture = false;
 
221
        }
 
222
        void open_playback (void) {
 
223
            _is_open_playback = true;
 
224
        }
 
225
        void open_capture (void) {
 
226
            _is_open_capture = true;
 
227
        }
 
228
        bool is_capture_open (void) {
 
229
            return _is_open_capture;
 
230
        }
 
231
        bool is_playback_open (void) {
 
232
            return _is_open_playback;
 
233
        }
 
234
 
 
235
        /**
 
236
         * Drop the pending frames and close the capture device
 
237
         * ALSA Library API
 
238
         */
 
239
        void closeCaptureStream (void);
 
240
        void stopCaptureStream (void);
 
241
        void startCaptureStream (void);
 
242
        void prepareCaptureStream (void);
 
243
 
 
244
        void closePlaybackStream (void);
 
245
        void stopPlaybackStream (void);
 
246
        void startPlaybackStream (void);
 
247
        void preparePlaybackStream (void);
 
248
 
 
249
        /**
 
250
         * Open the specified device.
 
251
         * ALSA Library API
 
252
         * @param pcm_p The string name for the playback device
 
253
         * @param pcm_c The string name for the capture device
 
254
         * @param flag  To indicate which kind of stream you want to open
 
255
         *                  SFL_PCM_CAPTURE
 
256
         *                  SFL_PCM_PLAYBACK
 
257
         *                  SFL_PCM_BOTH
 
258
         * @return true if successful
 
259
         *             false otherwise
 
260
         */
 
261
        bool open_device (std::string pcm_p, std::string pcm_c, std::string pcm_r,  int flag);
 
262
 
 
263
        bool alsa_set_params (snd_pcm_t *pcm_handle, int type, int rate);
 
264
 
 
265
        /**
 
266
         * Copy a data buffer in the internal ring buffer
 
267
         * ALSA Library API
 
268
         * @param buffer The data to be copied
 
269
         * @param length The size of the buffer
 
270
         * @return int The number of frames actually copied
 
271
         */
 
272
        int write (void* buffer, int length, snd_pcm_t *handle);
 
273
 
 
274
        /**
 
275
         * Read data from the internal ring buffer
 
276
         * ALSA Library API
 
277
         * @param buffer  The buffer to stock the read data
 
278
         * @param toCopy  The number of bytes to get
 
279
         * @return int The number of frames actually read
 
280
         */
 
281
        int read (void* buffer, int toCopy);
 
282
 
 
283
        /**
 
284
         * Recover from XRUN state for capture
 
285
         * ALSA Library API
 
286
         */
 
287
        void handle_xrun_capture (void);
 
288
 
 
289
        /**
 
290
         * Recover from XRUN state for playback
 
291
         * ALSA Library API
 
292
         */
 
293
        void handle_xrun_playback (snd_pcm_t *handle);
 
294
 
 
295
        void* adjustVolume (void* buffer , int len, int stream);
 
296
 
 
297
        /**
 
298
         * Handles to manipulate playback stream
 
299
         * ALSA Library API
 
300
         */
 
301
        snd_pcm_t* _PlaybackHandle;
 
302
 
 
303
        /**
 
304
         * Handles to manipulate ringtone stream
 
305
         *
 
306
         */
 
307
        snd_pcm_t *_RingtoneHandle;
 
308
 
 
309
        /**
 
310
         * Handles to manipulate capture stream
 
311
         * ALSA Library API
 
312
         */
 
313
        snd_pcm_t* _CaptureHandle;
 
314
 
 
315
        /**
 
316
         * Alsa parameter - Size of a period in the hardware ring buffer
 
317
         */
 
318
        snd_pcm_uframes_t _periodSize;
 
319
 
 
320
        /**
 
321
         * name of the alsa audio plugin used
 
322
         */
 
323
        std::string _audioPlugin;
 
324
 
 
325
        /** Vector to manage all soundcard index - description association of the system */
 
326
        std::vector<HwIDPair> IDSoundCards;
 
327
 
 
328
        bool _is_prepared_playback;
 
329
        bool _is_prepared_capture;
 
330
        bool _is_running_playback;
 
331
        bool _is_running_capture;
 
332
        bool _is_open_playback;
 
333
        bool _is_open_capture;
 
334
        bool _trigger_request;
 
335
 
 
336
        AudioThread* _audioThread;
 
337
 
 
338
        /** Sample rate converter object */
 
339
        SamplerateConverter* _converter;
 
340
 
 
341
        // ofstream *captureFile;
286
342
 
287
343
};
288
344