additional Andrew provided Termux mods +
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / units.C
index 9c2f1d27106b7f4be2cee7ec37f70c5bd91edf04..c8e5e482650ab23dba66f36ab1ec3e97206e0d85 100644 (file)
@@ -90,14 +90,14 @@ int Freq::fromfreq()
        int i = 0;
        while( i<TOTALFREQS && freqtable[i]<freq ) ++i;
        return i;
-};
+}
 
 int Freq::fromfreq(int index)
 {
        int i = 0;
        while( i<TOTALFREQS && freqtable[i]<index ) ++i;
        return i;
-};
+}
 
 int Freq::tofreq(int index)
 {
@@ -105,6 +105,25 @@ int Freq::tofreq(int index)
        return freqtable[index];
 }
 
+// frequency doubles for every OCTAVE slots.  OCTAVE must be divisible by 3
+// 27.5 is at i=1
+// 55 is at i=106
+// 110 is at i=211
+// 220 is at i=316
+// 440 is at i=421
+// 880 is at i=526
+double Freq::tofreq_f(double index)
+{
+       if( index < 0.5 ) return 0;
+       return 440.0 * pow(2, (double)(index - 421) / OCTAVE);
+}
+double Freq::fromfreq_f(double f)
+{
+       if( f < 0.5 ) return 0;
+       double result = log(f / 440) / log(2.0) * OCTAVE + 421;
+       return result < 0 ? 0 : result;
+}
+
 Freq& Freq::operator++()
 {
        if(freq < TOTALFREQS) ++freq;
@@ -136,17 +155,8 @@ void Units::init()
        topower[INFINITYGAIN * 10] = 0;   // infinity gain
 
        Freq::freqtable = new int[TOTALFREQS + 1];
-// starting frequency
-       double freq1 = 27.5, freq2 = 55;
-// Some number divisable by three.  This depends on the value of TOTALFREQS
-       int scale = 105;
-
-       Freq::freqtable[0] = 0;
-       for(int i = 1, j = 0; i <= TOTALFREQS; i++, j++) {
-               Freq::freqtable[i] = (int)(freq1 + (freq2 - freq1) / scale * j + 0.5);
-               if(j < scale) continue;
-               freq1 = freq2;  freq2 *= 2;  j = 0;
-       }
+       for( int i=0; i<=TOTALFREQS; ++i )
+               Freq::freqtable[i] = Freq::tofreq_f(i);
 }
 void Units::finit()
 {
@@ -156,7 +166,8 @@ void Units::finit()
 
 // give text representation as time
 char* Units::totext(char *text, double seconds, int time_format,
-                       int sample_rate, float frame_rate, float frames_per_foot)
+                       int sample_rate, float frame_rate, float frames_per_foot,
+                       double timecode_offset)
 {
        int64_t hour, feet, frame;
        int minute, second, thousandths;
@@ -198,6 +209,8 @@ char* Units::totext(char *text, double seconds, int time_format,
                sprintf(text, "%02d:%02d:%02d", (int)hour, minute, second);
                break; }
 
+       case TIME_TIMECODE:
+               seconds += timecode_offset; // fall thru
        case TIME_HMSF: {
                seconds = fabs(seconds) + 1.0e-6;
                hour = seconds/3600;
@@ -253,10 +266,11 @@ char* Units::totext(char *text, double seconds, int time_format,
 
 // give text representation as time
 char* Units::totext(char *text, int64_t samples, int samplerate,
-               int time_format, float frame_rate, float frames_per_foot)
+               int time_format, float frame_rate, float frames_per_foot,
+               double timecode_offset)
 {
        return totext(text, (double)samples/samplerate, time_format,
-                       samplerate, frame_rate, frames_per_foot);
+               samplerate, frame_rate, frames_per_foot, timecode_offset);
 }
 
 int64_t Units::get_int64(const char *&bp)
@@ -289,7 +303,8 @@ void Units::skip_seperators(const char *&bp)
 }
 
 int64_t Units::fromtext(const char *text, int samplerate, int time_format,
-                       float frame_rate, float frames_per_foot)
+                       float frame_rate, float frames_per_foot,
+                       double timecode_offset)
 {
        int64_t hours, total_samples;
        int minutes, frames, feet;
@@ -306,16 +321,19 @@ int64_t Units::fromtext(const char *text, int samplerate, int time_format,
        case TIME_HMS3: {
                hours = get_int64(text);    skip_seperators(text);
                minutes = get_int64(text);  skip_seperators(text);
-               seconds = get_int64(text);
+               seconds = get_double(text);
                total_seconds = seconds + minutes*60 + hours*3600;
                break; }
 
+       case TIME_TIMECODE:
        case TIME_HMSF: {
                hours = get_int64(text);    skip_seperators(text);
                minutes = get_int64(text);  skip_seperators(text);
                seconds = get_int64(text);  skip_seperators(text);
-               frames = get_int64(text);
+               frames = get_double(text);
                total_seconds = frames/frame_rate + seconds + minutes*60 + hours*3600;
+               if( time_format == TIME_TIMECODE )
+                       total_seconds -= timecode_offset;
                break; }
 
        case TIME_SAMPLES: {
@@ -355,22 +373,42 @@ int64_t Units::fromtext(const char *text, int samplerate, int time_format,
 }
 
 double Units::text_to_seconds(const char *text, int samplerate, int time_format,
-                               float frame_rate, float frames_per_foot)
+                               float frame_rate, float frames_per_foot,
+                               double timecode_offset)
 {
        return (double)fromtext(text, samplerate, time_format,
-                               frame_rate, frames_per_foot) / samplerate;
+               frame_rate, frames_per_foot, timecode_offset) / samplerate;
 }
 
 
 
+const char *Units::timetype_toformat(int type)
+{
+       switch( type ) {
+       case TIME_HMS:          return TIME_HMS__STR;
+       case TIME_HMSF:         return TIME_HMSF__STR;
+       case TIME_SAMPLES:      return TIME_SAMPLES__STR;
+       case TIME_SAMPLES_HEX:  return TIME_SAMPLES_HEX__STR;
+       case TIME_FRAMES:       return TIME_FRAMES__STR;
+       case TIME_FEET_FRAMES:  return TIME_FEET_FRAMES__STR;
+       case TIME_HMS2:         return TIME_HMS2__STR;
+       case TIME_HMS3:         return TIME_HMS3__STR;
+       case TIME_SECONDS:      return TIME_SECONDS__STR;
+       case TIME_MS1:          return TIME_MS1__STR;
+       case TIME_MS2:          return TIME_MS2__STR;
+       case TIME_TIMECODE:     return TIME_TIMECODE__STR;
+       }
+       return "(err)";
+}
 
-int Units::timeformat_totype(char *tcf)
+int Units::timeformat_totype(const char *tcf)
 {
        if (!strcmp(tcf,TIME_SECONDS__STR)) return(TIME_SECONDS);
        if (!strcmp(tcf,TIME_HMS__STR)) return(TIME_HMS);
        if (!strcmp(tcf,TIME_HMS2__STR)) return(TIME_HMS2);
        if (!strcmp(tcf,TIME_HMS3__STR)) return(TIME_HMS3);
        if (!strcmp(tcf,TIME_HMSF__STR)) return(TIME_HMSF);
+       if (!strcmp(tcf,TIME_TIMECODE__STR)) return(TIME_TIMECODE);
        if (!strcmp(tcf,TIME_SAMPLES__STR)) return(TIME_SAMPLES);
        if (!strcmp(tcf,TIME_SAMPLES_HEX__STR)) return(TIME_SAMPLES_HEX);
        if (!strcmp(tcf,TIME_FRAMES__STR)) return(TIME_FRAMES);
@@ -488,6 +526,7 @@ const char* Units::print_time_format(int time_format, char *string)
        case TIME_SECONDS:     fmt = TIME_SECONDS_TEXT;               break;
        case TIME_MS1:
        case TIME_MS2:         fmt = TIME_MS2_TEXT;                   break;
+       case TIME_TIMECODE:    fmt = TIME_TIMECODE_TEXT;              break;
        }
        return strcpy(string,fmt);
 }
@@ -503,6 +542,7 @@ int Units::text_to_format(const char *string)
        if(!strcmp(string, TIME_HMS3_TEXT)) return TIME_HMS3;
        if(!strcmp(string, TIME_SECONDS_TEXT)) return TIME_SECONDS;
        if(!strcmp(string, TIME_MS2_TEXT)) return TIME_MS2;
+       if(!strcmp(string, TIME_TIMECODE_TEXT)) return TIME_TIMECODE;
        return TIME_HMS;
 }
 
@@ -607,6 +647,7 @@ const char* Units::format_to_separators(int time_format)
                case TIME_HMS:         return "0:00:00.000";
                case TIME_HMS2:        return "0:00:00";
                case TIME_HMS3:        return "00:00:00";
+               case TIME_TIMECODE:
                case TIME_HMSF:        return "0:00:00:00";
                case TIME_SAMPLES:     return 0;
                case TIME_SAMPLES_HEX: return 0;