From 42995d7bf396933ee60c5f89c354ea89cf13df0d Mon Sep 17 00:00:00 2001
From: tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>
Date: Tue, 5 Jan 2010 00:01:18 +0000
Subject: Copy of aRts for Trinity modifications

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/arts@1070145 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
---
 flow/stereovolumecontrol_impl.cc | 197 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 197 insertions(+)
 create mode 100644 flow/stereovolumecontrol_impl.cc

(limited to 'flow/stereovolumecontrol_impl.cc')

diff --git a/flow/stereovolumecontrol_impl.cc b/flow/stereovolumecontrol_impl.cc
new file mode 100644
index 0000000..ae90ae6
--- /dev/null
+++ b/flow/stereovolumecontrol_impl.cc
@@ -0,0 +1,197 @@
+    /*
+
+    Copyright (C) 2000 Stefan Westerfeld
+                       stefan@space.twc.de
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+  
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.
+
+    */
+
+#include <math.h>
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "flowsystem.h"
+#include <debug.h>
+
+#include <cstring>
+
+using namespace Arts;
+
+namespace Arts {
+
+class StereoVolumeControl_impl : virtual public StereoVolumeControl_skel,
+								 virtual public StdSynthModule
+{
+	float _scaleFactor;
+	float _currentVolumeLeft;
+	float _currentVolumeRight;
+	bool _virtualized;
+	bool _calcVolume;
+public:
+	StereoVolumeControl_impl() :_scaleFactor(1.0), _currentVolumeLeft(0.0),
+	                            _currentVolumeRight(0.0), _virtualized( false ),
+	                            _calcVolume( false )
+	{
+		virtualize();
+	}
+
+	/*attribute float scaleFactor;*/
+	void scaleFactor(float newFactor) {
+		if(_scaleFactor != newFactor)
+		{
+			_scaleFactor = newFactor;
+			scaleFactor_changed(newFactor);
+			if( _scaleFactor == 1.0 )
+			{
+				if( !_calcVolume && !_virtualized )
+					virtualize();
+			}
+			else if( _virtualized )
+				devirtualize();
+		}
+	}
+	float scaleFactor() { return _scaleFactor; }
+
+	/*
+	  readonly attribute float currentVolumeLeft;
+	  readonly attribute float currentVolumeRight;
+	*/
+	float currentVolumeLeft()
+	{
+		if( _virtualized && !_calcVolume )
+			needVolumeCalculation();
+
+		return _currentVolumeLeft;
+	}
+
+	float currentVolumeRight()
+	{
+		if( _virtualized && !_calcVolume )
+			needVolumeCalculation();
+
+		return _currentVolumeRight;
+	}
+
+	void needVolumeCalculation()
+	{
+		arts_debug( "calculate Volume in StereoVolumeControl" );
+		_calcVolume = true;
+		devirtualize();
+	}
+
+	void virtualize()
+	{
+		arts_debug( "virtualize StereoVolumeControl" );
+		_virtualized = true;
+		_node()->virtualize( "inleft", _node(), "outleft" );
+		_node()->virtualize( "inright", _node(), "outright" );
+		_currentVolumeRight = _currentVolumeLeft = 0.0;
+	}
+	void devirtualize()
+	{
+		arts_debug( "devirtualize StereoVolumeControl" );
+		_virtualized = false;
+		_node()->devirtualize( "inleft", _node(), "outleft" );
+		_node()->devirtualize( "inright", _node(), "outright" );
+	}
+	/*
+	  in audio stream inleft, inright;
+	  out audio stream outleft, outright;
+	*/
+	void calculateBlock(unsigned long samples)
+	{
+		if( _scaleFactor == 1.0 )
+		{
+			if( _calcVolume )
+			{
+				/*
+				 * make sure that we reach zero sometimes - otherwise there are
+				 * performance issues with calculations close to zero
+				 */
+				if(fabs(_currentVolumeLeft) < 0.001)	_currentVolumeLeft = 0.0;
+				if(fabs(_currentVolumeRight) < 0.001)	_currentVolumeRight = 0.0;
+
+				for( unsigned long i = 0; i < samples; i += 10 )
+				{
+					/* measure volume */
+					float delta;
+
+					// left
+					delta = fabs( outleft[ i ] ) - _currentVolumeLeft;
+					if( delta > 0.0 )
+						_currentVolumeLeft += 0.1 * delta;
+					else
+						_currentVolumeLeft += 0.003 * delta;
+
+					// right
+					delta = fabs( outright[ i ] ) - _currentVolumeRight;
+					if( delta > 0.0 )
+						_currentVolumeRight += 0.1 * delta;
+					else
+						_currentVolumeRight += 0.003 * delta;
+				}
+				memcpy( outleft, inleft, samples * sizeof( float ) );
+				memcpy( outright, inright, samples * sizeof( float ) );
+			}
+			return;
+		}
+
+		unsigned long i;
+
+		/*
+		 * make sure that we reach zero sometimes - otherwise there are
+		 * performance issues with calculations close to zero
+		 */
+		if(fabs(_currentVolumeLeft) < 0.001)	_currentVolumeLeft = 0.0;
+		if(fabs(_currentVolumeRight) < 0.001)	_currentVolumeRight = 0.0;
+
+		for(i=0;i<samples;i++)
+		{
+			/* scale */
+			outleft[i] = inleft[i] * _scaleFactor;
+			outright[i] = inright[i] * _scaleFactor;
+
+			/* measure volume */
+			float delta;
+
+			// left
+			delta = fabs(outleft[i])-_currentVolumeLeft;
+			if(delta > 0.0)
+				_currentVolumeLeft += 0.01 * delta;
+			else
+				_currentVolumeLeft += 0.0003 * delta;
+
+			// right
+			delta = fabs(outright[i])-_currentVolumeRight;
+			if(delta > 0.0)
+				_currentVolumeRight += 0.01 * delta;
+			else
+				_currentVolumeRight += 0.0003 * delta;
+		}
+	}
+
+	AutoSuspendState autoSuspend() {
+		return (_currentVolumeLeft+_currentVolumeRight<0.001)? 
+			asSuspend : asNoSuspend;
+	}
+
+};
+
+REGISTER_IMPLEMENTATION(StereoVolumeControl_impl);
+
+}
+
+// vim: sw=4 ts=4 noet
-- 
cgit v1.2.1