Bug 1943650 - Command-line --help output misformatted after --dbus-service. r=emilio
[gecko.git] / dom / media / driftcontrol / AudioChunkList.cpp
blobe0010c2ff0e27e1eeebc4b017903a39f45721588
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "AudioChunkList.h"
8 namespace mozilla {
10 AudioChunkList::AudioChunkList(uint32_t aTotalDuration, uint32_t aChannels,
11 const PrincipalHandle& aPrincipalHandle)
12 : mPrincipalHandle(aPrincipalHandle) {
13 uint32_t numOfChunks = aTotalDuration / mChunkCapacity;
14 if (aTotalDuration % mChunkCapacity) {
15 ++numOfChunks;
17 CreateChunks(numOfChunks, aChannels);
20 void AudioChunkList::CreateChunks(uint32_t aNumOfChunks, uint32_t aChannels) {
21 MOZ_ASSERT(!mChunks.Length());
22 MOZ_ASSERT(aNumOfChunks);
23 MOZ_ASSERT(aChannels);
24 mChunks.AppendElements(aNumOfChunks);
26 for (AudioChunk& chunk : mChunks) {
27 AutoTArray<nsTArray<float>, 2> buffer;
28 buffer.AppendElements(aChannels);
30 AutoTArray<const float*, 2> bufferPtrs;
31 bufferPtrs.AppendElements(aChannels);
33 for (uint32_t i = 0; i < aChannels; ++i) {
34 float* ptr = buffer[i].AppendElements(mChunkCapacity);
35 bufferPtrs[i] = ptr;
38 chunk.mBuffer = new mozilla::SharedChannelArrayBuffer(std::move(buffer));
39 chunk.mChannelData.AppendElements(aChannels);
40 for (uint32_t i = 0; i < aChannels; ++i) {
41 chunk.mChannelData[i] = bufferPtrs[i];
46 void AudioChunkList::UpdateToMonoOrStereo(uint32_t aChannels) {
47 MOZ_ASSERT(mChunks.Length());
48 MOZ_ASSERT(mSampleFormat == AUDIO_FORMAT_S16 ||
49 mSampleFormat == AUDIO_FORMAT_FLOAT32);
50 MOZ_ASSERT(aChannels == 1 || aChannels == 2);
52 for (AudioChunk& chunk : mChunks) {
53 MOZ_ASSERT(chunk.ChannelCount() != (uint32_t)aChannels);
54 MOZ_ASSERT(chunk.ChannelCount() == 1 || chunk.ChannelCount() == 2);
55 chunk.mChannelData.SetLengthAndRetainStorage(aChannels);
56 if (mSampleFormat == AUDIO_FORMAT_S16) {
57 SharedChannelArrayBuffer<short>* channelArray =
58 static_cast<SharedChannelArrayBuffer<short>*>(chunk.mBuffer.get());
59 channelArray->mBuffers.SetLengthAndRetainStorage(aChannels);
60 if (aChannels == 2) {
61 // This an indirect allocation, unfortunately.
62 channelArray->mBuffers[1].SetLength(mChunkCapacity);
63 chunk.mChannelData[1] = channelArray->mBuffers[1].Elements();
65 } else {
66 SharedChannelArrayBuffer<float>* channelArray =
67 static_cast<SharedChannelArrayBuffer<float>*>(chunk.mBuffer.get());
68 channelArray->mBuffers.SetLengthAndRetainStorage(aChannels);
69 if (aChannels == 2) {
70 // This an indirect allocation, unfortunately.
71 channelArray->mBuffers[1].SetLength(mChunkCapacity);
72 chunk.mChannelData[1] = channelArray->mBuffers[1].Elements();
78 void AudioChunkList::SetSampleFormat(AudioSampleFormat aFormat) {
79 MOZ_ASSERT(mSampleFormat == AUDIO_FORMAT_SILENCE);
80 MOZ_ASSERT(aFormat == AUDIO_FORMAT_S16 || aFormat == AUDIO_FORMAT_FLOAT32);
81 mSampleFormat = aFormat;
82 if (mSampleFormat == AUDIO_FORMAT_S16) {
83 mChunkCapacity = 2 * mChunkCapacity;
87 AudioChunk& AudioChunkList::GetNext() {
88 AudioChunk& chunk = mChunks[mIndex];
89 MOZ_ASSERT(!chunk.mChannelData.IsEmpty());
90 MOZ_ASSERT(chunk.mBuffer);
91 MOZ_ASSERT(!chunk.mBuffer->IsShared());
92 MOZ_ASSERT(mSampleFormat == AUDIO_FORMAT_S16 ||
93 mSampleFormat == AUDIO_FORMAT_FLOAT32);
94 chunk.mDuration = 0;
95 chunk.mVolume = 1.0f;
96 chunk.mPrincipalHandle = mPrincipalHandle;
97 chunk.mBufferFormat = mSampleFormat;
98 IncrementIndex();
99 return chunk;
102 void AudioChunkList::Update(uint32_t aChannels) {
103 MOZ_ASSERT(mChunks.Length());
104 if (mChunks[0].ChannelCount() == aChannels) {
105 return;
108 // Special handling between mono and stereo to avoid reallocations.
109 if (aChannels <= 2 && mChunks[0].ChannelCount() <= 2) {
110 UpdateToMonoOrStereo(aChannels);
111 return;
114 uint32_t numOfChunks = mChunks.Length();
115 mChunks.ClearAndRetainStorage();
116 CreateChunks(numOfChunks, aChannels);
119 } // namespace mozilla