Commit: d5ee031f76137339e3af0fdadb706fbb8db4c961
Author: Jörg Müller
Date:   Sat Oct 22 13:38:41 2016 +0200
Branches: master
https://developer.blender.org/rBd5ee031f76137339e3af0fdadb706fbb8db4c961

Fix T49764: Audio strips crackle when animating the volume

- Implemented linear interpolation for volume changes in the software
mixer.
- Using this in the software device.

===================================================================

M       intern/audaspace/intern/AUD_Mixer.cpp
M       intern/audaspace/intern/AUD_Mixer.h
M       intern/audaspace/intern/AUD_SoftwareDevice.cpp
M       intern/audaspace/intern/AUD_SoftwareDevice.h

===================================================================

diff --git a/intern/audaspace/intern/AUD_Mixer.cpp 
b/intern/audaspace/intern/AUD_Mixer.cpp
index 380affa..78dfadd 100644
--- a/intern/audaspace/intern/AUD_Mixer.cpp
+++ b/intern/audaspace/intern/AUD_Mixer.cpp
@@ -95,6 +95,21 @@ void AUD_Mixer::mix(sample_t* buffer, int start, int length, 
float volume)
                out[i + start] += buffer[i] * volume;
 }
 
+void AUD_Mixer::mix(sample_t* buffer, int start, int length, float volume_to, 
float volume_from)
+{
+       sample_t* out = m_buffer.getBuffer();
+
+       length = (std::min(m_length, length + start) - start);
+
+       for(int i = 0; i < length; i++)
+       {
+               float volume = volume_from * (1.0f - i / float(length)) + 
volume_to * (i / float(length));
+
+               for(int c = 0; c < m_specs.channels; c++)
+                       out[(i + start) * m_specs.channels + c] += buffer[i * 
m_specs.channels + c] * volume;
+       }
+}
+
 void AUD_Mixer::read(data_t* buffer, float volume)
 {
        sample_t* out = m_buffer.getBuffer();
diff --git a/intern/audaspace/intern/AUD_Mixer.h 
b/intern/audaspace/intern/AUD_Mixer.h
index 3dd03b0..0735fee 100644
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -95,6 +95,8 @@ public:
         */
        void mix(sample_t* buffer, int start, int length, float volume);
 
+       void mix(sample_t* buffer, int start, int length, float volume_to, 
float volume_from);
+
        /**
         * Writes the mixing buffer into an output buffer.
         * \param buffer The target buffer for superposing.
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp 
b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index c4277a6..15594d3 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -89,7 +89,7 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause(bool keep)
 }
 
 AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* 
device, boost::shared_ptr<AUD_IReader> reader, 
boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> 
resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
-       m_reader(reader), m_pitch(pitch), m_resampler(resampler), 
m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), 
m_user_pan(0.0f), m_volume(1.0f), m_loopcount(0),
+       m_reader(reader), m_pitch(pitch), m_resampler(resampler), 
m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), 
m_user_pan(0.0f), m_volume(1.0f), m_old_volume(1.0f), m_loopcount(0),
        m_relative(true), m_volume_max(1.0f), m_volume_min(0), 
m_distance_max(std::numeric_limits<float>::max()),
        m_distance_reference(1.0f), m_attenuation(1.0f), 
m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
        m_flags(AUD_RENDER_CONE), m_stop(NULL), m_stop_data(NULL), 
m_status(AUD_STATUS_PLAYING), m_device(device)
@@ -100,6 +100,8 @@ void AUD_SoftwareDevice::AUD_SoftwareHandle::update()
 {
        int flags = 0;
 
+       m_old_volume = m_volume;
+
        AUD_Vector3 SL;
        if(m_relative)
                SL = -m_location;
@@ -404,7 +406,7 @@ bool 
AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume)
 
        if(volume == 0)
        {
-               m_volume = volume;
+               m_old_volume = m_volume = volume;
                m_flags |= AUD_RENDER_VOLUME;
        }
        else
@@ -772,7 +774,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
                        // in case of looping
                        while(pos + len < length && sound->m_loopcount && eos)
                        {
-                               m_mixer->mix(buf, pos, len, sound->m_volume);
+                               m_mixer->mix(buf, pos, len, sound->m_volume, 
sound->m_old_volume);
 
                                pos += len;
 
@@ -789,7 +791,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
                                        break;
                        }
 
-                       m_mixer->mix(buf, pos, len, sound->m_volume);
+                       m_mixer->mix(buf, pos, len, sound->m_volume, 
sound->m_old_volume);
 
                        // in case the end of the sound is reached
                        if(eos && !sound->m_loopcount)
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h 
b/intern/audaspace/intern/AUD_SoftwareDevice.h
index 3c8c1e4..54e49c8 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -84,6 +84,7 @@ protected:
 
                /// The calculated final volume of the source.
                float m_volume;
+               float m_old_volume;
 
                /// The loop count of the source.
                int m_loopcount;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to