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

« back to all changes in this revision

Viewing changes to sflphone-common/src/audio/mainbuffer.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:
31
31
 
32
32
#include "mainbuffer.h"
33
33
 
34
 
#include "audioprocessing.h"
35
 
 
36
 
 
37
 
MainBuffer::MainBuffer() : _internalSamplingRate (0)
 
34
#include "manager.h"
 
35
 
 
36
MainBuffer::MainBuffer() : _internalSamplingRate (8000)
38
37
{
39
38
    mixBuffer = new SFLDataFormat[STATIC_BUFSIZE];
40
39
}
43
42
MainBuffer::~MainBuffer()
44
43
{
45
44
 
46
 
    delete [] mixBuffer; mixBuffer = NULL;
 
45
    delete [] mixBuffer;
 
46
    mixBuffer = NULL;
47
47
}
48
48
 
49
49
 
50
50
void MainBuffer::setInternalSamplingRate (int sr)
51
51
{
52
 
    ost::MutexLock guard (_mutex);
53
52
 
54
53
    if (sr != _internalSamplingRate) {
55
54
 
 
55
        _debug ("MainBuffer: Internal sampling rate changed %d", sr);
 
56
 
 
57
        // This call takes the mutex
 
58
        flushAllBuffers();
 
59
 
 
60
        ost::MutexLock guard (_mutex);
 
61
 
56
62
        _internalSamplingRate = sr;
57
63
 
58
 
        flushAllBuffers();
 
64
        Manager::instance().audioSamplingRateChanged();
59
65
 
60
66
    }
61
67
}
91
97
 
