~audio-recorder/audio-recorder/trunk

« back to all changes in this revision

Viewing changes to src/timer.c

  • Committer: Osmo Antero
  • Date: 2015-02-06 14:13:34 UTC
  • Revision ID: osmoma@gmail.com-20150206141334-ifaeqyan4ygxo49g
Updated README and INSTALL files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 *
9
9
 * This library is distributed in the hope that it will be useful,
10
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
12
 * See the GNU Library General Public License 3 for more details.
13
13
 *
14
14
 * You should have received a copy of the GNU Library General Public
97
97
       * Make sure VAD is running.
98
98
       * Send threshold signals to gst-recorder.c.
99
99
       * Recorder will START if threshold >= limit, and PAUSE if threshold < limit.
100
 
  ---------------------------------------------------------    
 
100
  ---------------------------------------------------------
101
101
 
102
102
  File size:
103
103
 
107
107
  -- During runtime:
108
108
       * Take recorded file size and compare it to value in the timer command (in timer.c).
109
109
       * Start recorder (pipeline) if condition is TRUE.
110
 
  ---------------------------------------------------------    
 
110
  ---------------------------------------------------------
111
111
 
112
112
  stop after 2 GB | 12 pm | silence 4s
113
 
  start at 10:20 pm | voice 
 
113
  start at 10:20 pm | voice
114
114
 
115
115
  Multiple conditions on one line, separated by "|" or "or".
116
 
  ---------------------------------------------------------    
 
116
  ---------------------------------------------------------
117
117
 
118
118
  Notice: The words "voice", "audio" and "sound" have all *same meaning*. Ok!
119
119
 
120
 
  The word "silence" is relative to the given volume level/threshold. 
 
120
  The word "silence" is relative to the given volume level/threshold.
121
121
  Silence has both duration (in seconds) and volume limit.
122
122
 
123
123
  Volume limit can be given as:
124
124
  -Decimal value between [0, 1.0].
125
125
  -% value between [0%, 100%]. So 1.0 = 100%.
126
126
  -Or decibel value.
127
 
  
 
127
 
128
128
*/
129
129
 
130
130
// Timer function call frequency in seconds
210
210
 
211
211
    case GST_STATE_PAUSED:
212
212
        //timer_update_records_2();
213
 
        break;  
 
213
        break;
214
214
 
215
215
    default:
216
216
        ;
235
235
    }
236
236
 
237
237
    // Start the timer function
238
 
    g_timer_func_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, TIMER_CALL_FREQ, (GSourceFunc)timer_func_cb, 
239
 
                                                 (gpointer)1/*!= 0*/, (GDestroyNotify)timer_func_exit_cb);
 
238
    g_timer_func_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, TIMER_CALL_FREQ, (GSourceFunc)timer_func_cb,
 
239
                      (gpointer)1/*!= 0*/, (GDestroyNotify)timer_func_exit_cb);
240
240
}
241
241
 
242
242
void timer_func_stop() {
278
278
    G_UNLOCK(g_t_list);
279
279
}
280
280
 
281
 
#if 0 
 
281
#if 0
282
282
static void timer_update_records_2() {
283
283
    // Reset timer nodes
284
284
 
337
337
    else if (threshold_unit[0] == '%')  {
338
338
        val = val / 100.0;
339
339
 
340
 
    // Already in [0 - 1.0]
 
340
        // Already in [0 - 1.0]
341
341
    } else {
342
342
        // val = threshold;
343
343
    }
351
351
        TimerRec *tr = (TimerRec*)item->data;
352
352
 
353
353
        if (!g_strcmp0(tr->label, "silence") ||
354
 
            !g_strcmp0(tr->label, "voice") ||
355
 
            !g_strcmp0(tr->label, "sound") ||
356
 
            !g_strcmp0(tr->label, "audio")) {
 
354
                !g_strcmp0(tr->label, "voice") ||
 
355
                !g_strcmp0(tr->label, "sound") ||
 
356
                !g_strcmp0(tr->label, "audio")) {
357
357
 
358
358
            return TRUE;
359
359
        }
395
395
    if (c1 == 'S' || c2 == 'S') { // Start
396
396
        return 'S';
397
397
    }
398
 
        
 
398
 
399
399
    if (c1 == 'C' || c2 == 'C') { // Continue
400
400
        return 'C';
401
401
    }
402
 
 
 
402
 
403
403
    // Lowest priority Pause
404
404
    return 'P';
405
405
}
445
445
 
446
446
        goto LBL_1;
447
447
    }
448
 
    
 
448
 
449
449
    // Set timer's start time
450
450
    timer_set_start_time();
