void main_loop_reverse(void) { LTCFrame f; const long long int end = ceil(duration * samplerate / 1000.0); long long int written = 0; active=1; short *snd = NULL; const short smult = rint(pow(10, volume_dbfs/20.0) * 32767.0); while(active==1 && (duration <= 0 || end >= written)) { int byteCnt; for (byteCnt = 9; byteCnt >= 0; byteCnt--) { int i; ltc_encoder_encode_byte(encoder, byteCnt, -1.0); const int len = ltc_encoder_get_buffer(encoder, enc_buf); if (!snd) snd = malloc(len * sizeof(short)); for (i=0;i<len;i++) { const short val = ( (int)(enc_buf[i] - 128) * smult / 90 ); snd[i] = val; } sf_writef_short(sf, snd, len); written += len; if (end < written) break; } /* end byteCnt - one video frames's worth of LTC */ ltc_encoder_get_frame(encoder, &f); ltc_frame_decrement(&f, ceil(fps_num/fps_den), fps_num/(double)fps_den == 25.0? LTC_TV_625_50 : LTC_TV_525_60, LTC_USE_DATE); ltc_encoder_set_frame(encoder, &f); } free(snd); printf("wrote %lld audio-samples\n", written); }
int detect_discontinuity(LTCFrameExt *frame, LTCFrameExt *prev, int fps, int use_date, int fuzzyfps) { int discontinuity_detected = 0; if (fuzzyfps && ( (frame->reverse && prev->ltc.frame_units == 0) ||(!frame->reverse && frame->ltc.frame_units == 0) )){ memcpy(prev, frame, sizeof(LTCFrameExt)); return 0; } if (frame->reverse) ltc_frame_decrement(&prev->ltc, fps, fps == 25? LTC_TV_625_50 : LTC_TV_525_60, use_date?LTC_USE_DATE:0); else ltc_frame_increment(&prev->ltc, fps, fps == 25? LTC_TV_625_50 : LTC_TV_525_60, use_date?LTC_USE_DATE:0); if (cmp_ltc_frametime(&prev->ltc, &frame->ltc, use_date?1:0)) discontinuity_detected = 1; memcpy(prev, frame, sizeof(LTCFrameExt)); return discontinuity_detected; }
int ltc_encoder_dec_timecode(LTCEncoder *e) { return ltc_frame_decrement (&e->f, rint(e->fps), e->standard, e->flags); }
int ltc_frame_decrement(LTCFrame* frame, int fps, enum LTC_TV_STANDARD standard, int flags) { int rv = 0; int frames = frame->frame_units + frame->frame_tens * 10; if (frames > 0) { frames--; } else { frames = fps -1; } frame->frame_units = frames % 10; frame->frame_tens = frames / 10; if (frames == fps -1) { int secs = frame->secs_units + frame->secs_tens * 10; if (secs > 0) { secs--; } else { secs = 59; } frame->secs_units = secs % 10; frame->secs_tens = secs / 10; if (secs == 59) { int mins = frame->mins_units + frame->mins_tens * 10; if (mins > 0) { mins--; } else { mins = 59; } frame->mins_units = mins % 10; frame->mins_tens = mins / 10; if (mins == 59) { int hours = frame->hours_units + frame->hours_tens * 10; if (hours > 0) { hours--; } else { hours = 23; } frame->hours_units = hours % 10; frame->hours_tens = hours / 10; if (hours == 23) { /* 24h wrap around */ rv=1; if (flags<C_USE_DATE) { /* wrap date */ SMPTETimecode stime; stime.years = frame->user5 + frame->user6*10; stime.months = frame->user3 + frame->user4*10; stime.days = frame->user1 + frame->user2*10; if (stime.months > 0 && stime.months < 13) { unsigned char dpm[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /* proper leap-year calc: * ((stime.years%4)==0 && ( (stime.years%100) != 0 || (stime.years%400) == 0) ) * simplified since year is 0..99 */ if ((stime.years%4)==0 /* && stime.years!=0 */ ) /* year 2000 was a leap-year */ dpm[1]=29; // if (stime.days > 1) { stime.days--; } else { stime.months = 1 + (stime.months + 10)%12; stime.days = dpm[stime.months-1]; if (stime.months == 12) { stime.years=(stime.years+99)%100; // XXX } } frame->user6 = stime.years/10; frame->user5 = stime.years%10; frame->user4 = stime.months/10; frame->user3 = stime.months%10; frame->user2 = stime.days/10; frame->user1 = stime.days%10; } else { rv=-1; } } } } } } if (frame->dfbit && /* prevent endless recursion */ fps > 2) { if ((frame->mins_units != 0) && (frame->secs_units == 0) && (frame->secs_tens == 0) && (frame->frame_units == 1) && (frame->frame_tens == 0) ) { ltc_frame_decrement(frame, fps, standard, flags<C_USE_DATE); ltc_frame_decrement(frame, fps, standard, flags<C_USE_DATE); } } if ((flags & LTC_NO_PARITY) == 0) { ltc_frame_set_parity(frame, standard); } return rv; }