Statistics
| Branch: | Tag: | Revision:

root / gnuradio-core / src / lib / general / gr_align_on_samplenumbers_ss.cc @ 78078fe0

History | View | Annotate | Download (16.6 kB)

1 5d69a524 jcorgan
/* -*- c++ -*- */
2 5d69a524 jcorgan
/*
3 0a9b999b Eric Blossom
 * Copyright 2005,2010 Free Software Foundation, Inc.
4 5d69a524 jcorgan
 * 
5 5d69a524 jcorgan
 * This file is part of GNU Radio
6 5d69a524 jcorgan
 * 
7 5d69a524 jcorgan
 * GNU Radio is free software; you can redistribute it and/or modify
8 5d69a524 jcorgan
 * it under the terms of the GNU General Public License as published by
9 937b719d eb
 * the Free Software Foundation; either version 3, or (at your option)
10 5d69a524 jcorgan
 * any later version.
11 5d69a524 jcorgan
 * 
12 5d69a524 jcorgan
 * GNU Radio is distributed in the hope that it will be useful,
13 5d69a524 jcorgan
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 5d69a524 jcorgan
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 5d69a524 jcorgan
 * GNU General Public License for more details.
16 5d69a524 jcorgan
 * 
17 5d69a524 jcorgan
 * You should have received a copy of the GNU General Public License
18 5d69a524 jcorgan
 * along with GNU Radio; see the file COPYING.  If not, write to
19 86f5c924 eb
 * the Free Software Foundation, Inc., 51 Franklin Street,
20 86f5c924 eb
 * Boston, MA 02110-1301, USA.
21 5d69a524 jcorgan
 */
22 5d69a524 jcorgan
23 5d69a524 jcorgan
#ifdef HAVE_CONFIG_H
24 5d69a524 jcorgan
#include "config.h"
25 5d69a524 jcorgan
#endif
26 5d69a524 jcorgan
27 5d69a524 jcorgan
#include <gr_align_on_samplenumbers_ss.h>
28 5d69a524 jcorgan
#include <gr_io_signature.h>
29 5d69a524 jcorgan
#include <assert.h>
30 5d69a524 jcorgan
#include <stdexcept>
31 38ea3a57 eb
#include <string.h>
32 3d96f593 anastas
#include <cstdio>
33 5d69a524 jcorgan
34 5d69a524 jcorgan
//define ALIGN_ADVANCED_IMPLEMENTATION to have an alternative implementation of the align algoritm which exactly follows the align_interval spec.
35 5d69a524 jcorgan
//It is more resource intensive, less tested and probably not needed
36 5d69a524 jcorgan
//define ALIGN_ADVANCED_IMPLEMENTATION
37 5d69a524 jcorgan
38 5d69a524 jcorgan
//define DEBUG_TOCONSUME to see debug messages about the synchronisation part of this block
39 5d69a524 jcorgan
//define DEBUG_TOCONSUME
40 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
41 5d69a524 jcorgan
#define tcPrintf if(dprint) printf
42 5d69a524 jcorgan
#else
43 5d69a524 jcorgan
#define tcPrintf //printf
44 5d69a524 jcorgan
#endif
45 5d69a524 jcorgan
46 5d69a524 jcorgan
#define ePrintf printf
47 5d69a524 jcorgan
48 5d69a524 jcorgan
gr_align_on_samplenumbers_ss_sptr
49 5d69a524 jcorgan
gr_make_align_on_samplenumbers_ss (int nchan, int align_interval)
50 5d69a524 jcorgan
{
51 0a9b999b Eric Blossom
  return gnuradio::get_initial_sptr(new gr_align_on_samplenumbers_ss (nchan,align_interval));
52 5d69a524 jcorgan
}
53 5d69a524 jcorgan
54 5d69a524 jcorgan
gr_align_on_samplenumbers_ss::gr_align_on_samplenumbers_ss (int nchan,int align_interval)
55 5d69a524 jcorgan
  : gr_block ("align_on_samplenumbers_ss",
56 5d69a524 jcorgan
        gr_make_io_signature (2, -1, sizeof (short)), //2, -1
57 5d69a524 jcorgan
        gr_make_io_signature (2, -1, sizeof (short))), //2,-1
58 5d69a524 jcorgan
  d_align_interval (align_interval),
59 5d69a524 jcorgan
  d_nchan(nchan),
60 5d69a524 jcorgan
  d_ninputs(0)
