Here is a quick and dirty patch to add SOWT audio. It applies to git
as of 27 Jun 2010.
It adds sowt.c and sowt.h, slightly modified from twos.c and twos.h,
changes a few
other files to include the new codec, and changes all Makefiles I could find to
hopefully include these changes no matter how it is built. It could be
more efficient,
and maybe some of the Makefiles are actually overwritten, but it works for me.

Mark
Common subdirectories: my_cinelerra/quicktime/docs and my_cinelerra_sowt/quicktime/docs
Common subdirectories: my_cinelerra/quicktime/encore50 and my_cinelerra_sowt/quicktime/encore50
Common subdirectories: my_cinelerra/quicktime/ffmpeg and my_cinelerra_sowt/quicktime/ffmpeg
diff -Nau my_cinelerra/quicktime/Makefile.2 my_cinelerra_sowt/quicktime/Makefile.2
--- my_cinelerra/quicktime/Makefile.2	2010-06-28 00:47:50.000000000 -0700
+++ my_cinelerra_sowt/quicktime/Makefile.2	2010-06-28 00:38:08.000000000 -0700
@@ -115,6 +115,7 @@
 	$(OBJDIR)/tkhd.o \
 	$(OBJDIR)/trak.o \
 	$(OBJDIR)/twos.o \
+	$(OBJDIR)/sowt.o \
 	$(OBJDIR)/udta.o \
 	$(OBJDIR)/ulaw.o \
 	$(OBJDIR)/util.o \
@@ -377,6 +378,7 @@
 $(OBJDIR)/tkhd.o:			  tkhd.c
 $(OBJDIR)/trak.o:			  trak.c
 $(OBJDIR)/twos.o:			  twos.c
+$(OBJDIR)/sowt.o:			  sowt.c
 $(OBJDIR)/udta.o:			  udta.c
 $(OBJDIR)/ulaw.o:			  ulaw.c
 $(OBJDIR)/util.o:			  util.c
diff -Nau my_cinelerra/quicktime/Makefile.50 my_cinelerra_sowt/quicktime/Makefile.50
--- my_cinelerra/quicktime/Makefile.50	2010-06-28 00:47:50.000000000 -0700
+++ my_cinelerra_sowt/quicktime/Makefile.50	2010-06-28 00:39:29.000000000 -0700
@@ -131,6 +131,7 @@
 	$(OBJDIR)/tkhd.o \
 	$(OBJDIR)/trak.o \
 	$(OBJDIR)/twos.o \
+	$(OBJDIR)/sowt.o \
 	$(OBJDIR)/udta.o \
 	$(OBJDIR)/ulaw.o \
 	$(OBJDIR)/util.o \
@@ -360,6 +361,7 @@
 $(OBJDIR)/tkhd.o:			  tkhd.c
 $(OBJDIR)/trak.o:			  trak.c
 $(OBJDIR)/twos.o:			  twos.c
+$(OBJDIR)/sowt.o:			  sowt.c
 $(OBJDIR)/udta.o:			  udta.c
 $(OBJDIR)/ulaw.o:			  ulaw.c
 $(OBJDIR)/util.o:			  util.c
diff -Nau my_cinelerra/quicktime/Makefile.am my_cinelerra_sowt/quicktime/Makefile.am
--- my_cinelerra/quicktime/Makefile.am	2010-06-28 00:47:50.000000000 -0700
+++ my_cinelerra_sowt/quicktime/Makefile.am	2010-06-28 00:40:42.000000000 -0700
@@ -66,7 +66,7 @@
 	rawaudio.c \
 	rle.c \
 													smhd.c stbl.c stco.c stsc.c stsd.c stsdtable.c stss.c stsz.c stts.c \
-													tkhd.c trak.c twos.c udta.c ulaw.c util.c v308.c v408.c v410.c vmhd.c \
+													tkhd.c trak.c twos.c sowt.c udta.c ulaw.c util.c v308.c v408.c v410.c vmhd.c \
 	vbraudio.c \
 													vorbis.c workarounds.c yuv2.c yuv4.c yv12.c wmx2.c \
 													wma.c mpeg4.c
@@ -103,6 +103,7 @@
 	rtjpeg.h \
 	rtjpeg_core.h \
 	twos.h \
+	sowt.h \
 	ulaw.h \
 	v308.h \
 	v408.h \
