michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/dom/ChannelSplitterNode.h" michael@0: #include "mozilla/dom/ChannelSplitterNodeBinding.h" michael@0: #include "AudioNodeEngine.h" michael@0: #include "AudioNodeStream.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED0(ChannelSplitterNode, AudioNode) michael@0: michael@0: class ChannelSplitterNodeEngine : public AudioNodeEngine michael@0: { michael@0: public: michael@0: ChannelSplitterNodeEngine(ChannelSplitterNode* aNode) michael@0: : AudioNodeEngine(aNode) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: } michael@0: michael@0: virtual void ProcessBlocksOnPorts(AudioNodeStream* aStream, michael@0: const OutputChunks& aInput, michael@0: OutputChunks& aOutput, michael@0: bool* aFinished) MOZ_OVERRIDE michael@0: { michael@0: MOZ_ASSERT(aInput.Length() == 1, "Should only have one input port"); michael@0: michael@0: aOutput.SetLength(OutputCount()); michael@0: for (uint16_t i = 0; i < OutputCount(); ++i) { michael@0: if (i < aInput[0].mChannelData.Length()) { michael@0: // Split out existing channels michael@0: AllocateAudioBlock(1, &aOutput[i]); michael@0: AudioBlockCopyChannelWithScale( michael@0: static_cast(aInput[0].mChannelData[i]), michael@0: aInput[0].mVolume, michael@0: static_cast(const_cast(aOutput[i].mChannelData[0]))); michael@0: } else { michael@0: // Pad with silent channels if needed michael@0: aOutput[i].SetNull(WEBAUDIO_BLOCK_SIZE); michael@0: } michael@0: } michael@0: } michael@0: michael@0: virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE michael@0: { michael@0: return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); michael@0: } michael@0: }; michael@0: michael@0: ChannelSplitterNode::ChannelSplitterNode(AudioContext* aContext, michael@0: uint16_t aOutputCount) michael@0: : AudioNode(aContext, michael@0: 2, michael@0: ChannelCountMode::Max, michael@0: ChannelInterpretation::Speakers) michael@0: , mOutputCount(aOutputCount) michael@0: { michael@0: mStream = aContext->Graph()->CreateAudioNodeStream(new ChannelSplitterNodeEngine(this), michael@0: MediaStreamGraph::INTERNAL_STREAM); michael@0: } michael@0: michael@0: JSObject* michael@0: ChannelSplitterNode::WrapObject(JSContext* aCx) michael@0: { michael@0: return ChannelSplitterNodeBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: } michael@0: } michael@0: