4 // NOTE: DB::allocated is the original allocation, to which we keep a
5 // pointer so that in theory we could have a destructor. DB::topower
6 // is a pointer into the middle of DB::allocated, which allows us to
7 // do lookups using negative array coefficients.
8 float* DB::topower = 0;
9 float* DB::allocated = NULL;
11 int* Freq::freqtable = 0;
14 DB::DB(float infinitygain)
16 this->infinitygain = infinitygain;
23 allocated = new float[(MAXGAIN - INFINITYGAIN) * 10 + 1];
24 topower = allocated + (-INFINITYGAIN * 10);
25 for(i = INFINITYGAIN * 10; i <= MAXGAIN * 10; i++)
27 topower[i] = pow(10, (float)i / 10 / 20);
29 //printf("%f %f\n", (float)i/10, topower[i]);
31 topower[INFINITYGAIN * 10] = 0; // infinity gain
36 // FUTURE: would bounds checking be possible here? Or at least make private?
37 float DB::fromdb_table()
39 return db = topower[(int)(db * 10)];
42 float DB::fromdb_table(float db)
44 if(db > MAXGAIN) db = MAXGAIN;
45 if(db <= INFINITYGAIN) return 0;
46 return db = topower[(int)(db * 10)];
51 return pow(10, db / 20);
54 float DB::fromdb(float db)
56 return pow(10, db / 20);
59 // set db to the power given using a formula
60 float DB::todb(float power)
67 db = (float)(20 * log10(power));
68 if(db < -100) db = -100;
80 Freq::Freq(const Freq& oldfreq)
82 this->freq = oldfreq.freq;
85 void Freq::init_table()
89 freqtable = new int[TOTALFREQS + 1];
91 double freq1 = 27.5, freq2 = 55;
92 // Some number divisable by three. This depends on the value of TOTALFREQS
96 for(int i = 1, j = 0; i <= TOTALFREQS; i++, j++)
98 freqtable[i] = (int)(freq1 + (freq2 - freq1) / scale * j + 0.5);
99 //printf("Freq::init_table %d\n", freqtable[i]);
114 for(i = 0; i < TOTALFREQS && freqtable[i] < freq; i++)
119 int Freq::fromfreq(int index)
124 for(i = 0; i < TOTALFREQS && freqtable[i] < index; i++)
129 int Freq::tofreq(int index)
132 int freq = freqtable[index];
136 Freq& Freq::operator++()
138 if(freq < TOTALFREQS) freq++;
142 Freq& Freq::operator--()
148 int Freq::operator>(Freq &newfreq) { return freq > newfreq.freq; }
149 int Freq::operator<(Freq &newfreq) { return freq < newfreq.freq; }
150 Freq& Freq::operator=(const Freq &newfreq) { freq = newfreq.freq; return *this; }
151 int Freq::operator=(const int newfreq) { freq = newfreq; return newfreq; }
152 int Freq::operator!=(Freq &newfreq) { return freq != newfreq.freq; }
153 int Freq::operator==(Freq &newfreq) { return freq == newfreq.freq; }
154 int Freq::operator==(int newfreq) { return freq == newfreq; }
156 char* Units::totext(char *text,
161 float frames_per_foot) // give text representation as time
163 int hour, minute, second, thousandths;
170 seconds = fabs(seconds);
171 hour = (int)(seconds / 3600);
172 minute = (int)(seconds / 60 - hour * 60);
173 second = (int)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
174 thousandths = (int)(seconds * 1000) % 1000;
175 sprintf(text, "%d:%02d:%02d.%03d",
187 seconds = fabs(seconds);
188 hour = (int)(seconds / 3600);
189 minute = (int)(seconds / 60 - hour * 60);
190 second = (float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
191 sprintf(text, "%d:%02d:%02d", hour, minute, (int)second);
199 seconds = fabs(seconds);
200 hour = (int)(seconds / 3600);
201 minute = (int)(seconds / 60 - hour * 60);
202 second = (float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60;
203 sprintf(text, "%02d:%02d:%02d", hour, minute, (int)second);
211 seconds = fabs(seconds);
212 hour = (int)(seconds / 3600);
213 minute = (int)(seconds / 60 - hour * 60);
214 second = (int)(seconds - hour * 3600 - minute * 60);
215 frame = (int64_t)round(frame_rate *
216 (float)((float)seconds - (int64_t)hour * 3600 - (int64_t)minute * 60 - second));
217 sprintf(text, "%01d:%02d:%02d:%02ld", hour, minute, second, frame);
223 sprintf(text, "%09ld", to_int64(seconds * sample_rate));
226 case TIME_SAMPLES_HEX:
227 sprintf(text, "%08x", to_int64(seconds * sample_rate));
231 frame = to_int64(seconds * frame_rate);
232 sprintf(text, "%06ld", frame);
236 case TIME_FEET_FRAMES:
237 frame = to_int64(seconds * frame_rate);
238 feet = (int64_t)(frame / frames_per_foot);
239 sprintf(text, "%05ld-%02ld",
241 (int64_t)(frame - feet * frames_per_foot));
249 char* Units::totext(char *text,
254 float frames_per_foot)
256 return totext(text, (double)samples / samplerate, time_format, samplerate, frame_rate, frames_per_foot);
257 } // give text representation as time
259 int64_t Units::fromtext(char *text,
263 float frames_per_foot)
265 int64_t hours, minutes, frames, total_samples, i, j;
278 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
280 hours = atol(string);
284 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
285 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
287 minutes = atol(string);
292 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
293 while((text[i] == '.' || (text[i] >=48 && text[i] <= 57)) && j < 10) string[j++] = text[i++];
295 seconds = atof(string);
297 total_samples = (uint64_t)(((double)seconds + minutes * 60 + hours * 3600) * samplerate);
298 return total_samples;
305 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
307 hours = atol(string);
312 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
313 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
315 minutes = atol(string);
320 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
321 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
323 seconds = atof(string);
326 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
329 while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
331 frames = atol(string);
333 total_samples = (int64_t)(((float)frames / frame_rate + seconds + minutes*60 + hours*3600) * samplerate);
334 return total_samples;
341 case TIME_SAMPLES_HEX:
342 sscanf(text, "%x", &total_samples);
343 return total_samples;
346 return (int64_t)(atof(text) / frame_rate * samplerate);
349 case TIME_FEET_FRAMES:
353 while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
358 while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
362 while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
364 frames = atol(string);
365 return (int64_t)(((float)feet * frames_per_foot + frames) / frame_rate * samplerate);
371 double Units::text_to_seconds(char *text,
375 float frames_per_foot)
377 return (double)fromtext(text,
381 frames_per_foot) / samplerate;
389 float Units::toframes(int64_t samples, int sample_rate, float framerate)
391 return (float)samples / sample_rate * framerate;
392 } // give position in frames
394 int64_t Units::toframes_round(int64_t samples, int sample_rate, float framerate)
397 float result_f = (float)samples / sample_rate * framerate;
398 int64_t result_l = (int64_t)(result_f + 0.5);
402 double Units::fix_framerate(double value)
404 if(value > 29.5 && value < 30)
405 value = (double)30000 / (double)1001;
407 if(value > 59.5 && value < 60)
408 value = (double)60000 / (double)1001;
410 if(value > 23.5 && value < 24)
411 value = (double)24000 / (double)1001;
416 double Units::atoframerate(char *text)
418 double result = atof(text);
419 return fix_framerate(result);
423 int64_t Units::tosamples(float frames, int sample_rate, float framerate)
425 float result = (frames / framerate * sample_rate);
427 if(result - (int)result) result += 1;
428 return (int64_t)result;
429 } // give position in samples
432 float Units::xy_to_polar(int x, int y)
437 angle = atan((float)-y / x) / (2 * M_PI) * 360;
442 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
447 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
452 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
473 void Units::polar_to_xy(float angle, int radius, int &x, int &y)
475 while(angle < 0) angle += 360;
477 x = (int)(cos(angle / 360 * (2 * M_PI)) * radius);
478 y = (int)(-sin(angle / 360 * (2 * M_PI)) * radius);
481 int64_t Units::round(double result)
483 return (int64_t)(result < 0 ? result - 0.5 : result + 0.5);
486 float Units::quantize10(float value)
488 int64_t temp = (int64_t)(value * 10 + 0.5);
489 value = (float)temp / 10;
493 float Units::quantize(float value, float precision)
495 int64_t temp = (int64_t)(value / precision + 0.5);
496 value = (float)temp * precision;
501 int64_t Units::to_int64(double result)
503 // This must round up if result is one sample within cieling.
504 // Sampling rates below 48000 may cause more problems.
505 return (int64_t)(result < 0 ? (result - 0.005) : (result + 0.005));
508 char* Units::print_time_format(int time_format, char *string)
512 case 0: sprintf(string, "Hours:Minutes:Seconds.xxx"); break;
513 case 1: sprintf(string, "Hours:Minutes:Seconds:Frames"); break;
514 case 2: sprintf(string, "Samples"); break;
515 case 3: sprintf(string, "Hex Samples"); break;
516 case 4: sprintf(string, "Frames"); break;
517 case 5: sprintf(string, "Feet-frames"); break;
524 #define BYTE_ORDER ((*(u_int32_t*)"a ") & 0x00000001)
526 void* Units::int64_to_ptr(uint64_t value)
528 unsigned char *value_dissected = (unsigned char*)&value;
530 unsigned char *data = (unsigned char*)&result;
532 // Must be done behind the compiler's back
533 if(sizeof(void*) == 4)
537 data[0] = value_dissected[4];
538 data[1] = value_dissected[5];
539 data[2] = value_dissected[6];
540 data[3] = value_dissected[7];
544 data[0] = value_dissected[0];
545 data[1] = value_dissected[1];
546 data[2] = value_dissected[2];
547 data[3] = value_dissected[3];
552 data[0] = value_dissected[0];
553 data[1] = value_dissected[1];
554 data[2] = value_dissected[2];
555 data[3] = value_dissected[3];
556 data[4] = value_dissected[4];
557 data[5] = value_dissected[5];
558 data[6] = value_dissected[6];
559 data[7] = value_dissected[7];
564 uint64_t Units::ptr_to_int64(void *ptr)
566 unsigned char *ptr_dissected = (unsigned char*)&ptr;
568 unsigned char *data = (unsigned char*)&result;
570 // Don't do this at home.
571 if(sizeof(void*) == 4)
575 data[4] = ptr_dissected[0];
576 data[5] = ptr_dissected[1];
577 data[6] = ptr_dissected[2];
578 data[7] = ptr_dissected[3];
582 data[0] = ptr_dissected[0];
583 data[1] = ptr_dissected[1];
584 data[2] = ptr_dissected[2];
585 data[3] = ptr_dissected[3];
590 data[0] = ptr_dissected[0];
591 data[1] = ptr_dissected[1];
592 data[2] = ptr_dissected[2];
593 data[3] = ptr_dissected[3];
594 data[4] = ptr_dissected[4];
595 data[5] = ptr_dissected[5];
596 data[6] = ptr_dissected[6];
597 data[7] = ptr_dissected[7];
602 char* Units::format_to_separators(int time_format)
606 case TIME_HMS: return "0:00:00.000";
607 case TIME_HMS2: return "0:00:00";
608 case TIME_HMS3: return "00:00:00";
609 case TIME_HMSF: return "0:00:00:00";
610 case TIME_SAMPLES: return 0;
611 case TIME_SAMPLES_HEX: return 0;
612 case TIME_FRAMES: return 0;
613 case TIME_FEET_FRAMES: return "00000-00";