/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_AUDIOCHANNELFORMAT_H_ #define MOZILLA_AUDIOCHANNELFORMAT_H_
/* * This file provides utilities for upmixing and downmixing channels. * * The channel layouts, upmixing and downmixing are consistent with the * Web Audio spec. * * Channel layouts for up to 6 channels: * mono { M } * stereo { L, R } * { L, R, C } * quad { L, R, SL, SR } * { L, R, C, SL, SR } * 5.1 { L, R, C, LFE, SL, SR } * * Only 1, 2, 4 and 6 are currently defined in Web Audio.
*/
/** * Return a channel count whose channel layout includes all the channels from * aChannels1 and aChannels2.
*/
uint32_t GetAudioChannelsSuperset(uint32_t aChannels1, uint32_t aChannels2);
/** * DownMixMatrix represents a conversion matrix efficiently by exploiting the * fact that each input channel contributes to at most one output channel, * except possibly for the C input channel in layouts that have one. Also, * every input channel is multiplied by the same coefficient for every output * channel it contributes to.
*/ constfloat SQRT_ONE_HALF = 0.7071067811865476f;
struct DownMixMatrix { // Every input channel c is copied to output channel mInputDestination[c] // after multiplying by mInputCoefficient[c].
uint8_t mInputDestination[CUSTOM_CHANNEL_LAYOUTS]; // If not IGNORE, then the C channel is copied to this output channel after // multiplying by its coefficient.
uint8_t mCExtraDestination; float mInputCoefficient[CUSTOM_CHANNEL_LAYOUTS];
};
/** * Given an array of input channels, downmix to aOutputChannelCount, and copy * the results to the channel buffers in aOutputChannels. Don't call this with * input count <= output count.
*/ template <typename SrcT, typename DstT> void AudioChannelsDownMix(Span<const SrcT* const> aInputChannels,
Span<DstT* const> aOutputChannels,
uint32_t aDuration) {
uint32_t inputChannelCount = aInputChannels.Length();
uint32_t outputChannelCount = aOutputChannels.Length();
NS_ASSERTION(inputChannelCount > outputChannelCount, "Nothing to do");
if (inputChannelCount > 6) { // Just drop the unknown channels. for (uint32_t o = 0; o < outputChannelCount; ++o) {
ConvertAudioSamples(aInputChannels[o], aOutputChannels[o], aDuration);
} return;
}
// This is slow, but general. We can define custom code for special // cases later. for (DstT* outChannel : aOutputChannels) {
std::fill_n(outChannel, aDuration, static_cast<DstT>(0));
} for (uint32_t c = 0; c < inputChannelCount; ++c) {
uint32_t dstIndex = m.mInputDestination[c]; if (dstIndex == IGNORE) { continue;
}
AddAudioSamplesWithScale(aInputChannels[c], aOutputChannels[dstIndex],
aDuration, m.mInputCoefficient[c]);
} // Utilize the fact that in every layout, C is the only channel that may // contribute to more than one output channel.
uint32_t dstIndex = m.mCExtraDestination; if (dstIndex != IGNORE) {
AddAudioSamplesWithScale(aInputChannels[SURROUND_C],
aOutputChannels[dstIndex], aDuration,
m.mInputCoefficient[SURROUND_C]);
}
}
/** * UpMixMatrix represents a conversion matrix by exploiting the fact that * each output channel comes from at most one input channel.
*/ struct UpMixMatrix {
uint8_t mInputDestination[CUSTOM_CHANNEL_LAYOUTS];
};
/** * Given an array of input channel data, and an output channel count, * replaces the array with an array of upmixed channels. * This shuffles the array and may set some channel buffers to aZeroChannel. * Don't call this with input count >= output count. * This may return *more* channels than requested. In that case, downmixing * is required to to get to aOutputChannelCount. (This is how we handle * odd cases like 3 -> 4 upmixing.) * If aChannelArray.Length() was the input to one of a series of * GetAudioChannelsSuperset calls resulting in aOutputChannelCount, * no downmixing will be required.
*/ template <typename T> void AudioChannelsUpMix(nsTArray<const T*>* aChannelArray,
uint32_t aOutputChannelCount, const T* aZeroChannel) {
uint32_t inputChannelCount = aChannelArray->Length();
uint32_t outputChannelCount =
GetAudioChannelsSuperset(aOutputChannelCount, inputChannelCount);
NS_ASSERTION(outputChannelCount > inputChannelCount, "No up-mix needed");
MOZ_ASSERT(inputChannelCount > 0, "Bad number of channels");
MOZ_ASSERT(outputChannelCount > 0, "Bad number of channels");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.