xoreos  0.0.5
interleaver.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <cassert>
26 #include <cstring>
27 
28 #include "src/common/error.h"
29 
30 #include "src/sound/audiostream.h"
31 #include "src/sound/interleaver.h"
32 
33 namespace Sound {
34 
35 class Interleaver : public AudioStream {
36 public:
37  Interleaver(int rate, const std::vector<AudioStream *> &streams, bool disposeAfterUse);
38  ~Interleaver();
39 
40  size_t readBuffer(int16 *buffer, const size_t numSamples);
41 
42  int getChannels() const;
43  int getRate() const;
44 
45  bool endOfData() const;
46  bool endOfStream() const;
47 
48 private:
49  int _rate;
50  int _channels;
51 
52  std::vector<AudioStream *> _streams;
54 };
55 
56 
57 Interleaver::Interleaver(int rate, const std::vector<AudioStream *> &streams,
58  bool disposeAfterUse) :
59  _rate(rate), _channels(0), _disposeAfterUse(disposeAfterUse) {
60 
61  _streams.reserve(streams.size());
62  for (std::vector<AudioStream *>::const_iterator s = streams.begin();
63  s != streams.end(); ++s) {
64 
65  assert(*s);
66 
67  _streams.push_back(*s);
68  _channels += (*s)->getChannels();
69  }
70 }
71 
73  if (_disposeAfterUse)
74  for (std::vector<AudioStream *>::iterator s = _streams.begin(); s != _streams.end(); ++s)
75  delete *s;
76 }
77 
78 size_t Interleaver::readBuffer(int16 *buffer, const size_t numSamples) {
79  size_t maxSamples = numSamples;
80  size_t samples = 0;
81 
82  for (; samples < maxSamples; ) {
83  if (endOfData())
84  break;
85 
86  // Read one sample of each channel of each stream
87  for (std::vector<AudioStream *>::iterator s = _streams.begin();
88  s != _streams.end(); ++s) {
89 
90  const size_t channels = (*s)->getChannels();
91  const size_t nRead = (*s)->readBuffer(buffer, channels);
92  if (nRead == kSizeInvalid)
93  return kSizeInvalid;
94 
95  if (nRead != channels)
96  std::memset(buffer, 0, 2 * channels);
97 
98  buffer += channels;
99  samples += (*s)->getChannels();
100  }
101  }
102 
103  return samples;
104 }
105 
107  return _channels;
108 }
109 
110 int Interleaver::getRate() const {
111  return _rate;
112 }
113 
115  // When at least one stream signals end of data, we do that too
116 
117  for (std::vector<AudioStream *>::const_iterator s = _streams.begin();
118  s != _streams.end(); ++s)
119  if ((*s)->endOfData())
120  return true;
121 
122  return false;
123 }
124 
126  // When all streams signal end of stream, we do that too
127 
128  for (std::vector<AudioStream *>::const_iterator s = _streams.begin();
129  s != _streams.end(); ++s)
130  if (!(*s)->endOfStream())
131  return false;
132 
133  return true;
134 }
135 
136 
137 AudioStream *makeInterleaver(int rate, const std::vector<AudioStream *> &streams,
138  bool disposeAfterUse) {
139 
140  if (streams.empty())
141  throw Common::Exception("makeInterleaver(): No streams");
142 
143  return new Interleaver(rate, streams, disposeAfterUse);
144 }
145 
146 
147 } // End of namespace Sound
int16_t int16
Definition: types.h:201
Exception that provides a stack of explanations.
Definition: error.h:36
Definition: game.h:37
AudioStream * makeInterleaver(int rate, const std::vector< AudioStream *> &streams, bool disposeAfterUse)
Takes several input audio streams and interleaves the sample data to create an audio stream with x ch...
Basic exceptions to throw.
static const size_t kSizeInvalid
Definition: audiostream.h:72
An audio stream interleaving several other audio streams.
bool endOfStream() const
End of stream reached? If this returns true, it means that all data in this stream is used up and no ...
int getChannels() const
Return the number channels in this stream.
Generic audio input stream.
Definition: audiostream.h:70
std::vector< AudioStream * > _streams
Definition: interleaver.cpp:52
Interleaver(int rate, const std::vector< AudioStream *> &streams, bool disposeAfterUse)
Definition: interleaver.cpp:57
bool endOfData() const
End of data reached? If this returns true, it means that at this time there is no data available in t...
int getRate() const
Sample rate of the stream.
Streaming audio.
size_t readBuffer(int16 *buffer, const size_t numSamples)
Fill the given buffer with up to numSamples samples.
Definition: interleaver.cpp:78