source: trunk/src/testing/src/sageAudioCircBuf.cpp @ 4

Revision 4, 17.7 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1/******************************************************************************
2 * SAGE - Scalable Adaptive Graphics Environment
3 *
4 * Module: sagesageAudioCircBuf.cpp - the circular buffer to managing audio sample blocks
5 * Author : Byungil Jeong, Hyejung Hur
6 *
7 * Copyright (C) 2004 Electronic Visualization Laboratory,
8 * University of Illinois at Chicago
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 *  * Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 *  * Redistributions in binary form must reproduce the above
18 *    copyright notice, this list of conditions and the following disclaimer
19 *    in the documentation and/or other materials provided with the distribution.
20 *  * Neither the name of the University of Illinois at Chicago nor
21 *    the names of its contributors may be used to endorse or promote
22 *    products derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 * Direct questions, comments etc about SAGE to sage_users@listserv.uic.edu or
37 * http://www.evl.uic.edu/cavern/forum/
38 *
39 *****************************************************************************/
40
41#include "sageAudioCircBuf.h"
42#include "sageAudioSync.h"
43#include "sageSync.h"
44#include "sageAudioModule.h"
45
46#define UINT8_TO_FLOAT(x) ( ((float)(x) -128.0)/ 127.0 )
47#define INT8_TO_FLOAT(x) ( (float) (x) / 127.0 )
48#define INT16_TO_FLOAT(x) ( (float)(x) / 32768.0 )
49#define FLOAT_TO_FLOAT(x) ( (float)(x) )
50
51sageAudioCircBuf::sageAudioCircBuf(sageSyncClient *sync, int nID, int keyframe)
52: readIndex(0), writeIndex(0), blocksNum(0), full(false), empty(true), bytesBlock(0),
53   sampleFmt(SAGE_SAMPLE_FLOAT32), sampleBuffSize(0), blockArray(NULL), audioId(-1),
54   synchronizer(NULL), syncClientObj(sync), locked(false), lastFrameIndex(-1), refRead(0), refMutex(0),
55   instID(nID), syncKeyFrame(keyframe), lastgFrameIndex(-0)
56{
57   queueLock = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
58   pthread_mutex_init(queueLock, NULL);
59   pthread_mutex_unlock(queueLock);
60   notFull = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
61   pthread_cond_init(notFull, NULL);
62}
63
64void sageAudioCircBuf::setKeyframe(int keyno)
65{
66   syncKeyFrame = keyno;
67}   
68
69sageAudioCircBuf::~sageAudioCircBuf()
70{
71   pthread_cond_signal(notFull);
72
73   //pthread_mutex_unlock(queueLock);
74
75   if(blockArray != NULL) {
76      clearBlocks();
77   }
78   
79   if(queueLock)
80      free(queueLock);
81   if(notFull)
82      free(notFull);   
83}
84
85
86int sageAudioCircBuf::init(int id, int blockNum, sageSampleFmt fmt, int size)
87{
88   audioId = id;
89   
90   refRead =0;
91   refMutex =0;
92   readers.clear();
93   readers.push_back(0);
94
95   if(blockArray != NULL) {
96      clearBlocks();
97   }
98
99   // initialize variables
100   writeIndex = readIndex = 0;
101   blocksNum = blockNum;
102   sampleFmt = fmt;
103   sampleBuffSize = size;
104         
105   blockArray = new audioBlock[blocksNum];
106   
107   switch(sampleFmt) {
108      case SAGE_SAMPLE_FLOAT32 :
109         {
110            float *array;
111            for( int j=0; j<blocksNum ; j++ ) {
112               array = new float[sampleBuffSize];
113               //array = (float*) malloc(sizeof(float) * sampleBuffSize);
114               for( int k=0; k< sampleBuffSize ; k++ ) {
115                  array[k] = 0.0;
116               }         
117               blockArray[j].buff = (void*) array;
118            }
119            bytesBlock = sizeof(float) * sampleBuffSize;   
120         }
121         break;
122      case SAGE_SAMPLE_INT16 :
123         {
124            short *array;   
125            for( int j=0; j<blocksNum ; j++ ) {
126               array = new short[sampleBuffSize];
127               for( int k=0; k< sampleBuffSize ; k++ ) {
128                  array[k] = 0;
129               }         
130               blockArray[j].buff = (void*) array;         
131            }
132            bytesBlock = sizeof(short) * sampleBuffSize;   
133         }   
134         break;
135      case SAGE_SAMPLE_INT8 :
136         {
137            char *array;         
138            for( int j=0; j<blocksNum ; j++ ) {
139               array = new char[sampleBuffSize];
140               for( int k=0; k< sampleBuffSize ; k++ ) {
141                  array[k] = '0';
142               }         
143               blockArray[j].buff = (void*) array;         
144            }
145            bytesBlock = sizeof(char) * sampleBuffSize;         
146         }     
147         break;
148      case SAGE_SAMPLE_UINT8 :
149         {
150            unsigned char *array;     
151            for( int j=0; j<blocksNum ; j++ ) {
152               array = new unsigned char[sampleBuffSize];
153               for( int k=0; k< sampleBuffSize ; k++ ) {
154                  array[k] = 128;
155               }         
156               blockArray[j].buff = (void*) array;               
157            }     
158            bytesBlock = sizeof(unsigned char) * sampleBuffSize;   
159         }     
160         break;
161   }
162   
163   full = false;
164   empty = true;
165   locked = false;
166   lastFrameIndex = -1;
167   synchronizer = NULL;
168   
169   return 0;
170}
171
172void sageAudioCircBuf::clearBlocks()
173{
174   switch(sampleFmt) {
175      case SAGE_SAMPLE_FLOAT32 :
176         {
177            float *array;
178            for( int j=0; j<blocksNum ; j++ ) {
179               array = (float*) blockArray[j].buff;
180               delete[] array;
181               blockArray[j].buff = NULL;
182            }   
183         }
184         break;
185      case SAGE_SAMPLE_INT16 :
186         {
187            short *array;
188            for( int j=0; j<blocksNum ; j++ ) {
189               array = (short*) blockArray[j].buff;
190               delete[] array;
191               blockArray[j].buff = NULL;
192            }
193         }   
194         break;
195      case SAGE_SAMPLE_INT8 :
196         {
197            char *array;
198            for( int j=0; j<blocksNum ; j++ ) {
199               array = (char*) blockArray[j].buff;
200               delete[] array;
201               blockArray[j].buff = NULL;
202            }
203         }     
204         break;
205      case SAGE_SAMPLE_UINT8 :
206         {
207            unsigned char *array;
208            for( int j=0; j<blocksNum ; j++ ) {
209               array = (unsigned char*) blockArray[j].buff;
210               delete[] array;
211               blockArray[j].buff = NULL;
212            }
213         }     
214         break;
215      default :
216         break;
217   }
218   delete [] blockArray;
219   blockArray = NULL;   
220   
221}
222
223void sageAudioCircBuf::reset()
224{
225   readIndex = 0;
226   writeIndex = 0;
227   full = false;
228   empty = true;
229   locked = false;
230   lastFrameIndex = -1;
231   //synchronizer = NULL;
232
233   refMutex =0;   
234   refRead =0;
235   readers.clear();
236   readers.push_back(0);   
237
238   switch(sampleFmt) {
239      case SAGE_SAMPLE_FLOAT32 :
240         {
241            float *array;
242            for( int j=0; j<blocksNum ; j++ ) {
243               array = (float*) blockArray[j].buff;
244               blockArray[j].reformatted = 0;           
245               for( int k=0; k< sampleBuffSize ; k++ ) {
246                  array[k] = 0.0;
247               }         
248            }
249         }
250         break;
251      case SAGE_SAMPLE_INT16 :
252         {
253            short *array;   
254            for( int j=0; j<blocksNum ; j++ ) {
255               array = (short*) blockArray[j].buff;
256               blockArray[j].reformatted = 0;               
257               for( int k=0; k< sampleBuffSize ; k++ ) {
258                  array[k] = 0;
259               }         
260            }
261         }   
262         break;
263      case SAGE_SAMPLE_INT8 :
264         {
265            char *array;         
266            for( int j=0; j<blocksNum ; j++ ) {
267               array = (char*) blockArray[j].buff;
268               blockArray[j].reformatted = 0;               
269               for( int k=0; k< sampleBuffSize ; k++ ) {
270                  array[k] = '0';
271               }         
272            }
273         }     
274         break;
275      case SAGE_SAMPLE_UINT8 :
276         {
277            unsigned char *array;     
278            for( int j=0; j<blocksNum ; j++ ) {
279               array =(unsigned char*) blockArray[j].buff;
280               blockArray[j].reformatted = 0;               
281               for( int k=0; k< sampleBuffSize ; k++ ) {
282                  array[k] = 128;
283               }         
284            }
285         }     
286         break;
287   }
288   
289   pthread_cond_signal(notFull);
290   //pthread_mutex_unlock(queueLock);   
291
292}
293
294
295
296audioBlock* sageAudioCircBuf::readBlock(int Id)
297{
298   if(refMutex == 1) return NULL;
299   if (empty) {
300      return NULL;
301   }
302   else {
303      if(readers[Id] == 0) {
304         readers[Id] = 1;
305         refRead++;
306      } else {
307         return NULL;
308      }
309   }
310   //std::cout << "readBlock " << std::endl;
311
312   return &blockArray[readIndex];
313}
314
315audioBlock* sageAudioCircBuf::readBlock(int Id, int frameNum)
316{
317   if(refMutex == 1) return NULL;
318   
319   if (empty) {
320      return NULL;
321   }
322   else   {
323      // ????? - not working correctly
324      if(readers[Id] == 0) {
325         readers[Id] = 1;
326         refRead++;
327      } else {
328         return NULL;
329      }
330           
331      //if (frameNum%10000 >= blockArray[readIndex].frameIndex) {
332      if (frameNum >= blockArray[readIndex].frameIndex) {
333         return &blockArray[readIndex];
334      }   
335   }   
336     
337   return NULL;
338}
339/*
340audioBlock* sageAudioCircBuf::readBlock()
341{
342   if (empty) {
343      return NULL;
344   }
345   else   
346      return &blockArray[readIndex];
347}
348
349audioBlock* sageAudioCircBuf::readBlock(int frameNum)
350{
351   if (empty) {
352      return NULL;
353   }
354   else   {   
355      //if (frameNum%10000 >= blockArray[readIndex].frameIndex) {
356      if (frameNum >= blockArray[readIndex].frameIndex) {
357         return &blockArray[readIndex];
358      }   
359   }   
360     
361   return NULL;
362}
363*/
364
365audioBlock* sageAudioCircBuf::getNextWriteBlock()
366{
367   if(synchronizer) {
368      if(locked == true) {
369         // waiting for signal from graphic stream receiver
370         locked = !synchronizer->checkSignal(audioId);
371         if(locked == true) {
372            //std::cout << "checkSignal : locked " << std::endl;
373         } else
374         {
375            std::cout << "checkSignal : free " << std::endl;
376         }
377      }
378   }
379
380   // if buffer is full or if buffer is locked for writing
381   pthread_mutex_lock(queueLock);
382   while (full) {
383      pthread_cond_wait(notFull, queueLock);
384      //return NULL;
385   }   
386   pthread_mutex_unlock(queueLock);
387   if (locked) {
388      return NULL;
389   }       
390   audioBlock *block = &blockArray[writeIndex];
391   clearBlock(writeIndex);
392
393   //std::cout << "wrote " << std::endl;
394
395   return block;
396}
397
398
399int sageAudioCircBuf::updateReadIndex()
400{
401   refMutex = 1;
402   int gframeIndex=0;
403   int size = readers.size();
404   if(refRead == size) {
405      gframeIndex = blockArray[readIndex].frameIndex;
406      clearBlock(readIndex);
407      readIndex = (readIndex+1) % blocksNum;
408     
409      full = false;
410      //pthread_mutex_unlock(queueLock);
411      pthread_cond_signal(notFull);
412           
413      if (readIndex == writeIndex) {
414         empty = true;
415      }
416      refRead = 0;
417      for(int i=0; i <size; i++)
418      {
419         readers[i] =0;
420      }
421   }
422   
423   if(syncClientObj)
424   {
425      int tempIndex = gframeIndex % syncKeyFrame;
426      int diff = lastgFrameIndex - tempIndex;
427     
428      if(diff > 0)
429      {
430         tempIndex = gframeIndex -tempIndex;
431         //std::cout << "-------> sync signal -- audio update" << tempIndex << instID << std::endl;
432         syncClientObj->sendSlaveUpdate(tempIndex, instID, syncKeyFrame, SAGE_UPDATE_AUDIO);
433
434         //syncClientObj->sendSlaveUpdate(gframeIndex + 1, instID,1, SAGE_UPDATE_AUDIO);
435      }
436      lastgFrameIndex = gframeIndex % syncKeyFrame;
437   }           
438   refMutex =0;   
439   return readIndex;
440}
441
442
443/*
444int sageAudioCircBuf::updateReadIndex()
445{
446   clearBlock(readIndex);
447   readIndex = (readIndex+1) % blocksNum;
448   full = false;
449   if (readIndex == writeIndex)
450      empty = true;
451     
452   return 0;
453}
454*/
455
456int sageAudioCircBuf::updateWriteIndex()
457{
458   audioBlock *block = &blockArray[writeIndex];
459   lastFrameIndex = block->frameIndex;
460
461   writeIndex = (writeIndex+1) % blocksNum;
462   int nextIndex = (writeIndex+1) % blocksNum;
463   if (nextIndex == readIndex) {
464      full = true;
465      //pthread_mutex_lock(queueLock);
466   }   
467
468   empty = false;
469
470   // check keyframe
471   if(synchronizer) {
472      locked = synchronizer->checkKeyFrame(audioId, lastFrameIndex);
473   }
474   //std::cout << "checkKeyFrame : " << lastFrameIndex << std::endl;
475   if(locked) {
476      std::cout << "checkKeyFrame : keyframe -> locked : " << lastFrameIndex << std::endl;
477   }
478   return 0;
479}
480
481int sageAudioCircBuf::getReadIndex()
482{
483   return readIndex;
484}
485int sageAudioCircBuf::getWriteIndex()
486{
487   return writeIndex;
488}
489
490int sageAudioCircBuf::convertToFloat(sageSampleFmt fmt, void* rawdata, audioBlock* block)
491{
492   if(sampleFmt != SAGE_SAMPLE_FLOAT32) return -1;
493
494   float *wptr = (float*) block->buff;
495
496   switch(fmt) {
497      case SAGE_SAMPLE_FLOAT32 :
498         {
499            float *rptr = (float*) rawdata;
500            for( int i=0; i< sampleBuffSize; i++ )
501            {
502               *wptr++ = FLOAT_TO_FLOAT(*rptr);
503               rptr++;
504            }
505         }
506         break;
507      case SAGE_SAMPLE_INT16 :
508         {
509            short *rptr = (short*) rawdata;
510            for( int i=0; i< sampleBuffSize; i++ )
511            {
512               *wptr++ = INT16_TO_FLOAT(*rptr);
513               rptr++;
514            }
515         }
516         break;
517      case SAGE_SAMPLE_INT8 :
518         {
519            char *rptr = (char*) rawdata;
520            for( int i=0; i< sampleBuffSize; i++ )
521            {
522               *wptr++ = INT8_TO_FLOAT(*rptr);
523               rptr++;
524            }
525         }
526         break;
527      case SAGE_SAMPLE_UINT8 :
528         {
529            unsigned char *rptr = (unsigned char*) rawdata;
530         
531            for( int i=0; i< sampleBuffSize; i++ )
532            {
533               *wptr++ = UINT8_TO_FLOAT(*rptr);
534               rptr++;
535            }
536         }
537         break;
538   }
539
540   return 1;
541}
542
543int sageAudioCircBuf::merge(audioBlock* block)
544{
545   std::vector<sageAudioCircBuf*> bufferList = sageAudioModule::_instance->getBufferList();
546
547   float size = 1.0 / bufferList.size();
548
549   float *wptr = (float*) block->buff;
550   /*for( int i=0; i< sampleBuffSize; i++ )
551   {
552      *wptr = *wptr * size ;
553      //*wptr = *wptr * 0.0 ;
554      wptr++;
555   }*/
556   float *rptr = NULL;
557
558   std::vector<sageAudioCircBuf*>::iterator iterBuffer;
559   sageAudioCircBuf* temp = NULL;
560   audioBlock *secondblock = NULL;
561   for(iterBuffer = bufferList.begin(); iterBuffer != bufferList.end(); iterBuffer++)
562   {
563      temp = (sageAudioCircBuf*) *iterBuffer;
564      if(temp->getAudioId() != audioId)
565      {
566         secondblock = temp->readBlock();
567         if(secondblock == NULL) continue;
568         if(secondblock->reformatted != 1) continue;
569
570         wptr = (float*) block->buff;
571         rptr = (float*) secondblock->buff;
572         for( int i=0; i< sampleBuffSize; i++ )
573         {
574            //*wptr = *rptr;
575            //*wptr = *wptr + size * (*rptr);
576            *wptr = *wptr + (*rptr);
577            //std::cout << *wptr << std::endl;
578            wptr++;
579            rptr++;
580         }
581         //std::cout << "merging " << temp->getAudioId() << ", mine: " << audioId << " size : " << size << std::endl;
582
583         temp->updateReadIndex();
584      }
585   }
586
587   return 1;
588}
589
590int sageAudioCircBuf::getSize()
591{
592   return blocksNum;
593}
594
595int sageAudioCircBuf::getAudioId()
596{
597   return audioId;
598}
599   
600void sageAudioCircBuf::clearBlock(int frameNum)
601{
602   switch(sampleFmt) {
603      case SAGE_SAMPLE_FLOAT32 :
604         {
605            float *array = (float*) blockArray[frameNum].buff;
606            for( int j=0; j< sampleBuffSize ; j++ ) {
607               array[j] = 0;
608            }     
609         }
610         break;
611      case SAGE_SAMPLE_INT16 :
612         {
613            short *array = (short*) blockArray[frameNum].buff;
614            for( int j=0; j< sampleBuffSize ; j++ ) {
615               array[j] = 0;
616            }     
617         }   
618         break;
619      case SAGE_SAMPLE_INT8 :
620         {
621            char *array = (char*) blockArray[frameNum].buff;
622            for( int j=0; j< sampleBuffSize ; j++ ) {
623               array[j] = '0';
624            }
625         }     
626         break;
627      case SAGE_SAMPLE_UINT8 :
628         {
629            unsigned char *array = (unsigned char*) blockArray[frameNum].buff;
630            for( int j=0; j< sampleBuffSize ; j++ ) {
631               array[j] = '0';
632            }         
633         }     
634         break;
635      default :
636         break;
637   }
638
639}
640
641int sageAudioCircBuf::getBytesBlock()
642{
643   return bytesBlock;
644}
645
646void sageAudioCircBuf::connectSync(sageAudioSync* synch)
647{
648   synchronizer = synch;
649
650}
651
652void sageAudioCircBuf::connectSyncClient(sageSyncClient* synch)
653{
654   syncClientObj = synch;
655   if(syncClientObj != NULL)
656   {
657      syncClientObj->sendSlaveUpdate(1, instID, syncKeyFrame, SAGE_UPDATE_AUDIO);
658   }
659}
660   
661void sageAudioCircBuf::setLock()
662{
663   //locked = true;
664}
665
666void sageAudioCircBuf::setFree()
667{
668   //locked = false;
669}
670
671int sageAudioCircBuf::getLastFrameIdx()
672{
673   return lastFrameIndex;
674}
675
676int sageAudioCircBuf::addReader()
677{
678   int index = readers.size();
679   readers.push_back(0);
680   return index;   
681}
682
683void sageAudioCircBuf::deleteReader(int Id)
684{
685   readers[Id] = -1;
686}
Note: See TracBrowser for help on using the repository browser.