[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37713] branches/soc-2011-pepper: 3D Audio GSoC:

Joerg Mueller nexyon at gmail.com
Tue Jun 21 22:25:49 CEST 2011


Revision: 37713
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37713
Author:   nexyon
Date:     2011-06-21 20:25:48 +0000 (Tue, 21 Jun 2011)
Log Message:
-----------
3D Audio GSoC:
Dynamic resampling for libsamplerate and linear resampling.

Modified Paths:
--------------
    branches/soc-2011-pepper/CMakeLists.txt
    branches/soc-2011-pepper/intern/audaspace/FX/AUD_ReverseReader.cpp
    branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
    branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
    branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.h
    branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
    branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleReader.cpp
    branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleReader.h

Modified: branches/soc-2011-pepper/CMakeLists.txt
===================================================================
--- branches/soc-2011-pepper/CMakeLists.txt	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/CMakeLists.txt	2011-06-21 20:25:48 UTC (rev 37713)
@@ -200,10 +200,6 @@
 	message(FATAL_ERROR "WITH_PLAYER requires WITH_GAMEENGINE")
 endif()
 
-if(NOT WITH_SAMPLERATE AND (WITH_OPENAL OR WITH_SDL OR WITH_JACK))
-	message(FATAL_ERROR "WITH_OPENAL/WITH_SDL/WITH_JACK require WITH_SAMPLERATE")
-endif()
-
 if(NOT WITH_IMAGE_OPENJPEG AND WITH_IMAGE_REDCODE)
 	message(FATAL_ERROR "WITH_IMAGE_REDCODE requires WITH_IMAGE_OPENJPEG")
 endif()

Modified: branches/soc-2011-pepper/intern/audaspace/FX/AUD_ReverseReader.cpp
===================================================================
--- branches/soc-2011-pepper/intern/audaspace/FX/AUD_ReverseReader.cpp	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/intern/audaspace/FX/AUD_ReverseReader.cpp	2011-06-21 20:25:48 UTC (rev 37713)
@@ -76,7 +76,7 @@
 	const AUD_Specs specs = getSpecs();
 	const int samplesize = AUD_SAMPLE_SIZE(specs);
 
-	sample_t temp[10];
+	sample_t temp[AUD_CHANNEL_MAX];
 
 	int len = length;
 

Modified: branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
===================================================================
--- branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp	2011-06-21 20:25:48 UTC (rev 37713)
@@ -40,10 +40,5 @@
 
 AUD_Reference<AUD_IReader> AUD_SRCResampleFactory::createReader()
 {
-	AUD_Reference<AUD_IReader> reader = getReader();
-
-	if(reader->getSpecs().rate != m_specs.rate)
-		reader = new AUD_SRCResampleReader(reader, m_specs.specs);
-
-	return reader;
+	return new AUD_SRCResampleReader(getReader(), m_specs.specs);
 }

Modified: branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
===================================================================
--- branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.cpp	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.cpp	2011-06-21 20:25:48 UTC (rev 37713)
@@ -46,17 +46,14 @@
 AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
 											 AUD_Specs specs) :
 		AUD_EffectReader(reader),
