Ticket #8862: mixer-rev.patch
File mixer-rev.patch, 37.3 KB (added by , 16 years ago) |
---|
-
common/system.h
810 810 */ 811 811 virtual Audio::Mixer *getMixer() = 0; 812 812 813 /**814 * Determine the output sample rate. Audio data provided by the sound815 * callback will be played using this rate.816 * @note Client code other than the sound mixer should _not_ use this817 * method. Instead, call Mixer::getOutputRate()!818 * @return the output sample rate819 */820 virtual int getOutputSampleRate() const = 0;821 822 813 //@} 823 814 824 815 -
sound/mixer.cpp
27 27 #include "common/util.h" 28 28 #include "common/system.h" 29 29 30 #include "sound/mixer .h"30 #include "sound/mixer_intern.h" 31 31 #include "sound/rate.h" 32 32 #include "sound/audiostream.h" 33 33 … … 103 103 #pragma mark - 104 104 105 105 106 Mixer ::Mixer() {107 _syst = g_system;106 MixerImpl::MixerImpl(OSystem *system) 107 : _syst(system), _sampleRate(0), _mixerReady(false), _handleSeed(0) { 108 108 109 _handleSeed = 0;109 int i; 110 110 111 int i = 0;112 113 111 for (i = 0; i < ARRAYSIZE(_volumeForSoundType); i++) 114 112 _volumeForSoundType[i] = kMaxMixerVolume; 115 113 116 114 for (i = 0; i != NUM_CHANNELS; i++) 117 115 _channels[i] = 0; 118 119 _mixerReady = false;120 116 } 121 117 122 Mixer ::~Mixer() {118 MixerImpl::~MixerImpl() { 123 119 for (int i = 0; i != NUM_CHANNELS; i++) 124 120 delete _channels[i]; 125 121 } 126 122 127 uint Mixer::getOutputRate() const{128 return (uint)_syst->getOutputSampleRate();123 void MixerImpl::setReady(bool ready) { 124 _mixerReady = ready; 129 125 } 130 126 131 void Mixer::insertChannel(SoundHandle *handle, Channel *chan) { 127 uint MixerImpl::getOutputRate() const { 128 return _sampleRate; 129 } 132 130 131 void MixerImpl::setOutputRate(uint sampleRate) { 132 if (_sampleRate != 0 && _sampleRate != sampleRate) 133 error("Changing the Audio::Mixer output sample rate is not supported"); 134 _sampleRate = sampleRate; 135 } 136 137 void MixerImpl::insertChannel(SoundHandle *handle, Channel *chan) { 138 133 139 int index = -1; 134 140 for (int i = 0; i != NUM_CHANNELS; i++) { 135 141 if (_channels[i] == 0) { … … 138 144 } 139 145 } 140 146 if (index == -1) { 141 warning("Mixer ::out of mixer slots");147 warning("MixerImpl::out of mixer slots"); 142 148 delete chan; 143 149 return; 144 150 } … … 151 157 } 152 158 } 153 159 154 void Mixer ::playRaw(160 void MixerImpl::playRaw( 155 161 SoundType type, 156 162 SoundHandle *handle, 157 163 void *sound, … … 166 172 playInputStream(type, handle, input, id, volume, balance, true, false, ((flags & Mixer::FLAG_REVERSE_STEREO) != 0)); 167 173 } 168 174 169 void Mixer ::playInputStream(175 void MixerImpl::playInputStream( 170 176 SoundType type, 171 177 SoundHandle *handle, 172 178 AudioStream *input, … … 198 204 insertChannel(handle, chan); 199 205 } 200 206 201 void Mixer::mix(int16 *buf, uint len) { 207 void MixerImpl::mixCallback(byte *samples, uint len) { 208 assert(samples); 209 202 210 Common::StackLock lock(_mutex); 211 212 int16 *buf = (int16 *)samples; 213 len >>= 2; 203 214 204 215 // Since the mixer callback has been called, the mixer must be ready... 205 216 _mixerReady = true; … … 218 229 } 219 230 } 220 231 221 void Mixer::mixCallback(void *s, byte *samples, int len) { 222 assert(s); 223 assert(samples); 224 // Len is the number of bytes in the buffer; we divide it by 225 // four to get the number of samples (stereo 16 bit). 226 ((Mixer *)s)->mix((int16 *)samples, len >> 2); 227 } 228 229 void Mixer::stopAll() { 232 void MixerImpl::stopAll() { 230 233 Common::StackLock lock(_mutex); 231 234 for (int i = 0; i != NUM_CHANNELS; i++) { 232 235 if (_channels[i] != 0 && !_channels[i]->isPermanent()) { … … 236 239 } 237 240 } 238 241 239 void Mixer ::stopID(int id) {242 void MixerImpl::stopID(int id) { 240 243 Common::StackLock lock(_mutex); 241 244 for (int i = 0; i != NUM_CHANNELS; i++) { 242 245 if (_channels[i] != 0 && _channels[i]->getId() == id) { … … 246 249 } 247 250 } 248 251 249 void Mixer ::stopHandle(SoundHandle handle) {252 void MixerImpl::stopHandle(SoundHandle handle) { 250 253 Common::StackLock lock(_mutex); 251 254 252 255 // Simply ignore stop requests for handles of sounds that already terminated … … 258 261 _channels[index] = 0; 259 262 } 260 263 261 void Mixer ::setChannelVolume(SoundHandle handle, byte volume) {264 void MixerImpl::setChannelVolume(SoundHandle handle, byte volume) { 262 265 Common::StackLock lock(_mutex); 263 266 264 267 const int index = handle._val % NUM_CHANNELS; … … 268 271 _channels[index]->setVolume(volume); 269 272 } 270 273 271 void Mixer ::setChannelBalance(SoundHandle handle, int8 balance) {274 void MixerImpl::setChannelBalance(SoundHandle handle, int8 balance) { 272 275 Common::StackLock lock(_mutex); 273 276 274 277 const int index = handle._val % NUM_CHANNELS; … … 278 281 _channels[index]->setBalance(balance); 279 282 } 280 283 281 uint32 Mixer ::getSoundElapsedTime(SoundHandle handle) {284 uint32 MixerImpl::getSoundElapsedTime(SoundHandle handle) { 282 285 Common::StackLock lock(_mutex); 283 286 284 287 const int index = handle._val % NUM_CHANNELS; … … 288 291 return _channels[index]->getElapsedTime(); 289 292 } 290 293 291 void Mixer ::pauseAll(bool paused) {294 void MixerImpl::pauseAll(bool paused) { 292 295 Common::StackLock lock(_mutex); 293 296 for (int i = 0; i != NUM_CHANNELS; i++) { 294 297 if (_channels[i] != 0) { … … 297 300 } 298 301 } 299 302 300 void Mixer ::pauseID(int id, bool paused) {303 void MixerImpl::pauseID(int id, bool paused) { 301 304 Common::StackLock lock(_mutex); 302 305 for (int i = 0; i != NUM_CHANNELS; i++) { 303 306 if (_channels[i] != 0 && _channels[i]->getId() == id) { … … 307 310 } 308 311 } 309 312 310 void Mixer ::pauseHandle(SoundHandle handle, bool paused) {313 void MixerImpl::pauseHandle(SoundHandle handle, bool paused) { 311 314 Common::StackLock lock(_mutex); 312 315 313 316 // Simply ignore (un)pause requests for sounds that already terminated … … 318 321 _channels[index]->pause(paused); 319 322 } 320 323 321 bool Mixer ::isSoundIDActive(int id) {324 bool MixerImpl::isSoundIDActive(int id) { 322 325 Common::StackLock lock(_mutex); 323 326 for (int i = 0; i != NUM_CHANNELS; i++) 324 327 if (_channels[i] && _channels[i]->getId() == id) … … 326 329 return false; 327 330 } 328 331 329 int Mixer ::getSoundID(SoundHandle handle) {332 int MixerImpl::getSoundID(SoundHandle handle) { 330 333 Common::StackLock lock(_mutex); 331 334 const int index = handle._val % NUM_CHANNELS; 332 335 if (_channels[index] && _channels[index]->_handle._val == handle._val) … … 334 337 return 0; 335 338 } 336 339 337 bool Mixer ::isSoundHandleActive(SoundHandle handle) {340 bool MixerImpl::isSoundHandleActive(SoundHandle handle) { 338 341 Common::StackLock lock(_mutex); 339 342 const int index = handle._val % NUM_CHANNELS; 340 343 return _channels[index] && _channels[index]->_handle._val == handle._val; 341 344 } 342 345 343 bool Mixer ::hasActiveChannelOfType(SoundType type) {346 bool MixerImpl::hasActiveChannelOfType(SoundType type) { 344 347 Common::StackLock lock(_mutex); 345 348 for (int i = 0; i != NUM_CHANNELS; i++) 346 349 if (_channels[i] && _channels[i]->_type == type) … … 348 351 return false; 349 352 } 350 353 351 void Mixer ::setVolumeForSoundType(SoundType type, int volume) {354 void MixerImpl::setVolumeForSoundType(SoundType type, int volume) { 352 355 assert(0 <= type && type < ARRAYSIZE(_volumeForSoundType)); 353 356 354 357 // Check range … … 363 366 _volumeForSoundType[type] = volume; 364 367 } 365 368 366 int Mixer ::getVolumeForSoundType(SoundType type) const {369 int MixerImpl::getVolumeForSoundType(SoundType type) const { 367 370 assert(0 <= type && type < ARRAYSIZE(_volumeForSoundType)); 368 371 369 372 return _volumeForSoundType[type]; … … 443 446 // Convert the number of samples into a time duration. To avoid 444 447 // overflow, this has to be done in a somewhat non-obvious way. 445 448 446 uint rate = _mixer->getOutputRate();449 uint32 rate = _mixer->getOutputRate(); 447 450 448 451 uint32 seconds = _samplesConsumed / rate; 449 452 uint32 milliseconds = (1000 * (_samplesConsumed % rate)) / rate; -
sound/mixer_intern.h
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 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef SOUND_MIXER_INTERN_H 27 #define SOUND_MIXER_INTERN_H 28 29 #include "common/scummsys.h" 30 #include "common/mutex.h" 31 #include "sound/mixer.h" 32 33 namespace Audio { 34 35 /** 36 * The (default) implementation of the ScummVM audio mixing subsystem. 37 * 38 * Backends are responsible for allocating (and later releasing) an instance 39 * of this class, which engines can access via OSystem::getMixer(). 40 * 41 * Initialisation of instances of this class usually happens as follows: 42 * 1) Creat a new Audio::MixerImpl instance. 43 * 2) Set the hardware output sample rate via the setSampleRate() method. 44 * 3) Hook up the mixCallback() in a suitable audio processing thread/callback. 45 * 4) Change the mixer into ready mode via setReady(true). 46 * 5) Start audio processing (e.g. by resuming the audio thread, if applicable). 47 * 48 * In the future, we might make it possible for backends to provide 49 * (partial) alternative implementations of the mixer, e.g. to make 50 * better use of native sound mixing support on low-end devices. 51 * 52 * @see OSystem::getMixer() 53 */ 54 class MixerImpl : public Mixer { 55 private: 56 enum { 57 NUM_CHANNELS = 16 58 }; 59 60 OSystem *_syst; 61 Common::Mutex _mutex; 62 63 uint _sampleRate; 64 bool _mixerReady; 65 uint32 _handleSeed; 66 67 int _volumeForSoundType[4]; 68 Channel *_channels[NUM_CHANNELS]; 69 70 71 public: 72 MixerImpl(OSystem *system); 73 ~MixerImpl(); 74 75 virtual bool isReady() const { return _mixerReady; } 76 77 virtual void playRaw( 78 SoundType type, 79 SoundHandle *handle, 80 void *sound, uint32 size, uint rate, byte flags, 81 int id = -1, byte volume = 255, int8 balance = 0, 82 uint32 loopStart = 0, uint32 loopEnd = 0); 83 84 virtual void playInputStream( 85 SoundType type, 86 SoundHandle *handle, 87 AudioStream *input, 88 int id = -1, byte volume = 255, int8 balance = 0, 89 bool autofreeStream = true, 90 bool permanent = false, 91 bool reverseStereo = false); 92 93 94 95 virtual void stopAll(); 96 virtual void stopID(int id); 97 virtual void stopHandle(SoundHandle handle); 98 99 virtual void pauseAll(bool paused); 100 virtual void pauseID(int id, bool paused); 101 virtual void pauseHandle(SoundHandle handle, bool paused); 102 103 virtual bool isSoundIDActive(int id); 104 virtual int getSoundID(SoundHandle handle); 105 106 virtual bool isSoundHandleActive(SoundHandle handle); 107 108 virtual void setChannelVolume(SoundHandle handle, byte volume); 109 virtual void setChannelBalance(SoundHandle handle, int8 balance); 110 111 virtual uint32 getSoundElapsedTime(SoundHandle handle); 112 113 virtual bool hasActiveChannelOfType(SoundType type); 114 115 virtual void setVolumeForSoundType(SoundType type, int volume); 116 virtual int getVolumeForSoundType(SoundType type) const; 117 118 virtual uint getOutputRate() const; 119 120 protected: 121 void insertChannel(SoundHandle *handle, Channel *chan); 122 123 public: 124 /** 125 * The mixer callback function, to be called at regular intervals by 126 * the backend (e.g. from an audio mixing thread). All the actual mixing 127 * work is done from here. 128 */ 129 void mixCallback(byte *samples, uint len); 130 131 /** 132 * Set the internal 'is ready' flag of the mixer. 133 * Backends should invoke Mixer::setReady(true) once initialisation of 134 * their audio system has been completed (and in particular, *after* 135 * setOutputRate() has been called). 136 */ 137 void setReady(bool ready); 138 139 /** 140 * Set the output sample rate. 141 * 142 * @param sampleRate the new output sample rate 143 * 144 * @note Right now, this can be done exactly ONCE. That is, the mixer 145 * currently does not support changing the output sample rate after it 146 * has been set for the first time. This may change in the future. 147 */ 148 void setOutputRate(uint sampleRate); 149 }; 150 151 152 } // End of namespace Audio 153 154 #endif -
sound/mixer.h
Property changes on: sound/mixer_intern.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native
38 38 class AudioStream; 39 39 class Channel; 40 40 class Mixer; 41 class MixerImpl; 41 42 42 43 /** 43 44 * A SoundHandle instances corresponds to a specific sound … … 47 48 */ 48 49 class SoundHandle { 49 50 friend class Channel; 50 friend class Mixer ;51 friend class MixerImpl; 51 52 uint32 _val; 52 53 public: 53 54 inline SoundHandle() : _val(0xFFFFFFFF) {} … … 104 105 kMaxMixerVolume = 256 105 106 }; 106 107 107 private:108 enum {109 NUM_CHANNELS = 16110 };111 112 OSystem *_syst;113 Common::Mutex _mutex;114 115 int _volumeForSoundType[4];116 117 uint32 _handleSeed;118 Channel *_channels[NUM_CHANNELS];119 120 bool _mixerReady;121 122 108 public: 123 Mixer() ;124 ~Mixer();109 Mixer() {} 110 virtual ~Mixer() {} 125 111 126 112 127 113 … … 132 118 * sync with an audio stream. In particular, the Adlib MIDI emulation... 133 119 * 134 120 * @return whether the mixer is ready and setup 121 * 122 * @todo get rid of this? 135 123 */ 136 bool isReady() const { return _mixerReady; }124 virtual bool isReady() const = 0; 137 125 138 126 139 127 … … 143 131 * (using the makeLinearInputStream factory function), which is then 144 132 * passed on to playInputStream. 145 133 */ 146 v oid playRaw(134 virtual void playRaw( 147 135 SoundType type, 148 136 SoundHandle *handle, 149 137 void *sound, uint32 size, uint rate, byte flags, 150 138 int id = -1, byte volume = 255, int8 balance = 0, 151 uint32 loopStart = 0, uint32 loopEnd = 0) ;139 uint32 loopStart = 0, uint32 loopEnd = 0) = 0; 152 140 153 141 /** 154 142 * Start playing the given audio input stream. … … 170 158 * not stop this particular stream 171 159 * @param reverseStereo a flag indicating whether left and right channels shall be swapped 172 160 */ 173 v oid playInputStream(161 virtual void playInputStream( 174 162 SoundType type, 175 163 SoundHandle *handle, 176 164 AudioStream *input, 177 165 int id = -1, byte volume = 255, int8 balance = 0, 178 166 bool autofreeStream = true, 179 167 bool permanent = false, 180 bool reverseStereo = false) ;168 bool reverseStereo = false) = 0; 181 169 182 170 183 171 184 172 /** 185 173 * Stop all currently playing sounds. 186 174 */ 187 v oid stopAll();175 virtual void stopAll() = 0; 188 176 189 177 /** 190 178 * Stop playing the sound with given ID. 191 179 * 192 180 * @param id the ID of the sound to affect 193 181 */ 194 v oid stopID(int id);182 virtual void stopID(int id) = 0; 195 183 196 184 /** 197 185 * Stop playing the sound corresponding to the given handle. 198 186 * 199 187 * @param handle the sound to affect 200 188 */ 201 v oid stopHandle(SoundHandle handle);189 virtual void stopHandle(SoundHandle handle) = 0; 202 190 203 191 204 192 … … 208 196 * 209 197 * @param paused true to pause everything, false to unpause 210 198 */ 211 v oid pauseAll(bool paused);199 virtual void pauseAll(bool paused) = 0; 212 200 213 201 /** 214 202 * Pause/unpause the sound with the given ID. … … 216 204 * @param id the ID of the sound to affect 217 205 * @param paused true to pause the sound, false to unpause it 218 206 */ 219 v oid pauseID(int id, bool paused);207 virtual void pauseID(int id, bool paused) = 0; 220 208 221 209 /** 222 210 * Pause/unpause the sound corresponding to the given handle. … … 224 212 * @param handle the sound to affect 225 213 * @param paused true to pause the sound, false to unpause it 226 214 */ 227 v oid pauseHandle(SoundHandle handle, bool paused);215 virtual void pauseHandle(SoundHandle handle, bool paused) = 0; 228 216 229 217 230 218 … … 234 222 * @param id the ID of the sound to query 235 223 * @return true if the sound is active 236 224 */ 237 bool isSoundIDActive(int id);225 virtual bool isSoundIDActive(int id) = 0; 238 226 239 227 /** 240 228 * Get the sound ID of handle sound … … 242 230 * @param handle sound to query 243 231 * @return sound ID if active 244 232 */ 245 int getSoundID(SoundHandle handle);233 virtual int getSoundID(SoundHandle handle) = 0; 246 234 247 235 /** 248 236 * Check if a sound with the given handle is active. … … 250 238 * @param handle sound to query 251 239 * @return true if the sound is active 252 240 */ 253 bool isSoundHandleActive(SoundHandle handle);241 virtual bool isSoundHandleActive(SoundHandle handle) = 0; 254 242 255 243 256 244 … … 260 248 * @param handle the sound to affect 261 249 * @param volume the new channel volume (0 - 255) 262 250 */ 263 v oid setChannelVolume(SoundHandle handle, byte volume);251 virtual void setChannelVolume(SoundHandle handle, byte volume) = 0; 264 252 265 253 /** 266 254 * Set the channel balance for the given handle. … … 269 257 * @param balance the new channel balance: 270 258 * (-127 ... 0 ... 127) corresponds to (left ... center ... right) 271 259 */ 272 v oid setChannelBalance(SoundHandle handle, int8 balance);260 virtual void setChannelBalance(SoundHandle handle, int8 balance) = 0; 273 261 274 262 /** 275 263 * Get approximation of for how long the channel has been playing. 276 264 */ 277 uint32 getSoundElapsedTime(SoundHandle handle);265 virtual uint32 getSoundElapsedTime(SoundHandle handle) = 0; 278 266 279 267 /** 280 268 * Check whether any channel of the given sound type is active. … … 284 272 * @param type the sound type to look for 285 273 * @return true if any channels of the specified type are active. 286 274 */ 287 bool hasActiveChannelOfType(SoundType type);275 virtual bool hasActiveChannelOfType(SoundType type) = 0; 288 276 289 277 /** 290 278 * Set the volume for the given sound type. … … 292 280 * @param type the sound type 293 281 * @param volume the new global volume, 0-kMaxMixerVolume 294 282 */ 295 v oid setVolumeForSoundType(SoundType type, int volume);283 virtual void setVolumeForSoundType(SoundType type, int volume) = 0; 296 284 297 285 /** 298 286 * Query the global volume. … … 300 288 * @param type the sound type 301 289 * @return the global music volume, 0-kMaxMixerVolume 302 290 */ 303 int getVolumeForSoundType(SoundType type) const;291 virtual int getVolumeForSoundType(SoundType type) const = 0; 304 292 305 293 /** 306 294 * Query the system's audio output sample rate. This returns … … 308 296 * 309 297 * @return the output sample rate in Hz 310 298 */ 311 uint getOutputRate() const; 312 313 protected: 314 void insertChannel(SoundHandle *handle, Channel *chan); 315 316 /** 317 * Internal main method -- all the actual mixing work is done from here. 318 */ 319 void mix(int16 * buf, uint len); 320 321 // FIXME: temporary "public" to allow access to mixCallback 322 // from within OSystem::makeMixer() 323 public: 324 /** 325 * The mixer callback function, passed on to OSystem::setSoundCallback(). 326 * This simply calls the mix() method. 327 */ 328 static void mixCallback(void *s, byte *samples, int len); 329 330 void setReady(bool ready) { _mixerReady = ready; } 299 virtual uint getOutputRate() const = 0; 331 300 }; 332 301 333 302 -
backends/timer/default/default-timer.h
38 38 void *_timerHandler; 39 39 TimerSlot *_head; 40 40 41 42 41 public: 43 42 DefaultTimerManager(); 44 43 ~DefaultTimerManager(); 45 44 bool installTimerProc(TimerProc proc, int32 interval, void *refCon); 46 45 void removeTimerProc(TimerProc proc); 47 46 48 // Timer callback, to be invoked at regular time intervals by the backend. 47 /** 48 * Timer callback, to be invoked at regular time intervals by the backend. 49 */ 49 50 void handler(); 50 51 }; 51 52 -
backends/platform/gp2x/gp2x.cpp
40 40 #include "backends/timer/default/default-timer.h" 41 41 #include "backends/plugins/posix/posix-provider.h" 42 42 #include "backends/fs/posix/posix-fs-factory.h" // for getFilesystemFactory() 43 #include "sound/mixer .h"43 #include "sound/mixer_intern.h" 44 44 45 45 #include <stdio.h> 46 46 #include <stdlib.h> … … 225 225 // Create and hook up the mixer, if none exists yet (we check for this to 226 226 // allow subclasses to provide their own). 227 227 if (_mixer == 0) { 228 _mixer = new Audio::Mixer(); 229 setSoundCallback(Audio::Mixer::mixCallback, _mixer); 228 setupMixer(); 230 229 } 231 230 232 231 // Create and hook up the timer manager, if none exists yet (we check for … … 445 444 #pragma mark --- Audio --- 446 445 #pragma mark - 447 446 448 bool OSystem_GP2X::setSoundCallback(SoundProc proc, void *param) {447 void OSystem_GP2X::setupMixer() { 449 448 SDL_AudioSpec desired; 450 449 SDL_AudioSpec obtained; 451 450 … … 467 466 desired.channels = 2; 468 467 //desired.samples = (uint16)samples; 469 468 desired.samples = 128; // Samples hack 470 desired.callback = proc; 471 desired.userdata = param; 469 desired.callback = mixCallback; 470 desired.userdata = this; 471 472 // Create the mixer instance 473 assert(!_mixer); 474 _mixer = new Audio::MixerImpl(this); 475 assert(_mixer); 476 472 477 if (SDL_OpenAudio(&desired, &obtained) != 0) { 473 478 warning("Could not open audio device: %s", SDL_GetError()); 474 return false; 479 _samplesPerSec = 0; 480 _mixer->setReady(false); 481 } else { 482 // Note: This should be the obtained output rate, but it seems that at 483 // least on some platforms SDL will lie and claim it did get the rate 484 // even if it didn't. Probably only happens for "weird" rates, though. 485 _samplesPerSec = obtained.freq; 486 debug(1, "Output sample rate: %d Hz", _samplesPerSec); 487 488 // Tell the mixer that we are ready and start the sound processing 489 _mixer->setOutputRate(_samplesPerSec); 490 _mixer->setReady(true); 491 SDL_PauseAudio(0); 475 492 } 476 _samplesPerSec = obtained.freq;477 SDL_PauseAudio(0);478 return true;479 493 } 480 494 481 void OSystem_GP2X::clearSoundCallback() {482 SDL_CloseAudio();483 }484 485 495 int OSystem_GP2X::getOutputSampleRate() const { 486 496 return _samplesPerSec; 487 497 } -
backends/platform/gp2x/gp2x-common.h
37 37 #include <SDL_gp2x.h> 38 38 39 39 namespace Audio { 40 class Mixer ;40 class MixerImpl; 41 41 } 42 42 43 43 namespace Common { … … 128 128 virtual bool pollEvent(Common::Event &event); // overloaded by CE backend 129 129 130 130 // Set function that generates samples 131 typedef void (*SoundProc)(void *param, byte *buf, int len); 132 virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend 131 virtual void setupMixer(); 133 132 virtual Audio::Mixer *getMixer(); 134 133 135 void clearSoundCallback();136 137 134 // Poll CD status 138 135 // Returns true if cd audio is playing 139 136 bool pollCD(); … … 369 366 Common::SaveFileManager *_savefile; 370 367 FilesystemFactory *getFilesystemFactory(); 371 368 372 Audio::Mixer *_mixer;369 Audio::MixerImpl *_mixer; 373 370 374 371 SDL_TimerID _timerID; 375 372 Common::TimerManager *_timer; -
backends/platform/sdl/sdl.cpp
30 30 31 31 #include "backends/saves/default/default-saves.h" 32 32 #include "backends/timer/default/default-timer.h" 33 #include "sound/mixer .h"33 #include "sound/mixer_intern.h" 34 34 35 35 #include "icons/scummvm.xpm" 36 36 … … 131 131 // Create and hook up the mixer, if none exists yet (we check for this to 132 132 // allow subclasses to provide their own). 133 133 if (_mixer == 0) { 134 _mixer = new Audio::Mixer(); 135 bool result = setSoundCallback(Audio::Mixer::mixCallback, _mixer); 136 _mixer->setReady(result); 134 setupMixer(); 137 135 } 138 136 139 137 // Create and hook up the timer manager, if none exists yet (we check for … … 391 389 #pragma mark --- Audio --- 392 390 #pragma mark - 393 391 394 bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) { 392 void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) { 393 OSystem_SDL *this_ = (OSystem_SDL *)sys; 394 assert(this_); 395 396 if (this_->_mixer) 397 this_->_mixer->mixCallback(samples, len); 398 } 399 400 void OSystem_SDL::setupMixer() { 395 401 SDL_AudioSpec desired; 396 402 SDL_AudioSpec obtained; 397 403 … … 415 421 desired.format = AUDIO_S16SYS; 416 422 desired.channels = 2; 417 423 desired.samples = (uint16)samples; 418 desired.callback = proc; 419 desired.userdata = param; 424 desired.callback = mixCallback; 425 desired.userdata = this; 426 427 // Create the mixer instance 428 assert(!_mixer); 429 _mixer = new Audio::MixerImpl(this); 430 assert(_mixer); 431 420 432 if (SDL_OpenAudio(&desired, &obtained) != 0) { 421 433 warning("Could not open audio device: %s", SDL_GetError()); 422 return false; 434 _samplesPerSec = 0; 435 _mixer->setReady(false); 436 } else { 437 // Note: This should be the obtained output rate, but it seems that at 438 // least on some platforms SDL will lie and claim it did get the rate 439 // even if it didn't. Probably only happens for "weird" rates, though. 440 _samplesPerSec = obtained.freq; 441 debug(1, "Output sample rate: %d Hz", _samplesPerSec); 442 443 // Tell the mixer that we are ready and start the sound processing 444 _mixer->setOutputRate(_samplesPerSec); 445 _mixer->setReady(true); 446 SDL_PauseAudio(0); 423 447 } 424 // Note: This should be the obtained output rate, but it seems that at425 // least on some platforms SDL will lie and claim it did get the rate426 // even if it didn't. Probably only happens for "weird" rates, though.427 _samplesPerSec = obtained.freq;428 debug(1, "Output sample rate: %d Hz", _samplesPerSec);429 SDL_PauseAudio(0);430 return true;431 448 } 432 449 433 int OSystem_SDL::getOutputSampleRate() const {434 return _samplesPerSec;435 }436 437 450 Audio::Mixer *OSystem_SDL::getMixer() { 438 451 assert(_mixer); 439 452 return _mixer; -
backends/platform/sdl/sdl.h
38 38 39 39 40 40 namespace Audio { 41 class Mixer ;41 class MixerImpl; 42 42 } 43 43 44 44 namespace Common { … … 134 134 virtual bool pollEvent(Common::Event &event); // overloaded by CE backend 135 135 136 136 // Set function that generates samples 137 typedef void (*SoundProc)(void *param, byte *buf, int len); 138 virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend 137 virtual void setupMixer(); 138 static void mixCallback(void *s, byte *samples, int len); 139 139 140 virtual Audio::Mixer *getMixer(); 140 141 141 142 // Poll CD status … … 186 187 187 188 virtual void setWindowCaption(const char *caption); 188 189 virtual bool openCD(int drive); 189 virtual int getOutputSampleRate() const;190 190 191 191 virtual bool hasFeature(Feature f); 192 192 virtual void setFeatureState(Feature f, bool enable); … … 371 371 372 372 373 373 Common::SaveFileManager *_savefile; 374 Audio::Mixer *_mixer;374 Audio::MixerImpl *_mixer; 375 375 376 376 SDL_TimerID _timerID; 377 377 Common::TimerManager *_timer; -
backends/platform/psp/osys_psp.cpp
34 34 #include "backends/timer/default/default-timer.h" 35 35 #include "graphics/surface.h" 36 36 #include "graphics/scaler.h" 37 #include "sound/mixer .h"37 #include "sound/mixer_intern.h" 38 38 39 39 #include <pspgu.h> 40 40 … … 99 99 100 100 void OSystem_PSP::initBackend() { 101 101 _savefile = new DefaultSaveFileManager(); 102 _mixer = new Audio::Mixer ();102 _mixer = new Audio::MixerImpl(this); 103 103 _timer = new DefaultTimerManager(); 104 104 setSoundCallback(Audio::Mixer::mixCallback, _mixer); 105 105 setTimerCallback(&timer_handler, 10); -
backends/platform/symbian/src/SymbianOS.cpp
173 173 OSystem_SDL::quit(); 174 174 } 175 175 176 bool OSystem_SDL_Symbian::setSoundCallback(SoundProc proc, void *param) {176 void OSystem_SDL_Symbian::setupMixer() { 177 177 178 // First save the proc and param179 _sound_proc_param = param;180 _sound_proc = proc;181 178 SDL_AudioSpec desired; 182 179 SDL_AudioSpec obtained; 183 180 … … 207 204 desired.format = AUDIO_S16SYS; 208 205 desired.channels = 2; 209 206 desired.samples = (uint16)samples; 210 #ifdef S60211 207 desired.callback = symbianMixCallback; 212 208 desired.userdata = this; 213 #else 214 desired.callback = proc; 215 desired.userdata = param; 216 #endif 209 210 // Create the mixer instance 211 assert(!_mixer); 212 _mixer = new Audio::MixerImpl(this); 213 assert(_mixer); 214 217 215 if (SDL_OpenAudio(&desired, &obtained) != 0) { 218 216 warning("Could not open audio device: %s", SDL_GetError()); 219 return false; 217 _samplesPerSec = 0; 218 _mixer->setReady(false); 219 } else { 220 // Note: This should be the obtained output rate, but it seems that at 221 // least on some platforms SDL will lie and claim it did get the rate 222 // even if it didn't. Probably only happens for "weird" rates, though. 223 _samplesPerSec = obtained.freq; 224 _channels = obtained.channels; 225 226 // Need to create mixbuffer for stereo mix to downmix 227 if (_channels != 2) { 228 _stereo_mix_buffer = new byte [obtained.size*2];//*2 for stereo values 229 } 230 231 // Tell the mixer that we are ready and start the sound processing 232 _mixer->setOutputRate(_samplesPerSec); 233 _mixer->setReady(true); 234 SDL_PauseAudio(0); 220 235 } 221 // Note: This should be the obtained output rate, but it seems that at222 // least on some platforms SDL will lie and claim it did get the rate223 // even if it didn't. Probably only happens for "weird" rates, though.224 _samplesPerSec = obtained.freq;225 _channels = obtained.channels;226 227 // Need to create mixbuffer for stereo mix to downmix228 if (_channels != 2) {229 _stereo_mix_buffer = new byte [obtained.size*2];//*2 for stereo values230 }231 232 SDL_PauseAudio(0);233 return true;234 236 } 235 237 236 238 /** 237 239 * The mixer callback function, passed on to OSystem::setSoundCallback(). 238 240 * This simply calls the mix() method. 239 241 */ 240 void OSystem_SDL_Symbian::symbianMixCallback(void *s , byte *samples, int len) {241 static_cast <OSystem_SDL_Symbian*>(s)->symbianMix(samples,len);242 } 242 void OSystem_SDL_Symbian::symbianMixCallback(void *sys, byte *samples, int len) { 243 OSystem_SDL_Symbian *this_ = (OSystem_SDL_Symbian *)sys; 244 assert(this_); 243 245 246 if (!this_->_mixer) 247 return; 244 248 245 /** 246 * Actual mixing implementation 247 */ 248 void OSystem_SDL_Symbian::symbianMix(byte *samples, int len) { 249 #ifdef S60 249 250 // If not stereo then we need to downmix 250 251 if (_channels != 2) { 251 _sound_proc(_sound_proc_param, _stereo_mix_buffer, len * 2); 252 this_->_mixer->mixCallback(_stereo_mix_buffer, len * 2); 253 252 254 int16 *bitmixDst = (int16 *)samples; 253 255 int16 *bitmixSrc = (int16 *)_stereo_mix_buffer; 254 256 … … 258 260 bitmixSrc += 2; 259 261 } 260 262 } else 261 _sound_proc(_sound_proc_param, samples, len); 263 #else 264 this_->_mixer->mixCallback(samples, len); 265 #endif 262 266 } 263 267 268 264 269 /** 265 270 * This is an implementation by the remapKey function 266 271 * @param SDL_Event to remap -
backends/platform/symbian/src/SymbianOS.h
58 58 // This function is overridden by the symbian port in order to provide MONO audio 59 59 // downmix is done by supplying our own audiocallback 60 60 // 61 virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend61 virtual void setupMixer(); // overloaded by CE backend 62 62 63 63 // Overloaded from SDL_Commmon 64 64 void quit(); … … 70 70 // 71 71 static void symbianMixCallback(void *s, byte *samples, int len); 72 72 73 //74 // Actual mixing implementation75 //76 void symbianMix(byte *samples, int len);77 78 73 virtual FilesystemFactory *getFilesystemFactory(); 79 74 public: 80 75 // vibration support … … 121 116 // Audio 122 117 int _channels; 123 118 124 SoundProc _sound_proc;125 void *_sound_proc_param;126 119 byte *_stereo_mix_buffer; 127 120 128 121 // Used to handle joystick navi zones -
backends/platform/iphone/osys_iphone.cpp
40 40 41 41 #include "backends/saves/default/default-saves.h" 42 42 #include "backends/timer/default/default-timer.h" 43 #include "sound/mixer .h"43 #include "sound/mixer_intern.h" 44 44 #include "gui/message.h" 45 45 46 46 #include "osys_iphone.h" … … 1128 1128 return true; 1129 1129 } 1130 1130 1131 void OSystem_IPHONE::clearSoundCallback() {1132 debug("clearSoundCallback()\n");1133 }1134 1135 1131 int OSystem_IPHONE::getOutputSampleRate() const { 1136 1132 return AUDIO_SAMPLE_RATE; 1137 1133 } -
backends/platform/iphone/osys_iphone.h
153 153 virtual void deleteMutex(MutexRef mutex); 154 154 155 155 virtual bool setSoundCallback(SoundProc proc, void *param); 156 virtual void clearSoundCallback();157 156 virtual int getOutputSampleRate() const; 158 157 virtual void setTimerCallback(TimerProc callback, int interval); 159 158 -
backends/platform/wince/wince-sdl.cpp
35 35 #include "base/main.h" 36 36 #include "base/plugins.h" 37 37 38 #include "sound/mixer .h"38 #include "sound/mixer_intern.h" 39 39 #include "sound/fmopl.h" 40 40 41 41 #include "backends/timer/default/default-timer.h" … … 404 404 // Instantiate our own sound mixer 405 405 // mixer init is postponed until a game engine is selected. 406 406 if (_mixer == 0) { 407 _mixer = new Audio::Mixer( );407 _mixer = new Audio::Mixer(this); 408 408 } 409 409 410 410 // Create the timer. CE SDL does not support multiple timers (SDL_AddTimer). … … 770 770 _toolbarHandler.setVisible(false); 771 771 } 772 772 773 bool OSystem_WINCE3::setSoundCallback(SoundProc proc, void *param) {773 void OSystem_WINCE3::setupMixer(SoundProc proc, void *param) { 774 774 SDL_AudioSpec desired; 775 775 int thread_priority; 776 776 … … 785 785 desired.channels = 2; 786 786 desired.samples = 128; 787 787 desired.callback = private_sound_proc; 788 desired.userdata = param;788 desired.userdata = this; 789 789 790 // Create the mixer instance 791 assert(!_mixer); 792 _mixer = new Audio::MixerImpl(this); 793 assert(_mixer); 794 790 795 // Add sound thread priority 791 if (!ConfMan.hasKey("sound_thread_priority")) {796 if (!ConfMan.hasKey("sound_thread_priority")) 792 797 thread_priority = THREAD_PRIORITY_NORMAL; 793 }794 798 else 795 799 thread_priority = ConfMan.getInt("sound_thread_priority"); 796 800 … … 799 803 SDL_CloseAudio(); 800 804 if (SDL_OpenAudio(&desired, NULL) != 0) { 801 805 warning("Could not open audio device: %s", SDL_GetError()); 802 return false; 806 _mixer->setReady(false); 807 808 } else { 809 debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate); 810 811 // Tell the mixer that we are ready and start the sound processing 812 _mixer->setOutputRate(_sampleRate); 813 _mixer->setReady(true); 814 SDL_PauseAudio(0); 803 815 } 804 else805 debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate);806 SDL_PauseAudio(0);807 return true;808 816 } 809 817 810 818 void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) { 811 (*_originalSoundProc)(param, buf, len); 819 OSystem_WINCE3 *this_ = (OSystem_WINCE3 *)param; 820 assert(this_); 821 822 if (this_->_mixer) 823 this_->_mixer->mixCallback(buf, len); 812 824 if (!_soundMaster) 813 825 memset(buf, 0, len); 814 826 } … … 838 850 } 839 851 #endif 840 852 841 void OSystem_WINCE3:: get_sample_rate() {853 void OSystem_WINCE3::compute_sample_rate() { 842 854 // Force at least medium quality FM synthesis for FOTAQ 843 855 Common::String gameid(ConfMan.get("gameid")); 844 856 if (gameid == "queen") { … … 875 887 876 888 //update_game_settings(); 877 889 // finalize mixer init 878 get_sample_rate(); 879 bool result = setSoundCallback(Audio::Mixer::mixCallback, _mixer); 880 _mixer->setReady(result); 890 compute_sample_rate(); 891 setupMixer(); 881 892 882 893 // handle the actual event 883 894 OSystem_SDL::setWindowCaption(caption); … … 1050 1061 } 1051 1062 } 1052 1063 1053 get_sample_rate();1064 compute_sample_rate(); 1054 1065 } 1055 1066 1056 1067 void OSystem_WINCE3::initSize(uint w, uint h) { -
backends/platform/wince/wince-sdl.h
82 82 // Overloaded from SDL_Commmon 83 83 void quit(); 84 84 // Overloaded from SDL_Commmon (master volume and sample rate subtleties) 85 bool setSoundCallback(SoundProc proc, void *param);85 void setupMixer(); 86 86 // Overloaded from OSystem 87 87 //void engineInit(); 88 88 void getTimeAndDate(struct tm &t) const; … … 160 160 #endif 161 161 162 162 static void private_sound_proc(void *param, byte *buf, int len); 163 static SoundProc _originalSoundProc;164 163 165 164 bool update_scalers(); 166 165 void create_toolbar(); 167 166 void update_game_settings(); 168 167 void check_mappings(); 169 void get_sample_rate();168 void compute_sample_rate(); 170 169 171 170 void retrieve_mouse_location(int &x, int &y); 172 171 -
backends/platform/PalmOS/Src/be_base.cpp
28 28 #include "common/config-file.h" 29 29 #include "common/config-manager.h" 30 30 #include "backends/timer/default/default-timer.h" 31 #include "sound/mixer .h"31 #include "sound/mixer_intern.h" 32 32 33 33 OSystem_PalmBase::OSystem_PalmBase() { 34 34 _overlayVisible = false; … … 106 106 // Create and hook up the mixer, if none exists yet (we check for this to 107 107 // allow subclasses to provide their own). 108 108 if (_mixerMgr == 0) { 109 _mixerMgr = new Audio::Mixer( );109 _mixerMgr = new Audio::Mixer(this); 110 110 setSoundCallback(Audio::Mixer::mixCallback, _mixerMgr); 111 111 } 112 112