pulselayer.h 6.08 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 *  Copyright (C) 2008 Savoir-Faire Linux inc.
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *                                                                              
 *  This program 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 General Public License for more details.
 *                                                                              
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef _PULSE_LAYER_H
#define _PULSE_LAYER_H

23
#include "audio/audiolayer.h"
24
#include "audio/samplerateconverter.h"
25
#include "audio/dcblocker.h"
26
#include "audiostream.h"
27

28
#include <pulse/pulseaudio.h>
29
#include <pulse/stream.h>
30

31 32 33
#define PLAYBACK_STREAM_NAME	    "SFLphone out"
#define CAPTURE_STREAM_NAME	    "SFLphone in"

34 35 36 37 38 39 40 41
class RingBuffer;
class ManagerImpl;

class PulseLayer : public AudioLayer {
  public:
    PulseLayer(ManagerImpl* manager);
    ~PulseLayer(void);

42
    bool closeLayer( void );
43

Emmanuel Milou's avatar
Emmanuel Milou committed
44 45 46 47 48 49 50 51 52 53 54 55
    /**
     * Check if no devices are opened, otherwise close them.
     * Then open the specified devices by calling the private functions open_device
     * @param indexIn	The number of the card choosen for capture
     * @param indexOut	The number of the card choosen for playback
     * @param sampleRate  The sample rate 
     * @param frameSize	  The frame size
     * @param stream	  To indicate which kind of stream you want to open
     *			  SFL_PCM_CAPTURE
     *			  SFL_PCM_PLAYBACK
     *			  SFL_PCM_BOTH
     * @param plugin	  The alsa plugin ( dmix , default , front , surround , ...)
56
     */
Emmanuel Milou's avatar
Emmanuel Milou committed
57 58
    bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize , int stream, std::string plugin) ;

59
    void startStream(void);
60

61 62
    void stopStream(void);

63 64 65 66
    /**
     * Query the capture device for number of bytes available in the hardware ring buffer
     * @return int The number of bytes available
     */
67
    int canGetMic();
68 69 70 71 72 73 74
    
    /**
     * Get data from the capture device
     * @param buffer The buffer for data
     * @param toCopy The number of bytes to get
     * @return int The number of bytes acquired ( 0 if an error occured)
     */
75
    int getMic(void *, int);
76
    
77 78
    static void overflow ( pa_stream* s, void* userdata );
    static void underflow ( pa_stream* s, void* userdata );
79
    static void stream_state_callback( pa_stream* s, void* user_data );	
80
    static void context_state_callback( pa_context* c, void* user_data );
81
    // static void stream_suspended_callback ( pa_stream* s, void* userdata );	
82

83
    bool isCaptureActive (void){return true;}
84 85

    /**
86
     * UNUSED in pulseaudio layer
87
     */
88 89 90 91
    //std::vector<std::string> getSoundCardsInfo( int stream UNUSED ) { 
      //std::vector<std::string> tmp;
      //return tmp; 
    //}
92

93 94 95
    /**
     * Reduce volume of every audio applications connected to the same sink
     */
96
    void reducePulseAppsVolume( void );
97 98 99 100 101
    
    /**
     * Restore the volume of every audio applications connected to the same sink to PA_VOLUME_NORM
     */
    void restorePulseAppsVolume( void );
102

103
    /**
104
     * Set the volume of a sink. 
105 106
     * @param index The index of the stream 
     * @param channels	The stream's number of channels
107
     * @param volume The new volume (between 0 and 100)
108
     */
109 110 111 112 113
    void setSinkVolume( int index, int channels, int volume );
    void setSourceVolume( int index, int channels, int volume );

    void setPlaybackVolume( int volume );
    void setCaptureVolume( int volume );
114

115 116 117 118
    /**
     * Accessor
     * @return AudioStream* The pointer on the playback AudioStream object
     */
119
    AudioStream* getPlaybackStream(){ return playback;}
120 121 122 123 124

    /**
     * Accessor
     * @return AudioStream* The pointer on the record AudioStream object
     */
125
    AudioStream* getRecordStream(){ return record;}
126

127 128 129 130 131
    int getSpkrVolume( void ) { return spkrVolume; }
    void setSpkrVolume( int value ) { spkrVolume = value; }

    int getMicVolume( void ) { return micVolume; }
    void setMicVolume( int value ) { micVolume = value; }
Emmanuel Milou's avatar
Emmanuel Milou committed
132

133
    void processData( void );
134
    
135
  private:
Yun Liu's avatar
Yun Liu committed
136 137 138 139 140 141
    // Copy Constructor
    PulseLayer(const PulseLayer& rh);

    // Assignment Operator
    PulseLayer& operator=( const PulseLayer& rh);

142

Emmanuel Milou's avatar
Emmanuel Milou committed
143 144 145 146 147
    /**
     * Drop the pending frames and close the capture device
     */
    void closeCaptureStream( void );

148 149 150
    /**
     * Write data from the ring buffer to the harware and read data from the hardware
     */
151 152
    void readFromMic( void );
    void writeToSpeaker( void );
153 154 155 156 157
    
    /**
     * Create the audio streams into the given context
     * @param c	The pulseaudio context
     */ 
158
    bool createStreams( pa_context* c );
159

Emmanuel Milou's avatar
Emmanuel Milou committed
160 161 162 163 164
    /**
     * Drop the pending frames and close the playback device
     */
    void closePlaybackStream( void );

165 166 167
    /**
     * Establishes the connection with the local pulseaudio server
     */
168 169 170 171 172
    void connectPulseAudioServer( void );

    /**
     * Close the connection with the local pulseaudio server
     */
173
    bool disconnectPulseAudioServer( void );
174

175 176 177
    /**
     * Get some information about the pulseaudio server
     */
178 179
    void serverinfo( void );

180
    /** PulseAudio context and asynchronous loop */
181 182
    pa_context* context;
    pa_threaded_mainloop* m;
183 184 185 186
    
    /**
     * A stream object to handle the pulseaudio playback stream
     */
187
    AudioStream* playback;
188 189 190 191

    /**
     * A stream object to handle the pulseaudio capture stream
     */
192
    AudioStream* record;
193

194 195 196
    /** Sample rate converter object */
    SamplerateConverter * _converter;

197
    bool is_started;
198

199 200 201
    int spkrVolume;
    int micVolume;

202 203
    DcBlocker* dcblocker;

204
    // private:
205

Yun Liu's avatar
Yun Liu committed
206
public: 
207 208

    friend class AudioLayerTest;
209 210 211 212
};

#endif // _PULSE_LAYER_H_