blob: 25c8e655cf379fd7adebfdac1d0c9485d9b38944 [file] [log] [blame]
Piotr Krysik34ce7a02017-10-31 11:30:59 +01001/* -*- c++ -*- */
2/* @file
3 * @author Piotr Krysik <ptrkrysik@gmail.com>
4 * @author Vadim Yanitskiy <axilirator@gmail.com>
5 * @section LICENSE
6 *
7 * Gr-gsm is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
11 *
12 * Gr-gsm is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with gr-gsm; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include <grgsm/misc_utils/fn_time.h>
25#include <math.h>
Piotr Krysik34ce7a02017-10-31 11:30:59 +010026
27#define GSM_HYPER_FRAME 26 * 51 * 2048
28#define GSM_SYM_RATE 13.0e6 / 48.0
29
30#define GSM_TS_PERIOD 156.25 / GSM_SYM_RATE
31#define GSM_FN_PERIOD 8 * GSM_TS_PERIOD
32
33namespace gr {
34 namespace gsm {
Piotr Krysik34ce7a02017-10-31 11:30:59 +010035 /**
36 * Computes difference between two frame numbers modulo
37 * GSM_HYPER_FRAME / 2. The result is correct if difference
38 * between the frame numbers is not bigger than GSM_HYPER_FRAME / 2.
39 * @param fn1 first frame number
40 * @param fn2 second frame number
41 * @return computed difference
42 */
43 static uint32_t fnmod_delta(uint32_t fn1, uint32_t fn2)
44 {
45 uint32_t delta, h2;
46
47 delta = (fn1 % GSM_HYPER_FRAME) - (fn2 % GSM_HYPER_FRAME);
48 h2 = GSM_HYPER_FRAME / 2;
49
50 if (delta >= h2)
51 delta -= GSM_HYPER_FRAME;
52 else
53 delta += GSM_HYPER_FRAME;
54
55 return delta;
56 }
57
58 static int fn_time_diff_delta(uint32_t fn, uint32_t fn_ref,
59 time_spec_t time_diff_hint)
60 {
61 int frames_diff, fn_delta;
62
63 frames_diff = int(round(time_diff_hint.get_real_secs() / GSM_FN_PERIOD));
64 fn_delta = fnmod_delta(fn, fn_ref + frames_diff) + frames_diff;
65
66 return fn_delta;
67 }
68
69 /**
70 * Computes difference between reference frame number
71 * and a second frame number.
72 * @param fn_ref reference frame number modulo GSM_HYPER_FRAME
73 * @param fn second frame number modulo GSM_HYPER_FRAME
74 * @param time_ref precise timestamp of the first sample in the fn_ref
75 * @param time_hint coarse time for fn that is used as a hint to avoid
76 * ambiguities caused by modulo operation applied to
77 * frame numbers
78 * @return difference between fn_ref and fn
79 */
Piotr Krysik1dd2afe2017-10-31 12:57:26 +010080 time_spec_t fn_time_delta2(uint32_t fn_ref, time_spec_t time_ref, uint32_t fn_x,
Piotr Krysik34ce7a02017-10-31 11:30:59 +010081 time_spec_t time_hint, uint32_t ts_num, uint32_t ts_ref)
82 {
83 time_spec_t time_diff_hint = time_hint - time_ref;
84 uint32_t fn_delta = fn_time_diff_delta(fn_x,fn_ref, time_diff_hint);
85 time_spec_t time_x_precise = fn_delta * GSM_FN_PERIOD
86 + time_ref + (ts_num - ts_ref) * GSM_TS_PERIOD;
87
88 return time_x_precise;
89 }
90/*
91 def fn_time_delta(fn_ref, time_ref, fn_x, time_hint=None, ts_num=0, ts_ref=0):
92 if time_hint is None:
93 time_hint = time_ref
94
95 time_diff_hint = time_hint-time_ref
96 fn_delta = fn_time_diff_delta(fn_x,fn_ref, time_diff_hint)
97 time_x_precise = fn_delta*__frame_period+time_ref+(ts_num-ts_ref)*__ts_period
98
99 return fn_delta, time_x_precise
100*/
101 } /* namespace gsm */
102} /* namespace gr */
103