2013-01-13 22:46:57 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
|
|
|
|
/* 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_AUDIONODESTREAM_H_
|
|
|
|
#define MOZILLA_AUDIONODESTREAM_H_
|
|
|
|
|
|
|
|
#include "MediaStreamGraph.h"
|
2013-04-27 23:25:23 +00:00
|
|
|
#include "mozilla/dom/AudioNodeBinding.h"
|
2013-09-05 20:25:17 +00:00
|
|
|
#include "AudioSegment.h"
|
2013-01-13 22:46:57 +00:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
2013-03-12 15:16:42 +00:00
|
|
|
namespace dom {
|
|
|
|
struct ThreeDPoint;
|
2013-05-02 01:02:31 +00:00
|
|
|
class AudioParamTimeline;
|
2013-08-26 17:19:36 +00:00
|
|
|
class DelayNodeEngine;
|
2014-01-15 11:08:20 +00:00
|
|
|
class AudioContext;
|
2013-03-12 15:16:42 +00:00
|
|
|
}
|
|
|
|
|
2013-01-13 22:46:57 +00:00
|
|
|
class ThreadSharedFloatArrayBufferList;
|
2013-09-05 20:25:17 +00:00
|
|
|
class AudioNodeEngine;
|
2013-01-13 22:46:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* An AudioNodeStream produces one audio track with ID AUDIO_TRACK.
|
|
|
|
* The start time of the AudioTrack is aligned to the start time of the
|
|
|
|
* AudioContext's destination node stream, plus some multiple of BLOCK_SIZE
|
|
|
|
* samples.
|
|
|
|
*
|
|
|
|
* An AudioNodeStream has an AudioNodeEngine plugged into it that does the
|
|
|
|
* actual audio processing. AudioNodeStream contains the glue code that
|
|
|
|
* integrates audio processing with the MediaStreamGraph.
|
|
|
|
*/
|
|
|
|
class AudioNodeStream : public ProcessedMediaStream {
|
|
|
|
public:
|
2014-01-15 11:08:20 +00:00
|
|
|
typedef mozilla::dom::AudioContext AudioContext;
|
|
|
|
|
2013-01-13 22:46:57 +00:00
|
|
|
enum { AUDIO_TRACK = 1 };
|
|
|
|
|
2013-05-05 15:48:45 +00:00
|
|
|
typedef nsAutoTArray<AudioChunk, 1> OutputChunks;
|
|
|
|
|
2013-01-13 22:46:57 +00:00
|
|
|
/**
|
|
|
|
* Transfers ownership of aEngine to the new AudioNodeStream.
|
|
|
|
*/
|
2013-03-18 00:37:47 +00:00
|
|
|
AudioNodeStream(AudioNodeEngine* aEngine,
|
2013-05-24 17:09:29 +00:00
|
|
|
MediaStreamGraph::AudioNodeStreamKind aKind,
|
|
|
|
TrackRate aSampleRate)
|
2013-03-18 00:37:47 +00:00
|
|
|
: ProcessedMediaStream(nullptr),
|
|
|
|
mEngine(aEngine),
|
2013-05-24 17:09:29 +00:00
|
|
|
mSampleRate(aSampleRate),
|
2013-04-14 01:37:04 +00:00
|
|
|
mKind(aKind),
|
2013-04-29 20:58:19 +00:00
|
|
|
mNumberOfInputChannels(2),
|
2013-05-02 01:02:31 +00:00
|
|
|
mMarkAsFinishedAfterThisBlock(false),
|
2013-08-26 17:19:36 +00:00
|
|
|
mAudioParamStream(false),
|
|
|
|
mMuted(false)
|
2013-01-13 22:46:57 +00:00
|
|
|
{
|
2013-05-24 17:09:29 +00:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2013-05-06 19:28:13 +00:00
|
|
|
mChannelCountMode = dom::ChannelCountMode::Max;
|
|
|
|
mChannelInterpretation = dom::ChannelInterpretation::Speakers;
|
2013-03-20 11:19:39 +00:00
|
|
|
// AudioNodes are always producing data
|
|
|
|
mHasCurrentData = true;
|
2013-04-01 20:06:55 +00:00
|
|
|
MOZ_COUNT_CTOR(AudioNodeStream);
|
2013-01-13 22:46:57 +00:00
|
|
|
}
|
|
|
|
~AudioNodeStream();
|
|
|
|
|
|
|
|
// Control API
|
|
|
|
/**
|
|
|
|
* Sets a parameter that's a time relative to some stream's played time.
|
|
|
|
* This time is converted to a time relative to this stream when it's set.
|
|
|
|
*/
|
2014-01-15 11:08:20 +00:00
|
|
|
void SetStreamTimeParameter(uint32_t aIndex, AudioContext* aContext,
|
2013-01-13 22:46:57 +00:00
|
|
|
double aStreamTime);
|
|
|
|
void SetDoubleParameter(uint32_t aIndex, double aValue);
|
|
|
|
void SetInt32Parameter(uint32_t aIndex, int32_t aValue);
|
2013-01-28 22:42:27 +00:00
|
|
|
void SetTimelineParameter(uint32_t aIndex, const dom::AudioParamTimeline& aValue);
|
2013-03-12 15:16:42 +00:00
|
|
|
void SetThreeDPointParameter(uint32_t aIndex, const dom::ThreeDPoint& aValue);
|
2013-01-13 22:46:57 +00:00
|
|
|
void SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList> aBuffer);
|
2013-05-14 04:12:30 +00:00
|
|
|
// This consumes the contents of aData. aData will be emptied after this returns.
|
|
|
|
void SetRawArrayData(nsTArray<float>& aData);
|
2013-04-27 23:25:23 +00:00
|
|
|
void SetChannelMixingParameters(uint32_t aNumberOfChannels,
|
|
|
|
dom::ChannelCountMode aChannelCountMoe,
|
|
|
|
dom::ChannelInterpretation aChannelInterpretation);
|
2013-05-02 01:02:31 +00:00
|
|
|
void SetAudioParamHelperStream()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mAudioParamStream, "Can only do this once");
|
|
|
|
mAudioParamStream = true;
|
|
|
|
}
|
2013-01-13 22:46:57 +00:00
|
|
|
|
2013-12-05 20:23:57 +00:00
|
|
|
virtual AudioNodeStream* AsAudioNodeStream() MOZ_OVERRIDE { return this; }
|
2013-01-13 22:46:57 +00:00
|
|
|
|
|
|
|
// Graph thread only
|
|
|
|
void SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelativeToStream,
|
|
|
|
double aStreamTime);
|
2013-04-27 23:25:23 +00:00
|
|
|
void SetChannelMixingParametersImpl(uint32_t aNumberOfChannels,
|
|
|
|
dom::ChannelCountMode aChannelCountMoe,
|
|
|
|
dom::ChannelInterpretation aChannelInterpretation);
|
2013-12-05 20:23:57 +00:00
|
|
|
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE;
|
2013-01-13 22:46:57 +00:00
|
|
|
TrackTicks GetCurrentPosition();
|
2013-05-02 01:02:31 +00:00
|
|
|
bool IsAudioParamStream() const
|
|
|
|
{
|
|
|
|
return mAudioParamStream;
|
|
|
|
}
|
2013-08-26 17:19:36 +00:00
|
|
|
void Mute() {
|
|
|
|
mMuted = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Unmute() {
|
|
|
|
mMuted = false;
|
|
|
|
}
|
|
|
|
|
2013-05-05 15:48:45 +00:00
|
|
|
const OutputChunks& LastChunks() const
|
2013-05-02 03:12:59 +00:00
|
|
|
{
|
2013-05-05 15:48:45 +00:00
|
|
|
return mLastChunks;
|
2013-05-02 03:12:59 +00:00
|
|
|
}
|
2013-06-19 03:09:44 +00:00
|
|
|
virtual bool MainThreadNeedsUpdates() const MOZ_OVERRIDE
|
|
|
|
{
|
|
|
|
// Only source and external streams need updates on the main thread.
|
|
|
|
return (mKind == MediaStreamGraph::SOURCE_STREAM && mFinished) ||
|
|
|
|
mKind == MediaStreamGraph::EXTERNAL_STREAM;
|
|
|
|
}
|
2013-07-24 10:11:35 +00:00
|
|
|
virtual bool IsIntrinsicallyConsumed() const MOZ_OVERRIDE
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2013-01-13 22:46:57 +00:00
|
|
|
|
|
|
|
// Any thread
|
|
|
|
AudioNodeEngine* Engine() { return mEngine; }
|
2013-05-24 17:09:29 +00:00
|
|
|
TrackRate SampleRate() const { return mSampleRate; }
|
2013-01-13 22:46:57 +00:00
|
|
|
|
2014-02-26 22:45:04 +00:00
|
|
|
/**
|
|
|
|
* Convert a time in seconds on the destination stream to seconds
|
|
|
|
* on this stream.
|
|
|
|
*/
|
|
|
|
double TimeFromDestinationTime(AudioNodeStream* aDestination,
|
|
|
|
double aSeconds);
|
2014-02-16 20:46:56 +00:00
|
|
|
/**
|
|
|
|
* Convert a time in seconds on the destination stream to TrackTicks
|
|
|
|
* on this stream.
|
|
|
|
*/
|
|
|
|
TrackTicks TicksFromDestinationTime(MediaStream* aDestination,
|
|
|
|
double aSeconds);
|
|
|
|
/**
|
|
|
|
* Get the destination stream time in seconds corresponding to a position on
|
|
|
|
* this stream.
|
|
|
|
*/
|
|
|
|
double DestinationTimeFromTicks(AudioNodeStream* aDestination,
|
|
|
|
TrackTicks aPosition);
|
|
|
|
|
2013-01-13 22:46:57 +00:00
|
|
|
protected:
|
2013-07-24 10:11:35 +00:00
|
|
|
void AdvanceOutputSegment();
|
2013-01-13 22:46:57 +00:00
|
|
|
void FinishOutput();
|
2013-07-24 10:11:35 +00:00
|
|
|
void AccumulateInputChunk(uint32_t aInputIndex, const AudioChunk& aChunk,
|
|
|
|
AudioChunk* aBlock,
|
|
|
|
nsTArray<float>* aDownmixBuffer);
|
|
|
|
void UpMixDownMixChunk(const AudioChunk* aChunk, uint32_t aOutputChannelCount,
|
|
|
|
nsTArray<const void*>& aOutputChannels,
|
|
|
|
nsTArray<float>& aDownmixBuffer);
|
|
|
|
|
|
|
|
uint32_t ComputeFinalOuputChannelCount(uint32_t aInputChannelCount);
|
2013-05-05 15:48:45 +00:00
|
|
|
void ObtainInputBlock(AudioChunk& aTmpChunk, uint32_t aPortIndex);
|
2013-01-13 22:46:57 +00:00
|
|
|
|
|
|
|
// The engine that will generate output for this node.
|
|
|
|
nsAutoPtr<AudioNodeEngine> mEngine;
|
|
|
|
// The last block produced by this node.
|
2013-05-05 15:48:45 +00:00
|
|
|
OutputChunks mLastChunks;
|
2013-05-24 17:09:29 +00:00
|
|
|
// The stream's sampling rate
|
|
|
|
const TrackRate mSampleRate;
|
2013-03-18 00:37:47 +00:00
|
|
|
// Whether this is an internal or external stream
|
|
|
|
MediaStreamGraph::AudioNodeStreamKind mKind;
|
2013-04-14 01:37:04 +00:00
|
|
|
// The number of input channels that this stream requires. 0 means don't care.
|
|
|
|
uint32_t mNumberOfInputChannels;
|
2013-04-27 23:25:23 +00:00
|
|
|
// The mixing modes
|
2013-05-06 19:28:13 +00:00
|
|
|
dom::ChannelCountMode mChannelCountMode;
|
|
|
|
dom::ChannelInterpretation mChannelInterpretation;
|
2013-04-29 20:58:19 +00:00
|
|
|
// Whether the stream should be marked as finished as soon
|
|
|
|
// as the current time range has been computed block by block.
|
|
|
|
bool mMarkAsFinishedAfterThisBlock;
|
2013-05-02 01:02:31 +00:00
|
|
|
// Whether the stream is an AudioParamHelper stream.
|
|
|
|
bool mAudioParamStream;
|
2013-08-26 17:19:36 +00:00
|
|
|
// Whether the stream is muted. Access only on the MediaStreamGraph thread.
|
|
|
|
bool mMuted;
|
2013-01-13 22:46:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* MOZILLA_AUDIONODESTREAM_H_ */
|