summaryrefslogtreecommitdiff
path: root/src/player/SoundNode.cpp
diff options
context:
space:
mode:
authorDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 16:10:52 +0000
committerDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 19:15:57 +0000
commitd20f4a64eba38690337ac914a04a113de7caf125 (patch)
tree6828990e93ca5d8847b8cde2f2febb6566b0d53f /src/player/SoundNode.cpp
parent28161e9209f21be1a600f637565ecede94855a36 (diff)
New upstream release. Closes: #721047debian/1.8.0-1
Drop all patches, none are needed with this new upstream release. Port to dh. Specify foreign in configure.ac.
Diffstat (limited to 'src/player/SoundNode.cpp')
-rw-r--r--src/player/SoundNode.cpp113
1 files changed, 67 insertions, 46 deletions
diff --git a/src/player/SoundNode.cpp b/src/player/SoundNode.cpp
index 9d31597..3bb089c 100644
--- a/src/player/SoundNode.cpp
+++ b/src/player/SoundNode.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,18 +20,18 @@
//
#include "SoundNode.h"
#include "Player.h"
-#include "NodeDefinition.h"
+#include "TypeDefinition.h"
#include "Canvas.h"
#include "../base/Exception.h"
#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"
+#include "../base/ObjectCounter.h"
-#include "../audio/SDLAudioEngine.h"
+#include "../audio/AudioEngine.h"
#include "../video/AsyncVideoDecoder.h"
-#include "../video/FFMpegDecoder.h"
#include <iostream>
#include <sstream>
@@ -40,33 +40,35 @@
#include <unistd.h>
#endif
-using namespace boost::python;
+using namespace boost;
using namespace std;
namespace avg {
-NodeDefinition SoundNode::createDefinition()
+void SoundNode::registerType()
{
- return NodeDefinition("sound", Node::buildNode<SoundNode>)
- .extendDefinition(AreaNode::createDefinition())
+ TypeDefinition def = TypeDefinition("sound", "areanode",
+ ExportedObject::buildObject<SoundNode>)
.addArg(Arg<UTF8String>("href", "", false, offsetof(SoundNode, m_href)))
.addArg(Arg<bool>("loop", false, false, offsetof(SoundNode, m_bLoop)))
- .addArg(Arg<double>("volume", 1.0, false, offsetof(SoundNode, m_Volume)))
+ .addArg(Arg<float>("volume", 1.0, false, offsetof(SoundNode, m_Volume)))
;
+ TypeRegistry::get()->registerType(def);
}
SoundNode::SoundNode(const ArgList& args)
: m_Filename(""),
m_pEOFCallback(0),
+ m_SeekBeforeCanRenderTime(0),
m_pDecoder(0),
m_Volume(1.0),
- m_State(Unloaded)
+ m_State(Unloaded),
+ m_AudioID(-1)
{
args.setMembers(this);
m_Filename = m_href;
initFilename(m_Filename);
- VideoDecoderPtr pSyncDecoder(new FFMpegDecoder());
- m_pDecoder = new AsyncVideoDecoder(pSyncDecoder, 8);
+ m_pDecoder = new AsyncVideoDecoder(8);
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -110,7 +112,7 @@ int SoundNode::getNumAudioChannels() const
long long SoundNode::getCurTime() const
{
exceptionIfUnloaded("getCurTime");
- return (long long)(m_pDecoder->getCurTime(SS_AUDIO)*1000);
+ return (long long)(m_pDecoder->getCurTime()*1000);
}
void SoundNode::seekToTime(long long Time)
@@ -129,13 +131,19 @@ void SoundNode::setEOFCallback(PyObject * pEOFCallback)
if (m_pEOFCallback) {
Py_DECREF(m_pEOFCallback);
}
- Py_INCREF(pEOFCallback);
- m_pEOFCallback = pEOFCallback;
+ if (pEOFCallback == Py_None) {
+ m_pEOFCallback = 0;
+ } else {
+ avgDeprecationWarning("1.8", "SoundNode.setEOFCallback()",
+ "Node.subscribe(END_OF_FILE)");
+ Py_INCREF(pEOFCallback);
+ m_pEOFCallback = pEOFCallback;
+ }
}
void SoundNode::connectDisplay()
{
- if (!SDLAudioEngine::get()) {
+ if (!AudioEngine::get()) {
throw Exception(AVG_ERR_UNSUPPORTED,
"Sound nodes can only be created if audio is not disabled.");
}
@@ -154,6 +162,7 @@ void SoundNode::connectDisplay()
void SoundNode::connect(CanvasPtr pCanvas)
{
+ checkReload();
AreaNode::connect(pCanvas);
pCanvas->registerFrameEndListener(this);
}
@@ -194,19 +203,19 @@ void SoundNode::setHRef(const UTF8String& href)
checkReload();
}
-double SoundNode::getVolume()
+float SoundNode::getVolume()
{
return m_Volume;
}
-void SoundNode::setVolume(double volume)
+void SoundNode::setVolume(float volume)
{
if (volume < 0) {
volume = 0;
}
m_Volume = volume;
- if (m_pDecoder) {
- m_pDecoder->setVolume(volume);
+ if (m_AudioID != -1) {
+ AudioEngine::get()->setSourceVolume(m_AudioID, volume);
}
}
@@ -215,13 +224,12 @@ void SoundNode::checkReload()
string fileName (m_href);
if (m_href != "") {
initFilename(fileName);
- if (fileName != m_Filename) {
- SoundState oldState = m_State;
+ if (fileName != m_Filename && m_State != Unloaded) {
changeSoundState(Unloaded);
m_Filename = fileName;
- if (oldState != Unloaded) {
- changeSoundState(Paused);
- }
+ changeSoundState(Paused);
+ } else {
+ m_Filename = fileName;
}
} else {
changeSoundState(Unloaded);
@@ -231,17 +239,12 @@ void SoundNode::checkReload()
void SoundNode::onFrameEnd()
{
- if (m_State == Playing && m_pDecoder->isEOF(SS_AUDIO)) {
- onEOF();
- }
-}
-
-int SoundNode::fillAudioBuffer(AudioBufferPtr pBuffer)
-{
if (m_State == Playing) {
- return m_pDecoder->fillAudioBuffer(pBuffer);
- } else {
- return 0;
+ m_pDecoder->updateAudioStatus();
+ }
+ if (m_State == Playing && m_pDecoder->isEOF()) {
+ NodePtr pTempThis = getSharedThis();
+ onEOF();
}
}
@@ -265,8 +268,10 @@ void SoundNode::changeSoundState(SoundState newSoundState)
}
if (newSoundState == Paused) {
m_PauseStartTime = curTime;
+ AudioEngine::get()->pauseSource(m_AudioID);
} else if (newSoundState == Playing && m_State == Paused) {
m_PauseTime += curTime-m_PauseStartTime;
+ AudioEngine::get()->playSource(m_AudioID);
}
}
m_State = newSoundState;
@@ -274,16 +279,22 @@ void SoundNode::changeSoundState(SoundState newSoundState)
void SoundNode::seek(long long destTime)
{
- m_pDecoder->seek(double(destTime)/1000);
- m_StartTime = Player::get()->getFrameTime() - destTime;
- m_PauseTime = 0;
- m_PauseStartTime = Player::get()->getFrameTime();
+ if (getState() == NS_CANRENDER) {
+ AudioEngine::get()->notifySeek(m_AudioID);
+ m_pDecoder->seek(float(destTime)/1000);
+ m_StartTime = Player::get()->getFrameTime() - destTime;
+ m_PauseTime = 0;
+ m_PauseStartTime = Player::get()->getFrameTime();
+ } else {
+ // If we get a seek command before decoding has really started, we need to defer
+ // the actual seek until the decoder is ready.
+ m_SeekBeforeCanRenderTime = destTime;
+ }
}
void SoundNode::open()
{
- m_pDecoder->setVolume(m_Volume);
- m_pDecoder->open(m_Filename, true);
+ m_pDecoder->open(m_Filename, false, true);
VideoInfo videoInfo = m_pDecoder->getVideoInfo();
if (!videoInfo.m_bHasAudio) {
throw Exception(AVG_ERR_VIDEO_GENERAL,
@@ -294,14 +305,23 @@ void SoundNode::open()
void SoundNode::startDecoding()
{
- SDLAudioEngine* pEngine = SDLAudioEngine::get();
+ AudioEngine* pEngine = AudioEngine::get();
m_pDecoder->startDecoding(false, pEngine->getParams());
- pEngine->addSource(this);
+ m_AudioID = pEngine->addSource(*m_pDecoder->getAudioMsgQ(),
+ *m_pDecoder->getAudioStatusQ());
+ pEngine->setSourceVolume(m_AudioID, m_Volume);
+ if (m_SeekBeforeCanRenderTime != 0) {
+ seek(m_SeekBeforeCanRenderTime);
+ m_SeekBeforeCanRenderTime = 0;
+ }
}
void SoundNode::close()
{
- SDLAudioEngine::get()->removeSource(this);
+ if (m_AudioID != -1) {
+ AudioEngine::get()->removeSource(m_AudioID);
+ m_AudioID = -1;
+ }
m_pDecoder->close();
}
@@ -309,7 +329,7 @@ void SoundNode::exceptionIfUnloaded(const std::string& sFuncName) const
{
if (m_State == Unloaded) {
throw Exception(AVG_ERR_VIDEO_GENERAL,
- string("SoundNode.")+sFuncName+" failed: video not loaded.");
+ string("SoundNode.")+sFuncName+" failed: sound not loaded.");
}
}
@@ -324,10 +344,11 @@ void SoundNode::onEOF()
PyObject * result = PyEval_CallObject(m_pEOFCallback, arglist);
Py_DECREF(arglist);
if (!result) {
- throw error_already_set();
+ throw py::error_already_set();
}
Py_DECREF(result);
}
+ notifySubscribers("END_OF_FILE");
}
}