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

« back to all changes in this revision

Viewing changes to sflphone-common/src/audio/pulseaudio/pulselayer.cpp

  • 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:
32
32
#include "pulselayer.h"
33
33
#include "managerimpl.h"
34
34
 
 
35
 
 
36
// #include <fstream>
 
37
 
35
38
int framesPerBuffer = 2048;
36
39
 
 
40
 
 
41
 
 
42
 
37
43
static  void playback_callback (pa_stream* s, size_t bytes, void* userdata)
38
44
{
39
45
 
49
55
    assert (s && bytes);
50
56
    assert (bytes > 0);
51
57
    static_cast<PulseLayer*> (userdata)->processCaptureData();
52
 
    
53
 
}
54
 
 
55
 
/*
56
 
static void stream_suspended_callback (pa_stream *s UNUSED, void *userdata UNUSED)
57
 
{
58
 
    _debug("Audio: Stream Suspended");
59
 
}
60
 
*/
61
 
 
62
 
/*
63
 
static void stream_moved_callback(pa_stream *s UNUSED, void *userdata UNUSED)
64
 
{
65
 
    _debug("Audio: Stream Moved");
66
 
}
67
 
*/
68
 
 
69
 
static void playback_underflow_callback (pa_stream* s,  void* userdata UNUSED)
70
 
{
71
 
    // _debug ("Audio: Buffer Underflow");
72
 
    // pa_stream_trigger (s, NULL, NULL);
 
58
 
 
59
}
 
60
 
 
61
static void ringtone_callback (pa_stream* s, size_t bytes, void* userdata)
 
62
{
 
63
 
 
64
    assert (s && bytes);
 
65
    assert (bytes > 0);
 
66
    static_cast<PulseLayer*> (userdata)->processRingtoneData();
 
67
 
 
68
}
 
69
 
 
70
static void stream_moved_callback (pa_stream *s, void *userdata UNUSED)
 
71
{
 
72
 
 
73
    _debug ("stream_moved_callback: stream %d to %d", pa_stream_get_index (s), pa_stream_get_device_index (s));
 
74
}
 
75
 
 
76
static void latency_update_callback (pa_stream *p, void *userdata UNUSED)
 
77
{
 
78
 
 
79
    pa_usec_t r_usec;
 
80
 
 
81
    pa_stream_get_latency (p, &r_usec, NULL);
 
82
 
 
83
    /*
 
84
    _debug ("Audio: Stream letency update %0.0f ms for device %s", (float) r_usec/1000, pa_stream_get_device_name (p));
 
85
    _debug ("Audio: maxlength %u", pa_stream_get_buffer_attr (p)->maxlength);
 
86
    _debug ("Audio: tlength %u", pa_stream_get_buffer_attr (p)->tlength);
 
87
    _debug ("Audio: prebuf %u", pa_stream_get_buffer_attr (p)->prebuf);
 
88
    _debug ("Audio: minreq %u", pa_stream_get_buffer_attr (p)->minreq);
 
89
    _debug ("Audio: fragsize %u", pa_stream_get_buffer_attr (p)->fragsize);
 
90
    */
 
91
}
 
92
 
 
93
static void sink_input_info_callback (pa_context *c UNUSED, const pa_sink_info *i, int eol, void *userdata)
 
94
{
 
95
    char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 
96
 
 
97
    if (!eol) {
 
98
 
 
99
        printf ("Sink %u\n"
 
100
                "    Name: %s\n"
 
101
                "    Driver: %s\n"
 
102
                "    Description: %s\n"
 
103
                "    Sample Specification: %s\n"
 
104
                "    Channel Map: %s\n"
 
105
                "    Owner Module: %u\n"
 
106
                "    Volume: %s\n"
 
107
                "    Monitor Source: %u\n"
 
108
                "    Latency: %0.0f usec\n"
 
109
                "    Flags: %s%s%s\n",
 
110
                i->index,
 
111
                i->name,
 
112
                i->driver,
 
113
                i->description,
 
114
                pa_sample_spec_snprint (s, sizeof (s), &i->sample_spec),
 
115
                pa_channel_map_snprint (cm, sizeof (cm), &i->channel_map),
 
116
                i->owner_module,
 
117
                i->mute ? "muted" : pa_cvolume_snprint (cv, sizeof (cv), &i->volume),
 
118
                i->monitor_source,
 
119
                (double) i->latency,
 
120
                i->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
 
121
                i->flags & PA_SINK_LATENCY ? "LATENCY " : "",
 
122
                i->flags & PA_SINK_HARDWARE ? "HARDWARE" : "");
 
123
 
 
124
        std::string deviceName (i->name);
 
125
        ( (PulseLayer *) userdata)->getSinkList()->push_back (deviceName);
 
126
 
 
127
    }
 
128
}
 
129
 
 
130
static void source_input_info_callback (pa_context *c UNUSED, const pa_source_info *i, int eol, void *userdata)
 
