00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef SUBSYNTH_AUDIO_FORMAT_UTILS____
00033 #define SUBSYNTH_AUDIO_FORMAT_UTILS____
00034
00035 #include <assert.h>
00036 #include <vector>
00037 #include <iostream>
00038 #include <memory.h>
00039 #ifdef max
00040 #undef max
00041 #endif
00042
00043 #ifdef min
00044 #undef min
00045 #endif
00046
00047 namespace syn
00048 {
00054 template <typename type>
00055 class audio_data_traits
00056 {
00057 public:
00058 static type min();
00059 static type max();
00060 static type bytes();
00061 static int range();
00062 static float rangef();
00063
00073 static type one_fourth_range();
00074 };
00075
00077 template <>
00078 class audio_data_traits<float>
00079 {
00080 public:
00081 static float min() { return -1.0f; }
00082 static float max() { return 1.0f; }
00083 static float bytes() { return 4; }
00084 static float rangef() { return 2.0f; }
00085 static int range() { return (int)rangef(); }
00086
00087 static float one_fourth_range()
00088 { return range() / 4.0f; }
00089 };
00090
00092 template <>
00093 class audio_data_traits<signed char>
00094 {
00095 public:
00096 static signed char min() { return -128; }
00097 static signed char max() { return 127; }
00098 static signed char bytes() { return 1; }
00099 static int range() { return 256; }
00100 static float rangef()
00101 { return (float)range(); }
00102
00103 static signed char one_fourth_range()
00104 { return range() / 4; }
00105 };
00106
00108 template <>
00109 class audio_data_traits<unsigned char>
00110 {
00111 public:
00112 static unsigned char min() { return 0; }
00113 static unsigned char max() { return 255; }
00114 static unsigned char bytes() { return 1; }
00115 static int range() { return 256; }
00116 static float rangef()
00117 { return (float)range(); }
00118
00119 static unsigned char one_fourth_range()
00120 { return range() / 4; }
00121 };
00122
00124 template <>
00125 class audio_data_traits<signed short>
00126 {
00127 public:
00128 static signed short min() { return -32768; }
00129 static signed short max() { return 32767; }
00130 static signed short bytes() { return 2; }
00131 static int range() { return 65536; }
00132 static float rangef()
00133 { return (float)range(); }
00134
00135 static signed short one_fourth_range()
00136 { return range() / 4; }
00137 };
00138
00140 template <>
00141 class audio_data_traits<unsigned short>
00142 {
00143 public:
00144 static unsigned short min() { return 0; }
00145 static unsigned short max() { return 65535; }
00146 static unsigned short bytes() { return 2; }
00147 static int range() { return 65536; }
00148 static float rangef()
00149 { return (float)range(); }
00150
00151 static unsigned short one_fourth_range()
00152 { return range() / 4; }
00153 };
00154
00158 template <typename in, typename out>
00159 inline void audio_convert( const in& i, out& o )
00160 {
00161 const in in_range = audio_data_traits<in>::one_fourth_range();
00162 const in in_min = audio_data_traits<in>::min();
00163
00164 const out out_range = audio_data_traits<out>::one_fourth_range();
00165 const out out_min = audio_data_traits<out>::min();
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 if ( (audio_data_traits<in>::range() >= audio_data_traits<out>::range() ||
00183
00184 audio_data_traits<in>::range() == audio_data_traits<float>::range()) &&
00185 audio_data_traits<out>::range() != audio_data_traits<float>::range() )
00186 {
00187 const in scale = ((in)out_range) / in_range;
00188 const in inv_scale = in_range / ((in)out_range);
00189 if (scale != 0.0)
00190 o = (out) (((i - in_min) * scale) + out_min);
00191 else
00192 o = (out) (((i - in_min) / inv_scale) + out_min);
00193 }
00194 else
00195 {
00196 const out scale = out_range / ((out)in_range);
00197 assert( scale != 0.0 && "scale should never be 0 in this case" );
00198
00199
00200
00201 o = (out) (((i - in_min) * scale) + out_min);
00202 }
00203
00204
00205 if (audio_data_traits<in>::range() == audio_data_traits<float>::range() &&
00206 audio_data_traits<out>::range() != audio_data_traits<float>::range() &&
00207 i >= 0.9999f)
00208 o -= (out)1;
00209 }
00210
00214 template <> inline void audio_convert( const signed char& i, signed char& o ) { o = i; }
00215 template <> inline void audio_convert( const unsigned char& i, unsigned char& o ) { o = i; }
00216 template <> inline void audio_convert( const signed short& i, signed short& o ) { o = i; }
00217 template <> inline void audio_convert( const unsigned short& i, unsigned short& o ) { o = i; }
00218 template <> inline void audio_convert( const float& i, float& o ) { o = i; }
00219
00220
00221
00222
00227 class AudioFormat
00228 {
00229 public:
00230 enum Packing
00231 {
00232 INTERLACED
00233 };
00234
00235 enum SampleType
00236 {
00237 UNSIGNED8, SIGNED8,
00238 UNSIGNED16, SIGNED16,
00239 FLOAT32
00240 };
00241
00243 AudioFormat( SampleType dt = FLOAT32, int chan = 1, int sampRate = 44100 ) : samplingRateHz( sampRate ),
00244 channels( chan ),
00245 datatype( dt )
00246 {
00247 }
00248
00252 void copy( const AudioFormat& af )
00253 {
00254 samplingRateHz = af.samplingRateHz;
00255 channels = af.channels;
00256 datatype = af.datatype;
00257 }
00258
00260 AudioFormat( const AudioFormat& af )
00261 {
00262 this->copy( af );
00263 }
00264
00266 const AudioFormat& operator=( const AudioFormat& af )
00267 {
00268 this->copy( af );
00269 return *this;
00270 }
00271
00273 bool operator==( const AudioFormat& af ) const
00274 {
00275 if (af.channels == this->channels &&
00276 af.datatype == this->datatype &&
00277 af.samplingRateHz == this->samplingRateHz)
00278 {
00279 return true;
00280 }
00281 return false;
00282 }
00283
00285 bool operator!=( const AudioFormat& af ) const
00286 {
00287 return !this->operator==( af );
00288 }
00289
00291 inline int sampsize() const
00292 {
00293 switch (datatype)
00294 {
00295 case UNSIGNED8: case SIGNED8:
00296 return 1;
00297 case UNSIGNED16: case SIGNED16:
00298 return 2;
00299 case FLOAT32:
00300 return 4;
00301 default:
00302 std::cout << "error: sampsize==" << datatype << std::endl;
00303 assert( false && "unknown sampsize" );
00304 return 0;
00305 }
00306 }
00307
00310 int samplingRateHz;
00311
00316 int channels;
00317
00321 SampleType datatype;
00322 };
00323
00324
00328 inline void* new_audio_data( const AudioFormat& fmt, int samples )
00329 {
00330 char* bok = new char[samples * fmt.channels * fmt.sampsize()];
00331 return (void*)bok;
00332 }
00333
00335 inline void delete_audio_data( void* d )
00336 {
00337 delete[] (char*)d;
00338 }
00339
00343 template <typename in, typename out>
00344 inline void size_calculator( const unsigned int& srcbytes, unsigned int& destbytes )
00345 {
00346 const float in_bytes = (float)audio_data_traits<in>::bytes();
00347 const float out_bytes = (float)audio_data_traits<out>::bytes();
00348 const float scale = in_bytes / out_bytes;
00349 destbytes = (unsigned int) (((float)srcbytes) * scale);
00350 }
00351
00354 inline void size_calculator( const AudioFormat& srcfmt, AudioFormat destfmt, const unsigned int& srcbytes, unsigned int& destbytes )
00355 {
00356 const float in_bytes = (float)srcfmt.sampsize();
00357 const float out_bytes = (float)destfmt.sampsize();
00358 const float scale = in_bytes / out_bytes;
00359 destbytes = (unsigned int) (((float)srcbytes) * scale);
00360 }
00361
00363 inline void bytes_calculator( AudioFormat fmt, const unsigned int& samples, unsigned int& destbytes )
00364 {
00365 destbytes = samples * fmt.sampsize();
00366 }
00367
00373 inline bool audio_channels_convert( const AudioFormat& srcfmt,
00374 const AudioFormat& destfmt,
00375 const void* srcdata,
00376 const int samples,
00377 void* destdata, int& destsamples )
00378 {
00379 destsamples = samples;
00380 assert( destfmt.sampsize() == srcfmt.sampsize() );
00381 int item_size = srcfmt.sampsize();
00382
00383
00384 if (srcfmt.channels == destfmt.channels)
00385 return false;
00386
00387
00388 const char* srcptr = (const char*)srcdata;
00389 char* destptr = (char*)destdata;
00390 if (srcfmt.channels == 1 && destfmt.channels == 2)
00391 {
00392 destsamples = samples * 2;
00393 for (int x = 0; x < samples * item_size; x += item_size)
00394 {
00395 memcpy( &destptr[x * destfmt.channels], &srcptr[x * srcfmt.channels], item_size );
00396 memcpy( &destptr[x * destfmt.channels + item_size], &srcptr[x * srcfmt.channels], item_size );
00397 }
00398 }
00399
00400 else if (srcfmt.channels == 2 && destfmt.channels == 1)
00401 {
00402 destsamples = samples / 2;
00403 for (int x = 0; x < samples * item_size; x += item_size)
00404 {
00405
00406 memcpy( &destptr[x * destfmt.channels], &srcptr[x * srcfmt.channels], item_size );
00407 }
00408 }
00409 return true;
00410 }
00411
00415 inline bool audio_samprate_convert( const AudioFormat& srcfmt,
00416 const AudioFormat& destfmt,
00417 const void* srcdata,
00418 const int samples,
00419 void* destdata )
00420 {return false;}
00421
00426 template< typename t, int stride >
00427 inline const t* audio_iterate( const t* data, int x )
00428 {
00429 return &data[x * stride];
00430 }
00431
00432 inline const char* audio_iterate( const char* data, const AudioFormat& fmt, int x )
00433 {
00434 return &data[x * fmt.channels * fmt.sampsize()];
00435 }
00436
00440 inline bool audio_format_convert( const AudioFormat& srcfmt,
00441 const AudioFormat& destfmt,
00442 const void* srcdata,
00443 const int samples,
00444 void* destdata )
00445 {
00446 const AudioFormat::SampleType& srctype = srcfmt.datatype;
00447 const AudioFormat::SampleType& desttype = destfmt.datatype;
00448
00449 assert( srcfmt.samplingRateHz == destfmt.samplingRateHz
00450 && "no rate conversion right now sorry." );
00451 assert( srcfmt.channels == destfmt.channels
00452 && "channels gotta be the same, sorry..." );
00453
00454 int x;
00455 switch (srctype)
00456 {
00457 case AudioFormat::UNSIGNED8:
00458 switch (desttype)
00459 {
00460 case AudioFormat::UNSIGNED8:
00461 for (x = 0; x < samples; ++x)
00462 audio_convert( ((unsigned char*)srcdata)[x], ((unsigned char*)destdata)[x] );
00463 break;
00464 case AudioFormat::SIGNED8:
00465 for (x = 0; x < samples; ++x)
00466 audio_convert( ((unsigned char*)srcdata)[x], ((signed char*)destdata)[x] );
00467 break;
00468 case AudioFormat::UNSIGNED16:
00469 for (x = 0; x < samples; ++x)
00470 audio_convert( ((unsigned char*)srcdata)[x], ((unsigned short*)destdata)[x] );
00471 break;
00472 case AudioFormat::SIGNED16:
00473 for (x = 0; x < samples; ++x)
00474 audio_convert( ((unsigned char*)srcdata)[x], ((signed short*)destdata)[x] );
00475 break;
00476 case AudioFormat::FLOAT32:
00477 for (x = 0; x < samples; ++x)
00478 audio_convert( ((unsigned char*)srcdata)[x], ((float*)destdata)[x] );
00479 break;
00480 }
00481 break;
00482 case AudioFormat::SIGNED8:
00483 switch (desttype)
00484 {
00485 case AudioFormat::UNSIGNED8:
00486 for (x = 0; x < samples; ++x)
00487 audio_convert( ((signed char*)srcdata)[x], ((unsigned char*)destdata)[x] );
00488 break;
00489 case AudioFormat::SIGNED8:
00490 for (x = 0; x < samples; ++x)
00491 audio_convert( ((signed char*)srcdata)[x], ((signed char*)destdata)[x] );
00492 break;
00493 case AudioFormat::UNSIGNED16:
00494 for (x = 0; x < samples; ++x)
00495 audio_convert( ((signed char*)srcdata)[x], ((unsigned short*)destdata)[x] );
00496 break;
00497 case AudioFormat::SIGNED16:
00498 for (x = 0; x < samples; ++x)
00499 audio_convert( ((signed char*)srcdata)[x], ((signed short*)destdata)[x] );
00500 break;
00501 case AudioFormat::FLOAT32:
00502 for (x = 0; x < samples; ++x)
00503 audio_convert( ((signed char*)srcdata)[x], ((float*)destdata)[x] );
00504 break;
00505 }
00506 break;
00507 case AudioFormat::UNSIGNED16:
00508 switch (desttype)
00509 {
00510 case AudioFormat::UNSIGNED8:
00511 for (x = 0; x < samples; ++x)
00512 audio_convert( ((unsigned short*)srcdata)[x], ((unsigned char*)destdata)[x] );
00513 break;
00514 case AudioFormat::SIGNED8:
00515 for (x = 0; x < samples; ++x)
00516 audio_convert( ((unsigned short*)srcdata)[x], ((signed char*)destdata)[x] );
00517 break;
00518 case AudioFormat::UNSIGNED16:
00519 for (x = 0; x < samples; ++x)
00520 audio_convert( ((unsigned short*)srcdata)[x], ((unsigned short*)destdata)[x] );
00521 break;
00522 case AudioFormat::SIGNED16:
00523 for (x = 0; x < samples; ++x)
00524 audio_convert( ((unsigned short*)srcdata)[x], ((signed short*)destdata)[x] );
00525 break;
00526 case AudioFormat::FLOAT32:
00527 for (x = 0; x < samples; ++x)
00528 audio_convert( ((unsigned short*)srcdata)[x], ((float*)destdata)[x] );
00529 break;
00530 }
00531 break;
00532 case AudioFormat::SIGNED16:
00533 switch (desttype)
00534 {
00535 case AudioFormat::UNSIGNED8:
00536 for (x = 0; x < samples; ++x)
00537 audio_convert( ((signed short*)srcdata)[x], ((unsigned char*)destdata)[x] );
00538 break;
00539 case AudioFormat::SIGNED8:
00540 for (x = 0; x < samples; ++x)
00541 audio_convert( ((signed short*)srcdata)[x], ((signed char*)destdata)[x] );
00542 break;
00543 case AudioFormat::UNSIGNED16:
00544 for (x = 0; x < samples; ++x)
00545 audio_convert( ((signed short*)srcdata)[x], ((unsigned short*)destdata)[x] );
00546 break;
00547 case AudioFormat::SIGNED16:
00548 for (x = 0; x < samples; ++x)
00549 audio_convert( ((signed short*)srcdata)[x], ((signed short*)destdata)[x] );
00550 break;
00551 case AudioFormat::FLOAT32:
00552 for (x = 0; x < samples; ++x)
00553 audio_convert( ((signed short*)srcdata)[x], ((float*)destdata)[x] );
00554 break;
00555 }
00556 break;
00557 case AudioFormat::FLOAT32:
00558 switch (desttype)
00559 {
00560 case AudioFormat::UNSIGNED8:
00561 for (x = 0; x < samples; ++x)
00562 audio_convert( ((float*)srcdata)[x], ((unsigned char*)destdata)[x] );
00563 break;
00564 case AudioFormat::SIGNED8:
00565 for (x = 0; x < samples; ++x)
00566 audio_convert( ((float*)srcdata)[x], ((signed char*)destdata)[x] );
00567 break;
00568 case AudioFormat::UNSIGNED16:
00569 for (x = 0; x < samples; ++x)
00570 audio_convert( ((float*)srcdata)[x], ((unsigned short*)destdata)[x] );
00571 break;
00572 case AudioFormat::SIGNED16:
00573 for (x = 0; x < samples; ++x)
00574 audio_convert( ((float*)srcdata)[x], ((signed short*)destdata)[x] );
00575 break;
00576 case AudioFormat::FLOAT32:
00577 for (x = 0; x < samples; ++x)
00578 audio_convert( ((float*)srcdata)[x], ((float*)destdata)[x] );
00579 break;
00580 }
00581 break;
00582 }
00583
00584 return true;
00585 }
00586
00590 inline bool audio_convert( const AudioFormat& srcfmt,
00591 const AudioFormat& destfmt,
00592 const void* srcdata,
00593 const int samples,
00594 void* destdata, int& destsamples )
00595 {
00596
00597 AudioFormat temp_fmt;
00598 const char* channel_convert_temp_buffer = NULL;
00599 std::vector<char> mChannelConvertTempBuffer;
00600 if (srcfmt.channels != destfmt.channels)
00601 {
00602 temp_fmt = srcfmt;
00603 temp_fmt.channels = destfmt.channels;
00604 unsigned int bytes;
00605 bytes_calculator( temp_fmt, samples * temp_fmt.channels, bytes );
00606 if (mChannelConvertTempBuffer.size() < bytes)
00607 mChannelConvertTempBuffer.resize( bytes );
00608
00609 audio_channels_convert( srcfmt, temp_fmt, srcdata, samples, &mChannelConvertTempBuffer[0], destsamples );
00610 channel_convert_temp_buffer = &mChannelConvertTempBuffer[0];
00611 }
00612 else
00613 {
00614 temp_fmt = srcfmt;
00615 channel_convert_temp_buffer = (const char*)srcdata;
00616 destsamples = samples;
00617 }
00618
00619
00620 assert( temp_fmt.channels == destfmt.channels );
00621 return audio_format_convert( temp_fmt, destfmt, channel_convert_temp_buffer, destsamples, destdata );
00622 }
00623
00628 template <class type>
00629 type audio_clamp( const type& t )
00630 {
00631 if (t > audio_data_traits<type>::max())
00632 return audio_data_traits<type>::max();
00633 else if (t < audio_data_traits<type>::min())
00634 return audio_data_traits<type>::min();
00635
00636 return t;
00637 }
00638
00639 }
00640
00641
00642 #endif