1 /*
2    gnauralnet_running.c
3    This should be the only place BinauralBeat.h variables are accessed
4    The point of this file is to contain only things that need BB vars.
5    Depends on:
6    gnauralnet.h
7    gnauralnet_clocksync.c
8    gnauralnet_lists.c
9    gnauralnet_main.c
10    gnauralnet_socket.c
11 
12    Copyright (C) 2008 Bret Logan
13 
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 2 of the License, or
17    (at your option) any later version.
18 
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  */
28 
29 #include "gnauralnet.h"
30 #include "BinauralBeat.h"
31 
32 ////////////////////////////////////////
33 //this prepares various local vars that will be loaded as
34 //outgoing data in gnauralnet_main
35 //Gets called by GN_Time_ProcessOutgoingData
GN_Running_ProcessOutgoingData(GN_Friend * curFriend)36 void GN_Running_ProcessOutgoingData (GN_Friend * curFriend)
37 {
38  if (NULL == curFriend)
39  {
40   return;
41  }
42  GN_My.CurrentSampleCount = BB_CurrentSampleCount;
43  if (0 > BB_LoopCount)
44  {
45   GN_My.LoopCount = -1;
46  }
47  else
48  {
49   if (0x7fff > BB_LoopCount)
50   {
51    GN_My.LoopCount = BB_LoopCount;
52   }
53   else
54   {
55    GN_My.LoopCount = 0x7fff;
56   }
57  }
58 }
59 
60 ////////////////////////////////////////
61 //Gets called by GN_Time_ProcessIncomingData
GN_Running_ProcessIncomingData(GN_Friend * curFriend)62 void GN_Running_ProcessIncomingData (GN_Friend * curFriend)
63 {
64  if (NULL == curFriend)
65  {
66   return;
67  }
68  /*
69     this will need to be in eventually:
70     if (0 == GN_My.RunningID || curFriend->RunningID != GN_My.RunningID)
71     {
72     return;
73     }
74   */
75  //  unsigned int CurrentSampleCount;
76  //  int LoopCount;
77  if (TRUE == BB_InCriticalLoopFlag)
78  {
79   GN_DBGOUT ("Not updating; BB in critical loop");
80   return;
81  }
82 
83  if (curFriend->ScheduleFingerprint != GN_My.ScheduleFingerprint)
84  {
85   GN_DBGOUT_INT ("NOT Same schedule:", curFriend->ScheduleFingerprint);
86   GN_DBGOUT_INT ("               Me:", GN_My.ScheduleFingerprint);
87  }
88  else
89  {
90   GN_DBGOUT_INT ("Same schedule:", GN_My.ScheduleFingerprint);
91  }
92 
93  //need to actually implement this:
94  if (curFriend->RunningID != GN_My.RunningID)
95  {
96   GN_DBGOUT_INT ("NOT Same running:", curFriend->RunningID);
97   GN_DBGOUT_INT ("              Me:", GN_My.RunningID);
98  }
99  else
100  {
101   GN_DBGOUT_INT ("Same running:", GN_My.RunningID);
102  }
103 
104  //Now see if incoming data has seniority over mine:
105  curFriend->CurrentSampleCount_diff = BB_CurrentSampleCount -
106   curFriend->CurrentSampleCount;
107  if (curFriend->RunningSeniority >
108      (curFriend->Time_Recv.tv_sec - GN_My.RunningStartTime.tv_sec))
109  {
110   GN_DBGOUT_INT ("I Follow, sample diff:",
111 		 curFriend->CurrentSampleCount_diff);
112   BB_CurrentSampleCount = curFriend->CurrentSampleCount;
113  }
114  else
115  {
116   GN_DBGOUT_INT ("I Lead, sample diff:", curFriend->CurrentSampleCount_diff);
117  }
118 }
119 
120 ////////////////////////////////////////////////////////////////
121 //A sort of low-grade PRNG seeded from major Schedule data features,
122 //in order to give a way to always return the same arbitrary number
123 //for a given schedule. 65k possibilities.
GN_Running_GetScheduleFingerprint()124 unsigned int GN_Running_GetScheduleFingerprint ()
125 {
126  unsigned short sum;
127  unsigned int i;
128  unsigned int j;
129 
130  sum = (unsigned short) 0xffff & (unsigned long)
131   (BB_Loops * BB_VoiceCount * BB_TotalDuration);
132 
133  for (i = 0; i < BB_VoiceCount; i++)
134  {
135   for (j = 0; j < BB_Voice[i].EntryCount; j++)
136   {
137    ++sum;
138    sum += (unsigned short) 0xffff & (unsigned long)
139     ((1 + BB_Voice[i].type) *
140      BB_Voice[i].Entry[j].duration *
141      BB_Voice[i].Entry[j].basefreq_start *
142      BB_Voice[i].Entry[j].beatfreq_start_HALF);
143   }
144  }
145 
146  GN_ScheduleFingerprint = sum;
147  return GN_ScheduleFingerprint;
148 }
149 
150 /*
151    //NOTE: THIS WAS NICE... except turns out that different endline
152    /chars, etc., made it not valid across platforms.
153    ////////////////////////////////////////////////////////////////
154    //Basically just a PRNG based on the Adler-32 algo: a given seed will
155    //always return the same arbitrary number for a given file.
156    //Seed can be any unsigned int range value, but 0 seems a weak
157    //choice (since  fingerprint wouldn't really begin until a non-zero
158    //input occurred, slightly reducing possible outcomes related to filesize).
159    //This should be run ONLY when a new file is opened (not to, say, check a
160    //file). Also, only half of this number is sent over network (because
161    //I can't imagine distinguishing between more than a hundred files).
162    unsigned int GN_Running_GetScheduleFingerprint (char *filename, unsigned int seed)
163    {
164    const unsigned int BASE = 65521U;    // largest prime smaller than 65536
165    unsigned int sum;
166    unsigned int file_len = 0;
167    FILE *stream;
168 
169    if ((stream = fopen (filename, "rb")) == NULL)
170    {
171    printf ("Couldn't open requested file \"%s\"\n", filename);
172    return 0;
173    }
174 
175    // split to make Adler32 component sums:
176    sum = (seed >> 16) & 0xffff;
177    seed &= 0xffff;
178 
179    while (feof (stream) == 0)
180    {
181    seed += (unsigned char) fgetc (stream);
182    if (seed >= BASE)
183    seed -= BASE;
184    sum += seed;
185    if (sum >= BASE)
186    sum -= BASE;
187    ++file_len;
188    }
189 
190    fclose (stream);
191    printf ("Measured size of file (bytes): %u\n", file_len);
192    GN_ScheduleFingerprint_FULL = seed | (sum << 16);
193    return GN_ScheduleFingerprint_FULL;
194    }
195  */
196