1 /*  $Id: LoopingSource.cpp,v 1.1 2012/07/08 00:45:57 sarrazip Exp $
2 
3     flatzebra - SDL-based sound renderer
4     Copyright (C) 2011 Pierre Sarrazin <http://sarrazip.com/>
5 
6     This program is free software; you can redistribute it and/or
7     modify it under the terms of the GNU General Public License
8     as published by the Free Software Foundation; either version 2
9     of the License, or (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public
17     License along with this program; if not, write to the Free
18     Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19     Boston, MA  02110-1301, USA.
20 */
21 
22 #include <roundbeetle/LoopingSource.h>
23 
24 
25 namespace roundbeetle {
26 
27 
LoopingSource(SampleSource * _src,size_t _numLoops)28 LoopingSource::LoopingSource(SampleSource *_src, size_t _numLoops /*= 0*/)
29 :   SampleSource(),
30     src(_src),
31     numLoops(_numLoops),
32     loopCounter(0)
33 {
34     //std::cout << "LoopingSource::LoopingSource(src=" << _src << ", " << _numLoops << ")" << std::endl;
35     assert(_src != NULL);
36 }
37 
38 
39 //virtual
~LoopingSource()40 LoopingSource::~LoopingSource()
41 {
42     delete src;
43 }
44 
45 
46 size_t  //virtual
getSamples(Sint16 * dest,size_t numRequested)47 LoopingSource::getSamples(Sint16 *dest, size_t numRequested)
48 {
49     /*std::cout << "LoopingSource::getSamples(" << dest << ", " << numRequested
50               << "): numLoops=" << numLoops
51               << ", loopCounter=" << loopCounter
52               << ", src=" << src << std::endl;*/
53     if (dest == NULL || numRequested == 0 || src == NULL)
54         return 0;
55 
56     size_t numReturned = 0;
57 
58     for (;;)
59     {
60         size_t numObtained = src->getSamples(dest, numRequested - numReturned);
61         assert(numObtained <= numRequested - numReturned);
62         numReturned += numObtained;
63         /*std::cout << "LoopingSource::getSamples:   asked " << numRequested - numReturned
64                   << " from " << src << ", got " << numObtained
65                   << "; numReturned now at " << numReturned
66                   << ", numRequested=" << numRequested
67                   << ", src " << (src->isFinished() ? "FINISHED" : "not finished")
68                   << std::endl;*/
69         if (numReturned == numRequested)
70             return numRequested;
71         dest += numObtained;
72 
73         if (src->isFinished())
74         {
75             ++loopCounter;
76             //std::cout << "LoopingSource::getSamples:   loopCounter=" << loopCounter << std::endl;
77 
78             if (isFinished())  // if finished number of loops to do
79                 return numReturned;  // stop
80 
81             if (!src->rewind())  // if source finished but rewinding it fails
82                 return numReturned;
83         }
84     }
85 }
86 
87 
88 bool  //virtual
isFinished() const89 LoopingSource::isFinished() const
90 {
91     // Number of loops to do is finite, and reached:
92     return numLoops > 0 && loopCounter >= numLoops;
93 }
94 
95 
96 bool  //virtual
rewind()97 LoopingSource::rewind()
98 {
99     loopCounter = 0;
100     if (src == NULL)
101         return false;
102     return src->rewind();
103 }
104 
105 
106 }  // namespace roundbeetle
107