131
{
 
132
    char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 
133
 
 
134
    if (!eol) {
 
135
 
 
136
        printf ("Sink %u\n"
 
137
                "    Name: %s\n"
 
138
                "    Driver: %s\n"
 
139
                "    Description: %s\n"
 
140
                "    Sample Specification: %s\n"
 
141
                "    Channel Map: %s\n"
 
142
                "    Owner Module: %u\n"
 
143
                "    Volume: %s\n"
 
144
                "    Monitor if Sink: %u\n"
 
145
                "    Latency: %0.0f usec\n"
 
146
                "    Flags: %s%s%s\n",
 
147
                i->index,
 
148
                i->name,
 
149
                i->driver,
 
150
                i->description,
 
151
                pa_sample_spec_snprint (s, sizeof (s), &i->sample_spec),
 
152
                pa_channel_map_snprint (cm, sizeof (cm), &i->channel_map),
 
153
                i->owner_module,
 
154
                i->mute ? "muted" : pa_cvolume_snprint (cv, sizeof (cv), &i->volume),
 
155
                i->monitor_of_sink,
 
156
                (double) i->latency,
 
157
                i->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
 
158
                i->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
 
159
                i->flags & PA_SOURCE_HARDWARE ? "HARDWARE" : "");
 
160
 
 
161
        std::string deviceName (i->name);
 
162
        ( (PulseLayer *) userdata)->getSourceList()->push_back (deviceName);
 
163
 
 
164
    }
 
165
}
 
166
 
 
167
 
 
168
static void context_changed_callback (pa_context* c, pa_subscription_event_type_t t, uint32_t idx UNUSED, void* userdata)
 
169
{
 
170
 
 
171
    switch (t) {
 
172
 
 
173
        case PA_SUBSCRIPTION_EVENT_SINK:
 
174
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_SINK");
 
175
            ( (PulseLayer *) userdata)->getSinkList()->clear();
 
176
            pa_context_get_sink_info_list (c, sink_input_info_callback,  userdata);
 
177
            break;
 
178
        case PA_SUBSCRIPTION_EVENT_SOURCE:
 
179
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_SOURCE");
 
180
            ( (PulseLayer *) userdata)->getSourceList()->clear();
 
181
            pa_context_get_source_info_list (c, source_input_info_callback,  userdata);
 
182
            break;
 
183
        case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
 
184
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_SINK_INPUT");
 
185
            break;
 
186
        case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
 
187
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT");
 
188
            break;
 
189
        case PA_SUBSCRIPTION_EVENT_MODULE:
 
190
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_MODULE");
 
191
            break;
 
192
        case PA_SUBSCRIPTION_EVENT_CLIENT:
 
193
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_CLIENT");
 
194
            break;
 
195
        case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE:
 
196
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE");
 
197
            break;
 
198
        case PA_SUBSCRIPTION_EVENT_SERVER:
 
199
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_SERVER");
 
200
            break;
 
201
        case PA_SUBSCRIPTION_EVENT_CARD:
 
202
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_CARD");
 
203
            break;
 
204
        case PA_SUBSCRIPTION_EVENT_FACILITY_MASK:
 
205
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_FACILITY_MASK");
 
206
            break;
 
207
        case PA_SUBSCRIPTION_EVENT_CHANGE:
 
208
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_CHANGE");
 
209
            break;
 
210
        case PA_SUBSCRIPTION_EVENT_REMOVE:
 
211
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_REMOVE");
 
212
            ( (PulseLayer *) userdata)->getSinkList()->clear();
 
213
            ( (PulseLayer *) userdata)->getSourceList()->clear();
 
214
            pa_context_get_sink_info_list (c, sink_input_info_callback,  userdata);
 
215
            pa_context_get_source_info_list (c, source_input_info_callback,  userdata);
 
216
            break;
 
217
        case PA_SUBSCRIPTION_EVENT_TYPE_MASK:
 
218
            _debug ("Audio: PA_SUBSCRIPTION_EVENT_TYPE_MASK");
 
219
            break;
 
220
        default:
 
221
            _debug ("Audio: Unknown event type");
 
222
 
 
223
    }
 
224
}
 
225
 
 
226
static void playback_underflow_callback (pa_stream* s UNUSED,  void* userdata UNUSED)
 
227
{
73
228
}
74
229
 
75
230
 
76
231
static void playback_overflow_callback (pa_stream* s UNUSED, void* userdata UNUSED)
77
232
{
78
 
    // _debug ("Audio: Buffer OverFlow");
79
 
 
80
233
}
81
234
 
82
235
 
83
236
PulseLayer::PulseLayer (ManagerImpl* manager)
84
 
        : AudioLayer (manager , PULSEAUDIO)
85
 
        , context (NULL)
86
 
        , m (NULL)
87
 
        , playback()
88
 
        , record()
 
237
    : AudioLayer (manager , PULSEAUDIO)
 
238
    , context (NULL)
 
