Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

filebaseaudio.C

Go to the documentation of this file.
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;       // number of bytes in a sample
00016         float *buffer_channel;    // channel in input buffer
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;  // rotating bits screws up the signs
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 // fix signed
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 // don't bother dithering 24 bits
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 //printf("FileBase::samples_to_raw 1\n");
00138                                 generate_ulaw_tables();
00139 //printf("FileBase::samples_to_raw 2\n");
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 //printf("FileBase::samples_to_raw 3\n");
00153                         }
00154                         break;
00155         }
00156 
00157 // swap bytes
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;  // position in output buffer
00217         int64_t input_len = samples;     // length of input buffer
00218 // The following are floats because they are multiplied by the slope to get the gain.
00219         float feather_current;     // input position for feather
00220 
00221         float sample; 
00222         char *inbuffer_8;               // point to actual byte being read
00223         int16_t *inbuffer_16;
00224         char *inbuffer_24;
00225         int sample_24;                                         
00226         float current_gain;
00227         int input_frame;                   // amount to advance the input buffer pointer
00228 
00229 // set up the parameters
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 // read the data
00255 // ================== calculate feathering and add to buffer ================
00256         if(feather)
00257         {
00258 // left feather
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 // central region
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 // ====================== don't feather and overwrite buffer =================
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;     // input position for feather
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 }

Generated on Sun Jan 8 13:38:54 2006 for Cinelerra-svn by  doxygen 1.4.4