Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2010-02-08 17:43:44 +0300
committerJoerg Mueller <nexyon@gmail.com>2010-02-08 17:43:44 +0300
commit6c8e3e303d15b59df4c592244a7650021b4e8bbb (patch)
treedc4d0693751795b506b7c4b3fea39875628b8e76
parent03bdfb6f312a0259a4bf3e560bff12fb50975a55 (diff)
2.5 Audio:
- Python script to crossfade two sound strips in the sequencer - Fix for the libsamplerate code producing awful audio when resampling sequencer strips - Changed default resampler to a linear one (as temporary workaround for a bug that seems to be in the samplerate code) - Fix for the OpenAL device to return a more accurate playback position
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp13
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp8
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h5
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp13
-rw-r--r--intern/audaspace/intern/AUD_Mixer.cpp3
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h6
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp12
-rw-r--r--intern/audaspace/intern/AUD_Space.h2
-rw-r--r--release/scripts/op/sequencer.py76
9 files changed, 123 insertions, 15 deletions
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index 9e153b9b34f..7ee8652f226 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -890,11 +890,14 @@ float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
if(isValid(handle))
{
AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
- if(h->isBuffered)
- alGetSourcef(h->source, AL_SEC_OFFSET, &position);
- else
- position = h->reader->getPosition() /
- (float)h->reader->getSpecs().rate;
+ alGetSourcef(h->source, AL_SEC_OFFSET, &position);
+ if(!h->isBuffered)
+ {
+ AUD_Specs specs = h->reader->getSpecs();
+ position += (h->reader->getPosition() - m_buffersize *
+ AUD_OPENAL_CYCLE_BUFFERS / specs.channels) /
+ (float)specs.rate;
+ }
}
unlock();
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
index 940f4245316..e89857635de 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
@@ -44,6 +44,7 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
m_tspecs = specs;
m_tspecs.channels = m_sspecs.channels;
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
+ m_position = 0;
int error;
m_src = src_callback_new(src_callback,
@@ -71,7 +72,7 @@ AUD_SRCResampleReader::~AUD_SRCResampleReader()
long AUD_SRCResampleReader::doCallback(float** data)
{
- int length = m_buffer->getSize() / 4 / m_tspecs.channels;
+ int length = m_buffer->getSize() / AUD_SAMPLE_SIZE(m_tspecs);
sample_t* buffer;
m_reader->read(length, buffer);
@@ -84,6 +85,7 @@ void AUD_SRCResampleReader::seek(int position)
{
m_reader->seek(position / m_factor);
src_reset(m_src);
+ m_position = position;
}
int AUD_SRCResampleReader::getLength()
@@ -93,7 +95,7 @@ int AUD_SRCResampleReader::getLength()
int AUD_SRCResampleReader::getPosition()
{
- return m_reader->getPosition() * m_factor;
+ return m_position;
}
AUD_Specs AUD_SRCResampleReader::getSpecs()
@@ -111,4 +113,6 @@ void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
buffer = m_buffer->getBuffer();
length = src_callback_read(m_src, m_factor, length, buffer);
+
+ m_position += length;
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
index 4fe30b48c6e..e09d1b66f13 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h
@@ -62,6 +62,11 @@ private:
*/
SRC_STATE* m_src;
+ /**
+ * The current playback position;
+ */
+ int m_position;
+
public:
/**
* Creates a resampling reader.
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index b363c4576b3..2e3ae4ef642 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -762,3 +762,16 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
return length;
}
+
+#ifdef AUD_DEBUG_MEMORY
+int AUD_References(int count, const char* text)
+{
+ static int m_count = 0;
+ m_count += count;
+ if(count > 0)
+ printf("+%s\n", text);
+ if(count < 0)
+ printf("-%s\n", text);
+ return m_count;
+}
+#endif
diff --git a/intern/audaspace/intern/AUD_Mixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp
index b2704602a89..e77d40fdbca 100644
--- a/intern/audaspace/intern/AUD_Mixer.cpp
+++ b/intern/audaspace/intern/AUD_Mixer.cpp
@@ -25,6 +25,7 @@
#include "AUD_Mixer.h"
#include "AUD_SRCResampleFactory.h"
+#include "AUD_LinearResampleFactory.h"
#include "AUD_ChannelMapperFactory.h"
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
@@ -86,7 +87,7 @@ void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
delete m_mapper; AUD_DELETE("factory")
}
- m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
+ m_resampler = new AUD_MIXER_RESAMPLER(specs); AUD_NEW("factory")
m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
int bigendian = 1;
diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h
index 5dcdef45eba..a24422a8a21 100644
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -26,9 +26,11 @@
#ifndef AUD_MIXER
#define AUD_MIXER
+#define AUD_MIXER_RESAMPLER AUD_LinearResampleFactory
+
#include "AUD_ConverterFunctions.h"
class AUD_ConverterFactory;
-class AUD_SRCResampleFactory;
+class AUD_MIXER_RESAMPLER;
class AUD_ChannelMapperFactory;
class AUD_Buffer;
class AUD_IReader;
@@ -54,7 +56,7 @@ private:
/**
* The resampling factory that resamples all readers for superposition.
*/
- AUD_SRCResampleFactory* m_resampler;
+ AUD_MIXER_RESAMPLER* m_resampler;
/**
* The channel mapper factory that maps all readers for superposition.
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
index 84c14762893..8869d8d54ca 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ b/intern/audaspace/intern/AUD_SequencerReader.cpp
@@ -100,13 +100,17 @@ void AUD_SequencerReader::add(AUD_SequencerEntry* entry)
{
AUD_SequencerStrip* strip = new AUD_SequencerStrip; AUD_NEW("seqstrip")
strip->entry = entry;
- strip->old_sound = NULL;
- if(strip->old_sound)
+ if(*strip->entry->sound)
+ {
+ strip->old_sound = *strip->entry->sound;
strip->reader = m_mixer.prepare(strip->old_sound->createReader());
+ }
else
+ {
strip->reader = NULL;
-
+ strip->old_sound = NULL;
+ }
m_strips.push_front(strip);
}
@@ -124,7 +128,7 @@ void AUD_SequencerReader::remove(AUD_SequencerEntry* entry)
delete strip->reader; AUD_DELETE("reader")
}
m_strips.remove(strip);
- delete strip;
+ delete strip; AUD_DELETE("seqstrip")
return;
}
}
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
index 9e192ac2cac..9e857ce73b0 100644
--- a/intern/audaspace/intern/AUD_Space.h
+++ b/intern/audaspace/intern/AUD_Space.h
@@ -97,7 +97,7 @@
//#define AUD_DEBUG_MEMORY
#ifdef AUD_DEBUG_MEMORY
-int AUD_References(int count = 0, const char* text = "");
+extern int AUD_References(int count, const char* text);
#define AUD_NEW(text) AUD_References(1, text);
#define AUD_DELETE(text) AUD_References(-1, text);
#else
diff --git a/release/scripts/op/sequencer.py b/release/scripts/op/sequencer.py
new file mode 100644
index 00000000000..e78084b3a7b
--- /dev/null
+++ b/release/scripts/op/sequencer.py
@@ -0,0 +1,76 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+
+class SequencerCrossfadeSounds(bpy.types.Operator):
+ '''Do crossfading volume animation of two selected sound strips.'''
+
+ bl_idname = "sequencer.crossfade_sounds"
+ bl_label = "Crossfade sounds"
+ bl_register = True
+ bl_undo = True
+
+ def poll(self, context):
+ if context.scene and context.scene.sequence_editor and context.scene.sequence_editor.active_strip:
+ return context.scene.sequence_editor.active_strip.type == 'SOUND'
+ else:
+ return False
+
+ def execute(self, context):
+ seq1 = None
+ seq2 = None
+ for s in context.scene.sequence_editor.sequences:
+ if s.selected and s.type == 'SOUND':
+ if seq1 == None:
+ seq1 = s
+ elif seq2 == None:
+ seq2 = s
+ else:
+ seq2 = None
+ break
+ if seq2 == None:
+ self.report({'ERROR'}, "Select 2 sound strips.")
+ return {'CANCELLED'}
+ if seq1.start_frame_final > seq2.start_frame_final:
+ s = seq1
+ seq1 = seq2
+ seq2 = s
+ if seq1.end_frame_final > seq2.start_frame_final:
+ tempcfra = context.scene.current_frame
+ context.scene.current_frame = seq2.start_frame_final
+ seq1.keyframe_insert('volume')
+ context.scene.current_frame = seq1.end_frame_final
+ seq1.volume = 0
+ seq1.keyframe_insert('volume')
+ seq2.keyframe_insert('volume')
+ context.scene.current_frame = seq2.start_frame_final
+ seq2.volume = 0
+ seq2.keyframe_insert('volume')
+ context.scene.current_frame = tempcfra
+ return {'FINISHED'}
+ else:
+ self.report({'ERROR'}, "The selected strips don't overlap.")
+ return {'CANCELLED'}
+
+bpy.types.register(SequencerCrossfadeSounds)
+
+if __name__ == "__main__":
+ bpy.ops.sequencer.crossfade_sounds()