1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program 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 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program 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 this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef AUDIO_AUDIOSTREAM_H 24 #define AUDIO_AUDIOSTREAM_H 25 26 namespace Audio { 27 28 /** 29 * Generic audio input stream. Subclasses of this are used to feed arbitrary 30 * sampled audio data into ScummVM's audio mixer. 31 */ 32 class AudioStream { 33 public: 34 int16 mVolume; 35 ~AudioStream()36 virtual ~AudioStream() {} 37 38 /** 39 * Fill the given buffer with up to numSamples samples. Returns the actual 40 * number of samples read, or -1 if a critical error occurred (note: you 41 * *must* check if this value is less than what you requested, this can 42 * happen when the stream is fully used up). 43 * 44 * Data has to be in native endianess, 16 bit per sample, signed. For stereo 45 * stream, buffer will be filled with interleaved left and right channel 46 * samples, starting with a left sample. Furthermore, the samples in the 47 * left and right are summed up. So if you request 4 samples from a stereo 48 * stream, you will get a total of two left channel and two right channel 49 * samples. 50 */ 51 virtual int readBuffer(int16 *buffer, const int numSamples) = 0; 52 53 /** Is this a stereo stream? */ 54 virtual bool isStereo() const = 0; 55 56 /** Sample rate of the stream. */ 57 virtual int getRate() const = 0; 58 59 /** 60 * End of data reached? If this returns true, it means that at this 61 * time there is no data available in the stream. However there may be 62 * more data in the future. 63 * This is used by e.g. a rate converter to decide whether to keep on 64 * converting data or stop. 65 */ 66 virtual bool endOfData() const = 0; 67 68 /** 69 * End of stream reached? If this returns true, it means that all data 70 * in this stream is used up and no additional data will appear in it 71 * in the future. 72 * This is used by the mixer to decide whether a given stream shall be 73 * removed from the list of active streams (and thus be destroyed). 74 * By default this maps to endOfData() 75 */ endOfStream() const76 virtual bool endOfStream() const { return endOfData(); } 77 }; 78 79 /** 80 * A rewindable audio stream. This allows for reseting the AudioStream 81 * to its initial state. Note that rewinding itself is not required to 82 * be working when the stream is being played by Mixer! 83 */ 84 class RewindableAudioStream : public virtual AudioStream { 85 public: 86 /** 87 * Rewinds the stream to its start. 88 * 89 * @return true on success, false otherwise. 90 */ 91 virtual bool rewind() = 0; 92 }; 93 94 /** 95 * A looping audio stream. This object does nothing besides using 96 * a RewindableAudioStream to play a stream in a loop. 97 */ 98 class LoopingAudioStream : public AudioStream { 99 public: 100 /** 101 * Creates a looping audio stream object. 102 * 103 * Note that on creation of the LoopingAudioStream object 104 * the underlying stream will be rewound. 105 * 106 * @see makeLoopingAudioStream 107 * 108 * @param stream Stream to loop 109 * @param loops How often to loop (0 = infinite) 110 * @param disposeAfterUse Destroy the stream after the LoopingAudioStream has finished playback. 111 */ 112 LoopingAudioStream(RewindableAudioStream *stream, size_t loops); 113 114 int readBuffer(int16 *buffer, const int numSamples); 115 bool endOfData() const; 116 bool endOfStream() const; 117 isStereo() const118 bool isStereo() const { return _parent->isStereo(); } getRate() const119 int getRate() const { return _parent->getRate(); } 120 121 /** 122 * Returns number of loops the stream has played. 123 */ getCompleteIterations() const124 size_t getCompleteIterations() const { return _completeIterations; } 125 private: 126 RewindableAudioStream* _parent; 127 128 size_t _loops; 129 size_t _completeIterations; 130 }; 131 132 /** 133 * Wrapper functionality to efficiently create a stream, which might be looped. 134 * 135 * Note that this function does not return a LoopingAudioStream, because it does 136 * not create one when the loop count is "1". This allows to keep the runtime 137 * overhead down, when the code does not require any functionality only offered 138 * by LoopingAudioStream. 139 * 140 * @param stream Stream to loop (will be automatically destroyed, when the looping is done) 141 * @param loops How often to loop (0 = infinite) 142 * @return A new AudioStream, which offers the desired functionality. 143 */ 144 AudioStream *makeLoopingAudioStream(RewindableAudioStream *stream, size_t loops); 145 146 } // End of namespace Audio 147 148 #endif 149