239
    , m (NULL)
 
240
    , playback (NULL)
 
241
    , record (NULL)
 
242
    , ringtone (NULL)
89
243
{
90
244
    _urgentRingBuffer.createReadPointer();
91
 
    dcblocker = new DcBlocker();
 
245
 
92
246
    is_started = false;
93
 
    
 
247
 
 
248
    AudioLayer::_noisesuppressstate = true;
 
249
 
 
250
    byteCounter = 0;
 
251
 
 
252
 
 
253
    // captureFile = new ofstream ("probeCaptureFile", ofstream::binary);
 
254
    // spkrFile = new ofstream ("probeSpkrFile", ofstream::binary);
 
255
 
94
256
    openLayer();
95
257
}
96
258
 
104
266
        _converter = NULL;
105
267
    }
106
268
 
107
 
    delete dcblocker;
108
 
 
109
 
    dcblocker = NULL;
 
269
    delete AudioLayer::_dcblocker;
 
270
    AudioLayer::_dcblocker = NULL;
 
271
 
 
272
    delete AudioLayer::_audiofilter;
 
273
    AudioLayer::_audiofilter = NULL;
 
274
 
 
275
 
 
276
    // captureFile->close();
 
277
    // spkrFile->close();
 
278
 
 
279
    // delete captureFile;
 
280
    // delete spkrFile;
110
281
}
111
282
 
112
283
void
113
284
PulseLayer::openLayer (void)
114
285
{
115
 
        if (!is_started) {
116
 
 
117
 
                _info("Audio: Open layer");
118
 
 
119
 
                if (!m) {
120
 
 
121
 
                        _info("Audio: Creating PulseAudio mainloop");
122
 
                        if (!(m = pa_threaded_mainloop_new()))
123
 
                                _warn ("Audio: Error: while creating pulseaudio mainloop");
124
 
 
125
 
                        if (pa_threaded_mainloop_start (m) < 0) {
126
 
                                _warn("Audio: Error: Failed to start pulseaudio mainloop");
127
 
                        }
128
 
                        
129
 
                        assert(m);
130
 
                }
131
 
 
132
 
                if (!context) {
133
 
                        
134
 
                        _info("Audio: Creating new PulseAudio Context");
135
 
                        pa_threaded_mainloop_lock (m);
136
 
 
137
 
                        // Instanciate a context
138
 
                        if (! (context = pa_context_new (pa_threaded_mainloop_get_api (m) , "SFLphone")))
139
 
                                _warn ("Audio: Error: while creating pulseaudio context");
140
 
 
141
 
                        pa_threaded_mainloop_unlock (m);
142
 
 
143
 
                        assert (context);
144
 
                }
145
 
 
146
 
                // Create Streams
147
 
                connectPulseAudioServer();
148
 
 
149
 
                is_started = true;
150
 
        }
 
286
    if (!is_started) {
 
287
 
 
288
        _info ("Audio: Open Pulseaudio layer");
 
289
 
 
290
        connectPulseAudioServer();
 
291
 
 
292
        is_started = true;
 
293
 
 
294
    }
151
295
 
152
296
}
153
297
 
