Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/libsoundtouch/src/FIFOSampleBuffer.cpp
Line
Count
Source (jump to first uncovered line)
1
////////////////////////////////////////////////////////////////////////////////
2
///
3
/// A buffer class for temporarily storaging sound samples, operates as a 
4
/// first-in-first-out pipe.
5
///
6
/// Samples are added to the end of the sample buffer with the 'putSamples' 
7
/// function, and are received from the beginning of the buffer by calling
8
/// the 'receiveSamples' function. The class automatically removes the 
9
/// outputted samples from the buffer, as well as grows the buffer size 
10
/// whenever necessary.
11
///
12
/// Author        : Copyright (c) Olli Parviainen
13
/// Author e-mail : oparviai 'at' iki.fi
14
/// SoundTouch WWW: http://www.surina.net/soundtouch
15
///
16
////////////////////////////////////////////////////////////////////////////////
17
//
18
// Last changed  : $Date: 2012-11-08 18:53:01 +0000 (Thu, 08 Nov 2012) $
19
// File revision : $Revision: 4 $
20
//
21
// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
22
//
23
////////////////////////////////////////////////////////////////////////////////
24
//
25
// License :
26
//
27
//  SoundTouch audio processing library
28
//  Copyright (c) Olli Parviainen
29
//
30
//  This library is free software; you can redistribute it and/or
31
//  modify it under the terms of the GNU Lesser General Public
32
//  License as published by the Free Software Foundation; either
33
//  version 2.1 of the License, or (at your option) any later version.
34
//
35
//  This library is distributed in the hope that it will be useful,
36
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
37
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
38
//  Lesser General Public License for more details.
39
//
40
//  You should have received a copy of the GNU Lesser General Public
41
//  License along with this library; if not, write to the Free Software
42
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
43
//
44
////////////////////////////////////////////////////////////////////////////////
45
46
#include <stdlib.h>
47
#include <memory.h>
48
#include <string.h>
49
#include <assert.h>
50
51
#include "FIFOSampleBuffer.h"
52
53
using namespace soundtouch;
54
55
// Constructor
56
FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
57
0
{
58
0
    assert(numChannels > 0);
59
0
    sizeInBytes = 0; // reasonable initial value
60
0
    buffer = NULL;
61
0
    bufferUnaligned = NULL;
62
0
    samplesInBuffer = 0;
63
0
    bufferPos = 0;
64
0
    channels = (uint)numChannels;
65
0
    ensureCapacity(32);     // allocate initial capacity 
66
0
}
67
68
69
// destructor
70
FIFOSampleBuffer::~FIFOSampleBuffer()
71
0
{
72
0
    delete[] bufferUnaligned;
73
0
    bufferUnaligned = NULL;
74
0
    buffer = NULL;
75
0
}
76
77
78
// Sets number of channels, 1 = mono, 2 = stereo
79
void FIFOSampleBuffer::setChannels(int numChannels)
80
0
{
81
0
    uint usedBytes;
82
0
83
0
    assert(numChannels > 0);
84
0
    usedBytes = channels * samplesInBuffer;
85
0
    channels = (uint)numChannels;
86
0
    samplesInBuffer = usedBytes / channels;
87
0
}
88
89
90
// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
91
// zeroes this pointer by copying samples from the 'bufferPos' pointer 
92
// location on to the beginning of the buffer.
93
void FIFOSampleBuffer::rewind()
94
0
{
95
0
    if (buffer && bufferPos) 
96
0
    {
97
0
        memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
98
0
        bufferPos = 0;
99
0
    }
100
0
}
101
102
103
// Adds 'numSamples' pcs of samples from the 'samples' memory position to 
104
// the sample buffer.
105
void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
106
0
{
107
0
    memcpy(ptrEnd(nSamples), samples, sizeof(SAMPLETYPE) * nSamples * channels);
108
0
    samplesInBuffer += nSamples;
109
0
}
110
111
112
// Increases the number of samples in the buffer without copying any actual
113
// samples.
114
//
115
// This function is used to update the number of samples in the sample buffer
116
// when accessing the buffer directly with 'ptrEnd' function. Please be 
117
// careful though!
118
void FIFOSampleBuffer::putSamples(uint nSamples)
119
0
{
120
0
    uint req;
121
0
122
0
    req = samplesInBuffer + nSamples;
123
0
    ensureCapacity(req);
124
0
    samplesInBuffer += nSamples;
125
0
}
126
127
128
// Returns a pointer to the end of the used part of the sample buffer (i.e. 
129
// where the new samples are to be inserted). This function may be used for 
130
// inserting new samples into the sample buffer directly. Please be careful! 
131
//
132
// Parameter 'slackCapacity' tells the function how much free capacity (in
133
// terms of samples) there _at least_ should be, in order to the caller to
134
// succesfully insert all the required samples to the buffer. When necessary, 
135
// the function grows the buffer size to comply with this requirement.
136
//
137
// When using this function as means for inserting new samples, also remember 
138
// to increase the sample count afterwards, by calling  the 
139
// 'putSamples(numSamples)' function.
140
SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity) 
141
0
{
142
0
    ensureCapacity(samplesInBuffer + slackCapacity);
143
0
    return buffer + samplesInBuffer * channels;
144
0
}
145
146
147
// Returns a pointer to the beginning of the currently non-outputted samples. 
148
// This function is provided for accessing the output samples directly. 
149
// Please be careful!
150
//
151
// When using this function to output samples, also remember to 'remove' the
152
// outputted samples from the buffer by calling the 
153
// 'receiveSamples(numSamples)' function
154
SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
155
0
{
156
0
    assert(buffer);
157
0
    return buffer + bufferPos * channels;
158
0
}
159
160
161
// Ensures that the buffer has enought capacity, i.e. space for _at least_
162
// 'capacityRequirement' number of samples. The buffer is grown in steps of
163
// 4 kilobytes to eliminate the need for frequently growing up the buffer,
164
// as well as to round the buffer size up to the virtual memory page size.
165
void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
166
0
{
167
0
    SAMPLETYPE *tempUnaligned, *temp;
168
0
169
0
    if (capacityRequirement > getCapacity()) 
170
0
    {
171
0
        // enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
172
0
        sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
173
0
        assert(sizeInBytes % 2 == 0);
174
0
        tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
175
0
        if (tempUnaligned == NULL)
176
0
        {
177
0
            ST_THROW_RT_ERROR("Couldn't allocate memory!\n");
178
0
        }
179
0
        // Align the buffer to begin at 16byte cache line boundary for optimal performance
180
0
        temp = (SAMPLETYPE *)SOUNDTOUCH_ALIGN_POINTER_16(tempUnaligned);
181
0
        if (samplesInBuffer)
182
0
        {
183
0
            memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
184
0
        }
185
0
        delete[] bufferUnaligned;
186
0
        buffer = temp;
187
0
        bufferUnaligned = tempUnaligned;
188
0
        bufferPos = 0;
189
0
    } 
190
0
    else 
191
0
    {
192
0
        // simply rewind the buffer (if necessary)
193
0
        rewind();
194
0
    }
195
0
}
196
197
198
// Returns the current buffer capacity in terms of samples
199
uint FIFOSampleBuffer::getCapacity() const
200
0
{
201
0
    return sizeInBytes / (channels * sizeof(SAMPLETYPE));
202
0
}
203
204
205
// Returns the number of samples currently in the buffer
206
uint FIFOSampleBuffer::numSamples() const
207
0
{
208
0
    return samplesInBuffer;
209
0
}
210
211
212
// Output samples from beginning of the sample buffer. Copies demanded number
213
// of samples to output and removes them from the sample buffer. If there
214
// are less than 'numsample' samples in the buffer, returns all available.
215
//
216
// Returns number of samples copied.
217
uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples)
218
0
{
219
0
    uint num;
220
0
221
0
    num = (maxSamples > samplesInBuffer) ? samplesInBuffer : maxSamples;
222
0
223
0
    memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num);