451
451
 
482
482
    // Important: Start VAD-pipeline only when we needed.
483
483
    // Only "silence", "voice", "audio" and "sound" commands/conditions need VAD (Voice Activity Detection).
484
484
    need_VAD = check_need_VAD();
485
 
    
 
485
 
486
486
    // Normalize values
487
487
    normalize_values();
488
488
 
489
489
    G_UNLOCK(g_t_list);
490
490
 
491
 
  EVAL_0:
 
491
EVAL_0:
492
492
 
493
493
    // Check if recorder was started with --debug-signal (or -d) argument
494
494
    need_VAD = need_VAD || vad_get_debug_flag();
532
532
 
533
533
        // Check the timer condition
534
534
        gchar c = timer_func_eval_command(tr);
535
 
    
 
535
 
536
536
        // Notice: The Timer list may have several commands like:
537
537
        //  start at 21:00
538
 
        //  stop at 21:30 
 
538
        //  stop at 21:30
539
539
        //  stop after 20MB | 09:20 pm | silence 4 sec 20%
540
540
        //
541
541
        // sTop ha higher priority than Start, Continue or Pause
542
542
        // Start has higher priority than Pause or Continue
543
543
        gchar highest = highest_priority(saved_action, c);
544
 
        
 
544
 
545
545
        if (highest == c || saved_action == 0) {
546
546
            // Save this action
547
547
            saved_action = c;
594
594
            action = timer_test_clock_time_T(tr);
595
595
 
596
596
        } else if (tr->action == 'P') { // 'P'ause
597
 
        
 
597
 
598
598
            action = timer_test_clock_time_P(tr);
599
599
        }
600
600
 
654
654
#if 0
655
655
static TimerRec *find_action(gchar action) {
656
656
    // Find latest TimeRec record for action.
657
 
    TimerRec *found_tr = NULL; 
 
657
    TimerRec *found_tr = NULL;
658
658
 
659
659
    // Try to set lock
660
660
    gboolean locked = G_TRYLOCK(g_t_list);
681
681
                    if (timer_secs > found_tr->norm_secs) {
682
682
                        found_tr = tr;
683
683
                    }
684
 
                }     
685
 
            
686
 
            break;
 
684
                }
 
685
 
 
686
                break;
687
687
 
688
688
            case 'd':
689
689
            case 'f':
690
 
               if (!found_tr) {
 
690
                if (!found_tr) {
691
691
                    found_tr = tr;
692
692
                }
693
 
            break;
 
693
                break;
694
694
 
695
695
            }
696
696
        }
713
713
    // start at ##:##:## am/pm (where ##:##:## is a clock time in hh:mm:ss format)
714
714
    // Examples:
715
715
    //  start at 10:15:00 pm
716
 
    //  start after 1 hour 
717
 
    
 
716
    //  start after 1 hour
 
717
 
718
718
    gchar action = 0;
719
719
 
720
720
    // Get date & time
726
726
    if (tr->day_of_year == tmp->tm_yday) {
727
727
        // Fire only once a day
728
728
 
729
 
        LOG_TIMER("Timer command 'S'tart already executed today. Current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d).\n", 
730
 
                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, tr->day_of_year);
 
729
        LOG_TIMER("Timer command 'S'tart already executed today. Current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d).\n",
 
730
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, tr->day_of_year);
731
731
 
732
732
        return 0;
733
733
    }
748
748
 
749
749
    action = 0;
750
750
    if (clock_secs > timer_secs && diff_secs < (60*60L)/*1 HOUR HARD-CODED*/) {
751
 
        // Start-time is over current clock time. 
 
751
        // Start-time is over current clock time.
752
752
 
753
753
        // Already fired today? (fire once a day)
754
754
        if (tr->day_of_year != tmp->tm_yday) {
755
755
            action = 'S';
756
756
        }
757
757
    }
758
 
 
 
758
 
759
759
    if (action) {
760
760
        // Save day_of_year so we know when the clock turns around (to the next day).
761
761
        // Then this timer command will become valid and fire again.
762
762
        tr->day_of_year = tmp->tm_yday;
763
763
    }
764
764
 
765
 
    LOG_TIMER("Test clock time for 'S'tart: current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d) diff in secs:%ld, -->%s\n", 
766
 
               tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, 
767
 
               tr->day_of_year, (long)(timer_secs - clock_secs), (action == 0 ? "FALSE" : "TRUE"));
 
765
    LOG_TIMER("Test clock time for 'S'tart: current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d) diff in secs:%ld, -->%s\n",
 
766
              tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday,
 
767
              tr->day_of_year, (long)(timer_secs - clock_secs), (action == 0 ? "FALSE" : "TRUE"));