92
98
    if (callid_set != NULL) {
93
99
        if (_callIDMap.erase (set_id) != 0) {
94
 
                delete callid_set; callid_set = NULL;
 
100
            delete callid_set;
 
101
            callid_set = NULL;
95
102
            return true;
96
103
        } else {
97
104
            _debug ("removeCallIDSet error while removing callid set %s!", set_id.c_str());
144
151
RingBuffer* MainBuffer::createRingBuffer (CallID call_id)
145
152
{
146
153
 
 
154
    _debug ("BufferManager: Create ring buffer %s", call_id.c_str());
 
155
 
147
156
    RingBuffer* newRingBuffer = new RingBuffer (SIZEBUF, call_id);
148
157
 
149
158
    _ringBufferMap.insert (pair<CallID, RingBuffer*> (call_id, newRingBuffer));
155
164
bool MainBuffer::removeRingBuffer (CallID call_id)
156
165
{
157
166
 
 
167
    _debug ("BufferManager: Remove Ringbuffer %s", call_id.c_str());
 
168
 
158
169
    RingBuffer* ring_buffer = getRingBuffer (call_id);
159
170
 
160
171
    if (ring_buffer != NULL) {
161
172
        if (_ringBufferMap.erase (call_id) != 0) {
162
 
                delete ring_buffer;
 
173
            delete ring_buffer;
163
174
            return true;
164
175
        } else {
165
176
            _error ("BufferManager: Error: Fail to delete ringbuffer %s!", call_id.c_str());
177
188
 
178
189
    ost::MutexLock guard (_mutex);
179
190
 
 
191
    _debug ("BufferManager: Bind  calls %s, %s", call_id1.c_str(), call_id2.c_str());
 
192
 
180
193
    RingBuffer* ring_buffer;
181
194
    CallIDSet* callid_set;
182
195
 
202
215
 
203
216
}
204
217
 
 
218
void MainBuffer::bindHalfDuplexOut (CallID process_id, CallID call_id)
 
219
{
 
220
 
 
221
    ost::MutexLock guard (_mutex);
 
222
 
 
223
    // This method is used only for active calls, if this call does not exist, do nothing
 
224
    if (!getRingBuffer (call_id))
 
225
        return;
 
226
 
 
227
    if (!getCallIDSet (process_id))
 
228
        createCallIDSet (process_id);
 
229
 
 
230
    getRingBuffer (call_id)->createReadPointer (process_id);
 
231
 
 
232
    addCallIDtoSet (process_id, call_id);
 
233
 
 
234
}
 
235
 
205
236
 
206
237
void MainBuffer::unBindCallID (CallID call_id1, CallID call_id2)
207
238
{
208
239
 
209
240
    ost::MutexLock guard (_mutex);
210
241
 
 
242
    _debug ("BufferManager: Unbind calls %s, %s", call_id1.c_str(), call_id2.c_str());
 
243
 
211
244
    removeCallIDfromSet (call_id1, call_id2);
212
245
    removeCallIDfromSet (call_id2, call_id1);
213
246
 
214
 
    RingBuffer* ringbuffer;
215
 
 
216
 
    ringbuffer = getRingBuffer (call_id2);
217
 
 
218
 
    if (ringbuffer != NULL) {
 
247
    RingBuffer* ringbuffer = getRingBuffer (call_id2);
 
248
 
 
249
    if (ringbuffer) {
219
250
 
220
251
        ringbuffer->removeReadPointer (call_id1);
221
252
 
228
259
 
229
260
    ringbuffer = getRingBuffer (call_id1);
230
261
 
231
 
    if (ringbuffer != NULL) {
 
262
    if (ringbuffer) {
 
263
 
232
264
        ringbuffer->removeReadPointer (call_id2);
233
265
 
234
266
        if (ringbuffer->getNbReadPointer() == 0) {
236
268
            removeRingBuffer (call_id1);
237
269
        }
238
270
    }
239
 
 
240
 
 
241
 
}
 
271
}
 
272
 
 
273
void MainBuffer::unBindHalfDuplexOut (CallID process_id, CallID call_id)
 
274
{
 
275
 
 
276
    ost::MutexLock guard (_mutex);
 
277
 
 
278
    removeCallIDfromSet (process_id, call_id);
 
279
 
 
280
    RingBuffer* ringbuffer = getRingBuffer (call_id);
 
281
 
 
282
    if (ringbuffer) {
 
283
        ringbuffer->removeReadPointer (process_id);
 
284
 
 
285
        if (ringbuffer->getNbReadPointer() == 0) {
 
286
            removeCallIDSet (call_id);
 
287
            removeRingBuffer (call_id);
 
288
        }
 
289
    } else {
 
290
        _debug ("Error: did not found ringbuffer %s", process_id.c_str());
 
291
        removeCallIDSet (process_id);
 
292
    }
 
293
 
 
294
 
 
295
    CallIDSet* callid_set = getCallIDSet (process_id);
 
296
 
 
297
    if (callid_set) {
 
298
        if (callid_set->empty())
 
299
            removeCallIDSet (process_id);
 
300
    }
 
301
 
 
302
}
 
303
 
242
304
 
243
305
void MainBuffer::unBindAll (CallID call_id)
244
306
{
245
307
 
246
 
    ost::MutexLock guard (_mutex);
247
 
 
248
308
    CallIDSet* callid_set = getCallIDSet (call_id);
249
309
 
250
310
    if (callid_set == NULL)
267
327
}
268
328
 
269
329
 
 
330
void MainBuffer::unBindAllHalfDuplexOut (CallID process_id)
 
331
{
 
332
 
 
333
    CallIDSet* callid_set = getCallIDSet (process_id);
 
334
 
 
335
    if (!callid_set)
 
336
        return;
 
337
 
 
338
    if (callid_set->empty())
 
339
        return;
 
340
 
 
341
    CallIDSet temp_set = *callid_set;
 
342
 
 
343
    CallIDSet::iterator iter_set = temp_set.begin();
 
344
 
 
345
    while (iter_set != temp_set.end()) {
 
346
        CallID call_id_in_set = *iter_set;
 
347
        unBindCallID (process_id, call_id_in_set);
 
348
 
 
349
        iter_set++;
 
350
    }
 
351
}
 
352
 
 
353
 
270
354
int MainBuffer::putData (void *buffer, int toCopy, unsigned short volume, CallID call_id)
271
355
{
272
 
 
273
356
    ost::MutexLock guard (_mutex);
274
357
 
275
358
    RingBuffer* ring_buffer = getRingBuffer (call_id);
280
363
 
281
364
    int a;
282
365
 
283
 
    // ost::MutexLock guard (_mutex);
284
366
    a = ring_buffer->AvailForPut();
285
367
 
286
368
    if (a >= toCopy) {
334
416
            return 0;
335
417
    } else {
336
418
 
337
 
        for (int k = 0; k < nbSmplToCopy; k++) {
338
 
            ( (SFLDataFormat*) (buffer)) [k] = 0;
339
 
        }
 
419
        memset (buffer, 0, nbSmplToCopy*sizeof (SFLDataFormat));
340
420
 
341
421
        int size = 0;
342
422
 
344
424
 
345
425
        while (iter_id != callid_set->end()) {
346
426
 
 
427
            memset (mixBuffer, 0, toCopy);
 
428
 
347
429
            size = getDataByID (mixBuffer, toCopy, volume, (CallID) (*iter_id), call_id);
348
430
 
349
431
            if (size > 0) {
395
477
            _debug ("This problem should not occur since we have %i element", (int) callid_set->size());
396
478
        }
397
479
 
398
 
        // else
399
480
        return availForGetByID (*iter_id, call_id);
 
481
 
400
482
    } else {
401
 
        // _debug("CallIDSet with ID: \"%s\" is a conference!", call_id.c_str());
 
483
 
402
484
        int avail_bytes = 99999;
403
485
        int nb_bytes;
404
486
        CallIDSet::iterator iter_id = callid_set->begin();
405
487
 
 
488
        syncBuffers (call_id);
 
489
 
406
490
        for (iter_id = callid_set->begin(); iter_id != callid_set->end(); iter_id++) {
407
491
            nb_bytes = availForGetByID (*iter_id, call_id);
408
492
 
420
504
{
421
505
 
422
506
    if ( (call_id != default_id) && (reader_id == call_id)) {
423
 
        _error("MainBuffer: Error: RingBuffer has a readpointer on tiself");
 
507
        _error ("MainBuffer: Error: RingBuffer has a readpointer on tiself");
424
508
    }
425
509
 
426
510
    RingBuffer* ringbuffer = getRingBuffer (call_id);
427
511
 
428
512
    if (ringbuffer == NULL) {
429
 
        _error("MainBuffer: Error: RingBuffer does not exist");
 
513
        _error ("MainBuffer: Error: RingBuffer does not exist");
430
514
        return 0;
431
515
    } else
432
516
        return ringbuffer->AvailForGet (reader_id);
436
520
 
437
521
int MainBuffer::discard (int toDiscard, CallID call_id)
438
522
{
439
 
    // _debug("MainBuffer::discard");
440
 
 
441
523
    ost::MutexLock guard (_mutex);
442
524
 
443
525
    CallIDSet* callid_set = getCallIDSet (call_id);
446
528
        return 0;
447
529
 
448
530
    if (callid_set->empty()) {
449
 
        // _debug("CallIDSet with ID: \"%s\" is empty!", call_id.c_str());
450
531
        return 0;
451
532
    }
452
533
 
467
548
 
468
549
        return toDiscard;
469
550
    }
470
 
 
471
551
}
472
552
 
473
553
 
544
624
    }
545
625
}
546
626
 
 
627
void MainBuffer:: syncBuffers (CallID call_id)
 
628
{
 
629
 
 
630
    CallIDSet* callid_set = getCallIDSet (call_id);
 
631
 
 
632
    if (callid_set == NULL)
 
633
        return;
 
634
 
 
635
    if (callid_set->empty()) {
 
636
        _debug ("MainBuffer: CallIDSet with ID: \"%s\" is empty!", call_id.c_str());
 
637
        return;
 
638
    }
 
639
 
 
640
    if (callid_set->size() == 1) {
 
641
        // no need to resync, only one session
 
642
        return;
 
643
    }
 
644
 
 
645
    int nbBuffers = 0;
 
646
    float mean_nbBytes = 0.0;
 
647
 
 
648
    CallIDSet::iterator iter_id = callid_set->begin();
 
649
 
 
650
 
 
651
    // compute mean nb byte in buffers
 
652
    for (iter_id = callid_set->begin(); iter_id != callid_set->end(); iter_id++) {
 
653
        nbBuffers++;
 
654
        mean_nbBytes += availForGetByID (*iter_id, call_id);
 
655
    }
 
656
 
 
657
    mean_nbBytes = mean_nbBytes / (float) nbBuffers;
 
658
 
 
659
    // resync buffers in this conference according to the computed mean
 
660
    for (iter_id = callid_set->begin(); iter_id != callid_set->end(); iter_id++) {
 
661
 
 
662
        if (availForGetByID (*iter_id, call_id) > (mean_nbBytes + 640))
 
663
            discardByID (640, *iter_id, call_id);
 
664
    }
 
665
}
 
666
 
547
667
 
548
668
void MainBuffer::stateInfo()
549
669
{
610
730
        iter_buffer++;
611
731
    }
612
732
 
613
 
 
614
 
 
615
 
 
616
733
}