61 5d69a524 jcorgan
{
62 5d69a524 jcorgan
  if (d_align_interval<0)
63 5d69a524 jcorgan
    set_output_multiple (d_nchan*2);
64 5d69a524 jcorgan
  else
65 5d69a524 jcorgan
  {
66 5d69a524 jcorgan
    set_output_multiple (d_align_interval*d_nchan*2);
67 5d69a524 jcorgan
  }
68 5d69a524 jcorgan
    
69 5d69a524 jcorgan
}
70 5d69a524 jcorgan
71 5d69a524 jcorgan
gr_align_on_samplenumbers_ss::~gr_align_on_samplenumbers_ss()
72 5d69a524 jcorgan
{
73 5d69a524 jcorgan
  
74 5d69a524 jcorgan
}
75 5d69a524 jcorgan
void
76 5d69a524 jcorgan
gr_align_on_samplenumbers_ss::forecast (int noutput_items, gr_vector_int &ninput_items_required)
77 5d69a524 jcorgan
{
78 5d69a524 jcorgan
  //assert (0 == noutput_items % d_align_interval);
79 5d69a524 jcorgan
  unsigned ninputs = ninput_items_required.size();
80 5d69a524 jcorgan
  for (unsigned int i = 0; i < ninputs; i++)
81 5d69a524 jcorgan
    ninput_items_required[i] = std::max(noutput_items*d_nchan*2+ history() - 1,1024*d_nchan*2+ history() - 1);//TODO include the diffs found in determine input_items_required
82 5d69a524 jcorgan
}
83 5d69a524 jcorgan
84 5d69a524 jcorgan
bool
85 5d69a524 jcorgan
gr_align_on_samplenumbers_ss::check_topology (int ninputs, int noutputs)
86 5d69a524 jcorgan
{
87 5d69a524 jcorgan
  bool result=true;
88 5d69a524 jcorgan
  if(noutputs!=ninputs)
89 5d69a524 jcorgan
  {
90 5d69a524 jcorgan
    result=false;
91 5d69a524 jcorgan
    ePrintf("gr_align_on_samplenumbers_ss: ERROR noutputs %i != ninputs %i\n",noutputs,ninputs);
92 5d69a524 jcorgan
  }
93 5d69a524 jcorgan
  if(d_nchan<2)
94 5d69a524 jcorgan
  {
95 5d69a524 jcorgan
    result=false;
96 5d69a524 jcorgan
    ePrintf("gr_align_on_samplenumbers_ss: ERROR nchan %i<2 \n",d_nchan);
97 5d69a524 jcorgan
  }
98 5d69a524 jcorgan
  if((int)d_ninputs!=ninputs)
99 5d69a524 jcorgan
  {
100 5d69a524 jcorgan
    //Only resize and reset the status if there really changed something
101 5d69a524 jcorgan
    //Don't reset the status if the user just called stop() and start(), although maybe we should.
102 5d69a524 jcorgan
    d_state.resize(ninputs);
103 5d69a524 jcorgan
    d_ninputs=ninputs;
104 5d69a524 jcorgan
    for(unsigned int i=0;i<d_ninputs;i++)
105 5d69a524 jcorgan
    {
106 5d69a524 jcorgan
      d_state[i].sync_found=false;
107 5d69a524 jcorgan
      d_state[i].sync_end_found=false;
108 5d69a524 jcorgan
    }
109 5d69a524 jcorgan
    d_in_presync=false;
110 5d69a524 jcorgan
  }
111 5d69a524 jcorgan
  return result;
112 5d69a524 jcorgan
}
113 5d69a524 jcorgan
114 5d69a524 jcorgan
#ifdef ALIGN_ADVANCED_IMPLEMENTATION
115 5d69a524 jcorgan
int
116 5d69a524 jcorgan
gr_align_on_samplenumbers_ss::general_work (int noutput_items,
117 5d69a524 jcorgan
        gr_vector_int &ninput_items,
118 5d69a524 jcorgan
        gr_vector_const_void_star &input_items,
119 5d69a524 jcorgan
        gr_vector_void_star &output_items)
