mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
d2c63bc836
Here we make the non-realtime graphs to go to sleep until they're shut down from the main thread. This allows us to use the common forced shutdown code path in MediaStreamGraphImpl::RunThread. We also need to delete the graph object when the last message is dispatched to it. In addition, we need to make sure that the AudioNodes also get released when they're no longer needed. To do this, we need for force the SelfReference of AudioBufferSourceNodes to be released when the context is shut down, and also trigger the destruction of the graph there.
162 lines
3.9 KiB
C++
162 lines
3.9 KiB
C++
/* -*- 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 AudioBufferSourceNode_h_
|
|
#define AudioBufferSourceNode_h_
|
|
|
|
#include "AudioNode.h"
|
|
#include "AudioBuffer.h"
|
|
#include "AudioParam.h"
|
|
#include "mozilla/dom/BindingUtils.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
class AudioBufferSourceNode : public AudioNode,
|
|
public MainThreadMediaStreamListener
|
|
{
|
|
public:
|
|
explicit AudioBufferSourceNode(AudioContext* aContext);
|
|
virtual ~AudioBufferSourceNode();
|
|
|
|
virtual void DestroyMediaStream() MOZ_OVERRIDE
|
|
{
|
|
if (mStream) {
|
|
mStream->RemoveMainThreadListener(this);
|
|
}
|
|
AudioNode::DestroyMediaStream();
|
|
}
|
|
virtual uint16_t NumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE
|
|
{
|
|
return 0;
|
|
}
|
|
virtual AudioBufferSourceNode* AsAudioBufferSourceNode() MOZ_OVERRIDE
|
|
{
|
|
return this;
|
|
}
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode, AudioNode)
|
|
|
|
virtual JSObject* WrapObject(JSContext* aCx,
|
|
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
|
|
|
void Start(double aWhen, double aOffset,
|
|
const Optional<double>& aDuration, ErrorResult& aRv);
|
|
void NoteOn(double aWhen, ErrorResult& aRv)
|
|
{
|
|
Start(aWhen, 0.0, Optional<double>(), aRv);
|
|
}
|
|
void NoteGrainOn(double aWhen, double aOffset,
|
|
double aDuration, ErrorResult& aRv)
|
|
{
|
|
Optional<double> duration;
|
|
duration.Construct(aDuration);
|
|
Start(aWhen, aOffset, duration, aRv);
|
|
}
|
|
void Stop(double aWhen, ErrorResult& aRv, bool aShuttingDown = false);
|
|
void NoteOff(double aWhen, ErrorResult& aRv)
|
|
{
|
|
Stop(aWhen, aRv);
|
|
}
|
|
|
|
AudioBuffer* GetBuffer(JSContext* aCx) const
|
|
{
|
|
return mBuffer;
|
|
}
|
|
void SetBuffer(JSContext* aCx, AudioBuffer* aBuffer)
|
|
{
|
|
mBuffer = aBuffer;
|
|
SendBufferParameterToStream(aCx);
|
|
SendLoopParametersToStream();
|
|
}
|
|
AudioParam* PlaybackRate() const
|
|
{
|
|
return mPlaybackRate;
|
|
}
|
|
AudioParam* Gain() const
|
|
{
|
|
return mGain;
|
|
}
|
|
bool Loop() const
|
|
{
|
|
return mLoop;
|
|
}
|
|
void SetLoop(bool aLoop)
|
|
{
|
|
mLoop = aLoop;
|
|
SendLoopParametersToStream();
|
|
}
|
|
double LoopStart() const
|
|
{
|
|
return mLoopStart;
|
|
}
|
|
void SetLoopStart(double aStart)
|
|
{
|
|
mLoopStart = aStart;
|
|
SendLoopParametersToStream();
|
|
}
|
|
double LoopEnd() const
|
|
{
|
|
return mLoopEnd;
|
|
}
|
|
void SetLoopEnd(double aEnd)
|
|
{
|
|
mLoopEnd = aEnd;
|
|
SendLoopParametersToStream();
|
|
}
|
|
void SendDopplerShiftToStream(double aDopplerShift);
|
|
|
|
IMPL_EVENT_HANDLER(ended)
|
|
|
|
virtual void NotifyMainThreadStateChanged() MOZ_OVERRIDE;
|
|
|
|
private:
|
|
friend class AudioBufferSourceNodeEngine;
|
|
// START, OFFSET and DURATION are always set by start() (along with setting
|
|
// mBuffer to something non-null).
|
|
// STOP is set by stop().
|
|
enum EngineParameters {
|
|
SAMPLE_RATE,
|
|
START,
|
|
STOP,
|
|
OFFSET,
|
|
DURATION,
|
|
LOOP,
|
|
LOOPSTART,
|
|
LOOPEND,
|
|
PLAYBACKRATE,
|
|
GAIN,
|
|
DOPPLERSHIFT
|
|
};
|
|
|
|
void SendLoopParametersToStream();
|
|
void SendBufferParameterToStream(JSContext* aCx);
|
|
void SendOffsetAndDurationParametersToStream(AudioNodeStream* aStream,
|
|
double aOffset,
|
|
double aDuration);
|
|
static void SendPlaybackRateToStream(AudioNode* aNode);
|
|
static void SendGainToStream(AudioNode* aNode);
|
|
|
|
private:
|
|
double mLoopStart;
|
|
double mLoopEnd;
|
|
double mOffset;
|
|
double mDuration;
|
|
nsRefPtr<AudioBuffer> mBuffer;
|
|
nsRefPtr<AudioParam> mPlaybackRate;
|
|
nsRefPtr<AudioParam> mGain;
|
|
SelfReference<AudioBufferSourceNode> mPlayingRef; // a reference to self while playing
|
|
bool mLoop;
|
|
bool mStartCalled;
|
|
bool mStopped;
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|