npv:_reasonable_ "pedanticage" of the code
[nyanmp.git] / npv / clk / public / code.frag.c
blobc8a4604d1a60fcaca8c5b013eed5942267de92cc
1 STATIC void npv_clk_init_once(void)
3 int r;
5 r = snd_pcm_status_malloc(&npv_clk_l.ref.status);
6 if (r != 0)
7 npv_clk_fatal("alsa:unable to allocate an alsa status structure\n");
8 r = snd_pcm_status_malloc(&npv_clk_l.now.status);
9 if (r != 0)
10 npv_clk_fatal("alsa:unable to allocate an alsa status structure\n");
11 /* we pre-allocate alsa pcm hw_params container */
12 r = snd_pcm_hw_params_malloc(&npv_clk_pcm_hw_params_l);
13 if (r < 0)
14 npv_clk_fatal("alsa:unable to allocate hardware parameters context\n");
15 npv_clk_l.paused = false;
17 #define NO_REF_TIME_POINT 1
18 STATIC u8 npv_clk_get_audio_st_ts(s64 *ts)
20 int r;
21 snd_pcm_audio_tstamp_config_t ac;
22 snd_htimestamp_t hts;
23 f64 now_ns;
24 f64 ref_ns;
25 f64 ref_status_ns;
26 f64 ref_delay_frs_n;
27 f64 ref_audio_ts;
28 f64 audio_tb_num;
29 f64 audio_tb_den;
30 f64 audio_rate_num;
31 unsigned int audio_rate_num_ui;
32 f64 audio_rate_den;
33 unsigned int audio_rate_den_ui;
34 f64 written_frs_n;
35 f64 now_audio_ts;
36 f64 now_video_ts;
38 if (!npv_clk_l.ref_valid)
39 return NO_REF_TIME_POINT;
40 if (!npv_clk_l.paused) {
41 memset(npv_clk_l.now.status, 0, snd_pcm_status_sizeof());
42 ac.report_delay = 0;
43 ac.type_requested = (unsigned int)npv_audio_selected_ts_type_p;
44 snd_pcm_status_set_audio_htstamp_config(npv_clk_l.now.status,
45 &ac);
46 r = snd_pcm_status(npv_audio_pcm_p, npv_clk_l.now.status);
47 if (r < 0)
48 npv_clk_fatal("alsa:unable to sample timing information for 'now' time point\n");
50 snd_pcm_status_get_audio_htstamp(npv_clk_l.now.status, &hts);
51 now_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec;
53 snd_pcm_status_get_audio_htstamp(npv_clk_l.ref.status, &hts);
54 ref_status_ns = (f64)hts.tv_sec * 1e9 + (f64)hts.tv_nsec;
56 ref_audio_ts = (f64)npv_clk_l.ref.audio_st_ts;
57 ref_delay_frs_n = (f64)snd_pcm_status_get_delay(npv_clk_l.ref.status);
58 audio_tb_num = (f64)npv_audio_st_p.tb.num;
59 audio_tb_den = (f64)npv_audio_st_p.tb.den;
60 /*--------------------------------------------------------------------*/
61 r = snd_pcm_hw_params_current(npv_audio_pcm_p, npv_clk_pcm_hw_params_l);
62 if (r != 0)
63 npv_clk_fatal("alsa:unable to get current hardware parameters\n");
64 r = snd_pcm_hw_params_get_rate_numden(npv_clk_pcm_hw_params_l,
65 &audio_rate_num_ui, &audio_rate_den_ui);
66 if (r < 0)
67 npv_clk_fatal("alsa:unable to get exact rate\n");
68 audio_rate_num = (f64)audio_rate_num_ui;
69 audio_rate_den = (f64)audio_rate_den_ui;
70 /*--------------------------------------------------------------------*/
71 written_frs_n = (f64)npv_clk_l.ref.written_ufrs_n;
73 /* time translation */
74 ref_ns = ref_status_ns + (ref_delay_frs_n - written_frs_n)
75 * audio_rate_den * 1e9 / audio_rate_num;
76 /* basic linear interpolation */
77 now_audio_ts = audio_tb_den * 1e-9 * (now_ns - ref_ns) / audio_tb_num
78 + ref_audio_ts;
79 *ts = (s64)lrint(now_audio_ts);
80 return TS_RETURNED;
82 #undef NO_REF_TIME_POINT
83 STATIC u8 npv_clk_get_video_st_ts(s64 *ts)
85 f64 audio_tb_num;
86 f64 audio_tb_den;
87 f64 video_tb_num;
88 f64 video_tb_den;
89 f64 now_audio_ts;
90 s64 now_audio_ts_s64;
91 f64 now_video_ts;
92 u8 r;
94 audio_tb_num = (f64)npv_audio_st_p.tb.num;
95 audio_tb_den = (f64)npv_audio_st_p.tb.den;
96 video_tb_num = (f64)npv_video_st_p.tb.num;
97 video_tb_den = (f64)npv_video_st_p.tb.den;
99 r = npv_clk_get_audio_st_ts(&now_audio_ts_s64);
100 if (r != TS_RETURNED)
101 return r;
102 now_audio_ts = (f64)now_audio_ts_s64;
103 /* basic conversion */
104 now_video_ts = audio_tb_num * video_tb_den * now_audio_ts
105 / (audio_tb_den * video_tb_num);
106 *ts = (s64)lrint(now_video_ts);
107 return TS_RETURNED;
109 STATIC void npv_clk_ref_time_point_update(s64 audio_ts,
110 snd_pcm_ufrs_t written_ufrs_n)
112 int r;
113 snd_pcm_audio_tstamp_config_t ac;
115 memset(npv_clk_l.ref.status, 0, snd_pcm_status_sizeof());
116 ac.report_delay = 0;
117 ac.type_requested = (unsigned int)npv_audio_selected_ts_type_p;
118 snd_pcm_status_set_audio_htstamp_config(npv_clk_l.ref.status, &ac);
119 r = snd_pcm_status(npv_audio_pcm_p, npv_clk_l.ref.status);
120 if (r < 0)
121 npv_clk_fatal("unable to sample timing information for reference time point\n");
122 npv_clk_l.ref.audio_st_ts = audio_ts;
123 npv_clk_l.ref.written_ufrs_n = written_ufrs_n;
124 npv_clk_l.ref_valid = true;
126 STATIC void npv_clk_invalidate(void)
128 npv_clk_l.ref_valid = false;
130 STATIC void npv_clk_pause(void)
132 int r;
133 snd_pcm_audio_tstamp_config_t ac;
135 npv_clk_l.paused = true;
136 memset(npv_clk_l.now.status, 0, snd_pcm_status_sizeof());
137 ac.report_delay = 0;
138 ac.type_requested = (unsigned int)npv_audio_selected_ts_type_p;
139 snd_pcm_status_set_audio_htstamp_config(npv_clk_l.now.status, &ac);
140 r = snd_pcm_status(npv_audio_pcm_p, npv_clk_l.now.status);
141 if (r < 0)
142 npv_clk_fatal("alsa:unable to sample timing information for 'paused' time point\n");
144 STATIC void npv_clk_unpause(void)
146 npv_clk_l.paused = false;
147 npv_clk_invalidate();