3030 *
3131 * todo:
3232 * sanity checks
33- * pad output on hop
3433 * frequency ranges could be stored better
3534 * auto-hop after time limit
3635 * peak detector to tune onto stronger signals
@@ -188,6 +187,8 @@ struct output_state
188187 pthread_rwlock_t rw ;
189188 pthread_cond_t ready ;
190189 pthread_mutex_t ready_m ;
190+ pthread_mutex_t trycond_m ;
191+ int trycond ;
191192};
192193
193194struct controller_state
@@ -238,7 +239,9 @@ void usage(void)
238239 "\t no-mod: enable no-mod direct sampling\n"
239240 "\t offset: enable offset tuning\n"
240241 "\t wav: generate WAV header\n"
241- "\t pad: pad output with zeros (broken)\n"
242+ #ifndef _WIN32
243+ "\t pad: pad output gaps with zeros\n"
244+ #endif
242245 "\tfilename ('- ' means stdout)\n"
243246 "\t omitting the filename also uses stdout\n\n"
244247 "Experimental options:\n"
@@ -927,18 +930,21 @@ static void *demod_thread_fn(void *arg)
927930 if (d -> exit_flag ) {
928931 do_exit = 1 ;
929932 }
933+ pthread_rwlock_wrlock (& o -> rw );
934+ o -> result = d -> lowpassed ;
935+ o -> result_len = d -> lp_len ;
936+ pthread_rwlock_unlock (& o -> rw );
930937 if (controller .freq_len > 1 && d -> squelch_level && \
931938 d -> squelch_hits > d -> conseq_squelch ) {
932939 unmark_shared_buffer (d -> lowpassed );
933940 d -> squelch_hits = d -> conseq_squelch + 1 ; /* hair trigger */
934941 safe_cond_signal (& controller .hop , & controller .hop_m );
935942 continue ;
936943 }
937- pthread_rwlock_wrlock (& o -> rw );
938- o -> result = d -> lowpassed ;
939- o -> result_len = d -> lp_len ;
940- pthread_rwlock_unlock (& o -> rw );
941944 safe_cond_signal (& o -> ready , & o -> ready_m );
945+ pthread_mutex_lock (& o -> trycond_m );
946+ o -> trycond = 0 ;
947+ pthread_mutex_unlock (& o -> trycond_m );
942948 }
943949 return 0 ;
944950}
@@ -954,7 +960,7 @@ static int get_nanotime(struct timespec *ts)
954960
955961 rv = gettimeofday (& tv , NULL );
956962 ts -> tv_sec = tv .tv_sec ;
957- ts -> tv_nsec = tv .tv_usec * 1000 ;
963+ ts -> tv_nsec = tv .tv_usec * 1000L ;
958964#endif
959965 return rv ;
960966}
@@ -964,11 +970,9 @@ static void *output_thread_fn(void *arg)
964970{
965971 int r = 0 ;
966972 struct output_state * s = arg ;
967- //struct timespec abstime;
968973 struct timespec start_time ;
969974 struct timespec now_time ;
970- struct timespec fut_time ;
971- int64_t interval , delay , samples , samples2 , i ;
975+ int64_t i , duration , samples , samples_now ;
972976 samples = 0L ;
973977#ifndef _WIN32
974978 get_nanotime (& start_time );
@@ -984,34 +988,33 @@ static void *output_thread_fn(void *arg)
984988 }
985989#ifndef _WIN32
986990 /* padding requires output at constant rate */
987- /* figure out how to do this with windows HPET */
988- pthread_mutex_lock ( & s -> ready_m );
989- delay = 1000000000L * ( int64_t ) s -> result_len / ( int64_t ) s -> rate ;
990- get_nanotime ( & fut_time );
991- fut_time . tv_nsec += delay ;
992- r = pthread_cond_timedwait ( & s -> ready , & s -> ready_m , & fut_time ) ;
993- pthread_mutex_unlock (& s -> ready_m );
994- if (r != ETIMEDOUT ) {
991+ /* pthread_cond_timedwait is terrible, roll our own trycond */
992+ // figure out how to do this with windows HPET
993+ usleep ( 2000 ) ;
994+ pthread_mutex_lock ( & s -> trycond_m );
995+ r = s -> trycond ;
996+ s -> trycond = 1 ;
997+ pthread_mutex_unlock (& s -> trycond_m );
998+ if (r == 0 ) {
995999 pthread_rwlock_rdlock (& s -> rw );
9961000 fwrite (s -> result , 2 , s -> result_len , s -> file );
9971001 unmark_shared_buffer (s -> result );
998- samples += s -> result_len ;
1002+ samples += ( int64_t ) s -> result_len ;
9991003 pthread_rwlock_unlock (& s -> rw );
10001004 continue ;
10011005 }
10021006 get_nanotime (& now_time );
1003- interval = now_time .tv_sec - start_time .tv_sec ;
1004- interval *= 1000000000L ;
1005- interval += (now_time .tv_nsec - start_time .tv_nsec );
1006- samples2 = interval * (int64_t )s -> rate / 1000000000L ;
1007- samples2 -= samples ;
1008- //fprintf(stderr, "%lli %lli %lli\n", delay, interval, samples);
1009- /* there must be a better way to write zeros */
1010- for (i = 0L ; i < samples2 ; i ++ ) {
1007+ duration = now_time .tv_sec - start_time .tv_sec ;
1008+ duration *= 1000000000L ;
1009+ duration += (now_time .tv_nsec - start_time .tv_nsec );
1010+ samples_now = (duration * (int64_t )s -> rate ) / 1000000000L ;
1011+ if (samples_now < samples ) {
1012+ continue ;}
1013+ for (i = samples ; i < samples_now ; i ++ ) {
10111014 fputc (0 , s -> file );
10121015 fputc (0 , s -> file );
10131016 }
1014- samples += samples2 ;
1017+ samples = samples_now ;
10151018#endif
10161019 }
10171020 return 0 ;
@@ -1163,6 +1166,8 @@ void output_init(struct output_state *s)
11631166 pthread_rwlock_init (& s -> rw , NULL );
11641167 pthread_cond_init (& s -> ready , NULL );
11651168 pthread_mutex_init (& s -> ready_m , NULL );
1169+ pthread_mutex_init (& s -> trycond_m , NULL );
1170+ s -> trycond = 1 ;
11661171 s -> result = NULL ;
11671172}
11681173
@@ -1171,6 +1176,7 @@ void output_cleanup(struct output_state *s)
11711176 pthread_rwlock_destroy (& s -> rw );
11721177 pthread_cond_destroy (& s -> ready );
11731178 pthread_mutex_destroy (& s -> ready_m );
1179+ pthread_mutex_destroy (& s -> trycond_m );
11741180}
11751181
11761182void controller_init (struct controller_state * s )
@@ -1430,6 +1436,7 @@ int main(int argc, char **argv)
14301436 signal (SIGPIPE , SIG_IGN );
14311437#else
14321438 SetConsoleCtrlHandler ( (PHANDLER_ROUTINE ) sighandler , TRUE );
1439+ output .padded = 0 ;
14331440#endif
14341441
14351442 if (demod .deemph ) {
0 commit comments