r454: Fixed that the color pickers (if opened) were not updated during playback.
[cinelerra_cv.git] / guicast / units.C
blobea8e6dae7970401e42cb657e466ba78a5125800a
1 #include "units.h"
2 #include <stdlib.h>
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;
17         if(allocated == NULL)
18         {
19                 int i;
20                 float value;
22                 // db to power table
23                 allocated = new float[(MAXGAIN - INFINITYGAIN) * 10 + 1];
24                 topower = allocated + (-INFINITYGAIN * 10);
25                 for(i = INFINITYGAIN * 10; i <= MAXGAIN * 10; i++)
26                 {
27                         topower[i] = pow(10, (float)i / 10 / 20);
28                         
29 //printf("%f %f\n", (float)i/10, topower[i]);
30                 }
31                 topower[INFINITYGAIN * 10] = 0;   // infinity gain
32         }
33         db = 0;
36 // FUTURE: would bounds checking be possible here?  Or at least make private?
37 float DB::fromdb_table() 
38
39         return db = topower[(int)(db * 10)]; 
42 float DB::fromdb_table(float db) 
43
44         if(db > MAXGAIN) db = MAXGAIN;
45         if(db <= INFINITYGAIN) return 0;
46         return db = topower[(int)(db * 10)]; 
49 float DB::fromdb()
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)
62         float db;
63         if(power == 0) 
64                 db = -100;
65         else 
66         {
67                 db = (float)(20 * log10(power));
68                 if(db < -100) db = -100;
69         }
70         return db;
74 Freq::Freq()
76         init_table();
77         freq = 0;
80 Freq::Freq(const Freq& oldfreq)
82         this->freq = oldfreq.freq;
85 void Freq::init_table()
87         if(!freqtable)
88         {
89                 freqtable = new int[TOTALFREQS + 1];
90 // starting frequency
91                 double freq1 = 27.5, freq2 = 55;  
92 // Some number divisable by three.  This depends on the value of TOTALFREQS
93                 int scale = 105;   
95                 freqtable[0] = 0;
96                 for(int i = 1, j = 0; i <= TOTALFREQS; i++, j++)
97                 {
98                 freqtable[i] = (int)(freq1 + (freq2 - freq1) / scale * j + 0.5);
99 //printf("Freq::init_table %d\n", freqtable[i]);
100                 if(j >= scale)
101                         {
102                                 freq1 = freq2;
103                                 freq2 *= 2;
104                                 j = 0;
105                         }
106                 }
107         }
110 int Freq::fromfreq() 
112         int i;
114         for(i = 0; i < TOTALFREQS && freqtable[i] < freq; i++)
115         ;
116         return(i);
119 int Freq::fromfreq(int index) 
121         int i;
123         init_table();
124         for(i = 0; i < TOTALFREQS && freqtable[i] < index; i++)
125         ;
126         return(i);
129 int Freq::tofreq(int index)
131         init_table();
132         int freq = freqtable[index]; 
133         return freq; 
136 Freq& Freq::operator++() 
138         if(freq < TOTALFREQS) freq++;
139         return *this;
141         
142 Freq& Freq::operator--()
144         if(freq > 0) freq--;
145         return *this;
147         
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, 
157                         double seconds, 
158                         int time_format, 
159                         int sample_rate, 
160                         float frame_rate, 
161                         float frames_per_foot)    // give text representation as time
163         int hour, minute, second, thousandths;
164         int64_t frame, feet;
166         switch(time_format)
167         {
168                 case TIME_HMS:
169                 {
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", 
176                                 hour, 
177                                 minute, 
178                                 second, 
179                                 thousandths);
180                         return text;
181                 }
182                   break;
183                 
184                 case TIME_HMS2:
185                 {
186                         float second;
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);
192                         return text;
193                 }
194                   break;
196                 case TIME_HMS3:
197                 {
198                         float 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);
204                         return text;
205                 }
206                   break;
208                 case TIME_HMSF:
209                 {
210                         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);
218                         return text;
219                 }
220                         break;
221                         
222                 case TIME_SAMPLES:
223                         sprintf(text, "%09ld", to_int64(seconds * sample_rate));
224                         break;
225                 
226                 case TIME_SAMPLES_HEX:
227                         sprintf(text, "%08x", to_int64(seconds * sample_rate));
228                         break;
229                 
230                 case TIME_FRAMES:
231                         frame = to_int64(seconds * frame_rate);
232                         sprintf(text, "%06ld", frame);
233                         return text;
234                         break;
235                 
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", 
240                                 feet, 
241                                 (int64_t)(frame - feet * frames_per_foot));
242                         return text;
243                         break;
244         }
245         return text;
249 char* Units::totext(char *text, 
250                 int64_t samples, 
251                 int samplerate, 
252                 int time_format, 
253                 float frame_rate,
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, 
260                         int samplerate, 
261                         int time_format, 
262                         float frame_rate,
263                         float frames_per_foot)
265         int64_t hours, minutes, frames, total_samples, i, j;
266         int64_t feet;
267         float seconds;
268         char string[256];
269         
270         switch(time_format)
271         {
272                 case TIME_HMS:
273                 case TIME_HMS2:
274                 case TIME_HMS3:
275 // get hours
276                         i = 0;
277                         j = 0;
278                         while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
279                         string[j] = 0;
280                         hours = atol(string);
281 // get minutes
282                         j = 0;
283 // skip separator
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++];
286                         string[j] = 0;
287                         minutes = atol(string);
288                         
289 // get seconds
290                         j = 0;
291 // skip separator
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++];
294                         string[j] = 0;
295                         seconds = atof(string);
297                         total_samples = (uint64_t)(((double)seconds + minutes * 60 + hours * 3600) * samplerate);
298                         return total_samples;
299                         break;
301                 case TIME_HMSF:
302 // get hours
303                         i = 0;
304                         j = 0;
305                         while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
306                         string[j] = 0;
307                         hours = atol(string);
308                         
309 // get minutes
310                         j = 0;
311 // skip separator
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++];
314                         string[j] = 0;
315                         minutes = atol(string);
316                         
317 // get seconds
318                         j = 0;
319 // skip separator
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++];
322                         string[j] = 0;
323                         seconds = atof(string);
324                         
325 // skip separator
326                         while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
327 // get frames
328                         j = 0;
329                         while(text[i] >=48 && text[i] <= 57 && j < 10) string[j++] = text[i++];
330                         string[j] = 0;
331                         frames = atol(string);
332                         
333                         total_samples = (int64_t)(((float)frames / frame_rate + seconds + minutes*60 + hours*3600) * samplerate);
334                         return total_samples;
335                         break;
337                 case TIME_SAMPLES:
338                         return atol(text);
339                         break;
340                 
341                 case TIME_SAMPLES_HEX:
342                         sscanf(text, "%x", &total_samples);
343                         return total_samples;
344                 
345                 case TIME_FRAMES:
346                         return (int64_t)(atof(text) / frame_rate * samplerate);
347                         break;
348                 
349                 case TIME_FEET_FRAMES:
350 // Get feet
351                         i = 0;
352                         j = 0;
353                         while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
354                         string[j] = 0;
355                         feet = atol(string);
357 // skip separator
358                         while((text[i] < 48 || text[i] > 57) && text[i] != 0) i++;
360 // Get frames
361                         j = 0;
362                         while(text[i] >=48 && text[i] <= 57 && text[i] != 0 && j < 10) string[j++] = text[i++];
363                         string[j] = 0;
364                         frames = atol(string);
365                         return (int64_t)(((float)feet * frames_per_foot + frames) / frame_rate * samplerate);
366                         break;
367         }
368         return 0;
371 double Units::text_to_seconds(char *text, 
372                                 int samplerate, 
373                                 int time_format, 
374                                 float frame_rate, 
375                                 float frames_per_foot)
377         return (double)fromtext(text, 
378                 samplerate, 
379                 time_format, 
380                 frame_rate, 
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) 
396 // used in editing
397         float result_f = (float)samples / sample_rate * framerate; 
398         int64_t result_l = (int64_t)(result_f + 0.5);
399         return result_l;
402 double Units::fix_framerate(double value)
404         if(value > 29.5 && value < 30) 
405                 value = (double)30000 / (double)1001;
406         else
407         if(value > 59.5 && value < 60) 
408                 value = (double)60000 / (double)1001;
409         else
410         if(value > 23.5 && value < 24) 
411                 value = (double)24000 / (double)1001;
412         
413         return value;
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);
426         
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)
434         float angle;
435         if(x > 0 && y <= 0)
436         {
437                 angle = atan((float)-y / x) / (2 * M_PI) * 360;
438         }
439         else
440         if(x < 0 && y <= 0)
441         {
442                 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
443         }
444         else
445         if(x < 0 && y > 0)
446         {
447                 angle = 180 - atan((float)-y / -x) / (2 * M_PI) * 360;
448         }
449         else
450         if(x > 0 && y > 0)
451         {
452                 angle = 360 + atan((float)-y / x) / (2 * M_PI) * 360;
453         }
454         else
455         if(x == 0 && y < 0)
456         {
457                 angle = 90;
458         }
459         else
460         if(x == 0 && y > 0)
461         {
462                 angle = 270;
463         }
464         else
465         if(x == 0 && y == 0)
466         {
467                 angle = 0;
468         }
470         return angle;
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;
490         return value;
493 float Units::quantize(float value, float precision)
495         int64_t temp = (int64_t)(value / precision + 0.5);
496         value = (float)temp * precision;
497         return value;
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)
510         switch(time_format)
511         {
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;
518         }
519         
520         return string;
523 #undef BYTE_ORDER
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;
529         void *result;
530         unsigned char *data = (unsigned char*)&result;
532 // Must be done behind the compiler's back
533         if(sizeof(void*) == 4)
534         {
535                 if(!BYTE_ORDER)
536                 {
537                         data[0] = value_dissected[4];
538                         data[1] = value_dissected[5];
539                         data[2] = value_dissected[6];
540                         data[3] = value_dissected[7];
541                 }
542                 else
543                 {
544                         data[0] = value_dissected[0];
545                         data[1] = value_dissected[1];
546                         data[2] = value_dissected[2];
547                         data[3] = value_dissected[3];
548                 }
549         }
550         else
551         {
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];
560         }
561         return result;
564 uint64_t Units::ptr_to_int64(void *ptr)
566         unsigned char *ptr_dissected = (unsigned char*)&ptr;
567         int64_t result = 0;
568         unsigned char *data = (unsigned char*)&result;
570 // Don't do this at home.
571         if(sizeof(void*) == 4)
572         {
573                 if(!BYTE_ORDER)
574                 {
575                         data[4] = ptr_dissected[0];
576                         data[5] = ptr_dissected[1];
577                         data[6] = ptr_dissected[2];
578                         data[7] = ptr_dissected[3];
579                 }
580                 else
581                 {
582                         data[0] = ptr_dissected[0];
583                         data[1] = ptr_dissected[1];
584                         data[2] = ptr_dissected[2];
585                         data[3] = ptr_dissected[3];
586                 }
587         }
588         else
589         {
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];
598         }
599         return result;
602 char* Units::format_to_separators(int time_format)
604         switch(time_format)
605         {
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";
614         }
615         return 0;