120 5d69a524 jcorgan
{
121 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
122 5d69a524 jcorgan
  static int dcount=0;
123 5d69a524 jcorgan
  bool dprint=false;
124 5d69a524 jcorgan
  dcount++;
125 5d69a524 jcorgan
  if(dcount>200)
126 5d69a524 jcorgan
  {
127 5d69a524 jcorgan
    dcount=0;
128 5d69a524 jcorgan
    dprint=true;
129 5d69a524 jcorgan
  } 
130 5d69a524 jcorgan
#endif
131 5d69a524 jcorgan
  const size_t item_size = output_signature()->sizeof_stream_item (0);
132 5d69a524 jcorgan
  const unsigned ninputs = input_items.size();
133 5d69a524 jcorgan
  const unsigned noutputs = output_items.size();
134 5d69a524 jcorgan
135 5d69a524 jcorgan
  int align_interval=d_align_interval*2*d_nchan;
136 5d69a524 jcorgan
  if(d_align_interval<0)
137 5d69a524 jcorgan
  {
138 5d69a524 jcorgan
    //align once per noutput_items
139 5d69a524 jcorgan
    align_interval=noutput_items;
140 5d69a524 jcorgan
    align_interval=align_interval/(2*d_nchan);
141 5d69a524 jcorgan
    align_interval=align_interval*(2*d_nchan);
142 5d69a524 jcorgan
  }
143 5d69a524 jcorgan
144 5d69a524 jcorgan
  int min_ninput_items=noutput_items;//numeric_limits<int>::max();
145 5d69a524 jcorgan
  int noutput_items_produced=0;
146 5d69a524 jcorgan
  for(unsigned int i=0;i<ninputs;i++)
147 5d69a524 jcorgan
  { 
148 5d69a524 jcorgan
    d_state[i].ninput_items=ninput_items[i];
149 5d69a524 jcorgan
    d_state[i].ninput_items_used=0;
150 5d69a524 jcorgan
    min_ninput_items=std::min(ninput_items[i],min_ninput_items);
151 5d69a524 jcorgan
  }
152 5d69a524 jcorgan
  for(int j=0;j<noutput_items-align_interval+1;j+=align_interval)
153 5d69a524 jcorgan
  {
154 5d69a524 jcorgan
    int common_end;
155 5d69a524 jcorgan
    if(min_ninput_items>=align_interval)
156 5d69a524 jcorgan
      common_end=align_interval;
157 5d69a524 jcorgan
    else
158 5d69a524 jcorgan
    {
159 5d69a524 jcorgan
      common_end=min_ninput_items/(d_nchan*2);
160 5d69a524 jcorgan
      common_end=common_end*(d_nchan*2);
161 5d69a524 jcorgan
    }
162 5d69a524 jcorgan
    if (common_end<=0) break;
163 5d69a524 jcorgan
    
164 5d69a524 jcorgan
    bool all_diffs_zero=true;
165 5d69a524 jcorgan
    //bool sync_found=false;
166 5d69a524 jcorgan
    int diff_comp_end_max=0;
167 5d69a524 jcorgan
    for(unsigned int i=0;i<ninputs;i++)
168 5d69a524 jcorgan
    {
169 5d69a524 jcorgan
      unsigned short * uin=&(((unsigned short*)input_items[i])[d_state[i].ninput_items_used]);
170 5d69a524 jcorgan
      unsigned int  x_high16bits = uin[0];
171 5d69a524 jcorgan
      unsigned int  x_low16bits = uin[1];
172 5d69a524 jcorgan
      d_state[i].ucounter_begin = x_high16bits<<16 | x_low16bits;
173 5d69a524 jcorgan
      d_state[i].diff=d_state[0].ucounter_begin-d_state[i].ucounter_begin;//Result is a signed value,Will wrap around on 32 bit boundary
174 5d69a524 jcorgan
      int common_last=std::max(common_end-d_nchan*2,0);
175 5d69a524 jcorgan
      x_high16bits = uin[d_nchan*2];
176 5d69a524 jcorgan
      x_low16bits = uin[d_nchan*2+1];
177 5d69a524 jcorgan
      unsigned int ucounter_begin2 = x_high16bits<<16 | x_low16bits;
178 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
179 5d69a524 jcorgan
      if((d_state[i].ucounter_begin+1)!=(ucounter_begin2))
180 5d69a524 jcorgan
        if(ucounter_begin2==0)
181 5d69a524 jcorgan
          ePrintf("SYNC counters are 0\n");
182 5d69a524 jcorgan
        else
183 5d69a524 jcorgan
           ePrintf("Error: counter not continuous.\n ucounter_begin[%i]=%i +1 !=  ucounter_begin2=%i\n",i,d_state[i].ucounter_begin,ucounter_begin2);
184 5d69a524 jcorgan
#endif
185 5d69a524 jcorgan
      x_high16bits = uin[common_last];
186 5d69a524 jcorgan
      x_low16bits = uin[common_last+1];
187 5d69a524 jcorgan
      d_state[i].ucounter_end = x_high16bits<<16 | x_low16bits;
188 5d69a524 jcorgan
      d_state[i].diff_end=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
189 5d69a524 jcorgan
      d_state[i].diff_comp_end=d_state[i].ucounter_end-d_state[0].ucounter_end;
190 5d69a524 jcorgan
      diff_comp_end_max=std::max(d_state[i].diff_comp_end,diff_comp_end_max);
191 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
192 5d69a524 jcorgan
      if(d_state[i].diff>256000000 || d_state[i].diff_end>256000000 || d_state[i].diff_comp_end>256000000)
193 5d69a524 jcorgan
      {
194 5d69a524 jcorgan
        tcPrintf("diff[%i]=%i diff_end=%i diff_comp_end=%i\n",i,d_state[i].diff,d_state[i].diff_end,d_state[i].diff_comp_end);
195 5d69a524 jcorgan
      }
196 5d69a524 jcorgan
#endif
197 5d69a524 jcorgan
      all_diffs_zero=all_diffs_zero && (0==d_state[i].diff_end);
198 5d69a524 jcorgan
      if(d_state[i].ucounter_end<d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2))) //(unsigned)(common_last/(d_nchan*2)))
199 5d69a524 jcorgan
      {
200 5d69a524 jcorgan
        //printf("sync 1 ");// found ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
201 5d69a524 jcorgan
        //sync_found=true;//sync_found or 32 bit counter  wraparound (0xffffffff -> 0x00000000)
202 5d69a524 jcorgan
        if(!d_in_presync)
203 5d69a524 jcorgan
        {
204 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
205 5d69a524 jcorgan
          printf("presync START with %i\n",i);
206 5d69a524 jcorgan
#endif
207 5d69a524 jcorgan
         for(unsigned int k=0;k<ninputs;k++)
208 5d69a524 jcorgan
         {
209 5d69a524 jcorgan
          d_state[k].sync_found=false;
210 5d69a524 jcorgan
          d_state[i].sync_end_found=false;
211 5d69a524 jcorgan
         }
212 5d69a524 jcorgan
         d_in_presync=true;
213 5d69a524 jcorgan
         d_state[i].sync_found=true;    
214 5d69a524 jcorgan
        } else
215 5d69a524 jcorgan
        {
216 5d69a524 jcorgan
          //d_in_presync=true;
217 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
218 5d69a524 jcorgan
          if(d_state[i].sync_found)
219 5d69a524 jcorgan
            printf("presync CONTINUE with %i\n",i);
220 5d69a524 jcorgan
          else
221 5d69a524 jcorgan
            printf("presync NEXT with %i\n",i);
222 5d69a524 jcorgan
#endif
223 5d69a524 jcorgan
          d_state[i].sync_found=true;  
224 5d69a524 jcorgan
          d_state[i].sync_end_found=false;  
225 5d69a524 jcorgan
        }             
226 5d69a524 jcorgan
      } else
227 5d69a524 jcorgan
      {
228 5d69a524 jcorgan
        if(d_in_presync && d_state[i].sync_found)
229 5d69a524 jcorgan
        {
230 5d69a524 jcorgan
          d_state[i].sync_end_found=true;
231 5d69a524 jcorgan
          bool all_syncs_found=true;
232 5d69a524 jcorgan
          for(unsigned int k=0;k<ninputs;k++)
233 5d69a524 jcorgan
            all_syncs_found=all_syncs_found && d_state[k].sync_end_found;
234 5d69a524 jcorgan
          d_in_presync=!all_syncs_found;
235 5d69a524 jcorgan
          if(!d_in_presync)
236 5d69a524 jcorgan
          {
237 5d69a524 jcorgan
            for(unsigned int k=0;k<ninputs;k++)
238 5d69a524 jcorgan
            {
239 5d69a524 jcorgan
              d_state[k].sync_found=false;
240 5d69a524 jcorgan
              d_state[i].sync_end_found=false;
241 5d69a524 jcorgan
            }
242 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
243 5d69a524 jcorgan
            printf("presync END\n");
244 5d69a524 jcorgan
#endif
245 5d69a524 jcorgan
          }
246 5d69a524 jcorgan
        }
247 5d69a524 jcorgan
      }
248 5d69a524 jcorgan
    }
