Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 : #include "AudioCompactor.h"
7 : #if defined(MOZ_MEMORY)
8 : # include "mozmemory.h"
9 : #endif
10 :
11 : namespace mozilla {
12 :
13 : static size_t
14 0 : MallocGoodSize(size_t aSize)
15 : {
16 : # if defined(MOZ_MEMORY)
17 0 : return malloc_good_size(aSize);
18 : # else
19 : return aSize;
20 : # endif
21 : }
22 :
23 : static size_t
24 0 : TooMuchSlop(size_t aSize, size_t aAllocSize, size_t aMaxSlop)
25 : {
26 : // If the allocated size is less then our target size, then we
27 : // are chunking. This means it will be completely filled with
28 : // zero slop.
29 0 : size_t slop = (aAllocSize > aSize) ? (aAllocSize - aSize) : 0;
30 0 : return slop > aMaxSlop;
31 : }
32 :
33 : uint32_t
34 0 : AudioCompactor::GetChunkSamples(uint32_t aFrames, uint32_t aChannels,
35 : size_t aMaxSlop)
36 : {
37 0 : size_t size = AudioDataSize(aFrames, aChannels);
38 0 : size_t chunkSize = MallocGoodSize(size);
39 :
40 : // Reduce the chunk size until we meet our slop goal or the chunk
41 : // approaches an unreasonably small size.
42 0 : while (chunkSize > 64 && TooMuchSlop(size, chunkSize, aMaxSlop)) {
43 0 : chunkSize = MallocGoodSize(chunkSize / 2);
44 : }
45 :
46 : // Calculate the number of samples based on expected malloc size
47 : // in order to allow as many frames as possible to be packed.
48 0 : return chunkSize / sizeof(AudioDataValue);
49 : }
50 :
51 : uint32_t
52 0 : AudioCompactor::NativeCopy::operator()(AudioDataValue *aBuffer,
53 : uint32_t aSamples)
54 : {
55 0 : NS_ASSERTION(aBuffer, "cannot copy to null buffer pointer");
56 0 : NS_ASSERTION(aSamples, "cannot copy zero values");
57 :
58 0 : size_t bufferBytes = aSamples * sizeof(AudioDataValue);
59 0 : size_t maxBytes = std::min(bufferBytes, mSourceBytes - mNextByte);
60 0 : uint32_t frames = maxBytes / BytesPerFrame(mChannels);
61 0 : size_t bytes = frames * BytesPerFrame(mChannels);
62 :
63 0 : NS_ASSERTION((mNextByte + bytes) <= mSourceBytes,
64 : "tried to copy beyond source buffer");
65 0 : NS_ASSERTION(bytes <= bufferBytes, "tried to copy beyond destination buffer");
66 :
67 0 : memcpy(aBuffer, mSource + mNextByte, bytes);
68 :
69 0 : mNextByte += bytes;
70 0 : return frames;
71 : }
72 :
73 : } // namespace mozilla
|