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

Reply via email to