249 5d69a524 jcorgan
    if(d_in_presync || all_diffs_zero)
250 5d69a524 jcorgan
    {
251 5d69a524 jcorgan
      for(unsigned int i=0;i<ninputs;i++)
252 5d69a524 jcorgan
      {
253 5d69a524 jcorgan
         memcpy(&(((unsigned short*)output_items[i])[j]),&(((const unsigned short*)input_items[i])[d_state[i].ninput_items_used]),common_end*item_size);
254 5d69a524 jcorgan
         //consume(i,common_end);
255 5d69a524 jcorgan
         d_state[i].ninput_items-=common_end;
256 5d69a524 jcorgan
         d_state[i].ninput_items_used+=common_end;
257 5d69a524 jcorgan
         min_ninput_items=std::min(d_state[i].ninput_items,min_ninput_items);
258 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
259 5d69a524 jcorgan
         if(common_end<256)
260 5d69a524 jcorgan
           tcPrintf("common_end %i\n",common_end);
261 5d69a524 jcorgan
#endif
262 5d69a524 jcorgan
      }
263 5d69a524 jcorgan
      //min_ninput_items-=common_end;
264 5d69a524 jcorgan
      noutput_items_produced+=common_end;
265 5d69a524 jcorgan
      //return common_end;
266 5d69a524 jcorgan
    } else