224
0
    return receiveSamples(num);
225
0
}
226
227
228
// Removes samples from the beginning of the sample buffer without copying them
229
// anywhere. Used to reduce the number of samples in the buffer, when accessing
230
// the sample buffer with the 'ptrBegin' function.
231
uint FIFOSampleBuffer::receiveSamples(uint maxSamples)
232
0
{
233
0
    if (maxSamples >= samplesInBuffer)
234
0
    {
235
0
        uint temp;
236
0
237
0
        temp = samplesInBuffer;
238
0
        samplesInBuffer = 0;
239
0
        return temp;
240
0
    }
241
0
242
0
    samplesInBuffer -= maxSamples;
243
0
    bufferPos += maxSamples;
244
0
245
0
    return maxSamples;
246
0
}
247
248
249
// Returns nonzero if the sample buffer is empty
250
int FIFOSampleBuffer::isEmpty() const
251
0
{
252
0
    return (samplesInBuffer == 0) ? 1 : 0;
253
0
}
254
255
256
// Clears the sample buffer
257
void FIFOSampleBuffer::clear()
258
0
{
259
0
    samplesInBuffer = 0;
260
0
    bufferPos = 0;
261
0
}
262
263
264
/// allow trimming (downwards) amount of samples in pipeline.
265
/// Returns adjusted amount of samples
266
uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
267
0
{
268
0
    if (numSamples < samplesInBuffer)
269
0
    {
270
0
        samplesInBuffer = numSamples;
271
0
    }
272
0
    return samplesInBuffer;
273
0
}
274