[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46035] trunk/blender: Audio:

Joerg Mueller nexyon at gmail.com
Sat Apr 28 15:16:31 CEST 2012


Revision: 46035
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46035
Author:   nexyon
Date:     2012-04-28 13:16:29 +0000 (Sat, 28 Apr 2012)
Log Message:
-----------
Audio:

* Fix for [#31099] Audio in Meta-Strips Plays Beyond Strip Cut
* Adding a split files option to the mixdown operator which then renders each channel into a separate file

Modified Paths:
--------------
    trunk/blender/intern/audaspace/intern/AUD_C-API.cpp
    trunk/blender/intern/audaspace/intern/AUD_C-API.h
    trunk/blender/intern/audaspace/intern/AUD_FileWriter.cpp
    trunk/blender/intern/audaspace/intern/AUD_FileWriter.h
    trunk/blender/source/blender/blenkernel/intern/sequencer.c
    trunk/blender/source/blender/editors/sound/sound_ops.c

Modified: trunk/blender/intern/audaspace/intern/AUD_C-API.cpp
===================================================================
--- trunk/blender/intern/audaspace/intern/AUD_C-API.cpp	2012-04-28 12:23:05 UTC (rev 46034)
+++ trunk/blender/intern/audaspace/intern/AUD_C-API.cpp	2012-04-28 13:16:29 UTC (rev 46035)
@@ -41,6 +41,7 @@
 #include <cstdlib>
 #include <cstring>
 #include <cmath>
+#include <sstream>
 
 #include "AUD_NULLDevice.h"
 #include "AUD_I3DDevice.h"
@@ -1236,6 +1237,47 @@
 	}
 }
 
+const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
+{
+	try
+	{
+		AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get());
+
+		f->setSpecs(specs.specs);
+
+		std::vector<AUD_Reference<AUD_IWriter> > writers;
+
+		int channels = specs.channels;
+		specs.channels = AUD_CHANNELS_MONO;
+
+		for(int i = 0; i < channels; i++)
+		{
+			std::stringstream stream;
+			std::string fn = filename;
+			size_t index = fn.find_last_of('.');
+			size_t index_slash = fn.find_last_of('/');
+			size_t index_backslash = fn.find_last_of('\\');
+			if((index == std::string::npos) ||
+					((index < index_slash) && (index_slash != std::string::npos)) ||
+					((index < index_backslash) && (index_backslash != std::string::npos)))
+				stream << filename << "_" << (i + 1);
+			else
+				stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
+			writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
+		}
+
+		AUD_Reference<AUD_IReader> reader = f->createQualityReader();
+		reader->seek(start);
+		AUD_FileWriter::writeReader(reader, writers, length, buffersize);
+
+		return NULL;
+	}
+	catch(AUD_Exception& e)
+	{
+		return e.str;
+	}
+}
+
 AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
 {
 	try

Modified: trunk/blender/intern/audaspace/intern/AUD_C-API.h
===================================================================
--- trunk/blender/intern/audaspace/intern/AUD_C-API.h	2012-04-28 12:23:05 UTC (rev 46034)
+++ trunk/blender/intern/audaspace/intern/AUD_C-API.h	2012-04-28 13:16:29 UTC (rev 46035)
@@ -710,6 +710,21 @@
 extern const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
 
 /**
+ * Mixes a sound down into multiple files.
+ * \param sound The sound scene to mix down.
+ * \param start The start frame.
+ * \param length The count of frames to write.
+ * \param buffersize How many samples should be written at once.
+ * \param filename The file to write to, the channel number and an underscore are added at the beginning.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return An error message or NULL in case of success.
+ */
+extern const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
+
+/**
  * Opens a read device and prepares it for mixdown of the sound scene.
  * \param specs Output audio specifications.
  * \param sequencer The sound scene to mix down.

Modified: trunk/blender/intern/audaspace/intern/AUD_FileWriter.cpp
===================================================================
--- trunk/blender/intern/audaspace/intern/AUD_FileWriter.cpp	2012-04-28 12:23:05 UTC (rev 46034)
+++ trunk/blender/intern/audaspace/intern/AUD_FileWriter.cpp	2012-04-28 13:16:29 UTC (rev 46035)
@@ -93,3 +93,39 @@
 		writer->write(len, buf);
 	}
 }
+
+void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize)
+{
+	AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
+	AUD_Buffer buffer2(buffersize * sizeof(sample_t));
+	sample_t* buf = buffer.getBuffer();
+	sample_t* buf2 = buffer2.getBuffer();
+
+	int len;
+	bool eos = false;
+	int channels = reader->getSpecs().channels;
+
+	for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
+	{
+		len = buffersize;
+		if((len > length - pos) && (length > 0))
+			len = length - pos;
+		reader->read(len, eos, buf);
+
+		for(int channel = 0; channel < channels; channel++)
+		{
+			for(int i = 0; i < len; i++)
+			{
+				// clamping!
+				if(buf[i * channels + channel] > 1)
+					buf2[i] = 1;
+				else if(buf[i * channels + channel] < -1)
+					buf2[i] = -1;
+				else
+					buf2[i] = buf[i * channels + channel];
+			}
+
+			writers[channel]->write(len, buf2);
+		}
+	}
+}

Modified: trunk/blender/intern/audaspace/intern/AUD_FileWriter.h
===================================================================
--- trunk/blender/intern/audaspace/intern/AUD_FileWriter.h	2012-04-28 12:23:05 UTC (rev 46034)
+++ trunk/blender/intern/audaspace/intern/AUD_FileWriter.h	2012-04-28 13:16:29 UTC (rev 46035)
@@ -31,6 +31,7 @@
 #define __AUD_FILEWRITER_H__
 
 #include <string>
+#include <vector>
 
 #include "AUD_Reference.h"
 
@@ -68,6 +69,15 @@
 	 * \param buffersize How many samples should be transfered at once.
 	 */
 	static void writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
+
+	/**
+	 * Writes a reader to several writers.
+	 * \param reader The reader to read from.
+	 * \param writers The writers to write to.
+	 * \param length How many samples should be transfered.
+	 * \param buffersize How many samples should be transfered at once.
+	 */
+	static void writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
 };
 
 #endif //__AUD_FILEWRITER_H__

