1 /*
2 gnauralnet_clocksync.c
3 Core methods and variables for common timing on the GnauralNet network
4 Depends on:
5 gnauralnet.h
6 gnauralnet_clocksync.c
7 gnauralnet_lists.c
8 gnauralnet_main.c
9 gnauralnet_socket.c
10
11 Copyright (C) 2008 Bret Logan
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28 #include "gnauralnet.h"
29
30 ////////////////////////////////////////
31 //This returns the number of microsecs (usecs) since last call;
32 //IMPORTANT: first call will return garbage, so it is
33 //STRONGLY recommended to make that first call before anything
34 //critical.
GN_Time_ElapsedSinceLastCall()35 unsigned int GN_Time_ElapsedSinceLastCall ()
36 {
37 static GTimeVal lasttime = { 0, 0 };
38 unsigned int result;
39 GTimeVal curtime;
40
41 g_get_current_time (&curtime);
42 result =
43 (((curtime.tv_sec - lasttime.tv_sec) * 1e6) +
44 (curtime.tv_usec - lasttime.tv_usec));
45 memcpy (&lasttime, &curtime, sizeof (GTimeVal));
46
47 return result;
48 }
49
50 ////////////////////////////////////////
51 //Update data for the friend's entry with this incoming Time data.
52 //returns GNAURALNET_SUCCESS if time info was legit (PacketID, etc.),
53 //GNAURALNET_FAILURE if not.
GN_Time_ProcessIncomingData(GN_Friend * curFriend)54 int GN_Time_ProcessIncomingData (GN_Friend * curFriend)
55 {
56 if (NULL == curFriend)
57 {
58 return GNAURALNET_FAILURE;
59 }
60
61 //do stuff that gets recorded even if packet gets discarded:
62 g_get_current_time (&(curFriend->Time_Recv));
63
64 //make sure this wasn't first packet between us, or that
65 //friend is remembering me from before I restarted:
66 if (2 > curFriend->RecvCount)
67 {
68 GN_DBGOUT ("Haven't known Friend long enough to share Time");
69 return GNAURALNET_FAILURE;
70 }
71
72 curFriend->Time_PacketRoundTrip =
73 (((curFriend->Time_Recv.tv_sec - curFriend->Time_Send.tv_sec) * 1e6) +
74 (curFriend->Time_Recv.tv_usec - curFriend->Time_Send.tv_usec));
75
76 GN_DBGOUT_INT ("PacketRoundTrip time:", curFriend->Time_PacketRoundTrip);
77
78 if (0 == curFriend->Time_AverageOffset)
79 {
80 curFriend->Time_AverageOffset = 0.5 * curFriend->Time_PacketRoundTrip;
81 GN_DBGOUT_DBL ("New friend, starting Offset at:",
82 curFriend->Time_AverageOffset);
83 }
84 else
85 {
86 curFriend->Time_AverageOffset =
87 (curFriend->Time_AverageOffset - (0.1 * curFriend->Time_AverageOffset)) +
88 (0.05 * curFriend->Time_PacketRoundTrip);
89 GN_DBGOUT_DBL ("Offset from Friend:", curFriend->Time_AverageOffset);
90 }
91
92 //do the BinauralBeat stuff if GN_STANDALONE is not defined:
93 GN_Running_ProcessIncomingData (curFriend);
94 return GNAURALNET_SUCCESS;
95 }
96
97 ////////////////////////////////////////
98 //Give this the friend in question for this incoming Time data.
99 //returns GNAURALNET_SUCCESS if time info was legit (PacketID, etc.),
100 //GNAURALNET_FAILURE if not.
GN_Time_ProcessOutgoingData(GN_Friend * curFriend)101 void GN_Time_ProcessOutgoingData (GN_Friend * curFriend)
102 {
103 if (NULL == curFriend)
104 {
105 return;
106 }
107
108 //++curFriend->PacketID; //uchar, so no need to net-order
109 //curFriend->PacketID_expected = curFriend->PacketID + 1; //uchar, so no need to net-order
110
111 g_get_current_time (&(curFriend->Time_Send));
112
113 //20080221: this segment is meaningless now:
114 if (0 != curFriend->RecvCount)
115 {
116 curFriend->Time_DelayOnMe =
117 ((curFriend->Time_Send.tv_sec - curFriend->Time_Recv.tv_sec) * 1e6) +
118 (curFriend->Time_Send.tv_usec - curFriend->Time_Recv.tv_usec);
119 GN_DBGOUT_UINT ("Delay on Me:", curFriend->Time_DelayOnMe);
120 }
121
122 //do the BinauralBeat stuff if GN_STANDALONE is not defined:
123 GN_Running_ProcessOutgoingData (curFriend);
124 }
125
126 ////////////////////////////////////////////////////////////////
127 //Called by anything that breaks continuity of a runing schedule.
128 //Like FF, RW, STOP, PAUSE, engine-reloading, etc.
GN_Time_ResetSeniority()129 void GN_Time_ResetSeniority ()
130 {
131 g_get_current_time (&(GN_My.RunningStartTime));
132 }
133
134 ////////////////////////////////////////////////////////////////
135 //The following was provided so that apps not requiring BB could
136 //be run; it was done by putting all calls that need BB vars in
137 //gnauralnet_running.c
138 #ifdef GN_STANDALONE
139 ////////////////////////////////////////
140 //THIS IS A DUMMY FUNCTIONl see gnauralnet_running.c for real one
GN_Running_ProcessIncomingData(GN_Friend * curFriend)141 void GN_Running_ProcessIncomingData (GN_Friend * curFriend)
142 {
143 if (NULL == curFriend)
144 {
145 return;
146 }
147
148 if (0 == GN_My.RunningID || curFriend->RunningID != GN_My.RunningID)
149 {
150 return;
151 }
152 // unsigned int CurrentSampleCount;
153 // int LoopCount;
154 }
155
156 ////////////////////////////////////////
157 //THIS IS A DUMMY FUNCTION see gnauralnet_running.c for real one
GN_Running_ProcessOutgoingData(GN_Friend * curFriend)158 void GN_Running_ProcessOutgoingData (GN_Friend * curFriend)
159 {
160 if (NULL == curFriend)
161 {
162 return;
163 }
164
165 if (0 == GN_My.RunningID || curFriend->RunningID != GN_My.RunningID)
166 {
167 return;
168 }
169 // unsigned int CurrentSampleCount;
170 // int LoopCount;
171 }
172 #endif
173