267 5d69a524 jcorgan
    {
268 5d69a524 jcorgan
      //printf("sync 2");
269 5d69a524 jcorgan
      for(unsigned int i=0;i<ninputs;i++)
270 5d69a524 jcorgan
      {
271 5d69a524 jcorgan
        int toconsume=std::min((d_state[i].diff_end+diff_comp_end_max)*d_nchan*2,d_state[i].ninput_items);
272 5d69a524 jcorgan
        toconsume=toconsume/(d_nchan*2);
273 5d69a524 jcorgan
        toconsume=toconsume*(d_nchan*2);
274 5d69a524 jcorgan
        d_state[i].ninput_items-=toconsume;
275 5d69a524 jcorgan
        d_state[i].ninput_items_used+=toconsume;
276 5d69a524 jcorgan
        min_ninput_items=std::min(d_state[i].ninput_items,min_ninput_items);
277 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
278 5d69a524 jcorgan
      static int toconsume_counter=0;
279 5d69a524 jcorgan
      toconsume_counter++;
280 5d69a524 jcorgan
      //if(toconsume_counter>10)
281 5d69a524 jcorgan
      {
282 5d69a524 jcorgan
        tcPrintf("toconsume=%i diff_end[%i]*d_nchan*2=%i diff_comp_end_max*d_nchan*2=%i ninput_items[%i]=%i\n",toconsume,i,d_state[i].diff_end*d_nchan*2,diff_comp_end_max*d_nchan*2,i,ninput_items[i]);
283 5d69a524 jcorgan
        toconsume_counter=0;
284 5d69a524 jcorgan
      }
285 5d69a524 jcorgan
#endif
286 5d69a524 jcorgan
        //printf("toconsume[%i]=%i\n",i,toconsume);
287 5d69a524 jcorgan
        //consume(i,toconsume);//skip the difference in samplenumber items
288 5d69a524 jcorgan
      }
289 5d69a524 jcorgan
      //return 0;
290 5d69a524 jcorgan
    }
291 5d69a524 jcorgan
  }
292 5d69a524 jcorgan
  for(unsigned int i=0;i<ninputs;i++)
293 5d69a524 jcorgan
    consume(i,d_state[i].ninput_items_used);
294 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
295 5d69a524 jcorgan
  if(noutput_items_produced<256)
296 5d69a524 jcorgan
    tcPrintf("noutput_items_produced %i\n",noutput_items_produced);
297 5d69a524 jcorgan
#endif
298 5d69a524 jcorgan
  return noutput_items_produced;