768
768
 
769
769
    return action;
770
770
}
787
787
    if (tr->day_of_year == tmp->tm_yday) {
788
788
        // Fire only once a day
789
789
 
790
 
        LOG_TIMER("Timer command s'T'op already executed today. Current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d).\n", 
791
 
                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, tr->day_of_year);
 
790
        LOG_TIMER("Timer command s'T'op already executed today. Current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d).\n",
 
791
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, tr->day_of_year);
792
792
 
793
793
        return 0;
794
794
    }
803
803
    action = 0;
804
804
 
805
805
    if (clock_secs > timer_secs) {
806
 
    // FIXME: Should we check tr->day_of_year != tmp->tm_yday here?
807
 
    // if (timer_secs > clock_secs && tr->day_of_year != tmp->tm_yday) {
 
806
        // FIXME: Should we check tr->day_of_year != tmp->tm_yday here?
 
807
        // if (timer_secs > clock_secs && tr->day_of_year != tmp->tm_yday) {
808
808
 
809
809
        // Already fired today? (fire once a day)
810
810
        if (tr->day_of_year != tmp->tm_yday) {
813
813
        }
814
814
    }
815
815
 
816
 
    LOG_TIMER("Test clock time for s'T'op: current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d) diff in secs:%ld, -->%s\n", 
817
 
              tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, 
 
816
    LOG_TIMER("Test clock time for s'T'op: current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d) diff in secs:%ld, -->%s\n",
 
817
              tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday,
818
818
              tr->day_of_year, (long)(timer_secs - clock_secs), (action == 0 ? "FALSE" : "TRUE"));
819
819
 
820
820
    return action;
838
838
    if (tr->day_of_year == tmp->tm_yday) {
839
839
        // Fire only once a day
840
840
 
841
 
        LOG_TIMER("Timer command 'P'ause already executed today. Current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d).\n", 
842
 
                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, tr->day_of_year);
 
841
        LOG_TIMER("Timer command 'P'ause already executed today. Current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d).\n",
 
842
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, tr->day_of_year);
843
843
 
844
844
        return 0;
845
845
    }
852
852
 
853
853
    // Check if clock-time is over pause-time
854
854
    if (clock_secs > timer_secs) {
855
 
    // FIXME: Should we check tr->day_of_year != tmp->tm_yday here?
856
 
    // if (timer_secs > clock_secs && tr->day_of_year != tmp->tm_yday) {
 
855
        // FIXME: Should we check tr->day_of_year != tmp->tm_yday here?
 
856
        // if (timer_secs > clock_secs && tr->day_of_year != tmp->tm_yday) {
857
857
 
858
858
        // Already fired today? (fire once a day)
859
859
        if (tr->day_of_year != tmp->tm_yday) {
862
862
        }
863
863
    }
864
864
 
865
 
    LOG_TIMER("Test clock time for 'P'ause: current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d) diff in secs:%ld, -->%s\n", 
866
 
             tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday, 
867
 
             tr->day_of_year, (long)(timer_secs - clock_secs), (action == 0 ? "FALSE" : "TRUE"));
 
865
    LOG_TIMER("Test clock time for 'P'ause: current time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f (day_of_year:%d/%d) diff in secs:%ld, -->%s\n",
 
866
              tmp->tm_hour, tmp->tm_min, tmp->tm_sec,  tr->val[0], tr->val[1], tr->val[2], tmp->tm_yday,
 
867
              tr->day_of_year, (long)(timer_secs - clock_secs), (action == 0 ? "FALSE" : "TRUE"));
868
868
 
869
869
    return action;
870
870
}
913
913
 
914
914
        gint64 diff = timer_secs - recording_time_secs;
915
915
 
916
 
        LOG_TIMER("Test time period for '%c' (%s): current rec.time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f diff secs:%ld, -->%s.\n", 
917
 
                  tr->action, parser_get_action_name(tr->action), 
 
916
        LOG_TIMER("Test time period for '%c' (%s): current rec.time:%02d:%02d:%02d timer value:%02.0f:%02.0f:%02.0f diff secs:%ld, -->%s.\n",
 
917
                  tr->action, parser_get_action_name(tr->action),
918
918
                  hh, mm, ss, tr->val[0], tr->val[1], tr->val[2], (long)diff, (action == 0 ? "FALSE" : "TRUE"));
919
919
#endif
920
920
 
934
934
 
935
935
            // Fire only once a day
936
936
            LOG_TIMER("Timer command 'S'tart already executed once!: clock time:%02d:%02d:%02d timer thread started:%02d:%02d:%02d"
937
 
                       " timer value (duration):%02.0f:%02.0f:%02.0f.\n",
938
 
                     tmp->tm_hour, tmp->tm_min, tmp->tm_sec, start_time.tm_hour, start_time.tm_min, start_time.tm_sec,
939
 
                     tr->val[0], tr->val[1], tr->val[2]);
 
937
                      " timer value (duration):%02.0f:%02.0f:%02.0f.\n",
 
938
                      tmp->tm_hour, tmp->tm_min, tmp->tm_sec, start_time.tm_hour, start_time.tm_min, start_time.tm_sec,
 
939
                      tr->val[0], tr->val[1], tr->val[2]);
