Backed out 35 changesets (bug 941158, bug 972518, bug 959520, bug 986063, bug 948895...
[gecko.git] / content / media / AudioSegment.h
blob563f0f76437172f6126f4ccf374bc1cf49853b7d
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 #ifndef MOZILLA_AUDIOSEGMENT_H_
7 #define MOZILLA_AUDIOSEGMENT_H_
9 #include "MediaSegment.h"
10 #include "AudioSampleFormat.h"
11 #include "SharedBuffer.h"
12 #ifdef MOZILLA_INTERNAL_API
13 #include "mozilla/TimeStamp.h"
14 #endif
16 namespace mozilla {
18 class AudioStream;
20 /**
21 * For auto-arrays etc, guess this as the common number of channels.
23 const int GUESS_AUDIO_CHANNELS = 2;
25 // We ensure that the graph advances in steps that are multiples of the Web
26 // Audio block size
27 const uint32_t WEBAUDIO_BLOCK_SIZE_BITS = 7;
28 const uint32_t WEBAUDIO_BLOCK_SIZE = 1 << WEBAUDIO_BLOCK_SIZE_BITS;
30 void InterleaveAndConvertBuffer(const void** aSourceChannels,
31 AudioSampleFormat aSourceFormat,
32 int32_t aLength, float aVolume,
33 int32_t aChannels,
34 AudioDataValue* aOutput);
36 /**
37 * Given an array of input channels (aChannelData), downmix to aOutputChannels,
38 * interleave the channel data. A total of aOutputChannels*aDuration
39 * interleaved samples will be copied to a channel buffer in aOutput.
41 void DownmixAndInterleave(const nsTArray<const void*>& aChannelData,
42 AudioSampleFormat aSourceFormat, int32_t aDuration,
43 float aVolume, uint32_t aOutputChannels,
44 AudioDataValue* aOutput);
46 /**
47 * An AudioChunk represents a multi-channel buffer of audio samples.
48 * It references an underlying ThreadSharedObject which manages the lifetime
49 * of the buffer. An AudioChunk maintains its own duration and channel data
50 * pointers so it can represent a subinterval of a buffer without copying.
51 * An AudioChunk can store its individual channels anywhere; it maintains
52 * separate pointers to each channel's buffer.
54 struct AudioChunk {
55 typedef mozilla::AudioSampleFormat SampleFormat;
57 // Generic methods
58 void SliceTo(TrackTicks aStart, TrackTicks aEnd)
60 NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration,
61 "Slice out of bounds");
62 if (mBuffer) {
63 MOZ_ASSERT(aStart < INT32_MAX, "Can't slice beyond 32-bit sample lengths");
64 for (uint32_t channel = 0; channel < mChannelData.Length(); ++channel) {
65 mChannelData[channel] = AddAudioSampleOffset(mChannelData[channel],
66 mBufferFormat, int32_t(aStart));
69 mDuration = aEnd - aStart;
71 TrackTicks GetDuration() const { return mDuration; }
72 bool CanCombineWithFollowing(const AudioChunk& aOther) const
74 if (aOther.mBuffer != mBuffer) {
75 return false;
77 if (mBuffer) {
78 NS_ASSERTION(aOther.mBufferFormat == mBufferFormat,
79 "Wrong metadata about buffer");
80 NS_ASSERTION(aOther.mChannelData.Length() == mChannelData.Length(),
81 "Mismatched channel count");
82 if (mDuration > INT32_MAX) {
83 return false;
85 for (uint32_t channel = 0; channel < mChannelData.Length(); ++channel) {
86 if (aOther.mChannelData[channel] != AddAudioSampleOffset(mChannelData[channel],
87 mBufferFormat, int32_t(mDuration))) {
88 return false;
92 return true;
94 bool IsNull() const { return mBuffer == nullptr; }
95 void SetNull(TrackTicks aDuration)
97 mBuffer = nullptr;
98 mChannelData.Clear();
99 mDuration = aDuration;
100 mVolume = 1.0f;
103 TrackTicks mDuration; // in frames within the buffer
104 nsRefPtr<ThreadSharedObject> mBuffer; // the buffer object whose lifetime is managed; null means data is all zeroes
105 nsTArray<const void*> mChannelData; // one pointer per channel; empty if and only if mBuffer is null
106 float mVolume; // volume multiplier to apply (1.0f if mBuffer is nonnull)
107 SampleFormat mBufferFormat; // format of frames in mBuffer (only meaningful if mBuffer is nonnull)
108 #ifdef MOZILLA_INTERNAL_API
109 mozilla::TimeStamp mTimeStamp; // time at which this has been fetched from the MediaEngine
110 #endif
114 * A list of audio samples consisting of a sequence of slices of SharedBuffers.
115 * The audio rate is determined by the track, not stored in this class.
117 class AudioSegment : public MediaSegmentBase<AudioSegment, AudioChunk> {
118 public:
119 typedef mozilla::AudioSampleFormat SampleFormat;
121 AudioSegment() : MediaSegmentBase<AudioSegment, AudioChunk>(AUDIO) {}
123 void AppendFrames(already_AddRefed<ThreadSharedObject> aBuffer,
124 const nsTArray<const float*>& aChannelData,
125 int32_t aDuration)
127 AudioChunk* chunk = AppendChunk(aDuration);
128 chunk->mBuffer = aBuffer;
129 for (uint32_t channel = 0; channel < aChannelData.Length(); ++channel) {
130 chunk->mChannelData.AppendElement(aChannelData[channel]);
132 chunk->mVolume = 1.0f;
133 chunk->mBufferFormat = AUDIO_FORMAT_FLOAT32;
134 #ifdef MOZILLA_INTERNAL_API
135 chunk->mTimeStamp = TimeStamp::Now();
136 #endif
138 void AppendFrames(already_AddRefed<ThreadSharedObject> aBuffer,
139 const nsTArray<const int16_t*>& aChannelData,
140 int32_t aDuration)
142 AudioChunk* chunk = AppendChunk(aDuration);
143 chunk->mBuffer = aBuffer;
144 for (uint32_t channel = 0; channel < aChannelData.Length(); ++channel) {
145 chunk->mChannelData.AppendElement(aChannelData[channel]);
147 chunk->mVolume = 1.0f;
148 chunk->mBufferFormat = AUDIO_FORMAT_S16;
149 #ifdef MOZILLA_INTERNAL_API
150 chunk->mTimeStamp = TimeStamp::Now();
151 #endif
153 // Consumes aChunk, and returns a pointer to the persistent copy of aChunk
154 // in the segment.
155 AudioChunk* AppendAndConsumeChunk(AudioChunk* aChunk)
157 AudioChunk* chunk = AppendChunk(aChunk->mDuration);
158 chunk->mBuffer = aChunk->mBuffer.forget();
159 chunk->mChannelData.SwapElements(aChunk->mChannelData);
160 chunk->mVolume = aChunk->mVolume;
161 chunk->mBufferFormat = aChunk->mBufferFormat;
162 #ifdef MOZILLA_INTERNAL_API
163 chunk->mTimeStamp = TimeStamp::Now();
164 #endif
165 return chunk;
167 void ApplyVolume(float aVolume);
168 void WriteTo(uint64_t aID, AudioStream* aOutput);
170 static Type StaticType() { return AUDIO; }
175 #endif /* MOZILLA_AUDIOSEGMENT_H_ */