-		m_sspecs(reader->getSpecs()),
-		m_factor(double(specs.rate) / double(m_sspecs.rate)),
-		m_tspecs(specs),
+		m_rate(specs.rate),
+		m_channels(reader->getSpecs().channels),
 		m_position(0)
 {
-	m_tspecs.channels = m_sspecs.channels;
-
 	int error;
 	m_src = src_callback_new(src_callback,
 							 SRC_SINC_MEDIUM_QUALITY,
-							 m_sspecs.channels,
+							 m_channels,
 							 &error,
 							 this);
 
@@ -74,8 +71,12 @@
 
 long AUD_SRCResampleReader::doCallback(float** data)
 {
-	int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(m_tspecs);
+	AUD_Specs specs;
+	specs.channels = m_channels;
+	specs.rate = m_rate;
 
+	int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(specs);
+
 	*data = m_buffer.getBuffer();
 	m_reader->read(length, m_eos, *data);
 
@@ -84,14 +85,18 @@
 
 void AUD_SRCResampleReader::seek(int position)
 {
-	m_reader->seek(position / m_factor);
+	AUD_Specs specs = m_reader->getSpecs();
+	double factor = double(m_rate) / double(specs.rate);
+	m_reader->seek(position / factor);
 	src_reset(m_src);
 	m_position = position;
 }
 
 int AUD_SRCResampleReader::getLength() const
 {
-	return m_reader->getLength() * m_factor;
+	AUD_Specs specs = m_reader->getSpecs();
+	double factor = double(m_rate) / double(specs.rate);
+	return m_reader->getLength() * factor;
 }
 
 int AUD_SRCResampleReader::getPosition() const
@@ -101,18 +106,46 @@
 
 AUD_Specs AUD_SRCResampleReader::getSpecs() const
 {
-	return m_tspecs;
+	AUD_Specs specs = m_reader->getSpecs();
+	specs.rate = m_rate;
+	return specs;
 }
 
 void AUD_SRCResampleReader::read(int& length, bool& eos, sample_t* buffer)
 {
+	AUD_Specs specs = m_reader->getSpecs();
+
+	double factor = double(m_rate) / double(specs.rate);
+
+	specs.rate = m_rate;
+
 	int size = length;
 
-	m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_tspecs));
+	m_buffer.assureSize(length * AUD_SAMPLE_SIZE(specs));
 
+	if(specs.channels != m_channels)
+	{
+		src_delete(m_src);
+
+		m_channels = specs.channels;
+
+		int error;
+		m_src = src_callback_new(src_callback,
+								 SRC_SINC_MEDIUM_QUALITY,
+								 m_channels,
+								 &error,
+								 this);
+
+		if(!m_src)
+		{
+			// XXX printf("%s\n", src_strerror(error));
+			AUD_THROW(AUD_ERROR_SRC, state_error);
+		}
+	}
+
 	m_eos = false;
 
-	length = src_callback_read(m_src, m_factor, length, buffer);
+	length = src_callback_read(m_src, factor, length, buffer);
 
 	m_position += length;
 

Modified: branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.h
===================================================================
--- branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.h	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/intern/audaspace/SRC/AUD_SRCResampleReader.h	2011-06-21 20:25:48 UTC (rev 37713)
@@ -44,26 +44,21 @@
 {
 private:
 	/**
-	 * The sample specification of the source.
+	 * The sound output buffer.
 	 */
-	const AUD_Specs m_sspecs;
+	AUD_Buffer m_buffer;
 
 	/**
-	 * The resampling factor.
+	 * The target sampling rate.
 	 */
-	const double m_factor;
+	AUD_SampleRate m_rate;
 
 	/**
-	 * The sound output buffer.
+	 * The reader channels.
 	 */
-	AUD_Buffer m_buffer;
+	AUD_Channels m_channels;
 
 	/**
-	 * The target specification.
-	 */
-	AUD_Specs m_tspecs;
-
-	/**
 	 * The src state structure.
 	 */
 	SRC_STATE* m_src;

Modified: branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
===================================================================
--- branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleFactory.cpp	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleFactory.cpp	2011-06-21 20:25:48 UTC (rev 37713)
@@ -40,10 +40,5 @@
 
 AUD_Reference<AUD_IReader> AUD_LinearResampleFactory::createReader()
 {
-	AUD_Reference<AUD_IReader> reader = getReader();
-
-	if(reader->getSpecs().rate != m_specs.rate)
-		reader = new AUD_LinearResampleReader(reader, m_specs.specs);
-
-	return reader;
+	return new AUD_LinearResampleReader(getReader(), m_specs.specs);
 }

Modified: branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleReader.cpp
===================================================================
--- branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleReader.cpp	2011-06-21 20:24:40 UTC (rev 37712)
+++ branches/soc-2011-pepper/intern/audaspace/intern/AUD_LinearResampleReader.cpp	2011-06-21 20:25:48 UTC (rev 37713)
@@ -34,94 +34,140 @@
 #include <cmath>
 #include <cstring>
 
-#define CC channels + channel
+#define CC m_channels + channel
 
 AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader,
 												   AUD_Specs specs) :
 	AUD_EffectReader(reader),
-	m_sspecs(reader->getSpecs()),
-	m_factor(float(specs.rate) / float(m_sspecs.rate)),
-	m_tspecs(specs),
+	m_rate(specs.rate),
+	m_channels(reader->getSpecs().channels),
 	m_position(0),
-	m_sposition(0)
+	m_cache_pos(0),
+	m_cache_ok(false)
 {
-	m_tspecs.channels = m_sspecs.channels;
-	m_cache.resize(2 * AUD_SAMPLE_SIZE(m_tspecs));
+	specs.channels = m_channels;
+	m_cache.resize(2 * AUD_SAMPLE_SIZE(specs));
 }
 
 void AUD_LinearResampleReader::seek(int position)
 {
-	m_position = position;
-	m_sposition = floor(position / m_factor);
-	m_reader->seek(m_sposition);
+	position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
+	m_reader->seek(position);
+	m_cache_ok = false;
+	m_cache_pos = 0;
 }
 
 int AUD_LinearResampleReader::getLength() const
 {
-	return m_reader->getLength() * m_factor;
+	return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
 }
 
 int AUD_LinearResampleReader::getPosition() const
 {
-	return m_position;
+	return floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 2 : 0))
+				 * m_rate / m_reader->getSpecs().rate);
 }
 
 AUD_Specs AUD_LinearResampleReader::getSpecs() const
 {
-	return m_tspecs;
+	AUD_Specs specs = m_reader->getSpecs();
+	specs.rate = m_rate;
+	return specs;
 }
 
 void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer)
 {
-	int samplesize = AUD_SAMPLE_SIZE(m_tspecs);
+	AUD_Specs specs = m_reader->getSpecs();
+
+	int samplesize = AUD_SAMPLE_SIZE(specs);
 	int size = length;
+	float factor = float(m_rate) / float(m_reader->getSpecs().rate);
+	float spos;
+	sample_t low, high;
+	eos = false;
 
-	m_buffer.assureSize(size * AUD_SAMPLE_SIZE(m_sspecs));
+	if(factor == 1 && (!m_cache_ok || m_cache_pos == 0))
+	{
+		// can read directly!
+		m_reader->read(length, eos, buffer);
+		return;
+	}
 
-	int need = ceil((m_position + length) / m_factor) + 1 - m_sposition;
-	int len = need;
-	sample_t* buf = m_buffer.getBuffer();
+	// check for channels changed
 
-	m_reader->read(len, eos, buf);
+	if(specs.channels != m_channels)
+	{
+		m_cache.resize(2 * samplesize);
+		m_channels = specs.channels;
+		m_cache_ok = false;
+	}
 
-	if(len < need)
-		length = floor((m_sposition + len - 1) * m_factor) - m_position;
+	int len;
+	sample_t* buf;
 
-	float spos;
-	sample_t low, high;
-	int channels = m_sspecs.channels;
+	if(m_cache_ok)
+	{
+		int need = ceil(length / factor - (1 - m_cache_pos));
 
-	for(int channel = 0; channel < channels; channel++)
+		len = need;
+
+		m_buffer.assureSize((len + 3) * samplesize);
+		buf = m_buffer.getBuffer();
+
+		memcpy(buf, m_cache.getBuffer(), 2 * samplesize);
+		m_reader->read(len, eos, buf + 2 * m_channels);
+
+		if(len < need)
+			length = floor((len + (1 - m_cache_pos)) * factor);
+	}
+	else
 	{
-		for(int i = 0; i < length; i++)
+		int need = ceil(length / factor) + 1;
+
+		len = need;
+
+		m_buffer.assureSize((len + 1) * samplesize);
+		buf = m_buffer.getBuffer();
+
+		m_reader->read(len, eos, buf);
+
+		if(len < need)
 		{
-			spos = (m_position + i) / m_factor - m_sposition;
-
-			if(floor(spos) < 0)
+			if(eos)
 			{
-				low = m_cache.getBuffer()[(int)(floor(spos) + 2) * CC];
-				if(ceil(spos) < 0)
-					high = m_cache.getBuffer()[(int)(ceil(spos) + 2) * CC];
-				else
-					high = buf[(int)ceil(spos) * CC];
+				length = floor(len * factor);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list