pulselayer.h 5.8 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
23
/*
 *  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

#include "audiolayer.h"
24
#include "audiostream.h"
25
#include "plug-in/audiorecorder/audiorecord.h"
26

27
28
#include <pulse/pulseaudio.h>

29
30
31
#define PLAYBACK_STREAM_NAME	    "SFLphone out"
#define CAPTURE_STREAM_NAME	    "SFLphone in"

32
33
34
35
36
37
38
39
class RingBuffer;
class ManagerImpl;

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

40
41
    void closeLayer( void );

Emmanuel Milou's avatar
Emmanuel Milou committed
42
43
44
45
46
47
48
49
50
51
52
53
    /**
     * 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 , ...)
54
     */
Emmanuel Milou's avatar
Emmanuel Milou committed
55
56
    bool openDevice(int indexIn, int indexOut, int sampleRate, int frameSize , int stream, std::string plugin) ;

57
    void startStream(void);
58

59
60
    void stopStream(void);

61
62
63
64
    /**
     * Query the capture device for number of bytes available in the hardware ring buffer
     * @return int The number of bytes available
     */
65
    int canGetMic();
66
67
68
69
70
71
72
    
    /**
     * 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)
     */
73
    int getMic(void *, int);
74
    
75
76
    static void overflow ( pa_stream* s, void* userdata );
    static void underflow ( pa_stream* s, void* userdata );
77
    static void stream_state_callback( pa_stream* s, void* user_data );	
Emmanuel Milou's avatar
Emmanuel Milou committed
78
    static void context_state_callback( pa_context* c, void* user_data );	
79

80
81
    bool isCaptureActive (void){return true;}

82
    /**
83
     * UNUSED in pulseaudio layer
84
     */
85
86
87
88
    //std::vector<std::string> getSoundCardsInfo( int stream UNUSED ) { 
      //std::vector<std::string> tmp;
      //return tmp; 
    //}
89

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

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

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

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

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

124
125
126
127
128
    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
129

130
    void processData( void );
131
  private:
Yun Liu's avatar
Yun Liu committed
132
133
134
135
136
137
    // Copy Constructor
    PulseLayer(const PulseLayer& rh);

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

138

Emmanuel Milou's avatar
Emmanuel Milou committed
139
140
141
142
143
    /**
     * Drop the pending frames and close the capture device
     */
    void closeCaptureStream( void );

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

Emmanuel Milou's avatar
Emmanuel Milou committed
156
157
158
159
160
    /**
     * Drop the pending frames and close the playback device
     */
    void closePlaybackStream( void );

161
162
163
    /**
     * Establishes the connection with the local pulseaudio server
     */
164
165
166
167
168
169
    void connectPulseAudioServer( void );

    /**
     * Close the connection with the local pulseaudio server
     */
    void disconnectPulseAudioServer( void );
170

171
172
173
    /**
     * Get some information about the pulseaudio server
     */
174
175
    void serverinfo( void );

176
    /** PulseAudio context and asynchronous loop */
177
178
    pa_context* context;
    pa_threaded_mainloop* m;
179
180
181
182
    
    /**
     * A stream object to handle the pulseaudio playback stream
     */
183
    AudioStream* playback;
184
185
186
187

    /**
     * A stream object to handle the pulseaudio capture stream
     */
188
    AudioStream* record;
189

190
191
192
    int spkrVolume;
    int micVolume;

Yun Liu's avatar
Yun Liu committed
193
194
public: 
    static int streamState;
195
196
197
198
};

#endif // _PULSE_LAYER_H_