michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 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 file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef MOZILLA_AUDIONODESTREAM_H_ michael@0: #define MOZILLA_AUDIONODESTREAM_H_ michael@0: michael@0: #include "MediaStreamGraph.h" michael@0: #include "mozilla/dom/AudioNodeBinding.h" michael@0: #include "AudioSegment.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: namespace dom { michael@0: struct ThreeDPoint; michael@0: class AudioParamTimeline; michael@0: class DelayNodeEngine; michael@0: class AudioContext; michael@0: } michael@0: michael@0: class ThreadSharedFloatArrayBufferList; michael@0: class AudioNodeEngine; michael@0: michael@0: /** michael@0: * An AudioNodeStream produces one audio track with ID AUDIO_TRACK. michael@0: * The start time of the AudioTrack is aligned to the start time of the michael@0: * AudioContext's destination node stream, plus some multiple of BLOCK_SIZE michael@0: * samples. michael@0: * michael@0: * An AudioNodeStream has an AudioNodeEngine plugged into it that does the michael@0: * actual audio processing. AudioNodeStream contains the glue code that michael@0: * integrates audio processing with the MediaStreamGraph. michael@0: */ michael@0: class AudioNodeStream : public ProcessedMediaStream { michael@0: typedef dom::ChannelCountMode ChannelCountMode; michael@0: typedef dom::ChannelInterpretation ChannelInterpretation; michael@0: michael@0: public: michael@0: typedef mozilla::dom::AudioContext AudioContext; michael@0: michael@0: enum { AUDIO_TRACK = 1 }; michael@0: michael@0: typedef nsAutoTArray OutputChunks; michael@0: michael@0: /** michael@0: * Transfers ownership of aEngine to the new AudioNodeStream. michael@0: */ michael@0: AudioNodeStream(AudioNodeEngine* aEngine, michael@0: MediaStreamGraph::AudioNodeStreamKind aKind, michael@0: TrackRate aSampleRate) michael@0: : ProcessedMediaStream(nullptr), michael@0: mEngine(aEngine), michael@0: mSampleRate(aSampleRate), michael@0: mKind(aKind), michael@0: mNumberOfInputChannels(2), michael@0: mMarkAsFinishedAfterThisBlock(false), michael@0: mAudioParamStream(false), michael@0: mMuted(false) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: mChannelCountMode = ChannelCountMode::Max; michael@0: mChannelInterpretation = ChannelInterpretation::Speakers; michael@0: // AudioNodes are always producing data michael@0: mHasCurrentData = true; michael@0: MOZ_COUNT_CTOR(AudioNodeStream); michael@0: } michael@0: ~AudioNodeStream(); michael@0: michael@0: // Control API michael@0: /** michael@0: * Sets a parameter that's a time relative to some stream's played time. michael@0: * This time is converted to a time relative to this stream when it's set. michael@0: */ michael@0: void SetStreamTimeParameter(uint32_t aIndex, AudioContext* aContext, michael@0: double aStreamTime); michael@0: void SetDoubleParameter(uint32_t aIndex, double aValue); michael@0: void SetInt32Parameter(uint32_t aIndex, int32_t aValue); michael@0: void SetTimelineParameter(uint32_t aIndex, const dom::AudioParamTimeline& aValue); michael@0: void SetThreeDPointParameter(uint32_t aIndex, const dom::ThreeDPoint& aValue); michael@0: void SetBuffer(already_AddRefed&& aBuffer); michael@0: // This consumes the contents of aData. aData will be emptied after this returns. michael@0: void SetRawArrayData(nsTArray& aData); michael@0: void SetChannelMixingParameters(uint32_t aNumberOfChannels, michael@0: ChannelCountMode aChannelCountMoe, michael@0: ChannelInterpretation aChannelInterpretation); michael@0: ChannelInterpretation GetChannelInterpretation() michael@0: { michael@0: return mChannelInterpretation; michael@0: } michael@0: michael@0: void SetAudioParamHelperStream() michael@0: { michael@0: MOZ_ASSERT(!mAudioParamStream, "Can only do this once"); michael@0: mAudioParamStream = true; michael@0: } michael@0: michael@0: virtual AudioNodeStream* AsAudioNodeStream() MOZ_OVERRIDE { return this; } michael@0: michael@0: // Graph thread only michael@0: void SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelativeToStream, michael@0: double aStreamTime); michael@0: void SetChannelMixingParametersImpl(uint32_t aNumberOfChannels, michael@0: ChannelCountMode aChannelCountMoe, michael@0: ChannelInterpretation aChannelInterpretation); michael@0: virtual void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE; michael@0: TrackTicks GetCurrentPosition(); michael@0: bool IsAudioParamStream() const michael@0: { michael@0: return mAudioParamStream; michael@0: } michael@0: void Mute() { michael@0: mMuted = true; michael@0: } michael@0: michael@0: void Unmute() { michael@0: mMuted = false; michael@0: } michael@0: michael@0: const OutputChunks& LastChunks() const michael@0: { michael@0: return mLastChunks; michael@0: } michael@0: virtual bool MainThreadNeedsUpdates() const MOZ_OVERRIDE michael@0: { michael@0: // Only source and external streams need updates on the main thread. michael@0: return (mKind == MediaStreamGraph::SOURCE_STREAM && mFinished) || michael@0: mKind == MediaStreamGraph::EXTERNAL_STREAM; michael@0: } michael@0: virtual bool IsIntrinsicallyConsumed() const MOZ_OVERRIDE michael@0: { michael@0: return true; michael@0: } michael@0: michael@0: // Any thread michael@0: AudioNodeEngine* Engine() { return mEngine; } michael@0: TrackRate SampleRate() const { return mSampleRate; } michael@0: michael@0: /** michael@0: * Convert a time in seconds on the destination stream to seconds michael@0: * on this stream. michael@0: */ michael@0: double TimeFromDestinationTime(AudioNodeStream* aDestination, michael@0: double aSeconds); michael@0: /** michael@0: * Convert a time in seconds on the destination stream to TrackTicks michael@0: * on this stream. michael@0: */ michael@0: TrackTicks TicksFromDestinationTime(MediaStream* aDestination, michael@0: double aSeconds); michael@0: /** michael@0: * Get the destination stream time in seconds corresponding to a position on michael@0: * this stream. michael@0: */ michael@0: double DestinationTimeFromTicks(AudioNodeStream* aDestination, michael@0: TrackTicks aPosition); michael@0: michael@0: size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; michael@0: size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; michael@0: michael@0: void SizeOfAudioNodesIncludingThis(MallocSizeOf aMallocSizeOf, michael@0: AudioNodeSizes& aUsage) const; michael@0: michael@0: protected: michael@0: void AdvanceOutputSegment(); michael@0: void FinishOutput(); michael@0: void AccumulateInputChunk(uint32_t aInputIndex, const AudioChunk& aChunk, michael@0: AudioChunk* aBlock, michael@0: nsTArray* aDownmixBuffer); michael@0: void UpMixDownMixChunk(const AudioChunk* aChunk, uint32_t aOutputChannelCount, michael@0: nsTArray& aOutputChannels, michael@0: nsTArray& aDownmixBuffer); michael@0: michael@0: uint32_t ComputedNumberOfChannels(uint32_t aInputChannelCount); michael@0: void ObtainInputBlock(AudioChunk& aTmpChunk, uint32_t aPortIndex); michael@0: michael@0: // The engine that will generate output for this node. michael@0: nsAutoPtr mEngine; michael@0: // The last block produced by this node. michael@0: OutputChunks mLastChunks; michael@0: // The stream's sampling rate michael@0: const TrackRate mSampleRate; michael@0: // Whether this is an internal or external stream michael@0: MediaStreamGraph::AudioNodeStreamKind mKind; michael@0: // The number of input channels that this stream requires. 0 means don't care. michael@0: uint32_t mNumberOfInputChannels; michael@0: // The mixing modes michael@0: ChannelCountMode mChannelCountMode; michael@0: ChannelInterpretation mChannelInterpretation; michael@0: // Whether the stream should be marked as finished as soon michael@0: // as the current time range has been computed block by block. michael@0: bool mMarkAsFinishedAfterThisBlock; michael@0: // Whether the stream is an AudioParamHelper stream. michael@0: bool mAudioParamStream; michael@0: // Whether the stream is muted. Access only on the MediaStreamGraph thread. michael@0: bool mMuted; michael@0: }; michael@0: michael@0: } michael@0: michael@0: #endif /* MOZILLA_AUDIONODESTREAM_H_ */