Gnash  0.8.11dev
LiveSound.h
Go to the documentation of this file.
1 // LiveSound.h: - base class for embedded sound handling, for gnash
2 //
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (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 License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 
20 #ifndef SOUND_LIVESOUND_H
21 #define SOUND_LIVESOUND_H
22 
23 #include <memory>
24 #include <cassert>
25 #include <cstdint> // For C99 int types
26 #include <iostream>
27 
28 #include "InputStream.h"
29 #include "AudioDecoder.h"
30 #include "SimpleBuffer.h"
31 
32 // Forward declarations
33 namespace gnash {
34  namespace media {
35  class MediaHandler;
36  class SoundInfo;
37  }
38 }
39 
40 namespace gnash {
41 namespace sound {
42 
43 
46 //
47 // TODO: this shares some functionality with CursoredBuffer, and the two
48 // classes might be merged.
49 class Buffers {
50 public:
51  Buffers(size_t in_point)
52  : _buffers(),
53  _index(0),
54  _pos(0),
55  _consumed(0),
56  _in_point(in_point)
57  {}
58 
59  Buffers(const Buffers&) = delete;
60  Buffers& operator=(const Buffers&) = delete;
61 
63  void append(SimpleBuffer buf) {
64  _buffers.push_back(std::move(buf));
65  consumeInPoint();
66  }
67 
68  void restart()
69  {
70  _index = 0;
71  _consumed = 0;
72  consumeInPoint();
73  }
74 
76  //
80  size_t copy(std::uint8_t* to, size_t bytes) {
81  assert(_consumed >= _in_point);
82 
83  size_t bytes_remaining = bytes;
84 
85  for (; _index < _buffers.size(); ++_index) {
86  const SimpleBuffer& buffer = _buffers[_index];
87 
88  size_t to_copy = std::min(bytes_remaining, buffer.size() - _pos);
89 
90  std::copy(buffer.data() + _pos, buffer.data() + _pos + to_copy, to);
91  to += to_copy;
92  bytes_remaining -= to_copy;
93  _pos += to_copy;
94 
95  if (_pos == buffer.size()) {
96  ++_index;
97  _pos = 0;
98  break;
99  }
100 
101  if (bytes_remaining == 0) {
102  break;
103  }
104  }
105 
106  size_t written = bytes - bytes_remaining;
107  _consumed += written;
108  return written;
109  }
110 
112  std::uint64_t countBytes() const
113  {
114  std::uint64_t bytes = 0;
115  for (const SimpleBuffer& buffer : _buffers) {
116  bytes += buffer.size();
117  }
118  return bytes;
119  }
120 
122  std::uint64_t consumed() const
123  {
124  return std::max<uint64_t>(_consumed, _in_point);
125  }
126 
127 private:
128  void consumeInPoint() {
129  if (_consumed >= _in_point) {
130  return;
131  }
132  size_t inPoint = _in_point;
133 
134  for (const SimpleBuffer& buffer : _buffers) {
135  size_t advance = std::min(inPoint, buffer.size());
136  if (advance == buffer.size()) {
137  ++_index;
138  inPoint -= advance;
139  } else {
140  _pos = advance;
141  break;
142  }
143  }
144  _consumed = _in_point;
145  }
146 
147  std::vector<SimpleBuffer> _buffers;
149  size_t _index;
151  size_t _pos;
153  std::uint64_t _consumed;
155  size_t _in_point;
156 };
157 
159 //
162 class LiveSound : public InputStream
163 {
164 protected:
165 
167  //
174  size_t inPoint);
175 
177  //
180  virtual bool moreData() = 0;
181 
183  //
185  virtual bool eof() const = 0;
186 
188  void restart() {
189  _samplesFetched = 0;
190  _decodedBuffers.restart();
191  }
192 
194  //
196  unsigned int samplesFetched() const {
197  return _samplesFetched;
198  }
199 
200  std::uint64_t playbackPosition() const {
201  return _decodedBuffers.consumed();
202  }
203 
205  return *_decoder;
206  }
207 
209  _decodedBuffers.append(std::move(data));
210  }
211 
214  unsigned int decodedSamplesAhead() const {
215 
216  const unsigned int dds = _decodedBuffers.countBytes();
217  if (dds <= playbackPosition()) return 0;
218 
219  size_t bytesAhead = dds - playbackPosition();
220  bytesAhead = checkEarlierEnd(bytesAhead, playbackPosition());
221 
222  assert(!(bytesAhead % 2));
223 
224  const unsigned int samplesAhead = bytesAhead / 2;
225  return samplesAhead;
226  }
227 
228 private:
229 
231  //
234  virtual size_t checkEarlierEnd(size_t left, size_t) const {
235  return left;
236  }
237 
238  // See dox in sound_handler.h (InputStream)
239  unsigned int fetchSamples(std::int16_t* to, unsigned int nSamples);
240 
241  void createDecoder(media::MediaHandler& mediaHandler,
242  const media::SoundInfo& info);
243 
244  virtual bool decodingCompleted() const = 0;
245 
247  unsigned long _samplesFetched;
248 
249  std::unique_ptr<media::AudioDecoder> _decoder;
250 
252  Buffers _decodedBuffers;
253 
254 };
255 
256 
257 } // gnash.sound namespace
258 } // namespace gnash
259 
260 #endif // SOUND_EMBEDSOUNDINST_H
Buffers(size_t in_point)
Definition: LiveSound.h:51
A sound input stream.
Definition: InputStream.h:47
void append(SimpleBuffer buf)
Append a buffer of data to be read by the consumer later.
Definition: LiveSound.h:63
std::uint64_t playbackPosition() const
Definition: LiveSound.h:200
Class containing information about an embedded sound definition.
Definition: SoundInfo.h:34
std::uint64_t countBytes() const
Definition: LiveSound.h:112
Buffers & operator=(const Buffers &)=delete
Instance of a defined sound (LiveSoundData)
Definition: LiveSound.h:162
LiveSound(media::MediaHandler &mh, const media::SoundInfo &info, size_t inPoint)
Create an embedded sound instance.
Definition: LiveSound.cpp:33
SimpleBuffer data
Definition: LocalConnection_as.cpp:151
Anonymous namespace for callbacks, local functions, event handlers etc.
Definition: dbus_ext.cpp:40
Definition: LiveSound.h:49
unsigned int samplesFetched() const
How many samples have been fetched since the beginning.
Definition: LiveSound.h:196
void restart()
Definition: LiveSound.h:68
std::uint8_t * data()
Get a pointer to start of data. May be NULL if size==0.
Definition: SimpleBuffer.h:92
The MediaHandler class acts as a factory to provide parser and decoders.
Definition: MediaHandler.h:69
void restart()
Start from the beginning again.
Definition: LiveSound.h:188
virtual bool eof() const =0
True if there is no more data ever.
size_t copy(std::uint8_t *to, size_t bytes)
Copy up to the given number of bytes to the given buffer.
Definition: LiveSound.h:80
A simple buffer of bytes.
Definition: SimpleBuffer.h:38
media::AudioDecoder & decoder() const
Definition: LiveSound.h:204
size_t size() const
Return size of the buffer.
Definition: SimpleBuffer.h:86
std::uint64_t consumed() const
Definition: LiveSound.h:122
Audio decoding base class.
Definition: AudioDecoder.h:36
virtual bool moreData()=0
Called when more decoded sound data is required.
unsigned int decodedSamplesAhead() const
Definition: LiveSound.h:214
void appendDecodedData(SimpleBuffer data)
Definition: LiveSound.h:208