Burkhard Plaum wrote:
>It's impossible as long as the codec is missing. Making a "sowt" codec
>from the already existing "twos" codec would be trivial though.
The following quick and dirty patch seems to work. sowt.c and sowt.h are
created and a few changes are made to other files to include them.
I know it is not elegant as it would be better to include the sowt codec
in twos.c and twos.h as the only real difference is
if(!file->use_avi)
instead of
if(file->use_avi)
but it works for my 7D files.
Please excuse the long post if attachments are preferred, but it is not
too long and won't get reformatted hopefully.
Mark
diff -Nau cinelerra-4.1.old/quicktime/Makefile cinelerra-4.1/quicktime/Makefile
--- cinelerra-4.1.old/quicktime/Makefile 2008-06-02 15:53:55.000000000
-0700
+++ cinelerra-4.1/quicktime/Makefile 2010-01-03 23:07:06.000000000 -0700
@@ -170,6 +170,7 @@
$(OBJDIR)/tkhd.o \
$(OBJDIR)/trak.o \
$(OBJDIR)/twos.o \
+ $(OBJDIR)/sowt.o \
$(OBJDIR)/udta.o \
$(OBJDIR)/ulaw.o \
$(OBJDIR)/util.o \
@@ -507,6 +508,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 cinelerra-4.1.old/quicktime/plugin.c cinelerra-4.1/quicktime/plugin.c
--- cinelerra-4.1.old/quicktime/plugin.c 2007-07-18 17:31:10.000000000
-0700
+++ cinelerra-4.1/quicktime/plugin.c 2010-01-03 23:12:28.000000000 -0700
@@ -42,6 +42,7 @@
#include "qtmp3.h"
#include "rawaudio.h"
#include "twos.h"
+#include "sowt.h"
#include "ulaw.h"
#include "wma.h"
#include "wmx2.h"
@@ -49,6 +50,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 cinelerra-4.1.old/quicktime/quicktime.h
cinelerra-4.1/quicktime/quicktime.h
--- cinelerra-4.1.old/quicktime/quicktime.h 2008-07-11 11:00:08.000000000
-0700
+++ cinelerra-4.1/quicktime/quicktime.h 2010-01-03 23:14:13.000000000 -0700
@@ -115,6 +115,7 @@
/* Twos compliment 8, 16, 24 */
#define QUICKTIME_TWOS "twos"
+#define QUICKTIME_SOWT "sowt"
/* ulaw */
#define QUICKTIME_ULAW "ulaw"
@@ -240,7 +241,7 @@
/* Get the samples per second */
long quicktime_sample_rate(quicktime_t *file, int track);
-/* Get the number of bits for the twos codec */
+/* Get the number of bits for the twos and sowt codecs */
int quicktime_audio_bits(quicktime_t *file, int track);
/* Get the number of audio channels in an audio track */
diff -Nau cinelerra-4.1.old/quicktime/sowt.c cinelerra-4.1/quicktime/sowt.c
--- cinelerra-4.1.old/quicktime/sowt.c 1969-12-31 17:00:00.000000000 -0700
+++ cinelerra-4.1/quicktime/sowt.c 2010-01-04 05:45:13.000000000 -0700
@@ -0,0 +1,343 @@
+#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++)
+ {
+ if(file->use_avi)
+ output_i[i] =
(int16_t)(((unsigned char)codec->work_buffer[j]) << 8) -
+ 0x7fff;
+ else
+ 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++)
+ {
+ if(file->use_avi)
+ output_f[i] =
((float)((unsigned char)codec->work_buffer[j]) - 0x7f) /
+ 0x7f;
+ else
+ 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 cinelerra-4.1.old/quicktime/sowt.h cinelerra-4.1/quicktime/sowt.h
--- cinelerra-4.1.old/quicktime/sowt.h 1969-12-31 17:00:00.000000000 -0700
+++ cinelerra-4.1/quicktime/sowt.h 2010-01-03 23:04:02.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
_______________________________________________
Cinelerra mailing list
[email protected]
https://init.linpro.no/mailman/skolelinux.no/listinfo/cinelerra