154
298
bool
155
299
PulseLayer::closeLayer (void)
156
300
{
157
 
    _info("Audio: Destroy pulselayer");
 
301
    _info ("Audio: Close Pulseaudio layer");
158
302
 
159
303
    disconnectAudioStream();
160
 
        
 
304
 
161
305
    if (m) {
162
306
        pa_threaded_mainloop_stop (m);
163
307
    }
180
324
void
181
325
PulseLayer::connectPulseAudioServer (void)
182
326
{
183
 
    _info("Audio: connect to pulseaudio server");
 
327
    _info ("Audio: Connect to Pulseaudio server");
184
328
 
185
329
    setenv ("PULSE_PROP_media.role", "phone", 1);
186
330
 
187
331
    pa_context_flags_t flag = PA_CONTEXT_NOAUTOSPAWN ;
188
332
 
189
 
    pa_threaded_mainloop_lock (m);
190
 
 
191
 
    _info("Audio: Connect the context to the server");
192
 
    pa_context_connect (context, NULL , flag , NULL);
193
 
 
 
333
    if (!m) {
 
334
 
 
335
        // Instantiate a mainloop
 
336
        _info ("Audio: Creating PulseAudio mainloop");
 
337
 
 
338
        if (! (m = pa_threaded_mainloop_new()))
 
339
            _warn ("Audio: Error: while creating pulseaudio mainloop");
 
340
 
 
341
        assert (m);
 
342
    }
 
343
 
 
344
    if (!context) {
 
345
 
 
346
        // Instantiate a context
 
347
        if (! (context = pa_context_new (pa_threaded_mainloop_get_api (m) , "SFLphone")))
 
348
            _warn ("Audio: Error: while creating pulseaudio context");
 
349
 
 
350
        assert (context);
 
351
    }
 
352
 
 
353
    // set context state callback before starting the mainloop
194
354
    pa_context_set_state_callback (context, context_state_callback, this);
195
 
    pa_threaded_mainloop_wait(m);
196
 
    
197
 
    
 
355
 
 
356
    _info ("Audio: Connect the context to the server");
 
357
 
 
358
    if (pa_context_connect (context, NULL , flag , NULL) < 0) {
 
359
        _warn ("Audio: Error: Could not connect context to the server");
 
360
    }
 
361
 
 
362
    // Lock the loop before starting it
 
363
    pa_threaded_mainloop_lock (m);
 
364
 
 
365
    if (pa_threaded_mainloop_start (m) < 0)
 
366
        _warn ("Audio: Error: Failed to start pulseaudio mainloop");
 
367
 
 
368
    pa_threaded_mainloop_wait (m);
 
369
 
 
370
 
198
371
    // Run the main loop
199
372
    if (pa_context_get_state (context) != PA_CONTEXT_READY) {
200
 
        _warn("Audio: Error: connecting to pulse audio server");
 
373
        _warn ("Audio: Error: connecting to pulse audio server");
201
374
    }
202
375
 
203
376
    pa_threaded_mainloop_unlock (m);
204
377
 
205
 
    _info("Audio: Context creation done");
 
378
    _info ("Audio: Context creation done");
206
379
 
207
380
}
208
381
 
209
382
void PulseLayer::context_state_callback (pa_context* c, void* user_data)
210
383
{
211
 
    _info("Audio: The state of the context changed");
 
384
    _info ("Audio: The state of the context changed");
212
385
    PulseLayer* pulse = (PulseLayer*) user_data;
213
386
    assert (c && pulse->m);
214
387
 
224
397
 
225
398
        case PA_CONTEXT_READY:
226
399
            _debug ("Audio: Connection to PulseAudio server established");
227
 
            pa_threaded_mainloop_signal(pulse->m, 0);
 
400
            pa_threaded_mainloop_signal (pulse->m, 0);
 
401
            pa_context_subscribe (c, (pa_subscription_mask_t) (PA_SUBSCRIPTION_MASK_SINK|
 
402
                                  PA_SUBSCRIPTION_MASK_SOURCE), NULL, pulse);
 
403
            pa_context_set_subscribe_callback (c, context_changed_callback, pulse);
 
404
            pulse->updateSinkList();
228
405
            break;
229
406
 
230
407
        case PA_CONTEXT_TERMINATED:
234
411
        case PA_CONTEXT_FAILED:
235
412
 
236
413
        default:
237
 
            _warn("Audio: Error : %s" , pa_strerror (pa_context_errno (c)));
 
414
            _warn ("Audio: Error : %s" , pa_strerror (pa_context_errno (c)));
238
415
            pulse->disconnectAudioStream();
239
416
            exit (0);
240
417
            break;
241
418
    }
242
419
}
243
420
 
244
 
bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int sampleRate, int frameSize , int stream UNUSED, std::string plugin UNUSED)
 
421
bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int indexRing UNUSED, int sampleRate, int frameSize , int stream UNUSED, std::string plugin UNUSED)
245
422
{
 
423
    _debug ("Audio: Open device sampling rate %d, frame size %d", _audioSampleRate, _frameSize);
 
424
 
246
425
    _audioSampleRate = sampleRate;
247
426
    _frameSize = frameSize;
248
427
 
251
430
    // use 1 sec buffer for resampling
252
431
    _converter = new SamplerateConverter (_audioSampleRate, 1000);
253
432
 
 
433
    // Instantiate the algorithm
 
434
    AudioLayer::_dcblocker = new DcBlocker();
 
435
    AudioLayer::_audiofilter = new AudioProcessing (static_cast<Algorithm *> (_dcblocker));
 
436
 
254
437
    return true;
255
438
}
256
439
 
257
440
 
 
441
void PulseLayer::updateSinkList (void)
 
442
{
 
443
 
 
444
    _debug ("Audio: Update sink list");
 
445
 
 
446
    getSinkList()->clear();
 
447
 
 
448
    pa_context_get_sink_info_list (context, sink_input_info_callback,  this);
 
449
}
 
450
 
 
451
void PulseLayer::updateSourceList (void)
 
452
{
 
453
    _debug ("Audio: Update source list");
 
454
 
 
455
    getSourceList()->clear();
 
456
 
 
457
    pa_context_get_source_info_list (context, source_input_info_callback, this);
 
458
 
 
459
}
 
460
 
 
461
bool PulseLayer::inSinkList (std::string deviceName)
 
462
{
 
463
    //   _debug("Audio: in device list %s", deviceName.c_str());
 
464
 
 
465
    DeviceList::iterator iter = _sinkList.begin();
 
466
 
 
467
    // _debug("_deviceList.size() %d", _sinkList.size());
 
468
 
 
469
    while (iter != _sinkList.end()) {
 
470
        if (*iter == deviceName) {
 
471
            // _debug("device name in list: %s", (*iter).c_str());
 
472
            return true;
 
473
        }
 
474
 
 
475
        iter++;
 
476
    }
 
477
 
 
478
    return false;
 
479
}
 
