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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to