00001 #include "asset.h"
00002 #include "byteorder.h"
00003 #include "file.h"
00004 #include "filebase.h"
00005
00006
00007 int64_t FileBase::samples_to_raw(char *out_buffer,
00008 float **in_buffer,
00009 int64_t input_len,
00010 int bits,
00011 int channels,
00012 int byte_order,
00013 int signed_)
00014 {
00015 int output_advance;
00016 float *buffer_channel;
00017 float *buffer_channel_end;
00018 int channel;
00019 int64_t int_sample, int_sample2;
00020 float float_sample;
00021 int64_t dither_value, dither_scale = 255;
00022 int64_t bytes = input_len * channels * (file->bytes_per_sample(bits));
00023 int machine_byte_order = get_byte_order();
00024
00025 switch(bits)
00026 {
00027 case BITSLINEAR8:
00028 {
00029 char *output_ptr, *output_end;
00030 output_advance = channels;
00031 for(channel = 0; channel < channels; channel++)
00032 {
00033 output_ptr = out_buffer + channel;
00034 buffer_channel = in_buffer[channel];
00035 buffer_channel_end = buffer_channel + input_len;
00036
00037 if(dither)
00038 {
00039 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
00040 {
00041 float_sample = *buffer_channel * 0x7fff;
00042 int_sample = (int64_t)float_sample;
00043 if(int_sample > -0x7f00) { dither_value = rand() % dither_scale; int_sample -= dither_value; }
00044 int_sample /= 0x100;
00045 *output_ptr = int_sample;
00046 output_ptr += output_advance;
00047 }
00048 }
00049 else
00050 {
00051 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
00052 {
00053 float_sample = *buffer_channel * 0x7f;
00054 *output_ptr = (char)float_sample;
00055 output_ptr += output_advance;
00056 }
00057 }
00058 }
00059
00060
00061 if(!signed_)
00062 {
00063 output_ptr = out_buffer;
00064 output_end = out_buffer + bytes;
00065
00066 for( ; output_ptr < output_end; output_ptr++)
00067 *output_ptr ^= 0x80;
00068 }
00069 }
00070 break;
00071
00072 case BITSLINEAR16:
00073 {
00074 int16_t *output_ptr, *output_end;
00075 output_advance = channels;
00076 for(channel = 0; channel < channels; channel++)
00077 {
00078 output_ptr = (int16_t*)out_buffer + channel;
00079 buffer_channel = in_buffer[channel];
00080 buffer_channel_end = buffer_channel + input_len;
00081
00082 if(dither)
00083 {
00084 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
00085 {
00086 float_sample = *buffer_channel * 0x7fffff;
00087 int_sample = (int64_t)float_sample;
00088 if(int_sample > -0x7fff00) { dither_value = rand() % dither_scale; int_sample -= dither_value; }
00089 int_sample /= 0x100;
00090 *output_ptr = int_sample;
00091 output_ptr += output_advance;
00092 }
00093 }
00094 else
00095 {
00096 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
00097 {
00098 float_sample = *buffer_channel * 0x7fff;
00099 *output_ptr = (int16_t)float_sample;
00100 output_ptr += output_advance;
00101 }
00102 }
00103 }
00104 }
00105 break;
00106
00107 case BITSLINEAR24:
00108 {
00109 char *output_ptr, *output_end;
00110 output_advance = asset->channels * 3 - 2;
00111 for(channel = 0; channel < channels; channel++)
00112 {
00113 output_ptr = out_buffer + channel * 3;
00114 buffer_channel = in_buffer[channel];
00115 buffer_channel_end = buffer_channel + input_len;
00116
00117
00118 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
00119 {
00120 float_sample = *buffer_channel * 0x7fffff;
00121 int_sample = (int64_t)float_sample;
00122 int_sample2 = int_sample & 0xff0000;
00123 *output_ptr++ = (int_sample & 0xff);
00124 int_sample &= 0xff00;
00125 *output_ptr++ = (int_sample >> 8);
00126 *output_ptr = (int_sample2 >> 16);
00127 output_ptr += output_advance;
00128 }
00129 }
00130 }
00131 break;
00132
00133 case BITSULAW:
00134 {
00135 char *output_ptr;
00136 output_advance = asset->channels;
00137
00138 generate_ulaw_tables();
00139
00140
00141 for(channel = 0; channel < channels; channel++)
00142 {
00143 output_ptr = out_buffer + channel;
00144 buffer_channel = in_buffer[channel];
00145 buffer_channel_end = buffer_channel + input_len;
00146 for( ; buffer_channel < buffer_channel_end; buffer_channel++)
00147 {
00148 *output_ptr = floattoulaw(*buffer_channel);
00149 output_ptr += output_advance;
00150 }
00151 }
00152
00153 }
00154 break;
00155 }
00156
00157
00158 if((bits == BITSLINEAR16 && byte_order != machine_byte_order) ||
00159 (bits == BITSLINEAR24 && !byte_order))
00160 {
00161 swap_bytes(file->bytes_per_sample(bits), (unsigned char*)out_buffer, bytes);
00162 }
00163
00164 return bytes;
00165 }
00166
00167
00168 #define READ_8_MACRO \
00169 sample = *inbuffer_8; \
00170 sample /= 0x7f; \
00171 inbuffer_8 += input_frame;
00172
00173 #define READ_16_MACRO \
00174 sample = *inbuffer_16; \
00175 sample /= 0x7fff; \
00176 inbuffer_16 += input_frame;
00177
00178 #define READ_24_MACRO \
00179 sample = (unsigned char)*inbuffer_24++; \
00180 sample_24 = (unsigned char)*inbuffer_24++; \
00181 sample_24 <<= 8; \
00182 sample += sample_24; \
00183 sample_24 = *inbuffer_24; \
00184 sample_24 <<= 16; \
00185 sample += sample_24; \
00186 sample /= 0x7fffff; \
00187 inbuffer_24 += input_frame; \
00188
00189 #define READ_ULAW_MACRO \
00190 sample = ulawtofloat(*inbuffer_8); \
00191 inbuffer_8 += input_frame;
00192
00193 #define LFEATHER_MACRO1 \
00194 for(feather_current = 0; feather_current < lfeather_len; \
00195 output_current++, feather_current++) \
00196 {
00197
00198 #define LFEATHER_MACRO2 \
00199 current_gain = lfeather_gain + lfeather_slope * feather_current; \
00200 out_buffer[output_current] = out_buffer[output_current] * (1 - current_gain) + sample * current_gain; \
00201 }
00202
00203 #define CENTER_MACRO1 \
00204 for(; output_current < samples; \
00205 output_current++) \
00206 {
00207
00208 #define CENTER_MACRO2 \
00209 out_buffer[output_current] += sample; \
00210 }
00211
00212 int FileBase::raw_to_samples(float *out_buffer, char *in_buffer,
00213 int64_t samples, int bits, int channels, int channel, int feather,
00214 float lfeather_len, float lfeather_gain, float lfeather_slope)
00215 {
00216 int64_t output_current = 0;
00217 int64_t input_len = samples;
00218
00219 float feather_current;
00220
00221 float sample;
00222 char *inbuffer_8;
00223 int16_t *inbuffer_16;
00224 char *inbuffer_24;
00225 int sample_24;
00226 float current_gain;
00227 int input_frame;
00228
00229
00230 switch(bits)
00231 {
00232 case BITSLINEAR8:
00233 inbuffer_8 = in_buffer + channel;
00234 input_frame = channels;
00235 break;
00236
00237 case BITSLINEAR16:
00238 inbuffer_16 = (int16_t *)in_buffer + channel;
00239 input_frame = channels;
00240 break;
00241
00242 case BITSLINEAR24:
00243 inbuffer_24 = in_buffer + channel * 3;
00244 input_frame = channels * file->bytes_per_sample(bits) - 2;
00245 break;
00246
00247 case BITSULAW:
00248 generate_ulaw_tables();
00249 inbuffer_8 = in_buffer + channel;
00250 input_frame = channels;
00251 break;
00252 }
00253
00254
00255
00256 if(feather)
00257 {
00258
00259 switch(bits)
00260 {
00261 case BITSLINEAR8:
00262 LFEATHER_MACRO1;
00263 READ_8_MACRO;
00264 LFEATHER_MACRO2;
00265 break;
00266
00267 case BITSLINEAR16:
00268 LFEATHER_MACRO1;
00269 READ_16_MACRO;
00270 LFEATHER_MACRO2;
00271 break;
00272
00273 case BITSLINEAR24:
00274 LFEATHER_MACRO1;
00275 READ_24_MACRO;
00276 LFEATHER_MACRO2;
00277 break;
00278
00279 case BITSULAW:
00280 LFEATHER_MACRO1;
00281 READ_ULAW_MACRO;
00282 LFEATHER_MACRO2;
00283 break;
00284 }
00285
00286
00287
00288 switch(bits)
00289 {
00290 case BITSLINEAR8:
00291 CENTER_MACRO1;
00292 READ_8_MACRO;
00293 CENTER_MACRO2;
00294 break;
00295
00296 case BITSLINEAR16:
00297 CENTER_MACRO1;
00298 READ_16_MACRO;
00299 CENTER_MACRO2;
00300 break;
00301
00302 case BITSLINEAR24:
00303 CENTER_MACRO1;
00304 READ_24_MACRO;
00305 CENTER_MACRO2;
00306 break;
00307
00308 case BITSULAW:
00309 CENTER_MACRO1;
00310 READ_ULAW_MACRO;
00311 CENTER_MACRO2;
00312 break;
00313 }
00314 }
00315 else
00316
00317 {
00318 switch(bits)
00319 {
00320 case BITSLINEAR8:
00321 for(; output_current < input_len;
00322 output_current++)
00323 { READ_8_MACRO; out_buffer[output_current] = sample; }
00324 break;
00325
00326 case BITSLINEAR16:
00327 for(; output_current < input_len;
00328 output_current++)
00329 { READ_16_MACRO; out_buffer[output_current] = sample; }
00330 break;
00331
00332 case BITSLINEAR24:
00333 for(; output_current < input_len;
00334 output_current++)
00335 { READ_24_MACRO; out_buffer[output_current] = sample; }
00336 break;
00337
00338 case BITSULAW:
00339 for(; output_current < input_len;
00340 output_current++)
00341 { READ_ULAW_MACRO; out_buffer[output_current] = sample; }
00342 break;
00343 }
00344 }
00345
00346 return 0;
00347 }
00348
00349 int FileBase::overlay_float_buffer(float *out_buffer, float *in_buffer,
00350 int64_t samples,
00351 float lfeather_len, float lfeather_gain, float lfeather_slope)
00352 {
00353 int64_t output_current = 0;
00354 float sample, current_gain;
00355 float feather_current;
00356
00357 LFEATHER_MACRO1
00358 sample = in_buffer[output_current];
00359 LFEATHER_MACRO2
00360
00361 CENTER_MACRO1
00362 sample = in_buffer[output_current];
00363 CENTER_MACRO2
00364
00365 return 0;
00366 }
00367
00368
00369 int FileBase::get_audio_buffer(char **buffer, int64_t len, int64_t bits, int64_t channels)
00370 {
00371 int64_t bytes = len * channels * (file->bytes_per_sample(bits));
00372 if(*buffer && bytes > prev_bytes)
00373 {
00374 delete [] *buffer;
00375 *buffer = 0;
00376 }
00377 prev_bytes = bytes;
00378
00379 if(!*buffer) *buffer = new char[bytes];
00380 }
00381
00382 int FileBase::get_float_buffer(float **buffer, int64_t len)
00383 {
00384 if(*buffer && len > prev_len)
00385 {
00386 delete [] *buffer;
00387 *buffer = 0;
00388 }
00389 prev_len = len;
00390
00391 if(!*buffer) *buffer = new float[len];
00392 }