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