~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/src/audio/audioloop.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
 
2
 *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
3
3
 *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
4
4
 *
5
5
 *  Inspired by tonegenerator of
32
32
 *  as that of the covered work.
33
33
 */
34
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include "config.h"
 
37
#endif
 
38
 
35
39
#include "audioloop.h"
36
 
#include "manager.h"
37
 
#include "dbus/callmanager.h"
 
40
 
38
41
#include <cmath>
39
42
#include <numeric>
40
43
#include <cstring>
41
44
#include <cassert>
42
45
#include "logger.h"
43
46
 
44
 
AudioLoop::AudioLoop(unsigned int sampleRate) : buffer_(0),  size_(0), pos_(0), sampleRate_(sampleRate), isRecording_(false)
 
47
AudioLoop::AudioLoop(unsigned int sampleRate) :
 
48
    buffer_(new AudioBuffer(0, 1, sampleRate)), pos_(0)
45
49
{}
46
50
 
47
51
AudioLoop::~AudioLoop()
48
52
{
49
 
    delete [] buffer_;
 
53
    delete buffer_;
50
54
}
51
55
 
52
56
void
53
57
AudioLoop::seek(double relative_position)
54
58
{
55
 
    size_t new_pos = (size_t)((double)size_ * (relative_position * 0.01));
56
 
 
57
 
    pos_ = new_pos;
 
59
    pos_ = static_cast<double>(buffer_->frames() * relative_position * 0.01);
58
60
}
59
61
 
60
 
static unsigned int updatePlaybackScale = 0;
61
 
 
62
62
void
63
 
AudioLoop::getNext(SFLDataFormat* output, size_t total_samples, short volume)
 
63
AudioLoop::getNext(AudioBuffer& output, double gain)
64
64
{
 
65
    if (!buffer_) {
 
66
        ERROR("buffer is NULL");
 
67
        return;
 
68
    }
 
69
 
 
70
    const size_t buf_samples = buffer_->frames();
65
71
    size_t pos = pos_;
 
72
    size_t total_samples = output.frames();
 
73
    size_t output_pos = 0;
66
74
 
67
 
    if (size_ == 0) {
 
75
    if (buf_samples == 0) {
68
76
        ERROR("Audio loop size is 0");
69
77
        return;
70
 
    } else if (pos >= size_) {
 
78
    } else if (pos >= buf_samples) {
71
79
        ERROR("Invalid loop position %d", pos);
72
80
        return;
73
81
    }
74
82
 
75
83
    while (total_samples > 0) {
76
 
        size_t samples = total_samples;
77
 
 
78
 
        if (samples > (size_ - pos))
79
 
            samples = size_ - pos;
80
 
 
81
 
        // short->char conversion
82
 
        memcpy(output, buffer_ + pos, samples * sizeof(SFLDataFormat));
83
 
 
84
 
        // Scaling needed
85
 
        if (volume != 100) {
86
 
            const double gain = volume * 0.01;
87
 
 
88
 
            for (size_t i = 0; i < samples; ++i, ++output)
89
 
                *output *= gain;
90
 
        } else
91
 
            output += samples; // this is the destination...
92
 
 
93
 
        pos = (pos + samples) % size_;
 
84
        size_t samples = std::min(total_samples, buf_samples - pos);
 
85
 
 
86
        output.copy(*buffer_, samples, pos, output_pos);
 
87
 
 
88
        output_pos += samples;
 
89
        pos = (pos + samples) % buf_samples;
94
90
 
95
91
        total_samples -= samples;
96
92
    }
97
93
 
 
94
    output.applyGain(gain);
 
95
 
98
96
    pos_ = pos;
99
97
 
100
 
    // We want to send values in milisecond
101
 
    int divisor = sampleRate_ / 1000;
102
 
    if(divisor == 0) {
103
 
        ERROR("Error cannot update playback slider, sampling rate is 0");
104
 
        return;
105
 
    }
106
 
 
107
 
    if(isRecording_) {
108
 
        if((updatePlaybackScale % 5) == 0) {
109
 
            CallManager *cm = Manager::instance().getDbusManager()->getCallManager();
110
 
            cm->updatePlaybackScale(pos_ / divisor, size_ / divisor);
111
 
        }
112
 
        updatePlaybackScale++;
113
 
    }
 
98
    onBufferFinish();
114
99
}
115
100
 
 
101
void AudioLoop::onBufferFinish() {}