diff -Nau my_cinelerra/quicktime/Makefile.encore2 my_cinelerra_sowt/quicktime/Makefile.encore2
--- my_cinelerra/quicktime/Makefile.encore2	2010-06-28 00:47:50.000000000 -0700
+++ my_cinelerra_sowt/quicktime/Makefile.encore2	2010-06-28 00:42:00.000000000 -0700
@@ -150,6 +150,7 @@
 	$(OBJDIR)/tkhd.o \
 	$(OBJDIR)/trak.o \
 	$(OBJDIR)/twos.o \
+	$(OBJDIR)/sowt.o \
 	$(OBJDIR)/udta.o \
 	$(OBJDIR)/ulaw.o \
 	$(OBJDIR)/util.o \
@@ -510,6 +511,7 @@
 $(OBJDIR)/tkhd.o:			  tkhd.c
 $(OBJDIR)/trak.o:			  trak.c
 $(OBJDIR)/twos.o:			  twos.c
+$(OBJDIR)/sowt.o:			  sowt.c
 $(OBJDIR)/udta.o:			  udta.c
 $(OBJDIR)/ulaw.o:			  ulaw.c
 $(OBJDIR)/util.o:			  util.c
diff -Nau my_cinelerra/quicktime/plugin.c my_cinelerra_sowt/quicktime/plugin.c
--- my_cinelerra/quicktime/plugin.c	2010-06-28 00:47:52.000000000 -0700
+++ my_cinelerra_sowt/quicktime/plugin.c	2010-06-28 00:43:24.000000000 -0700
@@ -41,6 +41,7 @@
 #include "qtmp3.h"
 #include "rawaudio.h"
 #include "twos.h"
+#include "sowt.h"
 #include "ulaw.h"
 #include "wma.h"
 #include "wmx2.h"