940
940
 
941
941
            return 0;
942
942
        }
943
943
 
944
 
        // Clock time in secs    
 
944
        // Clock time in secs
945
945
        gint64 curr_time_secs = tmp->tm_hour*3600.0 + tmp->tm_min*60.0 + tmp->tm_sec;
946
946
 
947
947
        // TimerRec's value in seconds
960
960
        (void) diff; // Avoid unused var message
961
961
 
962
962
        LOG_TIMER("Test time period for 'S'tart: clock time:%02d:%02d:%02d timer thread started:%02d:%02d:%02d"
963
 
                   " timer value (duration):%02.0f:%02.0f:%02.0f  diff secs:%ld, -->%s\n",
 
963
                  " timer value (duration):%02.0f:%02.0f:%02.0f  diff secs:%ld, -->%s\n",
964
964
                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec, start_time.tm_hour, start_time.tm_min, start_time.tm_sec,
965
965
                  tr->val[0], tr->val[1], tr->val[2], (long)diff, (action == 0 ? "FALSE" : "TRUE"));
966
966
 
1020
1020
    const gchar *state_name = rec_manager_get_state_name(state);
1021
1021
 
1022
1022
    LOG_TIMER("Silence test. timer value:%3.1f sec, count seconds:%3.1f sec, *RMS:%3.2f, threshold:%3.1f%s (%3.2f), state:%s\n",
1023
 
        seconds, tr->time_below, rms, tr->threshold, (tr->threshold_unit ? tr->threshold_unit : ""), tr->norm_threshold, state_name);
 
1023
              seconds, tr->time_below, rms, tr->threshold, (tr->threshold_unit ? tr->threshold_unit : ""), tr->norm_threshold, state_name);
1024
1024
#endif
1025
1025
 
1026
1026
    // RMS > tr->threshold?
1030
1030
 
1031
1031
        if (tr->action == 'P') { // Pause
1032
1032
            // Resume (continue) recording after pause
1033
 
            action = 'C'; 
 
1033
            action = 'C';
1034
1034
            goto LBL_1;
1035
1035
        }
1036
1036
        return;
1067
1067
              rms, tr->norm_threshold, tr->threshold, (tr->threshold_unit ? tr->threshold_unit : ""),
1068
1068
              seconds, parser_get_action_name(action));
1069
1069
 
1070
 
  LBL_1:
1071
 
    // Exceute action 
 
1070
LBL_1:
 
1071
    // Exceute action
1072
1072
    execute_action(tr, action);
1073
1073
 
1074
1074
    // Reset counters
1095
1095
    const gchar *state_name = rec_manager_get_state_name(state);
1096
1096
 
1097
1097
    LOG_TIMER("Sound/Voice/Audio test. timer value:%3.1f sec, count seconds:%3.1f sec, *RMS:%3.2f, threshold:%3.1f%s (%3.2f), state:%s\n",
1098
 
        seconds, tr->time_above, rms, tr->threshold, (tr->threshold_unit ? tr->threshold_unit : ""), tr->norm_threshold, state_name);
 
1098
              seconds, tr->time_above, rms, tr->threshold, (tr->threshold_unit ? tr->threshold_unit : ""), tr->norm_threshold, state_name);
1099
1099
#endif
1100
1100
 
1101
1101
    // rms over threshold?
1109
1109
            tr->time_below = 0.0;
1110
1110
            goto LBL_1;
1111
1111
        }
1112
 
        
 
1112
 
1113
1113
        // Add time_diff to tr->time_above, convert to seconds
1114
1114
        tr->time_above += ((gdouble)time_diff / GST_SECOND);
1115
1115
 
1152
1152
    tr->time_above = 0.0;
1153
1153
    tr->time_below = 0.0;
1154
1154
 
1155
 
  LBL_1:
1156
 
    // Excecute action 
 
1155
LBL_1:
 
1156
    // Excecute action
1157
1157
    execute_action(tr, action);
1158
1158
 
1159
1159
}