~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* 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: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
4
4
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
5
5
 *
29
29
 */
30
30
 
31
31
#include "samplerateconverter.h"
32
 
#include "manager.h"
33
 
#include <cassert>
34
 
#include "logger.h"
 
32
#include "sfl_types.h"
35
33
 
36
 
SamplerateConverter::SamplerateConverter(int freq) : floatBufferIn_(0),
37
 
    floatBufferOut_(0), samples_(0), maxFreq_(freq), src_state_(0)
 
34
SamplerateConverter::SamplerateConverter(int freq, size_t channels /* = 1 */) : floatBufferIn_(),
 
35
    floatBufferOut_(), scratchBuffer_(), samples_(0), channels_(channels), maxFreq_(freq), src_state_(0)
38
36
{
39
37
    int err;
40
 
    src_state_ = src_new(SRC_LINEAR, 1, &err);
 
38
    src_state_ = src_new(SRC_LINEAR, channels_, &err);
41
39
 
42
40
    samples_ = (freq * 20) / 1000; // start with 20 ms buffers
43
41
 
44
 
    floatBufferIn_ = new float[samples_];
45
 
    floatBufferOut_ = new float[samples_];
 
42
    floatBufferIn_.resize(samples_);
 
43
    floatBufferOut_.resize(samples_);
 
44
    scratchBuffer_.resize(samples_);
46
45
}
47
46
 
48
47
SamplerateConverter::~SamplerateConverter()
49
48
{
50
 
    delete [] floatBufferIn_;
51
 
    delete [] floatBufferOut_;
52
 
 
53
49
    src_delete(src_state_);
54
50
}
55
51
 
56
52
void
57
 
SamplerateConverter::Short2FloatArray(const short *in, float *out, int len)
 
53
SamplerateConverter::Short2FloatArray(const SFLAudioSample *in, float *out, int len)
58
54
{
59
55
    // factor is 1/(2^15), used to rescale the short int range to the
60
56
    // [-1.0 - 1.0] float range.
 
57
    static const float FACTOR = 1.0f / (1 << 15);
61
58
 
62
59
    while (len--)
63
 
        out[len] = (float) in[len] * .000030517578125f;
 
60
        out[len] = (float) in[len] * FACTOR;
64
61
}
65
62
 
66
 
void SamplerateConverter::resample(SFLDataFormat *dataIn,
67
 
                                   SFLDataFormat *dataOut,
68
 
                                   size_t dataOutSize, int inputFreq,
69
 
                                   int outputFreq, size_t nbSamples)
 
63
void SamplerateConverter::resample(const AudioBuffer &dataIn, AudioBuffer &dataOut)
70
64
{
71
 
    double sampleFactor = (double) outputFreq / inputFreq;
 
65
    const double inputFreq = dataIn.getSampleRate();
 
66
    const double outputFreq = dataOut.getSampleRate();
 
67
    const double sampleFactor = outputFreq / inputFreq;
72
68
 
73
69
    if (sampleFactor == 1.0)
74
70
        return;
75
71
 
76
 
    size_t outSamples = nbSamples * sampleFactor;
77
 
    const unsigned int maxSamples = std::max(outSamples, nbSamples);
 
72
    const size_t nbFrames = dataIn.frames();
 
73
    const size_t nbChans = dataIn.channels();
78
74
 
79
 
    if (maxSamples > samples_) {
80
 
        /* grow buffer if needed */
81
 
        samples_ = maxSamples;
82
 
        delete [] floatBufferIn_;
83
 
        delete [] floatBufferOut_;
84
 
        floatBufferIn_ = new float[samples_];
85
 
        floatBufferOut_ = new float[samples_];
 
75
    if (nbChans != channels_) {
 
76
        // change channel num if needed
 
77
        int err;
 
78
        src_delete(src_state_);
 
79
        src_state_ = src_new(SRC_LINEAR, nbChans, &err);
 
80
        channels_ = nbChans;
86
81
    }
87
82
 
 
83
    size_t inSamples = nbChans * nbFrames;
 
84
    size_t outSamples = inSamples * sampleFactor;
 
85
 
 
86
    // grow buffer if needed
 
87
    samples_ = std::max(inSamples, outSamples);
 
88
    floatBufferIn_.resize(inSamples);
 
89
    floatBufferOut_.resize(outSamples);
 
90
    scratchBuffer_.resize(outSamples);
 
91
 
88
92
    SRC_DATA src_data;
89
 
    src_data.data_in = floatBufferIn_;
90
 
    src_data.data_out = floatBufferOut_;
91
 
    src_data.input_frames = nbSamples;
92
 
    src_data.output_frames = outSamples;
 
93
    src_data.data_in = floatBufferIn_.data();
 
94
    src_data.data_out = floatBufferOut_.data();
 
95
    src_data.input_frames = nbFrames;
 
96
    src_data.output_frames = nbFrames * sampleFactor;
93
97
    src_data.src_ratio = sampleFactor;
94
98
    src_data.end_of_input = 0; // More data will come
95
99
 
96
 
    Short2FloatArray(dataIn, floatBufferIn_, nbSamples);
 
100
    dataIn.interleaveFloat(floatBufferIn_.data());
 
101
 
97
102
    src_process(src_state_, &src_data);
98
103
 
99
 
    if (outSamples > dataOutSize) {
100
 
        ERROR("Outsamples exceeds output buffer size, clamping to %u", dataOutSize);
101
 
        outSamples = dataOutSize;
102
 
    }
103
 
    src_float_to_short_array(floatBufferOut_, dataOut, outSamples);
 
104
    /*
 
105
    TODO: one-shot deinterleave and float-to-short conversion
 
106
    */
 
107
    src_float_to_short_array(floatBufferOut_.data(), scratchBuffer_.data(), outSamples);
 
108
    dataOut.deinterleave(scratchBuffer_.data(), src_data.output_frames, nbChans);
104
109
}