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

filebaseima4.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 #include "sizes.h"
00006 
00007 int FileBase::ima4_step[89] = 
00008 {
00009     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
00010     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
00011     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
00012     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
00013     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
00014     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
00015     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
00016     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
00017     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
00018 };
00019 
00020 int FileBase::ima4_index[16] = 
00021 {
00022     -1, -1, -1, -1, 2, 4, 6, 8,
00023     -1, -1, -1, -1, 2, 4, 6, 8
00024 };
00025 
00026 
00027 
00028 int FileBase::init_ima4()
00029 {
00030         ima4_block_samples = 1024;
00031         ima4_block_size = (ima4_block_samples - 1) * asset->channels / 2 + 4;
00032         last_ima4_samples = 0;
00033         last_ima4_indexes = 0;
00034 }
00035 
00036 int FileBase::delete_ima4()
00037 {
00038         if(last_ima4_samples) delete last_ima4_samples;
00039         if(last_ima4_indexes) delete last_ima4_indexes;
00040         last_ima4_samples = 0;
00041         last_ima4_indexes = 0;  
00042 }
00043 
00044 int FileBase::ima4_decode_block(int16_t *output, unsigned char *input)
00045 {
00046 return 0;
00047 //      int predictor[asset->channels];
00048 //      int index[asset->channels];
00049 //      int step[asset->channels];
00050 //      int i, j, nibble;
00051 //      unsigned char *block_ptr;
00052 //      unsigned char *input_end = input + ima4_block_size;
00053 //      int buffer_advance = asset->channels;
00054 //      int16_t *suboutput;
00055 // 
00056 // // Get the chunk header
00057 //      for(int i = 0; i < asset->channels; i++)
00058 //      {
00059 //              predictor[i] = *input++;
00060 //              predictor[i] |= (int)(*input++) << 8;
00061 //              index[i] = *input++;
00062 //              if(index[i] > 88) index[i] = 88;
00063 //              if(predictor[i] & 0x8000) predictor[i] -= 0x10000;
00064 //              step[i] = ima4_step[index[i]];
00065 //              *output++ = predictor[i];
00066 //              input++;
00067 //      }
00068 // 
00069 // // Read the input buffer sequentially, one nibble at a time
00070 //      while(input < input_end)
00071 //      {
00072 //              for(i = 0; i < asset->channels; i++)
00073 //              {
00074 //                      suboutput = output + i;
00075 // 
00076 //                      for(j = 0; j < 4; j++)
00077 //                      {
00078 //                              ima4_decode_sample(&predictor[i], *input & 0x0f, &index[i], &step[i]);
00079 //                              *suboutput = predictor[i];
00080 //                              suboutput += buffer_advance;
00081 //                              ima4_decode_sample(&predictor[i], (*input++ >> 4) & 0x0f, &index[i], &step[i]);
00082 //                              *suboutput = predictor[i];
00083 //                              suboutput += buffer_advance;
00084 //                      }
00085 //              }
00086 // 
00087 //              output += 8 * asset->channels;
00088 //      }
00089 }
00090 
00091 int FileBase::ima4_decode_sample(int *predictor, int nibble, int *index, int *step)
00092 {
00093         int difference, sign;
00094 
00095 // Get new index value
00096         *index += ima4_index[nibble];
00097 
00098         if(*index < 0) *index = 0; 
00099         else 
00100         if(*index > 88) *index = 88;
00101 
00102 // Get sign and magnitude from nibble
00103         sign = nibble & 8;
00104         nibble = nibble & 7;
00105 
00106 // Get difference
00107         difference = *step >> 3;
00108         if(nibble & 4) difference += *step;
00109         if(nibble & 2) difference += *step >> 1;
00110         if(nibble & 1) difference += *step >> 2;
00111 
00112 // Predict value
00113         if(sign) 
00114         *predictor -= difference;
00115         else 
00116         *predictor += difference;
00117 
00118         if(*predictor > 32767) *predictor = 32767;
00119         else
00120         if(*predictor < -32768) *predictor = -32768;
00121 
00122 // Update the step value
00123         *step = ima4_step[*index];
00124 
00125         return 0;
00126 }
00127 
00128 
00129 int FileBase::ima4_encode_block(unsigned char *output, int16_t *input, int step, int channel)
00130 {
00131         int i, j, nibble;
00132         int16_t *input_end = input + ima4_block_size;
00133         int16_t *subinput;
00134         int buffer_advance = asset->channels;
00135 
00136         if(!last_ima4_samples)
00137         {
00138                 last_ima4_samples = new int[asset->channels];
00139                 for(i = 0; i < asset->channels; i++) last_ima4_samples[i] = 0;
00140         }
00141 
00142         if(!last_ima4_indexes)
00143         {
00144                 last_ima4_indexes = new int[asset->channels];
00145                 for(i = 0; i < asset->channels; i++) last_ima4_indexes[i] = 0;
00146         }
00147 
00148         for(i = 0; i < asset->channels; i++)
00149         {
00150                 *output++ = last_ima4_samples[i] & 0xff;
00151                 *output++ = (last_ima4_samples[i] >> 8) & 0xff;
00152                 *output++ = last_ima4_indexes[i];
00153                 *output++ = 0;
00154         }
00155 
00156         while(input < input_end)
00157         {
00158                 for(i = 0; i < asset->channels; i++)
00159                 {
00160                         subinput = input + i;
00161                         for(j = 0; j < 4; j++)
00162                         {
00163                                 ima4_encode_sample(&(last_ima4_samples[i]), 
00164                                                                 &(last_ima4_indexes[i]), 
00165                                                                 &nibble, 
00166                                                                 *subinput);
00167 
00168                                 subinput += buffer_advance;
00169                                 *output = nibble;
00170                                 
00171                                 ima4_encode_sample(&(last_ima4_samples[i]), 
00172                                                                 &(last_ima4_indexes[i]), 
00173                                                                 &nibble, 
00174                                                                 *subinput);
00175 
00176                                 subinput += buffer_advance;
00177                                 *output++ |= (nibble << 4);
00178                         }
00179                 }
00180                 input += 8 * asset->channels;
00181         }
00182 
00183         return 0;
00184 }
00185 
00186 int FileBase::ima4_encode_sample(int *last_sample, int *last_index, int *nibble, int next_sample)
00187 {
00188         int difference, new_difference, mask, step;
00189 
00190         difference = next_sample - *last_sample;
00191         *nibble = 0;
00192         step = ima4_step[*last_index];
00193         new_difference = step >> 3;
00194 
00195         if(difference < 0)
00196         {
00197                 *nibble = 8;
00198                 difference = -difference;
00199         }
00200 
00201         mask = 4;
00202         while(mask)
00203         {
00204                 if(difference >= step)
00205                 {
00206                         *nibble |= mask;
00207                         difference -= step;
00208                         new_difference += step;
00209                 }
00210 
00211                 step >>= 1;
00212                 mask >>= 1;
00213         }
00214 
00215         if(*nibble & 8)
00216                 *last_sample -= new_difference;
00217         else
00218                 *last_sample += new_difference;
00219 
00220         if(*last_sample > 32767) *last_sample = 32767;
00221         else
00222         if(*last_sample < -32767) *last_sample = -32767;
00223 
00224         *last_index += ima4_index[*nibble];
00225 
00226         if(*last_index < 0) *last_index = 0;
00227         else
00228         if(*last_index > 88) *last_index= 88;
00229 
00230         return 0;
00231 }
00232 
00233 // Convert the number of samples in a chunk into the number of bytes in that
00234 // chunk.  The number of samples in a chunk should end on a block boundary.
00235 int64_t FileBase::ima4_samples_to_bytes(int64_t samples, int channels)
00236 {
00237         int64_t bytes = (int64_t)(samples / ima4_block_samples) * ima4_block_size * channels;
00238         return bytes;
00239 }
00240 
00241 int64_t FileBase::ima4_bytes_to_samples(int64_t bytes, int channels)
00242 {
00243         int64_t samples = (int64_t)(bytes / channels / ima4_block_size) * ima4_block_samples;
00244         return samples;
00245 }

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