00001 #include "bcwindowbase.inc"
00002 #include "units.h"
00003
00004
00005 #include <stdlib.h>
00006 #include <string.h>
00007
00008
00009
00010
00011
00012 float* DB::topower = 0;
00013 float* DB::allocated = NULL;
00014
00015 int* Freq::freqtable = 0;
00016
00017
00018 DB::DB(float infinitygain)
00019 {
00020 this->infinitygain = infinitygain;
00021 if(allocated == NULL)
00022 {
00023 int i;
00024 float value;
00025
00026
00027 allocated = new float[(MAXGAIN - INFINITYGAIN) * 10 + 1];
00028 topower = allocated + (-INFINITYGAIN * 10);
00029 for(i = INFINITYGAIN * 10; i <= MAXGAIN * 10; i++)
00030 {
00031 topower[i] = pow(10, (float)i / 10 / 20);
00032
00033
00034 }
00035 topower[INFINITYGAIN * 10] = 0;
00036 }
00037 db = 0;
00038 }
00039
00040
00041 float DB::fromdb_table()
00042 {
00043 return db = topower[(int)(db * 10)];
00044 }
00045
00046 float DB::fromdb_table(float db)
00047 {
00048 if(db > MAXGAIN) db = MAXGAIN;
00049 if(db <= INFINITYGAIN) return 0;
00050 return db = topower[(int)(db * 10)];
00051 }
00052
00053 float DB::fromdb()
00054 {
00055 return pow(10, db / 20);
00056 }
00057
00058 float DB::fromdb(float db)
00059 {
00060 return pow(10, db / 20);
00061 }
00062
00063
00064 float DB::todb(float power)
00065 {
00066 float db;
00067 if(power == 0)
00068 db = -100;
00069 else
00070 {
00071 db = (float)(20 * log10(power));
00072 if(db < -100) db = -100;
00073 }
00074 return db;
00075 }
00076
00077
00078 Freq::Freq()
00079 {
00080 init_table();
00081 freq = 0;
00082 }
00083
00084 Freq::Freq(const Freq& oldfreq)
00085 {
00086 this->freq = oldfreq.freq;
00087 }
00088
00089 void Freq::init_table()
00090 {
00091 if(!freqtable)
00092 {
00093 freqtable = new int[TOTALFREQS + 1];
00094
00095 double freq1 = 27.5, freq2 = 55;
00096
00097 int scale = 105;
00098
00099 freqtable[0] = 0;
00100 for(int i = 1, j = 0; i <= TOTALFREQS; i++, j++)
00101 {
00102 freqtable[i] = (int)(freq1 + (freq2 - freq1) / scale * j + 0.5);
00103
00104 if(j >= scale)
00105 {
00106 freq1 = freq2;
00107 freq2 *= 2;
00108 j = 0;
00109 }
00110 }
00111 }
00112 }
00113
00114 int Freq::fromfreq()
00115 {
00116 int i;
00117
00118 for(i = 0; i < TOTALFREQS && freqtable[i] < freq; i++)
00119 ;
00120 return(i);
00121 };
00122
00123 int Freq::fromfreq(int index)
00124 {
00125 int i;
00126
00127 init_table();
00128 for(i = 0; i < TOTALFREQS && freqtable[i] < index; i++)
00129 ;
00130 return(i);
00131 };
00132
00133 int Freq::tofreq(int index)
00134 {
00135 init_table();
00136 int freq = freqtable[index];
00137 return freq;
00138 }
00139
00140 Freq& Freq::operator++()
00141 {
00142 if(freq < TOTALFREQS) freq++;
00143 return *this;
00144 }
00145
00146 Freq& Freq::operator--()
00147 {
00148 if(freq > 0) freq--;
00149 return *this;
00150 }
00151
00152 int Freq::operator>(Freq &newfreq) { return freq > newfreq.freq; }
00153 int Freq::operator<(Freq &newfreq) { return freq < newfreq.freq; }
00154 Freq& Freq::operator=(const Freq &newfreq) { freq = newfreq.freq; return *this; }
00155 int Freq::operator=(const int newfreq) { freq = newfreq; return newfreq; }
00156 int Freq::operator!=(Freq &newfreq) { return freq != newfreq.freq; }
00157 int Freq::operator==(Freq &newfreq) { return freq == newfreq.freq; }
00158 int Freq::operator==(int newfreq) { return freq == newfreq; }
00159
00160 char* Units::totext(char *text,
00161 double seconds,
00162 int time_format,
00163 int sample_rate,
00164 float frame_rate,
00165 float frames_per_foot)
00166 {
00167 int hour, minute, second, thousandths;
00168 int64_t frame, feet;
00169
00170 switch(time_format)
00171 {
00172 case TIME_SECONDS:
00173 seconds = fabs(seconds);
00174 sprintf(text, "%04d.%03d", (int)seconds, (int)(seconds * 1000) % 1000);
00175 return text;
00176 break;
00177
00178 case TIME_HMS:
00179 seconds = fabs(seconds);
00180 hour = (int)(seconds / 3600);
00181 minute = (int)(seconds / 60 - hour * 60);
00182 second = (int)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
00183 thousandths = (int)(seconds * 1000) % 1000;
00184 sprintf(text, "%d:%02d:%02d.%03d",
00185 hour,
00186 minute,
00187 second,
00188 thousandths);
00189 return text;
00190 break;
00191
00192 case TIME_HMS2:
00193 {
00194 float second;
00195 seconds = fabs(seconds);
00196 hour = (int)(seconds / 3600);
00197 minute = (int)(seconds / 60 - hour * 60);
00198 second = (float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
00199 sprintf(text, "%d:%02d:%02d", hour, minute, (int)second);
00200 return text;
00201 }
00202 break;
00203
00204 case TIME_HMS3:
00205 {
00206 float second;
00207 seconds = fabs(seconds);
00208 hour = (int)(seconds / 3600);
00209 minute = (int)(seconds / 60 - hour * 60);
00210 second = (float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
00211 sprintf(text, "%02d:%02d:%02d", hour, minute, (int)second);
00212 return text;
00213 }
00214 break;
00215
00216 case TIME_HMSF:
00217 {
00218 int second;
00219 seconds = fabs(seconds);
00220 hour = (int)(seconds / 3600);
00221 minute = (int)(seconds / 60 - hour * 60);
00222 second = (int)(seconds - hour * 3600 - minute * 60);
00223
00224
00225
00226 frame = (int64_t)((double)frame_rate *
00227 seconds +
00228 0.0000001) -
00229 (int64_t)((double)frame_rate *
00230 (hour *
00231 3600 +
00232 minute *
00233 60 +
00234 second) +
00235 0.0000001);
00236 sprintf(text, "%01d:%02d:%02d:%02ld", hour, minute, second, frame);
00237 return text;
00238 }
00239 break;
00240
00241 case TIME_SAMPLES:
00242 sprintf(text, "%09ld", to_int64(seconds * sample_rate));
00243 break;
00244
00245 case TIME_SAMPLES_HEX:
00246 sprintf(text, "%08x", to_int64(seconds * sample_rate));
00247 break;
00248
00249 case TIME_FRAMES:
00250 frame = to_int64(seconds * frame_rate);
00251 sprintf(text, "%06ld", frame);
00252 return text;
00253 break;
00254
00255 case TIME_FEET_FRAMES:
00256 frame = to_int64(seconds * frame_rate);
00257 feet = (int64_t)(frame / frames_per_foot);
00258 sprintf(text, "%05ld-%02ld",
00259 feet,
00260 (int64_t)(frame - feet * frames_per_foot));
00261 return text;
00262 break;
00263 }
00264 return text;
00265 }
00266
00267
00268
00269 char* Units::totext(char *text,
00270 int64_t samples,
00271 int samplerate,
00272 int time_format,
00273 float frame_rate,
00274 float frames_per_foot)
00275 {
00276 return totext(text, (double)samples / samplerate, time_format, samplerate, frame_rate, frames_per_foot);
00277 }
00278
00279 int64_t Units::fromtext(char *text,
00280 int samplerate,
00281 int time_format,
00282 float frame_rate,
00283 float frames_per_foot)
00284 {
00285 int64_t hours, minutes, frames, total_samples, i, j;
00286 int64_t feet;
00287 double seconds;
00288 char string[BCTEXTLEN];
00289
00290 switch(time_format)
00291 {
00292 case TIME_SECONDS:
00293 seconds = atof(text);
00294 return (int64_t)(seconds * samplerate);
00295 break;
00296
00297 case TIME_HMS:
00298 case TIME_HMS2:
00299 case TIME_HMS3:
00300
00301 i = 0;
00302 j = 0;
00303 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
00304 string[j] = 0;
00305 hours = atol(string);
00306
00307 j = 0;
00308
00309 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
00310 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
00311 string[j] = 0;
00312 minutes = atol(string);
00313
00314
00315 j = 0;
00316
00317 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
00318 while((text[i] == '.' || (text[i] >=48 && text[i] <= 57)) && j < 10) string[j++] = text[i++];
00319 string[j] = 0;
00320 seconds = atof(string);
00321
00322 total_samples = (uint64_t)(((double)seconds + minutes * 60 + hours * 3600) * samplerate);
00323 return total_samples;
00324 break;
00325
00326 case TIME_HMSF:
00327
00328 i = 0;
00329 j = 0;
00330 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
00331 string[j] = 0;
00332 hours = atol(string);
00333
00334
00335 j = 0;
00336
00337 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
00338 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
00339 string[j] = 0;
00340 minutes = atol(string);
00341
00342
00343 j = 0;
00344
00345 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
00346 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
00347 string[j] = 0;
00348 seconds = atof(string);
00349
00350
00351 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
00352
00353 j = 0;
00354 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
00355 string[j] = 0;
00356 frames = atol(string);
00357
00358 total_samples = (int64_t)(((float)frames / frame_rate + seconds + minutes*60 + hours*3600) * samplerate);
00359 return total_samples;
00360 break;
00361
00362 case TIME_SAMPLES:
00363 return atol(text);
00364 break;
00365
00366 case TIME_SAMPLES_HEX:
00367 sscanf(text, "%x", &total_samples);
00368 return total_samples;
00369
00370 case TIME_FRAMES:
00371 return (int64_t)(atof(text) / frame_rate * samplerate);
00372 break;
00373
00374 case TIME_FEET_FRAMES:
00375
00376 i = 0;
00377 j = 0;
00378 while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
00379 string[j] = 0;
00380 feet = atol(string);
00381
00382
00383 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
00384
00385
00386 j = 0;
00387 while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
00388 string[j] = 0;
00389 frames = atol(string);
00390 return (int64_t)(((float)feet * frames_per_foot + frames) / frame_rate * samplerate);
00391 break;
00392 }
00393 return 0;
00394 }
00395
00396 double Units::text_to_seconds(char *text,
00397 int samplerate,
00398 int time_format,
00399 float frame_rate,
00400 float frames_per_foot)
00401 {
00402 return (double)fromtext(text,
00403 samplerate,
00404 time_format,
00405 frame_rate,
00406 frames_per_foot) / samplerate;
00407 }
00408
00409
00410
00411
00412
00413
00414 float Units::toframes(int64_t samples, int sample_rate, float framerate)
00415 {
00416 return (float)samples / sample_rate * framerate;
00417 }
00418
00419 int64_t Units::toframes_round(int64_t samples, int sample_rate, float framerate)
00420 {
00421
00422 float result_f = (float)samples / sample_rate * framerate;
00423 int64_t result_l = (int64_t)(result_f + 0.5);
00424 return result_l;
00425 }
00426
00427 double Units::fix_framerate(double value)
00428 {
00429 if(value > 29.5 && value < 30)
00430 value = (double)30000 / (double)1001;
00431 else
00432 if(value > 59.5 && value < 60)
00433 value = (double)60000 / (double)1001;
00434 else
00435 if(value > 23.5 && value < 24)
00436 value = (double)24000 / (double)1001;
00437
00438 return value;
00439 }
00440
00441 double Units::atoframerate(char *text)
00442 {
00443 double result = atof(text);
00444 return fix_framerate(result);
00445 }
00446
00447
00448 int64_t Units::tosamples(float frames, int sample_rate, float framerate)
00449 {
00450 float result = (frames / framerate * sample_rate);
00451
00452 if(result - (int)result) result += 1;
00453 return (int64_t)result;
00454 }
00455
00456
00457 float Units::xy_to_polar(int x, int y)
00458 {
00459 float angle;
00460 if(x > 0 && y <= 0)
00461 {
00462 angle = atan((float)-y / x) / (2 * M_PI) * 360;
00463 }
00464 else
00465 if(x < 0 && y <= 0)
00466 {
00467 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
00468 }
00469 else
00470 if(x < 0 && y > 0)
00471 {
00472 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
00473 }
00474 else
00475 if(x > 0 && y > 0)
00476 {
00477 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
00478 }
00479 else
00480 if(x == 0 && y < 0)
00481 {
00482 angle = 90;
00483 }
00484 else
00485 if(x == 0 && y > 0)
00486 {
00487 angle = 270;
00488 }
00489 else
00490 if(x == 0 && y == 0)
00491 {
00492 angle = 0;
00493 }
00494
00495 return angle;
00496 }
00497
00498 void Units::polar_to_xy(float angle, int radius, int &x, int &y)
00499 {
00500 while(angle < 0) angle += 360;
00501
00502 x = (int)(cos(angle / 360 * (2 * M_PI)) * radius);
00503 y = (int)(-sin(angle / 360 * (2 * M_PI)) * radius);
00504 }
00505
00506 int64_t Units::round(double result)
00507 {
00508 return (int64_t)(result < 0 ? result - 0.5 : result + 0.5);
00509 }
00510
00511 float Units::quantize10(float value)
00512 {
00513 int64_t temp = (int64_t)(value * 10 + 0.5);
00514 value = (float)temp / 10;
00515 return value;
00516 }
00517
00518 float Units::quantize(float value, float precision)
00519 {
00520 int64_t temp = (int64_t)(value / precision + 0.5);
00521 value = (float)temp * precision;
00522 return value;
00523 }
00524
00525
00526 int64_t Units::to_int64(double result)
00527 {
00528
00529
00530 return (int64_t)(result < 0 ? (result - 0.005) : (result + 0.005));
00531 }
00532
00533 char* Units::print_time_format(int time_format, char *string)
00534 {
00535 switch(time_format)
00536 {
00537 case 0: sprintf(string, "Hours:Minutes:Seconds.xxx"); break;
00538 case 1: sprintf(string, "Hours:Minutes:Seconds:Frames"); break;
00539 case 2: sprintf(string, "Samples"); break;
00540 case 3: sprintf(string, "Hex Samples"); break;
00541 case 4: sprintf(string, "Frames"); break;
00542 case 5: sprintf(string, "Feet-frames"); break;
00543 case 8: sprintf(string, "Seconds"); break;
00544 }
00545
00546 return string;
00547 }
00548
00549 #undef BYTE_ORDER
00550 #define BYTE_ORDER ((*(u_int32_t*)"a ") & 0x00000001)
00551
00552 void* Units::int64_to_ptr(uint64_t value)
00553 {
00554 unsigned char *value_dissected = (unsigned char*)&value;
00555 void *result;
00556 unsigned char *data = (unsigned char*)&result;
00557
00558
00559 if(sizeof(void*) == 4)
00560 {
00561 if(!BYTE_ORDER)
00562 {
00563 data[0] = value_dissected[4];
00564 data[1] = value_dissected[5];
00565 data[2] = value_dissected[6];
00566 data[3] = value_dissected[7];
00567 }
00568 else
00569 {
00570 data[0] = value_dissected[0];
00571 data[1] = value_dissected[1];
00572 data[2] = value_dissected[2];
00573 data[3] = value_dissected[3];
00574 }
00575 }
00576 else
00577 {
00578 data[0] = value_dissected[0];
00579 data[1] = value_dissected[1];
00580 data[2] = value_dissected[2];
00581 data[3] = value_dissected[3];
00582 data[4] = value_dissected[4];
00583 data[5] = value_dissected[5];
00584 data[6] = value_dissected[6];
00585 data[7] = value_dissected[7];
00586 }
00587 return result;
00588 }
00589
00590 uint64_t Units::ptr_to_int64(void *ptr)
00591 {
00592 unsigned char *ptr_dissected = (unsigned char*)&ptr;
00593 int64_t result = 0;
00594 unsigned char *data = (unsigned char*)&result;
00595
00596 if(sizeof(void*) == 4)
00597 {
00598 if(!BYTE_ORDER)
00599 {
00600 data[4] = ptr_dissected[0];
00601 data[5] = ptr_dissected[1];
00602 data[6] = ptr_dissected[2];
00603 data[7] = ptr_dissected[3];
00604 }
00605 else
00606 {
00607 data[0] = ptr_dissected[0];
00608 data[1] = ptr_dissected[1];
00609 data[2] = ptr_dissected[2];
00610 data[3] = ptr_dissected[3];
00611 }
00612 }
00613 else
00614 {
00615 data[0] = ptr_dissected[0];
00616 data[1] = ptr_dissected[1];
00617 data[2] = ptr_dissected[2];
00618 data[3] = ptr_dissected[3];
00619 data[4] = ptr_dissected[4];
00620 data[5] = ptr_dissected[5];
00621 data[6] = ptr_dissected[6];
00622 data[7] = ptr_dissected[7];
00623 }
00624 return result;
00625 }
00626
00627 char* Units::format_to_separators(int time_format)
00628 {
00629 switch(time_format)
00630 {
00631 case TIME_SECONDS: return "0000.000";
00632 case TIME_HMS: return "0:00:00.000";
00633 case TIME_HMS2: return "0:00:00";
00634 case TIME_HMS3: return "00:00:00";
00635 case TIME_HMSF: return "0:00:00:00";
00636 case TIME_SAMPLES: return 0;
00637 case TIME_SAMPLES_HEX: return 0;
00638 case TIME_FRAMES: return 0;
00639 case TIME_FEET_FRAMES: return "00000-00";
00640 }
00641 return 0;
00642 }
00643
00644 void Units::punctuate(char *string)
00645 {
00646 int len = strlen(string);
00647 int commas = (len - 1) / 3;
00648 for(int i = len + commas, j = len, k; j >= 0 && i >= 0; i--, j--)
00649 {
00650 k = (len - j - 1) / 3;
00651 if(k * 3 == len - j - 1 && j != len - 1 && string[j] != 0)
00652 {
00653 string[i--] = ',';
00654 }
00655
00656 string[i] = string[j];
00657 }
00658 }
00659
00660
00661
00662