00001 #include "funcprotos.h"
00002 #include "quicktime.h"
00003 #include "twos.h"
00004
00005
00006
00007
00008 typedef struct
00009 {
00010 char *work_buffer;
00011 long buffer_size;
00012 } quicktime_twos_codec_t;
00013
00014 static int byte_order(void)
00015 {
00016 int16_t byteordertest;
00017 int byteorder;
00018
00019 byteordertest = 0x0001;
00020 byteorder = *((unsigned char *)&byteordertest);
00021 return byteorder;
00022 }
00023
00024 static int get_work_buffer(quicktime_t *file, int track, long bytes)
00025 {
00026 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
00027
00028 if(codec->work_buffer && codec->buffer_size != bytes)
00029 {
00030 free(codec->work_buffer);
00031 codec->work_buffer = 0;
00032 }
00033
00034 if(!codec->work_buffer)
00035 {
00036 codec->buffer_size = bytes;
00037 if(!(codec->work_buffer = malloc(bytes))) return 1;
00038 }
00039 return 0;
00040 }
00041
00042
00043
00044 static int delete_codec(quicktime_audio_map_t *atrack)
00045 {
00046 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00047
00048 if(codec->work_buffer) free(codec->work_buffer);
00049 codec->work_buffer = 0;
00050 codec->buffer_size = 0;
00051 free(codec);
00052 return 0;
00053 }
00054
00055 static int swap_bytes(char *buffer, long samples, int channels, int bits)
00056 {
00057 long i = 0;
00058 char byte1, byte2, byte3;
00059 char *buffer1, *buffer2, *buffer3;
00060
00061 if(!byte_order()) return 0;
00062
00063 switch(bits)
00064 {
00065 case 8:
00066 break;
00067
00068 case 16:
00069 buffer1 = buffer;
00070 buffer2 = buffer + 1;
00071 while(i < samples * channels * 2)
00072 {
00073 byte1 = buffer2[i];
00074 buffer2[i] = buffer1[i];
00075 buffer1[i] = byte1;
00076 i += 2;
00077 }
00078 break;
00079
00080 case 24:
00081 buffer1 = buffer;
00082 buffer2 = buffer + 2;
00083 while(i < samples * channels * 3)
00084 {
00085 byte1 = buffer2[i];
00086 buffer2[i] = buffer1[i];
00087 buffer1[i] = byte1;
00088 i += 3;
00089 }
00090 break;
00091
00092 default:
00093 break;
00094 }
00095 return 0;
00096 }
00097
00098
00099 static int decode(quicktime_t *file,
00100 int16_t *output_i,
00101 float *output_f,
00102 long samples,
00103 int track,
00104 int channel)
00105 {
00106 int result = 0;
00107 long i, j;
00108 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00109 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00110 int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
00111
00112 get_work_buffer(file, track, samples * step);
00113
00114
00115
00116
00117 result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
00118
00119
00120
00121 track_map->current_position -= samples;
00122
00123
00124 if(file->use_avi)
00125 swap_bytes(codec->work_buffer,
00126 samples,
00127 track_map->channels,
00128 quicktime_audio_bits(file, track));
00129
00130 switch(quicktime_audio_bits(file, track))
00131 {
00132 case 8:
00133 if(output_i && !result)
00134 {
00135 for(i = 0, j = channel; i < samples; i++)
00136 {
00137 output_i[i] = ((int16_t)codec->work_buffer[j]) << 8;
00138 j += step;
00139 }
00140 }
00141 else
00142 if(output_f && !result)
00143 {
00144 for(i = 0, j = channel; i < samples; i++)
00145 {
00146 output_f[i] = ((float)codec->work_buffer[j]) / 0x7f;
00147 j += step;
00148 }
00149 }
00150 break;
00151
00152 case 16:
00153 if(output_i && !result)
00154 {
00155 for(i = 0, j = channel * 2; i < samples; i++)
00156 {
00157 output_i[i] = ((int16_t)codec->work_buffer[j]) << 8 |
00158 ((unsigned char)codec->work_buffer[j + 1]);
00159 j += step;
00160 }
00161 }
00162 else
00163 if(output_f && !result)
00164 {
00165 for(i = 0, j = channel * 2; i < samples; i++)
00166 {
00167 output_f[i] = (float)((((int16_t)codec->work_buffer[j]) << 8) |
00168 ((unsigned char)codec->work_buffer[j + 1])) / 0x7fff;
00169 j += step;
00170 }
00171 }
00172 break;
00173
00174 case 24:
00175 if(output_i && !result)
00176 {
00177 for(i = 0, j = channel * 3; i < samples; i++)
00178 {
00179 output_i[i] = (((int16_t)codec->work_buffer[j]) << 8) |
00180 ((unsigned char)codec->work_buffer[j + 1]);
00181 j += step;
00182 }
00183 }
00184 else
00185 if(output_f && !result)
00186 {
00187 for(i = 0, j = channel * 3; i < samples; i++)
00188 {
00189 output_f[i] = (float)((((int)codec->work_buffer[j]) << 16) |
00190 (((unsigned char)codec->work_buffer[j + 1]) << 8) |
00191 ((unsigned char)codec->work_buffer[j + 2])) / 0x7fffff;
00192 j += step;
00193 }
00194 }
00195 break;
00196
00197 default:
00198 break;
00199 }
00200
00201
00202 return result;
00203 }
00204
00205 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
00206
00207 static int encode(quicktime_t *file,
00208 int16_t **input_i,
00209 float **input_f,
00210 int track,
00211 long samples)
00212 {
00213 int result = 0;
00214 long i, j, offset;
00215 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00216 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00217 int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
00218 int sample;
00219 float sample_f;
00220
00221 get_work_buffer(file, track, samples * step);
00222
00223 if(input_i)
00224 {
00225 for(i = 0; i < track_map->channels; i++)
00226 {
00227 switch(quicktime_audio_bits(file, track))
00228 {
00229 case 8:
00230 for(j = 0; j < samples; j++)
00231 {
00232 sample = input_i[i][j] >> 8;
00233 codec->work_buffer[j * step + i] = sample;
00234 }
00235 break;
00236 case 16:
00237 for(j = 0; j < samples; j++)
00238 {
00239 sample = input_i[i][j];
00240 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
00241 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
00242 }
00243 break;
00244 case 24:
00245 for(j = 0; j < samples; j++)
00246 {
00247 sample = input_i[i][j];
00248 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8;
00249 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff);
00250 codec->work_buffer[j * step + i * 3 + 2] = 0;
00251 }
00252 break;
00253 }
00254 }
00255 }
00256 else
00257 {
00258 for(i = 0; i < track_map->channels; i++)
00259 {
00260 switch(quicktime_audio_bits(file, track))
00261 {
00262 case 8:
00263 for(j = 0; j < samples; j++)
00264 {
00265 sample_f = input_f[i][j];
00266 if(sample_f < 0)
00267 sample = (int)(sample_f * 0x7f - 0.5);
00268 else
00269 sample = (int)(sample_f * 0x7f + 0.5);
00270 CLAMP(sample, -0x7f, 0x7f);
00271 codec->work_buffer[j * step + i] = sample;
00272 }
00273 break;
00274 case 16:
00275 for(j = 0; j < samples; j++)
00276 {
00277 sample_f = input_f[i][j];
00278 if(sample_f < 0)
00279 sample = (int)(sample_f * 0x7fff - 0.5);
00280 else
00281 sample = (int)(sample_f * 0x7fff + 0.5);
00282 CLAMP(sample, -0x7fff, 0x7fff);
00283 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
00284 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
00285 }
00286 break;
00287 case 24:
00288 for(j = 0; j < samples; j++)
00289 {
00290 sample_f = input_f[i][j];
00291 if(sample_f < 0)
00292 sample = (int)(sample_f * 0x7fffff - 0.5);
00293 else
00294 sample = (int)(sample_f * 0x7fffff + 0.5);
00295 CLAMP(sample, -0x7fffff, 0x7fffff);
00296 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff0000) >> 16;
00297 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff00) >> 8;
00298 codec->work_buffer[j * step + i * 3 + 2] = ((unsigned int)sample) & 0xff;
00299 }
00300 break;
00301 }
00302 }
00303 }
00304
00305
00306 if(file->use_avi)
00307 swap_bytes(codec->work_buffer,
00308 samples,
00309 track_map->channels,
00310 quicktime_audio_bits(file, track));
00311
00312 result = quicktime_write_audio(file, codec->work_buffer, samples, track);
00313
00314 return result;
00315 }
00316
00317 void quicktime_init_codec_twos(quicktime_audio_map_t *atrack)
00318 {
00319 quicktime_twos_codec_t *codec;
00320 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
00321
00322
00323 codec_base->delete_acodec = delete_codec;
00324 codec_base->decode_audio = decode;
00325 codec_base->encode_audio = encode;
00326 codec_base->fourcc = QUICKTIME_TWOS;
00327 codec_base->title = "Twos complement";
00328 codec_base->desc = "Twos complement";
00329 codec_base->wav_id = 0x01;
00330
00331
00332 codec = codec_base->priv = calloc(1, sizeof(quicktime_twos_codec_t));
00333 codec->work_buffer = 0;
00334 codec->buffer_size = 0;
00335 }