Modified: trunk/blender/source/blender/blenkernel/intern/sequencer.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/sequencer.c	2012-04-28 12:23:05 UTC (rev 46034)
+++ trunk/blender/source/blender/blenkernel/intern/sequencer.c	2012-04-28 13:16:29 UTC (rev 46035)
@@ -515,32 +515,46 @@
 	*seqar = tseqar;
 }
 
+static int metaseq_start(Sequence *metaseq)
+{
+	return metaseq->start + metaseq->startofs;
+}
 
-static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+static int metaseq_end(Sequence *metaseq)
 {
+	return metaseq->start + metaseq->len - metaseq->endofs;
+}
+
+static void seq_update_sound_bounds_recursive_rec(Scene *scene, Sequence *metaseq, int start, int end)
+{
 	Sequence *seq;
 
 	/* for sound we go over full meta tree to update bounds of the sound strips,
 	 * since sound is played outside of evaluating the imbufs, */
 	for (seq = metaseq->seqbase.first; seq; seq = seq->next) {
 		if (seq->type == SEQ_META) {
-			seq_update_sound_bounds_recursive(scene, seq);
+			seq_update_sound_bounds_recursive_rec(scene, seq, MAX2(start, metaseq_start(seq)), MIN2(end, metaseq_end(seq)));
 		}
 		else if (ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
 			if (seq->scene_sound) {
 				int startofs = seq->startofs;
 				int endofs = seq->endofs;
-				if (seq->startofs + seq->start < metaseq->start + metaseq->startofs)
-					startofs = metaseq->start + metaseq->startofs - seq->start;
+				if (seq->startofs + seq->start < start)
+					startofs = start - seq->start;
 
-				if (seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
-					endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
+				if (seq->start + seq->len - seq->endofs > end)
+					endofs = seq->start + seq->len - end;
 				sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start + seq->len - endofs, startofs);
 			}
 		}
 	}
 }
 
+static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+{
+	seq_update_sound_bounds_recursive_rec(scene, metaseq, metaseq_start(metaseq), metaseq_end(metaseq));
+}
+
 void calc_sequence_disp(Scene *scene, Sequence *seq)
 {
 	if (seq->startofs && seq->startstill) seq->startstill = 0;

Modified: trunk/blender/source/blender/editors/sound/sound_ops.c
===================================================================
--- trunk/blender/source/blender/editors/sound/sound_ops.c	2012-04-28 12:23:05 UTC (rev 46034)
+++ trunk/blender/source/blender/editors/sound/sound_ops.c	2012-04-28 13:16:29 UTC (rev 46035)
@@ -318,6 +318,7 @@
 	char filename[FILE_MAX];
 	Scene *scene;
 	Main *bmain;
+	int split;
 
 	int bitrate, accuracy;
 	AUD_DeviceSpecs specs;
@@ -333,6 +334,7 @@
 	specs.format = RNA_enum_get(op->ptr, "format");
 	container = RNA_enum_get(op->ptr, "container");
 	codec = RNA_enum_get(op->ptr, "codec");
+	split = RNA_boolean_get(op->ptr, "split_channels");
 	scene = CTX_data_scene(C);
 	bmain = CTX_data_main(C);
 	specs.channels = scene->r.ffcodecdata.audio_channels;
@@ -341,8 +343,12 @@
 	BLI_strncpy(filename, path, sizeof(filename));
 	BLI_path_abs(filename, bmain->name);
 
-	result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
-						 accuracy, filename, specs, container, codec, bitrate);
+	if(split)
+		result = AUD_mixdown_per_channel(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
+										 accuracy, filename, specs, container, codec, bitrate);
+	else
+		result = AUD_mixdown(scene->sound_scene, SFRA * specs.rate / FPS, (EFRA - SFRA) * specs.rate / FPS,
+							 accuracy, filename, specs, container, codec, bitrate);
 
 	if (result) {
 		BKE_report(op->reports, RPT_ERROR, result);
@@ -590,6 +596,7 @@
 	RNA_def_enum(ot->srna, "codec", codec_items, AUD_CODEC_FLAC, "Codec", "Audio Codec");
 	RNA_def_enum(ot->srna, "format", format_items, AUD_FORMAT_S16, "Format", "Sample format");
 	RNA_def_int(ot->srna, "bitrate", 192, 32, 512, "Bitrate", "Bitrate in kbit/s", 32, 512);
+	RNA_def_boolean(ot->srna, "split_channels", 0, "Split channels", "Each channel will be rendered into a mono file.");
 #endif // WITH_AUDASPACE
 }
 




More information about the Bf-blender-cvs mailing list