480
 
 
481
 
 
482
bool PulseLayer::inSourceList (std::string deviceName)
 
483
{
 
484
 
 
485
    DeviceList::iterator iter = _sourceList.begin();
 
486
 
 
487
    while (iter != _sourceList.end()) {
 
488
 
 
489
        if (*iter == deviceName) {
 
490
            return true;
 
491
        }
 
492
 
 
493
        iter++;
 
494
    }
 
495
 
 
496
    return false;
 
497
}
 
498
 
 
499
 
258
500
bool PulseLayer::createStreams (pa_context* c)
259
501
{
260
 
    _info("Audio: Create streams");
 
502
    _info ("Audio: Create streams");
 
503
 
 
504
    // _debug("Device list size %d", getDevicelist()->size());
 
505
 
 
506
    std::string playbackDevice =  _manager->audioPreference.getDevicePlayback();
 
507
    std::string recordDevice =  _manager->audioPreference.getDeviceRecord();
 
508
    std::string ringtoneDevice =  _manager->audioPreference.getDeviceRingtone();
 
509
 
 
510
    _debug ("Audio: Device stored in config for playback: %s", playbackDevice.c_str());
 
511
    _debug ("Audio: Device stored in config for record: %s", recordDevice.c_str());
 
512
    _debug ("Audio: Device stored in config for ringtone: %s", ringtoneDevice.c_str());
261
513
 
262
514
    PulseLayerType * playbackParam = new PulseLayerType();
263
515
    playbackParam->context = c;
267
519
    playbackParam->mainloop = m;
268
520
 
269
521
    playback = new AudioStream (playbackParam, _audioSampleRate);
270
 
    playback->connectStream();
 
522
 
 
523
    if (inSinkList (playbackDevice)) {
 
524
        playback->connectStream (&playbackDevice);
 
525
    } else {
 
526
        playback->connectStream (NULL);
 
527
    }
 
528
 
271
529
    pa_stream_set_write_callback (playback->pulseStream(), playback_callback, this);
272
530
    pa_stream_set_overflow_callback (playback->pulseStream(), playback_overflow_callback, this);
273
531
    pa_stream_set_underflow_callback (playback->pulseStream(), playback_underflow_callback, this);
274
532
    // pa_stream_set_suspended_callback(playback->pulseStream(), stream_suspended_callback, this);
275
 
    // pa_stream_set_moved_callback(playback->pulseStream(), stream_moved_callback, this);
 
533
    pa_stream_set_moved_callback (playback->pulseStream(), stream_moved_callback, this);
 
534
    pa_stream_set_latency_update_callback (playback->pulseStream(), latency_update_callback, this);
276
535
    delete playbackParam;
277
536
 
278
537
    PulseLayerType * recordParam = new PulseLayerType();
283
542
    recordParam->mainloop = m;
284
543
 
285
544
    record = new AudioStream (recordParam, _audioSampleRate);
286
 
    record->connectStream();
 
545
 
 
546
    if (inSourceList (recordDevice)) {
 
547
        record->connectStream (&recordDevice);
 
548
    } else {
 
549
        record->connectStream (NULL);
 
550
    }
 
551
 
287
552
    pa_stream_set_read_callback (record->pulseStream() , capture_callback, this);
288
553
    // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this);
289
 
    // pa_stream_set_moved_callback(record->pulseStream(), stream_moved_callback, this);
 
554
    pa_stream_set_moved_callback (record->pulseStream(), stream_moved_callback, this);
 
555
    pa_stream_set_latency_update_callback (record->pulseStream(), latency_update_callback, this);
290
556
    delete recordParam;
291
557
 
 
558
    PulseLayerType * ringtoneParam = new PulseLayerType();
 
559
    ringtoneParam->context = c;
 
560
    ringtoneParam->type = RINGTONE_STREAM;
 
561
    ringtoneParam->description = RINGTONE_STREAM_NAME;
 
562
    ringtoneParam->volume = _manager->getSpkrVolume();
 
563
    ringtoneParam->mainloop = m;
 
564
 
 
565
    ringtone = new AudioStream (ringtoneParam, _audioSampleRate);
 
566
 
 
567
    if (inSourceList (ringtoneDevice)) {
 
568
        ringtone->connectStream (&ringtoneDevice);
 
569
    } else {
 
570
        ringtone->connectStream (NULL);
 
571
    }
 
572
 
 
573
    pa_stream_set_write_callback (ringtone->pulseStream(), ringtone_callback, this);
 
574
    pa_stream_set_moved_callback (ringtone->pulseStream(), stream_moved_callback, this);
 
575
    delete ringtoneParam;
 
576
 
292
577
    pa_threaded_mainloop_signal (m , 0);
293
578
 
294
579
    flushMain();
300
585
 
301
586
bool PulseLayer::disconnectAudioStream (void)
302
587
{
303
 
    _info("Audio: Disconnect audio stream");
 
588
    _info ("Audio: Disconnect audio stream");
304
589
 
305
590
    closePlaybackStream();
306
591
    closeCaptureStream();
315
600
void PulseLayer::closeCaptureStream (void)
316
601
{
317
602
    if (record) {
 
603
 
 
604
        std::string deviceName (pa_stream_get_device_name (record->pulseStream()));
 
605
        _debug ("Audio: record device to be stored in config: %s", deviceName.c_str());
 
606
        _manager->audioPreference.setDeviceRecord (deviceName);
318
607
        delete record;
319
608
        record=NULL;
320
609
    }
324
613
void PulseLayer::closePlaybackStream (void)
325
614
{
326
615
    if (playback) {
 
616
        std::string deviceName (pa_stream_get_device_name (playback->pulseStream()));
 
617
        _debug ("Audio: playback device to be stored in config: %s", deviceName.c_str());
 
618
        _manager->audioPreference.setDevicePlayback (deviceName);
327
619
        delete playback;
328
620
        playback=NULL;
329
621
    }
 
622
 
 
623
    if (ringtone) {
 
624
        std::string deviceName (pa_stream_get_device_name (ringtone->pulseStream()));
 
625
        _debug ("Audio: ringtone device to be stored in config: %s", deviceName.c_str());
 
626
        _manager->audioPreference.setDeviceRingtone (deviceName);
 
627
        delete ringtone;
 
628
        ringtone  = NULL;
 
629
    }
330
630
}
331
631
 
332
632
 
339
639
}
340
640
 
341
641
 
342
 
int PulseLayer::getMic (void *buffer, int toCopy)
343
 
{
344
 
    if (record) {
345
 
        return 0;
346
 
    } else
347
 
        return 0;
348
 
}
349
 
 
350
 
 
351
642
void PulseLayer::startStream (void)
352
643
{
 
644
 
353
645
    // Create Streams
354
 
        if(!playback || !record)
355
 
                createStreams(context);
 
646
    if (!playback || !record)
 
647
        createStreams (context);
 
648
 
356
649
 
357
650
    // Flush outside the if statement: every time start stream is
358
651
    // called is to notify a new event
367
660
PulseLayer::stopStream (void)
368
661
{
369
662
 
370
 
        _info("Audio: Stop audio stream");
371
 
 
372
 
        pa_threaded_mainloop_lock (m);
373
 
 
374
 
        if(playback)
375
 
            pa_stream_flush (playback->pulseStream(), NULL, NULL);
376
 
 
377
 
        if(record)
378
 
            pa_stream_flush (record->pulseStream(), NULL, NULL);
379
 
 
380
 
        pa_threaded_mainloop_unlock (m);
381
 
 
382
 
        disconnectAudioStream();
 
663
    _info ("Audio: Stop audio stream");
 
664
 
 
665
    pa_threaded_mainloop_lock (m);
 
666
 
 
667
    if (playback)
 
668
        pa_stream_flush (playback->pulseStream(), NULL, NULL);
 
669
 
 
670
    if (record)
 
671
        pa_stream_flush (record->pulseStream(), NULL, NULL);
 
672
 
 
673
    pa_threaded_mainloop_unlock (m);
 
674
 
 
675
    disconnectAudioStream();
383
676
}
384
677
 
385
678
 
409
702
 
410
703
}
411
704
 
 
705
void PulseLayer::processRingtoneData (void)
 
706
{
 
707
    // handle ringtone playback
 
708
    if (ringtone && (ringtone)->pulseStream() && (pa_stream_get_state (ringtone->pulseStream()) == PA_STREAM_READY)) {
 
709
 
 
710
        // If the playback buffer is full, we don't overflow it; wait for it to have free space
 
711
        if (pa_stream_writable_size (ringtone->pulseStream()) == 0)
 
712
            return;
 
713
 
 
714
        ringtoneToSpeaker();
 
715
    }
 
716
}
 
717
 
412
718
 
413
719
void PulseLayer::processData (void)
414
720
{
430
736
 
431
737
}
432
738
 
 
739
void PulseLayer::setNoiseSuppressState (bool state)
 
740
{
 
741
    // if a stream already opened
 
742
    AudioLayer::_noisesuppressstate = state;
 
743
 
 
744
}
 
745
 
433
746
 
434
747
void PulseLayer::writeToSpeaker (void)
435
748
{
444
757
    SFLDataFormat* out;// = (SFLDataFormat*)pa_xmalloc(framesPerBuffer);
445
758
    urgentAvailBytes = _urgentRingBuffer.AvailForGet();
446
759
 
447
 
 
448
760
    // available bytes to be written in pulseaudio internal buffer
449
761
    int writeableSize = pa_stream_writable_size (playback->pulseStream());
450
762
 
455
767
    if (urgentAvailBytes > writeableSize) {
456
768
 
457
769
        out = (SFLDataFormat*) pa_xmalloc (writeableSize);
 
770
        memset (out, 0, writeableSize);
 
771
 
458
772
        _urgentRingBuffer.Get (out, writeableSize, 100);
459
773
 
 
774
        // spkrFile->write ( (const char *) out, writeableSize);
460
775
        pa_stream_write (playback->pulseStream(), out, writeableSize, NULL, 0, PA_SEEK_RELATIVE);
461
776
 
462
777
        pa_xfree (out);
467
782
 
468
783
    } else {
469
784
 
 
785
        // Get ringtone
470
786
        AudioLoop* tone = _manager->getTelephoneTone();
471
 
        AudioLoop* file_tone = _manager->getTelephoneFile();
 
787
 
 
788
        // We must test if data have been received from network in case of early media
 
789
        normalAvailBytes = getMainBuffer()->availForGet();
472
790
 
473
791
        // flush remaining samples in _urgentRingBuffer
474
792
        flushUrgent();
475
793
 
476
 
        if (tone != 0) {
 
794
        if ( (tone != 0) && (normalAvailBytes <= 0)) {
477
795
 
478
796
            if (playback->getStreamState() == PA_STREAM_READY) {
479
797
 
480
798
                out = (SFLDataFormat*) pa_xmalloc (writeableSize);
 
799
                memset (out, 0, writeableSize);
 
800
 
481
801
                int copied = tone->getNext (out, writeableSize / sizeof (SFLDataFormat), 100);
482
 
                
483
 
                pa_stream_write (playback->pulseStream(), out, copied * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
484
 
 
485
 
                pa_xfree (out);
486
 
 
487
 
            }
488
 
        }
489
 
 
490
 
        else if (file_tone != 0) {
491
 
 
492
 
            if (playback->getStreamState() == PA_STREAM_READY) {
493
 
 
494
 
                out = (SFLDataFormat*) pa_xmalloc (writeableSize);
495
 
                int copied = file_tone->getNext (out, writeableSize / sizeof (SFLDataFormat), 100);
496
 
 
 
802
 
 
803
                //spkrFile->write ( (const char *) out, copied*sizeof (SFLDataFormat));
497
804
                pa_stream_write (playback->pulseStream(), out, copied * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
498
805
 
499
806
                pa_xfree (out);
506
813
 
507
814
            int maxNbBytesToGet = 0;
508
815
 
509
 
 
510
816
            // test if audio resampling is needed
511
 
 
512
817
            if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
513
818
 
514
819
                // upsamplefactor is used to compute the number of bytes to get in the ring buffer
523
828
 
524
829
            }
525
830
 
526
 
            normalAvailBytes = getMainBuffer()->availForGet();
527
 
 
528
831
            byteToGet = (normalAvailBytes < (int) (maxNbBytesToGet)) ? normalAvailBytes : maxNbBytesToGet;
529
832
 
530
833
            if (byteToGet) {
535
838
                    byteToGet = byteToGet-1;
536
839
 
537
840
                out = (SFLDataFormat*) pa_xmalloc (maxNbBytesToGet);
 
841
                memset (out, 0, maxNbBytesToGet);
538
842
 
539
843
                getMainBuffer()->getData (out, byteToGet, 100);
540
844
 
542
846
                if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
543
847
 
544
848
                    SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (writeableSize);
 
849
                    memset (out, 0, writeableSize);
545
850
 
546
851
                    // Do sample rate conversion
547
852
                    int nb_sample_down = byteToGet / sizeof (SFLDataFormat);
549
854
                    int nbSample = _converter->upsampleData ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down);
550
855
 
551
856
                    if ( (nbSample*sizeof (SFLDataFormat)) > (unsigned int) writeableSize)
552
 
                        _warn("Audio: Error: nbsbyte exceed buffer length");
 
857
                        _warn ("Audio: Error: nbsbyte exceed buffer length");
553
858
 
 
859
                    // spkrFile->write ( (const char *) out, nbSample*sizeof (SFLDataFormat));
554
860
                    pa_stream_write (playback->pulseStream(), rsmpl_out, nbSample*sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
555
861
 
556
862
                    pa_xfree (rsmpl_out);
557
863
 
558
864
                } else {
559
 
 
 
865
                    // spkrFile->write ( (const char *) out, byteToGet);
560
866
                    pa_stream_write (playback->pulseStream(), out, byteToGet, NULL, 0, PA_SEEK_RELATIVE);
561
867
 
 
868
 
562
869
                }
563
870
 
564
871
                pa_xfree (out);
565
872
 
566
873
            } else {
567
874
 
568
 
                if ( (tone == 0) && (file_tone == 0)) {
 
875
                if (tone == 0) {
569
876
 
570
877
                    SFLDataFormat* zeros = (SFLDataFormat*) pa_xmalloc (writeableSize);
571
 
 
572
878
                    bzero (zeros, writeableSize);
573
879
 
 
880
                    // spkrFile->write ( (const char *) zeros, writeableSize);
574
881
                    pa_stream_write (playback->pulseStream(), zeros, writeableSize, NULL, 0, PA_SEEK_RELATIVE);
575
882
 
576
883
                    pa_xfree (zeros);
596
903
 
597
904
 
598
905
    if (pa_stream_peek (record->pulseStream() , (const void**) &data , &r) < 0 || !data) {
599
 
        _warn("Audio: Error capture stream peek failed: %s" , pa_strerror (pa_context_errno (context)));
 
906
        _warn ("Audio: Error capture stream peek failed: %s" , pa_strerror (pa_context_errno (context)));
600
907
    }
601
908
 
602
 
 
603
909
    if (data != 0) {
604
910
 
605
911
        int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
608
914
        if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
609
915
 
610
916
            SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (readableSize);
 
917
            memset (rsmpl_out, 0, readableSize);
611
918
 
612
919
            int nbSample = r / sizeof (SFLDataFormat);
613
920
 
614
921
            int nb_sample_up = nbSample;
615
922
 
 
923
            nbSample = _converter->downsampleData ( (SFLDataFormat *) data, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up);
616
924
 
617
 
            nbSample = _converter->downsampleData ( (SFLDataFormat*) data, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up);
 
925
            // captureRsmplFile->write ((const char *)rsmpl_out, nbSample*sizeof(SFLDataFormat));
618
926
 
619
927
            // remove dc offset
620
 
            dcblocker->filter_signal (rsmpl_out, nbSample);
621
 
 
622
 
            getMainBuffer()->putData ( (void*) rsmpl_out, nbSample*sizeof (SFLDataFormat), 100);
 
928
            _audiofilter->processAudio (rsmpl_out, nbSample*sizeof (SFLDataFormat));
 
929
 
 
930
            // captureFilterFile->write ((const char *)rsmpl_out, nbSample*sizeof(SFLDataFormat));
 
931
 
 
932
            getMainBuffer()->putData (rsmpl_out, nbSample*sizeof (SFLDataFormat), 100);
623
933
 
624
934
            pa_xfree (rsmpl_out);
625
935
 
626
936
        } else {
627
937
 
628
 
            // no resampling required
629
 
            getMainBuffer()->putData ( (void*) data, r, 100);
 
938
 
 
939
            SFLDataFormat* filter_out = (SFLDataFormat*) pa_xmalloc (r);
 
940
            memset (filter_out, 0, r);
 
941
 
 
942
            // remove dc offset
 
943
            _audiofilter->processAudio ( (SFLDataFormat *) data, filter_out, r);
 
944
 
 
945
            // captureFile->write ( (const char *) filter_out, r);
 
946
 
 
947
            getMainBuffer()->putData (filter_out, r, 100);
 
948
 
 
949
            pa_xfree (filter_out);
630
950
        }
631
951
 
632
952
 
634
954
    }
635
955
 
636
956
    if (pa_stream_drop (record->pulseStream()) < 0) {
637
 
        _warn("Audio: Error: capture stream drop failed: %s" , pa_strerror( pa_context_errno( context) ));
638
 
    }
 
957
        _warn ("Audio: Error: capture stream drop failed: %s" , pa_strerror (pa_context_errno (context)));
 
958
    }
 
959
 
 
960
}
 
961
 
 
962
 
 
963
void PulseLayer::ringtoneToSpeaker (void)
 
964
{
 
965
    AudioLoop* file_tone = _manager->getTelephoneFile();
 
966
 
 
967
    SFLDataFormat* out;
 
968
 
 
969
    int writableSize = pa_stream_writable_size (ringtone->pulseStream());
 
970
 
 
971
    if (file_tone) {
 
972
 
 
973
        if (ringtone->getStreamState() == PA_STREAM_READY) {
 
974
 
 
975
            out = (SFLDataFormat *) pa_xmalloc (writableSize);
 
976
            memset (out, 0, writableSize);
 
977
 
 
978
            int copied = file_tone->getNext (out, writableSize/sizeof (SFLDataFormat), 100);
 
979
            pa_stream_write (ringtone->pulseStream(), out, copied*sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
 
980
 
 
981
            pa_xfree (out);
 
982
        }
 
983
    } else {
 
984
 
 
985
        if (ringtone->getStreamState() == PA_STREAM_READY) {
 
986
 
 
987
            out = (SFLDataFormat*) pa_xmalloc (writableSize);
 
988
            memset (out, 0, writableSize);
 
989
 
 
990
            pa_stream_write (ringtone->pulseStream(), out, writableSize, NULL, 0, PA_SEEK_RELATIVE);
 
991
 
 
992
            pa_xfree (out);
 
993
        }
 
994
    }
 
995
 
639
996
 
640
997
}
641
998