299 5d69a524 jcorgan
}
300 5d69a524 jcorgan
301 5d69a524 jcorgan
302 5d69a524 jcorgan
#else /*ALIGN_ADVANCED_IMPLEMENTATION*/
303 5d69a524 jcorgan
int
304 5d69a524 jcorgan
gr_align_on_samplenumbers_ss::general_work (int noutput_items,
305 5d69a524 jcorgan
        gr_vector_int &ninput_items,
306 5d69a524 jcorgan
        gr_vector_const_void_star &input_items,
307 5d69a524 jcorgan
        gr_vector_void_star &output_items)
308 5d69a524 jcorgan
{
309 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
310 5d69a524 jcorgan
  static int dcount=0;
311 5d69a524 jcorgan
  bool dprint=false;
312 5d69a524 jcorgan
  dcount++;
313 5d69a524 jcorgan
  if(dcount>2000)
314 5d69a524 jcorgan
  {
315 5d69a524 jcorgan
    dcount=0;
316 5d69a524 jcorgan
    dprint=true;
317 5d69a524 jcorgan
  } 
318 5d69a524 jcorgan
#endif
319 5d69a524 jcorgan
  const size_t item_size = output_signature()->sizeof_stream_item (0);
320 5d69a524 jcorgan
  const unsigned ninputs = input_items.size();
321 5d69a524 jcorgan
  
322 5d69a524 jcorgan
  int common_end=noutput_items;
323 5d69a524 jcorgan
  //int diff_min=INT_MAX;
324 5d69a524 jcorgan
  //int diff_max=INT_MIN;
325 5d69a524 jcorgan
  for(unsigned int i=0;i<ninputs;i++)
326 5d69a524 jcorgan
  {
327 5d69a524 jcorgan
    unsigned short * uin=(unsigned short*)input_items[i];
328 5d69a524 jcorgan
    unsigned int  x_high16bits = uin[0];
329 5d69a524 jcorgan
    unsigned int  x_low16bits = uin[1];
330 5d69a524 jcorgan
    d_state[i].ucounter_begin = x_high16bits<<16 | x_low16bits;
331 5d69a524 jcorgan
    d_state[i].diff=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
332 5d69a524 jcorgan
    x_high16bits = uin[d_nchan*2];
333 5d69a524 jcorgan
    x_low16bits = uin[d_nchan*2+1];
334 5d69a524 jcorgan
    unsigned int ucounter_begin2 = x_high16bits<<16 | x_low16bits;
335 0aa33cf5 eb
    if((d_state[i].ucounter_begin+1)!=(ucounter_begin2)){
336 5d69a524 jcorgan
      if(ucounter_begin2==0)
337 5d69a524 jcorgan
      {
338 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
339 5d69a524 jcorgan
        ePrintf("SYNC counters are 0\n");
340 5d69a524 jcorgan
#endif
341 5d69a524 jcorgan
      }
342 5d69a524 jcorgan
      else
343 5d69a524 jcorgan
      {
344 5d69a524 jcorgan
        ePrintf("Error: counter not continuous.\n ucounter_begin[%i]=%i +1 !=  ucounter_begin2=%i\n",i,d_state[i].ucounter_begin,ucounter_begin2);
345 5d69a524 jcorgan
      }
346 0aa33cf5 eb
    }
347 5d69a524 jcorgan
      
348 5d69a524 jcorgan
    //diff_comp[i]=ucounter[i]-ucounter[0];
349 5d69a524 jcorgan
    //diff_min=std::min(diff[i],diff_min);
350 5d69a524 jcorgan
    //diff_max=std::max(diff[i],diff_max);
351 5d69a524 jcorgan
    common_end=std::max(std::min(ninput_items[i],common_end),0);
352 5d69a524 jcorgan
  }
353 5d69a524 jcorgan
  common_end=common_end/(d_nchan*2);
354 5d69a524 jcorgan
  common_end=common_end*(d_nchan*2);
355 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
356 5d69a524 jcorgan
  if(common_end<d_nchan*2)
357 5d69a524 jcorgan
  {
358 5d69a524 jcorgan
    printf(" common_end %i\n",common_end);
359 5d69a524 jcorgan
    for(int j=0;j<ninputs;j++)
360 5d69a524 jcorgan
      printf("ninput_items[%i]=%i\n",j,ninput_items[j]);
361 5d69a524 jcorgan
  }
362 5d69a524 jcorgan
#endif
363 5d69a524 jcorgan
  bool all_diffs_zero=true;
364 5d69a524 jcorgan
  bool sync_found=false;
365 5d69a524 jcorgan
  int diff_comp_end_max=0;
366 5d69a524 jcorgan
  for(unsigned int i=0;i<ninputs;i++)
367 5d69a524 jcorgan
  {
368 5d69a524 jcorgan
    unsigned short * uin=(unsigned short*)input_items[i];
369 5d69a524 jcorgan
    int common_last=common_end-(d_nchan*2);
370 5d69a524 jcorgan
    unsigned int  x_high16bits = uin[common_last];
371 5d69a524 jcorgan
    unsigned int  x_low16bits = uin[common_last+1];
372 5d69a524 jcorgan
    d_state[i].ucounter_end = x_high16bits<<16 | x_low16bits;
373 5d69a524 jcorgan
    d_state[i].diff_end=d_state[0].ucounter_end-d_state[i].ucounter_end;//Result is a signed value,Will wrap around on 32 bit boundary
374 5d69a524 jcorgan
    d_state[i].diff_comp_end=d_state[i].ucounter_end-d_state[0].ucounter_end;
375 5d69a524 jcorgan
    //diff_end_min=std::min(diff_end[i],diff_end_min);
376 5d69a524 jcorgan
    //diff_end_max=std::max(diff_end[i],diff_end_max);
377 5d69a524 jcorgan
    diff_comp_end_max=std::max(d_state[i].diff_comp_end,diff_comp_end_max);
378 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
379 5d69a524 jcorgan
    if(d_state[i].diff_end!=d_state[i].diff)
380 5d69a524 jcorgan
    {
381 5d69a524 jcorgan
      //samples_lost_or_syncstart=true;
382 5d69a524 jcorgan
      printf("Us%i %i %i ",i,d_state[i].diff_end,d_state[i].diff);
383 5d69a524 jcorgan
    }
384 5d69a524 jcorgan
#endif
385 5d69a524 jcorgan
    all_diffs_zero=all_diffs_zero && (0==d_state[i].diff_end);
386 5d69a524 jcorgan
    if((d_state[i].ucounter_end<d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2))) || (0==d_state[i].ucounter_end) || (0==d_state[i].ucounter_begin)) //(unsigned)(common_last/(d_nchan*2)))
