| 261 | */ |
---|
| 262 | /* but we're not that naive anymore... */ |
---|
| 263 | int i; |
---|
| 264 | int xrun; |
---|
| 265 | unsigned int offset=0; |
---|
| 266 | |
---|
| 267 | freebob_ringbuffer_data_t vec[2]; |
---|
| 268 | // we received one period of frames |
---|
| 269 | // this is period_size*dimension of events |
---|
| 270 | int events2write=m_period*m_dimension; |
---|
| 271 | int bytes2write=events2write*sizeof(quadlet_t); |
---|
| 272 | |
---|
| 273 | /* write events2write bytes to the ringbuffer |
---|
| 274 | * first see if it can be done in one read. |
---|
| 275 | * if so, ok. |
---|
| 276 | * otherwise write up to a multiple of clusters directly to the buffer |
---|
| 277 | * then do the buffer wrap around using ringbuffer_write |
---|
| 278 | * then write the remaining data directly to the buffer in a third pass |
---|
| 279 | * Make sure that we cannot end up on a non-cluster aligned position! |
---|
| 280 | */ |
---|
| 281 | int cluster_size=m_dimension*sizeof(quadlet_t); |
---|
| 282 | |
---|
| 283 | while(bytes2write>0) { |
---|
| 284 | int byteswritten=0; |
---|
| 285 | |
---|
| 286 | unsigned int frameswritten=(m_period*cluster_size-bytes2write)/cluster_size; |
---|
| 287 | offset=frameswritten; |
---|
| 288 | |
---|
| 289 | freebob_ringbuffer_get_write_vector(m_event_buffer, vec); |
---|
| 290 | |
---|
| 291 | if(vec[0].len==0) { // this indicates a full event buffer |
---|
| 292 | debugError("Event buffer overrun in processor %d\n",this); |
---|
| 293 | break; |
---|
| 294 | } |
---|
| 295 | |
---|
| 296 | /* if we don't take care we will get stuck in an infinite loop |
---|
| 297 | * because we align to a cluster boundary later |
---|
| 298 | * the remaining nb of bytes in one write operation can be |
---|
| 299 | * smaller than one cluster |
---|
| 300 | * this can happen because the ringbuffer size is always a power of 2 |
---|
| 301 | */ |
---|
| 302 | if(vec[0].len<cluster_size) { |
---|
| 303 | |
---|
| 304 | // encode to the temporary buffer |
---|
| 305 | xrun = transmitBlock(m_cluster_buffer, 1, offset); |
---|
| 306 | |
---|
| 307 | if(xrun<0) { |
---|
| 308 | // xrun detected |
---|
| 309 | debugError("Frame buffer underrun in processor %d\n",this); |
---|
| 310 | break; |
---|
| 311 | } |
---|
| 312 | |
---|
| 313 | // use the ringbuffer function to write one cluster |
---|
| 314 | // the write function handles the wrap around. |
---|
| 315 | freebob_ringbuffer_write(m_event_buffer, |
---|
| 316 | m_cluster_buffer, |
---|
| 317 | cluster_size); |
---|
| 318 | |
---|
| 319 | // we advanced one cluster_size |
---|
| 320 | bytes2write-=cluster_size; |
---|
| 321 | |
---|
| 322 | } else { // |
---|
| 323 | |
---|
| 324 | if(bytes2write>vec[0].len) { |
---|
| 325 | // align to a cluster boundary |
---|
| 326 | byteswritten=vec[0].len-(vec[0].len%cluster_size); |
---|
| 327 | } else { |
---|
| 328 | byteswritten=bytes2write; |
---|
| 329 | } |
---|
| 330 | |
---|
| 331 | xrun = transmitBlock(vec[0].buf, |
---|
| 332 | byteswritten/cluster_size, |
---|
| 333 | offset); |
---|
| 334 | |
---|
| 335 | if(xrun<0) { |
---|
| 336 | // xrun detected |
---|
| 337 | debugError("Frame buffer underrun in processor %d\n",this); |
---|
| 338 | break; |
---|
| 339 | } |
---|
| 340 | |
---|
| 341 | freebob_ringbuffer_write_advance(m_event_buffer, byteswritten); |
---|
| 342 | bytes2write -= byteswritten; |
---|
| 343 | } |
---|
| 344 | |
---|
| 345 | // the bytes2write should always be cluster aligned |
---|
| 346 | assert(bytes2write%cluster_size==0); |
---|
| 347 | |
---|
| 348 | } |
---|
| 625 | */ |
---|
| 626 | int i; |
---|
| 627 | int xrun; |
---|
| 628 | unsigned int offset=0; |
---|
| 629 | |
---|
| 630 | freebob_ringbuffer_data_t vec[2]; |
---|
| 631 | // we received one period of frames on each connection |
---|
| 632 | // this is period_size*dimension of events |
---|
| 633 | |
---|
| 634 | int events2read=m_period*m_dimension; |
---|
| 635 | int bytes2read=events2read*sizeof(quadlet_t); |
---|
| 636 | /* read events2read bytes from the ringbuffer |
---|
| 637 | * first see if it can be done in one read. |
---|
| 638 | * if so, ok. |
---|
| 639 | * otherwise read up to a multiple of clusters directly from the buffer |
---|
| 640 | * then do the buffer wrap around using ringbuffer_read |
---|
| 641 | * then read the remaining data directly from the buffer in a third pass |
---|
| 642 | * Make sure that we cannot end up on a non-cluster aligned position! |
---|
| 643 | */ |
---|
| 644 | int cluster_size=m_dimension*sizeof(quadlet_t); |
---|
| 645 | |
---|
| 646 | while(bytes2read>0) { |
---|
| 647 | unsigned int framesread=(m_period*cluster_size-bytes2read)/cluster_size; |
---|
| 648 | offset=framesread; |
---|
| 649 | |
---|
| 650 | int bytesread=0; |
---|
| 651 | |
---|
| 652 | freebob_ringbuffer_get_read_vector(m_event_buffer, vec); |
---|
| 653 | |
---|
| 654 | if(vec[0].len==0) { // this indicates an empty event buffer |
---|
| 655 | debugError("Frame buffer underrun in processor %d\n",this); |
---|
| 656 | break; |
---|
| 657 | } |
---|
| 658 | |
---|
| 659 | /* if we don't take care we will get stuck in an infinite loop |
---|
| 660 | * because we align to a cluster boundary later |
---|
| 661 | * the remaining nb of bytes in one read operation can be smaller than one cluster |
---|
| 662 | * this can happen because the ringbuffer size is always a power of 2 |
---|
| 663 | */ |
---|
| 664 | if(vec[0].len<cluster_size) { |
---|
| 665 | // use the ringbuffer function to read one cluster |
---|
| 666 | // the read function handles wrap around |
---|
| 667 | freebob_ringbuffer_read(m_event_buffer,m_cluster_buffer,cluster_size); |
---|
| 668 | |
---|
| 669 | xrun = receiveBlock(m_cluster_buffer, 1, offset); |
---|
| 670 | |
---|
| 671 | if(xrun<0) { |
---|
| 672 | // xrun detected |
---|
| 673 | debugError("Frame buffer underrun in processor %d\n",this); |
---|
| 674 | break; |
---|
| 675 | } |
---|
| 676 | |
---|
| 677 | // we advanced one cluster_size |
---|
| 678 | bytes2read-=cluster_size; |
---|
| 679 | |
---|
| 680 | } else { // |
---|
| 681 | |
---|
| 682 | if(bytes2read>vec[0].len) { |
---|
| 683 | // align to a cluster boundary |
---|
| 684 | bytesread=vec[0].len-(vec[0].len%cluster_size); |
---|
| 685 | } else { |
---|
| 686 | bytesread=bytes2read; |
---|
| 687 | } |
---|
| 688 | |
---|
| 689 | xrun = receiveBlock(vec[0].buf, bytesread/cluster_size, offset); |
---|
| 690 | |
---|
| 691 | if(xrun<0) { |
---|
| 692 | // xrun detected |
---|
| 693 | debugError("Frame buffer underrun in processor %d\n",this); |
---|
| 694 | break; |
---|
| 695 | } |
---|
| 696 | |
---|
| 697 | freebob_ringbuffer_read_advance(m_event_buffer, bytesread); |
---|
| 698 | bytes2read -= bytesread; |
---|
| 699 | } |
---|
| 700 | |
---|
| 701 | // the bytes2read should always be cluster aligned |
---|
| 702 | assert(bytes2read%cluster_size==0); |
---|
| 703 | } |
---|