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