387 5d69a524 jcorgan
    {
388 5d69a524 jcorgan
      sync_found=true;//sync_found or 32 bit counter  wraparound (0xffffffff -> 0x00000000)
389 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
390 5d69a524 jcorgan
      tcPrintf("SYNC diff_end[%i]=%i ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].diff_end,i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
391 5d69a524 jcorgan
      tcPrintf("ucounter_end=%i < %i = ucounter_begin+(unsigned)(common_last/(d_nchan*2) \n",d_state[i].ucounter_end,d_state[i].ucounter_begin+(unsigned)(common_last/(d_nchan*2)));
392 5d69a524 jcorgan
393 5d69a524 jcorgan
      printf("ucounter_end[%i]=%i ucounter_begin[%i]=%i\n",i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);      
394 5d69a524 jcorgan
      int expected_sync_position=common_last - d_state[i].ucounter_end*(d_nchan*2);
395 5d69a524 jcorgan
      if(0==uin[expected_sync_position] && 0==uin[expected_sync_position+1])
396 5d69a524 jcorgan
      {
397 5d69a524 jcorgan
        printf("sync found on input %i at position %i \n",i,expected_sync_position);
398 5d69a524 jcorgan
        //sync_start[i]=expected_sync_position;
399 5d69a524 jcorgan
      } else
400 5d69a524 jcorgan
      {
401 5d69a524 jcorgan
        printf("sync found on input %i position unclear, expected at %i value there %i\n",i,expected_sync_position,uin[expected_sync_position]<<16 | uin[expected_sync_position+1]);
402 5d69a524 jcorgan
        //sync_start[i]=-1;
403 5d69a524 jcorgan
      }
404 5d69a524 jcorgan
    } else
405 5d69a524 jcorgan
    {
406 5d69a524 jcorgan
      tcPrintf("NOsync diff_end[%i]=%i ucounter_end[%i]=%i ucounter_begin[%i]=%i \n",i,d_state[i].diff_end,i,d_state[i].ucounter_end,i,d_state[i].ucounter_begin);
407 5d69a524 jcorgan
#endif    
408 5d69a524 jcorgan
    }
409 5d69a524 jcorgan
  }
410 5d69a524 jcorgan
  bool problem=false;
411 5d69a524 jcorgan
  for(unsigned int i=0;i<ninputs;i++)