@@ -48,6 +49,7 @@
 static void register_acodecs()
 {
 	register_acodec(quicktime_init_codec_twos);
+	register_acodec(quicktime_init_codec_sowt);
 	register_acodec(quicktime_init_codec_rawaudio);
 	register_acodec(quicktime_init_codec_ima4);
 	register_acodec(quicktime_init_codec_mp4a);
diff -Nau my_cinelerra/quicktime/quicktime.h my_cinelerra_sowt/quicktime/quicktime.h
--- my_cinelerra/quicktime/quicktime.h	2010-06-28 00:47:52.000000000 -0700
+++ my_cinelerra_sowt/quicktime/quicktime.h	2010-06-28 00:44:40.000000000 -0700
@@ -115,6 +115,7 @@
 
 /* Twos compliment 8, 16, 24 */
 #define QUICKTIME_TWOS "twos"
+#define QUICKTIME_SOWT "sowt"
 
 /* ulaw */
 #define QUICKTIME_ULAW "ulaw"
diff -Nau my_cinelerra/quicktime/sowt.c my_cinelerra_sowt/quicktime/sowt.c
--- my_cinelerra/quicktime/sowt.c	1969-12-31 17:00:00.000000000 -0700
+++ my_cinelerra_sowt/quicktime/sowt.c	2010-06-28 00:35:39.000000000 -0700
@@ -0,0 +1,335 @@
+#include "funcprotos.h"
+#include "quicktime.h"
+#include "sowt.h"
+
+/* =================================== private for sowt */
+
+
+typedef struct
+{
+	char *work_buffer;
+	long buffer_size;
+} quicktime_sowt_codec_t;
+
+static int byte_order(void)
+{                /* 1 if little endian */
+	int16_t byteordertest;
+	int byteorder;
+
+	byteordertest = 0x0001;
+	byteorder = *((unsigned char *)&byteordertest);
+	return byteorder;
+}
+
+static int get_work_buffer(quicktime_t *file, int track, long bytes)
+{
+	quicktime_sowt_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
+
+	if(codec->work_buffer && codec->buffer_size != bytes)
+	{
+		free(codec->work_buffer);
+		codec->work_buffer = 0;
+	}
+	
+	if(!codec->work_buffer) 
+	{
+		codec->buffer_size = bytes;
+		if(!(codec->work_buffer = malloc(bytes))) return 1;
+	}
+	return 0;
+}
+
+/* =================================== public for sowt */
+
+static int delete_codec(quicktime_audio_map_t *atrack)
+{
+	quicktime_sowt_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
+
+	if(codec->work_buffer) free(codec->work_buffer);
+	codec->work_buffer = 0;
+	codec->buffer_size = 0;
+	free(codec);
+	return 0;
+}
+
+static int swap_bytes(char *buffer, long samples, int channels, int bits)
+{
+	long i = 0;
+	char byte1, byte2, byte3;
+	char *buffer1, *buffer2, *buffer3;
+
+	if(!byte_order()) return 0;
+
+	switch(bits)
+	{
+		case 8:
+			break;
+
+		case 16:
+			buffer1 = buffer;
+			buffer2 = buffer + 1;
+			while(i < samples * channels * 2)
+			{
+				byte1 = buffer2[i];
+				buffer2[i] = buffer1[i];
+				buffer1[i] = byte1;
+				i += 2;
+			}
+			break;
+
+		case 24:
+			buffer1 = buffer;
+			buffer2 = buffer + 2;
+			while(i < samples * channels * 3)
+			{
+				byte1 = buffer2[i];
+				buffer2[i] = buffer1[i];
+				buffer1[i] = byte1;
+				i += 3;
+			}
+			break;
+
+		default:
+			break;
+	}
+	return 0;
+}
+
+
+static int decode(quicktime_t *file, 
+					int16_t *output_i, 
+					float *output_f, 
+					long samples, 
+					int track, 
+					int channel)
+{
+	int result = 0;
+	long i, j;
+	quicktime_audio_map_t *track_map = &(file->atracks[track]);
+	quicktime_sowt_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
+	int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
+
+	get_work_buffer(file, track, samples * step);
+/*
+ * printf("decode 1 %d\n", quicktime_audio_bits(file, track));
+ * sleep(1);
+ */
+	result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
+
+
+/* Undo increment since this is done in codecs.c */
+	track_map->current_position -= samples;
+
+/* Handle AVI byte order */
+	if(!file->use_avi)
+		swap_bytes(codec->work_buffer, 
+			samples, 
+			track_map->channels, 
+			quicktime_audio_bits(file, track));
+
+	switch(quicktime_audio_bits(file, track))
+	{
+		case 8:
+			if(output_i && !result)
+			{
+				for(i = 0, j = channel; i < samples; i++)
+				{
+					output_i[i] = ((int16_t)codec->work_buffer[j]) << 8;
+					j += step;
+				}
+			}
+			else
+			if(output_f && !result)
+			{
+				for(i = 0, j = channel; i < samples; i++)
+				{
+					output_f[i] = ((float)codec->work_buffer[j]) / 0x7f;
+					j += step;
+				}
+			}
+			break;
+		
+		case 16:
+			if(output_i && !result)
+			{
+				for(i = 0, j = channel * 2; i < samples; i++)
+				{
+					output_i[i] = ((int16_t)codec->work_buffer[j]) << 8 |
+									((unsigned char)codec->work_buffer[j + 1]);
+					j += step;
+				}
+			}
+			else
+			if(output_f && !result)
+			{
+				for(i = 0, j = channel * 2; i < samples; i++)
+				{
+					output_f[i] = (float)((((int16_t)codec->work_buffer[j]) << 8) |
+									((unsigned char)codec->work_buffer[j + 1])) / 0x7fff;
+					j += step;
+				}
+			}
+			break;
+		
+		case 24:
+			if(output_i && !result)
+			{
+				for(i = 0, j = channel * 3; i < samples; i++)
+				{
+					output_i[i] = (((int16_t)codec->work_buffer[j]) << 8) | 
+									((unsigned char)codec->work_buffer[j + 1]);
+					j += step;
+				}
+			}
+			else
+			if(output_f && !result)
+			{
+				for(i = 0, j = channel * 3; i < samples; i++)
+				{
+					output_f[i] = (float)((((int)codec->work_buffer[j]) << 16) | 
+									(((unsigned char)codec->work_buffer[j + 1]) << 8) |
+									((unsigned char)codec->work_buffer[j + 2])) / 0x7fffff;
+					j += step;
+				}
+			}
+			break;
+		
+		default:
+			break;
+	}
+
+
+	return result;
+}
+
+#define CLAMP(x, y, z) ((x) = ((x) <  (y) ? (y) : ((x) > (z) ? (z) : (x))))
+
+static int encode(quicktime_t *file, 
+							int16_t **input_i, 
+							float **input_f, 
+							int track, 
+							long samples)
+{
+	int result = 0;
+	long i, j, offset;
+	quicktime_audio_map_t *track_map = &(file->atracks[track]);
+	quicktime_sowt_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
+	int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
+	int sample;
+	float sample_f;
+
+	get_work_buffer(file, track, samples * step);
+
+	if(input_i)
+	{
+		for(i = 0; i < track_map->channels; i++)
+		{
+			switch(quicktime_audio_bits(file, track))
+			{
+				case 8:
+					for(j = 0; j < samples; j++)
+					{
+						sample = input_i[i][j] >> 8;
+						codec->work_buffer[j * step + i] = sample;
+					}
+					break;
+				case 16:
+					for(j = 0; j < samples; j++)
+					{
+						sample = input_i[i][j];
+						codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
+						codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
+					}
+					break;
+				case 24:
+					for(j = 0; j < samples; j++)
+					{
+						sample = input_i[i][j];
+						codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8;
+						codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff);
+						codec->work_buffer[j * step + i * 3 + 2] = 0;
+					}
+					break;
+			}
+		}
+	}
+	else
+	{
+		for(i = 0; i < track_map->channels; i++)
+		{
+			switch(quicktime_audio_bits(file, track))
+			{
+				case 8:
+					for(j = 0; j < samples; j++)
+					{
+						sample_f = input_f[i][j];
+						if(sample_f < 0)
+							sample = (int)(sample_f * 0x7f - 0.5);
+						else
+							sample = (int)(sample_f * 0x7f + 0.5);
+						CLAMP(sample, -0x7f, 0x7f);
+						codec->work_buffer[j * step + i] = sample;
+					}
+					break;
+				case 16:
+					for(j = 0; j < samples; j++)
+					{
+						sample_f = input_f[i][j];
+						if(sample_f < 0)
+							sample = (int)(sample_f * 0x7fff - 0.5);
+						else
+							sample = (int)(sample_f * 0x7fff + 0.5);
+						CLAMP(sample, -0x7fff, 0x7fff);
+						codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
+						codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
+					}
+					break;
+				case 24:
+					for(j = 0; j < samples; j++)
+					{
+						sample_f = input_f[i][j];
+						if(sample_f < 0)
+							sample = (int)(sample_f * 0x7fffff - 0.5);
+						else
+							sample = (int)(sample_f * 0x7fffff + 0.5);
+						CLAMP(sample, -0x7fffff, 0x7fffff);
+						codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff0000) >> 16;
+						codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff00) >> 8;
+						codec->work_buffer[j * step + i * 3 + 2] = ((unsigned int)sample) & 0xff;
+					}
+					break;
+			}
+		}
+	}
+
+/* Handle AVI byte order */
+	if(!file->use_avi)
+		swap_bytes(codec->work_buffer, 
+			samples, 
+			track_map->channels, 
+			quicktime_audio_bits(file, track));
+
+	result = quicktime_write_audio(file, codec->work_buffer, samples, track);
+
+	return result;
+}
+
+void quicktime_init_codec_sowt(quicktime_audio_map_t *atrack)
+{
+	quicktime_sowt_codec_t *codec;
+	quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
+
+/* Init public items */
+	codec_base->delete_acodec = delete_codec;
+	codec_base->decode_audio = decode;
+	codec_base->encode_audio = encode;
+	codec_base->fourcc = QUICKTIME_SOWT;
+	codec_base->title = "Sowt complement";
+	codec_base->desc = "Sowt complement";
+	codec_base->wav_id = 0x01;
+
+/* Init private items */
+	codec = codec_base->priv = calloc(1, sizeof(quicktime_sowt_codec_t));
+	codec->work_buffer = 0;
+	codec->buffer_size = 0;
+}
diff -Nau my_cinelerra/quicktime/sowt.h my_cinelerra_sowt/quicktime/sowt.h
--- my_cinelerra/quicktime/sowt.h	1969-12-31 17:00:00.000000000 -0700
+++ my_cinelerra_sowt/quicktime/sowt.h	2010-06-28 00:29:18.000000000 -0700
@@ -0,0 +1,6 @@
+#ifndef QUICKTIME_SOWT_H
+#define QUICKTIME_SOWT_H
+
+extern void quicktime_init_codec_sowt(quicktime_audio_map_t *);
+
+#endif

Reply via email to