1 #include "bcwindowbase.inc"
8 // NOTE: DB::allocated is the original allocation, to which we keep a
9 // pointer so that in theory we could have a destructor. DB::topower
10 // is a pointer into the middle of DB::allocated, which allows us to
11 // do lookups using negative array coefficients.
12 float* DB::topower = 0;
13 float* DB::allocated = NULL;
15 int* Freq::freqtable = 0;
18 DB::DB(float infinitygain)
20 this->infinitygain = infinitygain;
27 allocated = new float[(MAXGAIN - INFINITYGAIN) * 10 + 1];
28 topower = allocated + (-INFINITYGAIN * 10);
29 for(i = INFINITYGAIN * 10; i <= MAXGAIN * 10; i++)
31 topower[i] = pow(10, (float)i / 10 / 20);
33 //printf("%f %f\n", (float)i/10, topower[i]);
35 topower[INFINITYGAIN * 10] = 0; // infinity gain
40 // FUTURE: would bounds checking be possible here? Or at least make private?
41 float DB::fromdb_table()
43 return db = topower[(int)(db * 10)];
46 float DB::fromdb_table(float db)
48 if(db > MAXGAIN) db = MAXGAIN;
49 if(db <= INFINITYGAIN) return 0;
50 return db = topower[(int)(db * 10)];
55 return pow(10, db / 20);
58 float DB::fromdb(float db)
60 return pow(10, db / 20);
63 // set db to the power given using a formula
64 float DB::todb(float power)
71 db = (float)(20 * log10(power));
72 if(db < -100) db = -100;
84 Freq::Freq(const Freq& oldfreq)
86 this->freq = oldfreq.freq;
89 void Freq::init_table()
93 freqtable = new int[TOTALFREQS + 1];
95 double freq1 = 27.5, freq2 = 55;
96 // Some number divisable by three. This depends on the value of TOTALFREQS
100 for(int i = 1, j = 0; i <= TOTALFREQS; i++, j++)
102 freqtable[i] = (int)(freq1 + (freq2 - freq1) / scale * j + 0.5);
103 //printf("Freq::init_table %d\n", freqtable[i]);
118 for(i = 0; i < TOTALFREQS && freqtable[i] < freq; i++)
123 int Freq::fromfreq(int index)
128 for(i = 0; i < TOTALFREQS && freqtable[i] < index; i++)
133 int Freq::tofreq(int index)
136 int freq = freqtable[index];
140 Freq& Freq::operator++()
142 if(freq < TOTALFREQS) freq++;
146 Freq& Freq::operator--()
152 int Freq::operator>(Freq &newfreq) { return freq > newfreq.freq; }
153 int Freq::operator<(Freq &newfreq) { return freq < newfreq.freq; }
154 Freq& Freq::operator=(const Freq &newfreq) { freq = newfreq.freq; return *this; }
155 int Freq::operator=(const int newfreq) { freq = newfreq; return newfreq; }
156 int Freq::operator!=(Freq &newfreq) { return freq != newfreq.freq; }
157 int Freq::operator==(Freq &newfreq) { return freq == newfreq.freq; }
158 int Freq::operator==(int newfreq) { return freq == newfreq; }
160 char* Units::totext(char *text,
165 float frames_per_foot) // give text representation as time
167 int hour, minute, second, thousandths;
173 seconds = fabs(seconds);
174 sprintf(text, "%04d.%03d", (int)seconds, (int)(seconds * 1000) % 1000);
179 seconds = fabs(seconds);
180 hour = (int)(seconds / 3600);
181 minute = (int)(seconds / 60 - hour * 60);
182 second = (int)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
183 thousandths = (int)(seconds * 1000) % 1000;
184 sprintf(text, "%d:%02d:%02d.%03d",
195 seconds = fabs(seconds);
196 hour = (int)(seconds / 3600);
197 minute = (int)(seconds / 60 - hour * 60);
198 second = (float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
199 sprintf(text, "%d:%02d:%02d", hour, minute, (int)second);
207 seconds = fabs(seconds);
208 hour = (int)(seconds / 3600);
209 minute = (int)(seconds / 60 - hour * 60);
210 second = (float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
211 sprintf(text, "%02d:%02d:%02d", hour, minute, (int)second);
219 seconds = fabs(seconds);
220 hour = (int)(seconds / 3600);
221 minute = (int)(seconds / 60 - hour * 60);
222 second = (int)(seconds - hour * 3600 - minute * 60);
223 // frame = (int64_t)round(frame_rate *
224 // (float)((float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60 - second));
225 // sprintf(text, "%01d:%02d:%02d:%02ld", hour, minute, second, frame);
226 frame = (int64_t)((double)frame_rate *
229 (int64_t)((double)frame_rate *
236 sprintf(text, "%01d:%02d:%02d:%02ld", hour, minute, second, frame);
242 sprintf(text, "%09ld", to_int64(seconds * sample_rate));
245 case TIME_SAMPLES_HEX:
246 sprintf(text, "%08x", to_int64(seconds * sample_rate));
250 frame = to_int64(seconds * frame_rate);
251 sprintf(text, "%06ld", frame);
255 case TIME_FEET_FRAMES:
256 frame = to_int64(seconds * frame_rate);
257 feet = (int64_t)(frame / frames_per_foot);
258 sprintf(text, "%05ld-%02ld",
260 (int64_t)(frame - feet * frames_per_foot));
268 // give text representation as time
269 char* Units::totext(char *text,
274 float frames_per_foot)
276 return totext(text, (double)samples / samplerate, time_format, samplerate, frame_rate, frames_per_foot);
279 int64_t Units::fromtext(char *text,
283 float frames_per_foot)
285 int64_t hours, minutes, frames, total_samples, i, j;
288 char string[BCTEXTLEN];
293 seconds = atof(text);
294 return (int64_t)(seconds * samplerate);
303 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
305 hours = atol(string);
309 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
310 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
312 minutes = atol(string);
317 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
318 while((text[i] == '.' || (text[i] >=48 && text[i] <= 57)) && j < 10) string[j++] = text[i++];
320 seconds = atof(string);
322 total_samples = (uint64_t)(((double)seconds + minutes * 60 + hours * 3600) * samplerate);
323 return total_samples;
330 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
332 hours = atol(string);
337 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
338 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
340 minutes = atol(string);
345 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
346 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
348 seconds = atof(string);
351 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
354 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
356 frames = atol(string);
358 total_samples = (int64_t)(((float)frames / frame_rate + seconds + minutes*60 + hours*3600) * samplerate);
359 return total_samples;
366 case TIME_SAMPLES_HEX:
367 sscanf(text, "%x", &total_samples);
368 return total_samples;
371 return (int64_t)(atof(text) / frame_rate * samplerate);
374 case TIME_FEET_FRAMES:
378 while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
383 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
387 while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
389 frames = atol(string);
390 return (int64_t)(((float)feet * frames_per_foot + frames) / frame_rate * samplerate);
396 double Units::text_to_seconds(char *text,
400 float frames_per_foot)
402 return (double)fromtext(text,
406 frames_per_foot) / samplerate;
412 int Units::timeformat_totype(char *tcf) {
413 if (!strcmp(tcf,TIME_SECONDS__STR)) return(TIME_SECONDS);
414 if (!strcmp(tcf,TIME_HMS__STR)) return(TIME_HMS);
415 if (!strcmp(tcf,TIME_HMS2__STR)) return(TIME_HMS2);
416 if (!strcmp(tcf,TIME_HMS3__STR)) return(TIME_HMS3);
417 if (!strcmp(tcf,TIME_HMSF__STR)) return(TIME_HMSF);
418 if (!strcmp(tcf,TIME_SAMPLES__STR)) return(TIME_SAMPLES);
419 if (!strcmp(tcf,TIME_SAMPLES_HEX__STR)) return(TIME_SAMPLES_HEX);
420 if (!strcmp(tcf,TIME_FRAMES__STR)) return(TIME_FRAMES);
421 if (!strcmp(tcf,TIME_FEET_FRAMES__STR)) return(TIME_FEET_FRAMES);
426 float Units::toframes(int64_t samples, int sample_rate, float framerate)
428 return (float)samples / sample_rate * framerate;
429 } // give position in frames
431 int64_t Units::toframes_round(int64_t samples, int sample_rate, float framerate)
434 float result_f = (float)samples / sample_rate * framerate;
435 int64_t result_l = (int64_t)(result_f + 0.5);
439 double Units::fix_framerate(double value)
441 if(value > 29.5 && value < 30)
442 value = (double)30000 / (double)1001;
444 if(value > 59.5 && value < 60)
445 value = (double)60000 / (double)1001;
447 if(value > 23.5 && value < 24)
448 value = (double)24000 / (double)1001;
453 double Units::atoframerate(char *text)
455 double result = atof(text);
456 return fix_framerate(result);
460 int64_t Units::tosamples(float frames, int sample_rate, float framerate)
462 float result = (frames / framerate * sample_rate);
464 if(result - (int)result) result += 1;
465 return (int64_t)result;
466 } // give position in samples
469 float Units::xy_to_polar(int x, int y)
474 angle = atan((float)-y / x) / (2 * M_PI) * 360;
479 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
484 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
489 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
510 void Units::polar_to_xy(float angle, int radius, int &x, int &y)
512 while(angle < 0) angle += 360;
514 x = (int)(cos(angle / 360 * (2 * M_PI)) * radius);
515 y = (int)(-sin(angle / 360 * (2 * M_PI)) * radius);
518 int64_t Units::round(double result)
520 return (int64_t)(result < 0 ? result - 0.5 : result + 0.5);
523 float Units::quantize10(float value)
525 int64_t temp = (int64_t)(value * 10 + 0.5);
526 value = (float)temp / 10;
530 float Units::quantize(float value, float precision)
532 int64_t temp = (int64_t)(value / precision + 0.5);
533 value = (float)temp * precision;
537 int64_t Units::to_int64(double result)
539 // This must round up if result is one sample within cieling.
540 // Sampling rates below 48000 may cause more problems.
541 return (int64_t)(result < 0 ? (result - 0.005) : (result + 0.005));
544 char* Units::print_time_format(int time_format, char *string)
548 case 0: sprintf(string, "Hours:Minutes:Seconds.xxx"); break;
549 case 1: sprintf(string, "Hours:Minutes:Seconds:Frames"); break;
550 case 2: sprintf(string, "Samples"); break;
551 case 3: sprintf(string, "Hex Samples"); break;
552 case 4: sprintf(string, "Frames"); break;
553 case 5: sprintf(string, "Feet-frames"); break;
554 case 8: sprintf(string, "Seconds"); break;
561 #define BYTE_ORDER ((*(u_int32_t*)"a ") & 0x00000001)
563 void* Units::int64_to_ptr(uint64_t value)
565 unsigned char *value_dissected = (unsigned char*)&value;
567 unsigned char *data = (unsigned char*)&result;
569 // Must be done behind the compiler's back
570 if(sizeof(void*) == 4)
574 data[0] = value_dissected[4];
575 data[1] = value_dissected[5];
576 data[2] = value_dissected[6];
577 data[3] = value_dissected[7];
581 data[0] = value_dissected[0];
582 data[1] = value_dissected[1];
583 data[2] = value_dissected[2];
584 data[3] = value_dissected[3];
589 data[0] = value_dissected[0];
590 data[1] = value_dissected[1];
591 data[2] = value_dissected[2];
592 data[3] = value_dissected[3];
593 data[4] = value_dissected[4];
594 data[5] = value_dissected[5];
595 data[6] = value_dissected[6];
596 data[7] = value_dissected[7];
601 uint64_t Units::ptr_to_int64(void *ptr)
603 unsigned char *ptr_dissected = (unsigned char*)&ptr;
605 unsigned char *data = (unsigned char*)&result;
606 // Don't do this at home.
607 if(sizeof(void*) == 4)
611 data[4] = ptr_dissected[0];
612 data[5] = ptr_dissected[1];
613 data[6] = ptr_dissected[2];
614 data[7] = ptr_dissected[3];
618 data[0] = ptr_dissected[0];
619 data[1] = ptr_dissected[1];
620 data[2] = ptr_dissected[2];
621 data[3] = ptr_dissected[3];
626 data[0] = ptr_dissected[0];
627 data[1] = ptr_dissected[1];
628 data[2] = ptr_dissected[2];
629 data[3] = ptr_dissected[3];
630 data[4] = ptr_dissected[4];
631 data[5] = ptr_dissected[5];
632 data[6] = ptr_dissected[6];
633 data[7] = ptr_dissected[7];
638 char* Units::format_to_separators(int time_format)
642 case TIME_SECONDS: return "0000.000";
643 case TIME_HMS: return "0:00:00.000";
644 case TIME_HMS2: return "0:00:00";
645 case TIME_HMS3: return "00:00:00";
646 case TIME_HMSF: return "0:00:00:00";
647 case TIME_SAMPLES: return 0;
648 case TIME_SAMPLES_HEX: return 0;
649 case TIME_FRAMES: return 0;
650 case TIME_FEET_FRAMES: return "00000-00";
655 void Units::punctuate(char *string)
657 int len = strlen(string);
658 int commas = (len - 1) / 3;
659 for(int i = len + commas, j = len, k; j >= 0 && i >= 0; i--, j--)
661 k = (len - j - 1) / 3;
662 if(k * 3 == len - j - 1 && j != len - 1 && string[j] != 0)
667 string[i] = string[j];
671 void Units::fix_double(double *x)
681 // c-file-style: "linux"