412 5d69a524 jcorgan
    if((d_state[i].diff_end+diff_comp_end_max) >0x4000000)
413 5d69a524 jcorgan
      {
414 5d69a524 jcorgan
        problem=true;
415 5d69a524 jcorgan
        ePrintf("Warning: counter diff greater as 64 Million\n");
416 5d69a524 jcorgan
        ePrintf("         You might want to swap master and slave.\n");
417 5d69a524 jcorgan
        ePrintf("          i=%i,d_state[i].diff_end+diff_comp_end_max=%i,d_state[i].diff_end=%i,diff_comp_end_max=%i,ucounter[i]=%i,ucounter[0]=%i\n",
418 5d69a524 jcorgan
                          i,d_state[i].diff_end+diff_comp_end_max,d_state[i].diff_end,diff_comp_end_max,d_state[i].ucounter_end,d_state[0].ucounter_end);
419 5d69a524 jcorgan
        //ePrintf("        toconsume=%i\n",toconsume); 
420 5d69a524 jcorgan
      }
421 5d69a524 jcorgan
  if(sync_found || all_diffs_zero || problem)
422 5d69a524 jcorgan
  {
423 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
424 5d69a524 jcorgan
    if(all_diffs_zero) tcPrintf("ZERO\n");
425 5d69a524 jcorgan
    if(sync_found) tcPrintf("SYNC\n");
426 5d69a524 jcorgan
#endif
427 5d69a524 jcorgan
    for(unsigned int i=0;i<ninputs;i++)
428 5d69a524 jcorgan
    {
429 5d69a524 jcorgan
       memcpy(output_items[i],input_items[i],common_end*item_size);
430 5d69a524 jcorgan
       consume(i,common_end);
431 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
432 5d69a524 jcorgan
      if(common_end<256)
433 5d69a524 jcorgan
        tcPrintf("common_end %i\n",common_end);
434 5d69a524 jcorgan
#endif
435 5d69a524 jcorgan
    }
436 5d69a524 jcorgan
    return common_end;
437 5d69a524 jcorgan
  } else
438 5d69a524 jcorgan
  {
439 5d69a524 jcorgan
    //int minconsume=0;//common_end/(2*d_nchan*2);
440 5d69a524 jcorgan
    //min_consume=min_consume*d_nchan*2;  
441 5d69a524 jcorgan
    for(unsigned int i=0;i<ninputs;i++)
442 5d69a524 jcorgan
    {
443 5d69a524 jcorgan
      int toconsume=std::min((d_state[i].diff_end+diff_comp_end_max)*d_nchan*2,ninput_items[i]);
444 5d69a524 jcorgan
      toconsume=toconsume/(d_nchan*2);
445 5d69a524 jcorgan
      toconsume=toconsume*(d_nchan*2);
446 5d69a524 jcorgan
#ifdef DEBUG_TOCONSUME
447 5d69a524 jcorgan
      //printf("dcount %i\n",dcount);
448 5d69a524 jcorgan
      static int toconsume_counter=0;
449 5d69a524 jcorgan
      toconsume_counter++;
450 5d69a524 jcorgan
      //if(toconsume_counter>10)
451 5d69a524 jcorgan
      {
452 5d69a524 jcorgan
        tcPrintf("toconsume=%i diff_end[[%i]*d_nchan*2=%i diff_comp_end_max)*d_nchan*2=%i ninput_items[%i]=%i\n",
453 5d69a524 jcorgan
                  toconsume,i,d_state[i].diff_end*d_nchan*2,diff_comp_end_max*d_nchan*2,i,ninput_items[i]);
454 5d69a524 jcorgan
        toconsume_counter=0;
455 5d69a524 jcorgan
      }
456 5d69a524 jcorgan
#endif
457 5d69a524 jcorgan
      consume(i,toconsume);//skip the difference in samplenumber items
458 5d69a524 jcorgan
      //printf("toconsume%i %i diff_comp_end_max %i diff_end[[%i] %i\n",i,toconsume,diff_comp_end_max,i,d_state[i].diff_end);
459 5d69a524 jcorgan
    }
460 5d69a524 jcorgan
    return 0;
461 5d69a524 jcorgan
  }
462 5d69a524 jcorgan
  return -1;//Should never come here
463 5d69a524 jcorgan
}
464 5d69a524 jcorgan
#endif /*ALIGN_ADVANCED_IMPLEMENTATION*/