00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "gui/EventRecorder.h"
00024
00025 #include "common/util.h"
00026 #include "common/system.h"
00027 #include "common/textconsole.h"
00028
00029 #include "audio/mixer_intern.h"
00030 #include "audio/rate.h"
00031 #include "audio/audiostream.h"
00032 #include "audio/timestamp.h"
00033
00034
00035 namespace Audio {
00036
00037 #pragma mark -
00038 #pragma mark --- Channel classes ---
00039 #pragma mark -
00040
00041
00045 class Channel {
00046 public:
00047 Channel(Mixer *mixer, Mixer::SoundType type, AudioStream *stream, DisposeAfterUse::Flag autofreeStream, bool reverseStereo, int id, bool permanent);
00048 ~Channel();
00049
00059 int mix(int16 *data, uint len);
00060
00064 bool isFinished() const { return _stream->endOfStream(); }
00065
00071 bool isPermanent() const { return _permanent; }
00072
00076 int getId() const { return _id; }
00077
00084 void pause(bool paused);
00085
00089 bool isPaused() const { return (_pauseLevel != 0); }
00090
00096 void setVolume(const byte volume);
00097
00103 byte getVolume();
00104
00110 void setBalance(const int8 balance);
00111
00117 int8 getBalance();
00118
00123 void notifyGlobalVolChange() { updateChannelVolumes(); }
00124
00128 Timestamp getElapsedTime();
00129
00133 Mixer::SoundType getType() const { return _type; }
00134
00140 void setHandle(const SoundHandle handle) { _handle = handle; }
00141
00145 SoundHandle getHandle() const { return _handle; }
00146
00147 private:
00148 const Mixer::SoundType _type;
00149 SoundHandle _handle;
00150 bool _permanent;
00151 int _pauseLevel;
00152 int _id;
00153
00154 byte _volume;
00155 int8 _balance;
00156
00157 void updateChannelVolumes();
00158 st_volume_t _volL, _volR;
00159
00160 Mixer *_mixer;
00161
00162 uint32 _samplesConsumed;
00163 uint32 _samplesDecoded;
00164 uint32 _mixerTimeStamp;
00165 uint32 _pauseStartTime;
00166 uint32 _pauseTime;
00167
00168 RateConverter *_converter;
00169 Common::DisposablePtr<AudioStream> _stream;
00170 };
00171
00172 #pragma mark -
00173 #pragma mark --- Mixer ---
00174 #pragma mark -
00175
00176
00177 MixerImpl::MixerImpl(OSystem *system, uint sampleRate)
00178 : _mutex(), _sampleRate(sampleRate), _mixerReady(false), _handleSeed(0), _soundTypeSettings() {
00179
00180 assert(sampleRate > 0);
00181
00182 for (int i = 0; i != NUM_CHANNELS; i++)
00183 _channels[i] = 0;
00184 }
00185
00186 MixerImpl::~MixerImpl() {
00187 for (int i = 0; i != NUM_CHANNELS; i++)
00188 delete _channels[i];
00189 }
00190
00191 void MixerImpl::setReady(bool ready) {
00192 _mixerReady = ready;
00193 }
00194
00195 uint MixerImpl::getOutputRate() const {
00196 return _sampleRate;
00197 }
00198
00199 void MixerImpl::insertChannel(SoundHandle *handle, Channel *chan) {
00200 int index = -1;
00201 for (int i = 0; i != NUM_CHANNELS; i++) {
00202 if (_channels[i] == 0) {
00203 index = i;
00204 break;
00205 }
00206 }
00207 if (index == -1) {
00208 warning("MixerImpl::out of mixer slots");
00209 delete chan;
00210 return;
00211 }
00212
00213 _channels[index] = chan;
00214
00215 SoundHandle chanHandle;
00216 chanHandle._val = index + (_handleSeed * NUM_CHANNELS);
00217
00218 chan->setHandle(chanHandle);
00219 _handleSeed++;
00220 if (handle)
00221 *handle = chanHandle;
00222 }
00223
00224 void MixerImpl::playStream(
00225 SoundType type,
00226 SoundHandle *handle,
00227 AudioStream *stream,
00228 int id, byte volume, int8 balance,
00229 DisposeAfterUse::Flag autofreeStream,
00230 bool permanent,
00231 bool reverseStereo) {
00232 Common::StackLock lock(_mutex);
00233
00234 if (stream == 0) {
00235 warning("stream is 0");
00236 return;
00237 }
00238
00239
00240 assert(_mixerReady);
00241
00242
00243 if (id != -1) {
00244 for (int i = 0; i != NUM_CHANNELS; i++)
00245 if (_channels[i] != 0 && _channels[i]->getId() == id) {
00246
00247
00248
00249
00250
00251
00252 if (autofreeStream == DisposeAfterUse::YES)
00253 delete stream;
00254 return;
00255 }
00256 }
00257
00258 #ifdef AUDIO_REVERSE_STEREO
00259 reverseStereo = !reverseStereo;
00260 #endif
00261
00262
00263 Channel *chan = new Channel(this, type, stream, autofreeStream, reverseStereo, id, permanent);
00264 chan->setVolume(volume);
00265 chan->setBalance(balance);
00266 insertChannel(handle, chan);
00267 }
00268
00269 int MixerImpl::mixCallback(byte *samples, uint len) {
00270 assert(samples);
00271
00272 Common::StackLock lock(_mutex);
00273
00274 int16 *buf = (int16 *)samples;
00275
00276 assert(len % 4 == 0);
00277 len >>= 2;
00278
00279
00280 _mixerReady = true;
00281
00282
00283 memset(buf, 0, 2 * len * sizeof(int16));
00284
00285
00286 int res = 0, tmp;
00287 for (int i = 0; i != NUM_CHANNELS; i++)
00288 if (_channels[i]) {
00289 if (_channels[i]->isFinished()) {
00290 delete _channels[i];
00291 _channels[i] = 0;
00292 } else if (!_channels[i]->isPaused()) {
00293 tmp = _channels[i]->mix(buf, len);
00294
00295 if (tmp > res)
00296 res = tmp;
00297 }
00298 }
00299
00300 return res;
00301 }
00302
00303 void MixerImpl::stopAll() {
00304 Common::StackLock lock(_mutex);
00305 for (int i = 0; i != NUM_CHANNELS; i++) {
00306 if (_channels[i] != 0 && !_channels[i]->isPermanent()) {
00307 delete _channels[i];
00308 _channels[i] = 0;
00309 }
00310 }
00311 }
00312
00313 void MixerImpl::stopID(int id) {
00314 Common::StackLock lock(_mutex);
00315 for (int i = 0; i != NUM_CHANNELS; i++) {
00316 if (_channels[i] != 0 && _channels[i]->getId() == id) {
00317 delete _channels[i];
00318 _channels[i] = 0;
00319 }
00320 }
00321 }
00322
00323 void MixerImpl::stopHandle(SoundHandle handle) {
00324 Common::StackLock lock(_mutex);
00325
00326
00327 const int index = handle._val % NUM_CHANNELS;
00328 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00329 return;
00330
00331 delete _channels[index];
00332 _channels[index] = 0;
00333 }
00334
00335 void MixerImpl::muteSoundType(SoundType type, bool mute) {
00336 assert(0 <= (int)type && (int)type < ARRAYSIZE(_soundTypeSettings));
00337 _soundTypeSettings[type].mute = mute;
00338
00339 for (int i = 0; i != NUM_CHANNELS; ++i) {
00340 if (_channels[i] && _channels[i]->getType() == type)
00341 _channels[i]->notifyGlobalVolChange();
00342 }
00343 }
00344
00345 bool MixerImpl::isSoundTypeMuted(SoundType type) const {
00346 assert(0 <= (int)type && (int)type < ARRAYSIZE(_soundTypeSettings));
00347 return _soundTypeSettings[type].mute;
00348 }
00349
00350 void MixerImpl::setChannelVolume(SoundHandle handle, byte volume) {
00351 Common::StackLock lock(_mutex);
00352
00353 const int index = handle._val % NUM_CHANNELS;
00354 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00355 return;
00356
00357 _channels[index]->setVolume(volume);
00358 }
00359
00360 byte MixerImpl::getChannelVolume(SoundHandle handle) {
00361 const int index = handle._val % NUM_CHANNELS;
00362 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00363 return 0;
00364
00365 return _channels[index]->getVolume();
00366 }
00367
00368 void MixerImpl::setChannelBalance(SoundHandle handle, int8 balance) {
00369 Common::StackLock lock(_mutex);
00370
00371 const int index = handle._val % NUM_CHANNELS;
00372 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00373 return;
00374
00375 _channels[index]->setBalance(balance);
00376 }
00377
00378 int8 MixerImpl::getChannelBalance(SoundHandle handle) {
00379 const int index = handle._val % NUM_CHANNELS;
00380 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00381 return 0;
00382
00383 return _channels[index]->getBalance();
00384 }
00385
00386 uint32 MixerImpl::getSoundElapsedTime(SoundHandle handle) {
00387 return getElapsedTime(handle).msecs();
00388 }
00389
00390 Timestamp MixerImpl::getElapsedTime(SoundHandle handle) {
00391 Common::StackLock lock(_mutex);
00392
00393 const int index = handle._val % NUM_CHANNELS;
00394 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00395 return Timestamp(0, _sampleRate);
00396
00397 return _channels[index]->getElapsedTime();
00398 }
00399
00400 void MixerImpl::pauseAll(bool paused) {
00401 Common::StackLock lock(_mutex);
00402 for (int i = 0; i != NUM_CHANNELS; i++) {
00403 if (_channels[i] != 0) {
00404 _channels[i]->pause(paused);
00405 }
00406 }
00407 }
00408
00409 void MixerImpl::pauseID(int id, bool paused) {
00410 Common::StackLock lock(_mutex);
00411 for (int i = 0; i != NUM_CHANNELS; i++) {
00412 if (_channels[i] != 0 && _channels[i]->getId() == id) {
00413 _channels[i]->pause(paused);
00414 return;
00415 }
00416 }
00417 }
00418
00419 void MixerImpl::pauseHandle(SoundHandle handle, bool paused) {
00420 Common::StackLock lock(_mutex);
00421
00422
00423 const int index = handle._val % NUM_CHANNELS;
00424 if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
00425 return;
00426
00427 _channels[index]->pause(paused);
00428 }
00429
00430 bool MixerImpl::isSoundIDActive(int id) {
00431 Common::StackLock lock(_mutex);
00432
00433 #ifdef ENABLE_EVENTRECORDER
00434 g_eventRec.updateSubsystems();
00435 #endif
00436
00437 for (int i = 0; i != NUM_CHANNELS; i++)
00438 if (_channels[i] && _channels[i]->getId() == id)
00439 return true;
00440 return false;
00441 }
00442
00443 int MixerImpl::getSoundID(SoundHandle handle) {
00444 Common::StackLock lock(_mutex);
00445 const int index = handle._val % NUM_CHANNELS;
00446 if (_channels[index] && _channels[index]->getHandle()._val == handle._val)
00447 return _channels[index]->getId();
00448 return 0;
00449 }
00450
00451 bool MixerImpl::isSoundHandleActive(SoundHandle handle) {
00452 Common::StackLock lock(_mutex);
00453
00454 #ifdef ENABLE_EVENTRECORDER
00455 g_eventRec.updateSubsystems();
00456 #endif
00457
00458 const int index = handle._val % NUM_CHANNELS;
00459 return _channels[index] && _channels[index]->getHandle()._val == handle._val;
00460 }
00461
00462 bool MixerImpl::hasActiveChannelOfType(SoundType type) {
00463 Common::StackLock lock(_mutex);
00464 for (int i = 0; i != NUM_CHANNELS; i++)
00465 if (_channels[i] && _channels[i]->getType() == type)
00466 return true;
00467 return false;
00468 }
00469
00470 void MixerImpl::setVolumeForSoundType(SoundType type, int volume) {
00471 assert(0 <= (int)type && (int)type < ARRAYSIZE(_soundTypeSettings));
00472
00473
00474 volume = CLIP<int>(volume, 0, kMaxMixerVolume);
00475
00476
00477
00478
00479 Common::StackLock lock(_mutex);
00480 _soundTypeSettings[type].volume = volume;
00481
00482 for (int i = 0; i != NUM_CHANNELS; ++i) {
00483 if (_channels[i] && _channels[i]->getType() == type)
00484 _channels[i]->notifyGlobalVolChange();
00485 }
00486 }
00487
00488 int MixerImpl::getVolumeForSoundType(SoundType type) const {
00489 assert(0 <= (int)type && (int)type < ARRAYSIZE(_soundTypeSettings));
00490
00491 return _soundTypeSettings[type].volume;
00492 }
00493
00494
00495 #pragma mark -
00496 #pragma mark --- Channel implementations ---
00497 #pragma mark -
00498
00499 Channel::Channel(Mixer *mixer, Mixer::SoundType type, AudioStream *stream,
00500 DisposeAfterUse::Flag autofreeStream, bool reverseStereo, int id, bool permanent)
00501 : _type(type), _mixer(mixer), _id(id), _permanent(permanent), _volume(Mixer::kMaxChannelVolume),
00502 _balance(0), _pauseLevel(0), _samplesConsumed(0), _samplesDecoded(0), _mixerTimeStamp(0),
00503 _pauseStartTime(0), _pauseTime(0), _converter(0), _volL(0), _volR(0),
00504 _stream(stream, autofreeStream) {
00505 assert(mixer);
00506 assert(stream);
00507
00508
00509 _converter = makeRateConverter(_stream->getRate(), mixer->getOutputRate(), _stream->isStereo(), reverseStereo);
00510 }
00511
00512 Channel::~Channel() {
00513 delete _converter;
00514 }
00515
00516 void Channel::setVolume(const byte volume) {
00517 _volume = volume;
00518 updateChannelVolumes();
00519 }
00520
00521 byte Channel::getVolume() {
00522 return _volume;
00523 }
00524
00525 void Channel::setBalance(const int8 balance) {
00526 _balance = balance;
00527 updateChannelVolumes();
00528 }
00529
00530 int8 Channel::getBalance() {
00531 return _balance;
00532 }
00533
00534 void Channel::updateChannelVolumes() {
00535
00536
00537
00538
00539
00540
00541
00542
00543 if (!_mixer->isSoundTypeMuted(_type)) {
00544 int vol = _mixer->getVolumeForSoundType(_type) * _volume;
00545
00546 if (_balance == 0) {
00547 _volL = vol / Mixer::kMaxChannelVolume;
00548 _volR = vol / Mixer::kMaxChannelVolume;
00549 } else if (_balance < 0) {
00550 _volL = vol / Mixer::kMaxChannelVolume;
00551 _volR = ((127 + _balance) * vol) / (Mixer::kMaxChannelVolume * 127);
00552 } else {
00553 _volL = ((127 - _balance) * vol) / (Mixer::kMaxChannelVolume * 127);
00554 _volR = vol / Mixer::kMaxChannelVolume;
00555 }
00556 } else {
00557 _volL = _volR = 0;
00558 }
00559 }
00560
00561 void Channel::pause(bool paused) {
00562
00563
00564 if (paused) {
00565 _pauseLevel++;
00566
00567 if (_pauseLevel == 1)
00568 _pauseStartTime = g_system->getMillis(true);
00569 } else if (_pauseLevel > 0) {
00570 _pauseLevel--;
00571
00572 if (!_pauseLevel) {
00573 _pauseTime = (g_system->getMillis(true) - _pauseStartTime);
00574 _pauseStartTime = 0;
00575 }
00576 }
00577 }
00578
00579 Timestamp Channel::getElapsedTime() {
00580 const uint32 rate = _mixer->getOutputRate();
00581 uint32 delta = 0;
00582
00583 Audio::Timestamp ts(0, rate);
00584
00585 if (_mixerTimeStamp == 0)
00586 return ts;
00587
00588 if (isPaused())
00589 delta = _pauseStartTime - _mixerTimeStamp;
00590 else
00591 delta = g_system->getMillis(true) - _mixerTimeStamp - _pauseTime;
00592
00593
00594
00595 ts = ts.addFrames(_samplesConsumed);
00596 ts = ts.addMsecs(delta);
00597
00598
00599
00600
00601
00602
00603
00604 return ts;
00605 }
00606
00607 int Channel::mix(int16 *data, uint len) {
00608 assert(_stream);
00609
00610 int res = 0;
00611 if (_stream->endOfData()) {
00612
00613 } else {
00614 assert(_converter);
00615 _samplesConsumed = _samplesDecoded;
00616 _mixerTimeStamp = g_system->getMillis(true);
00617 _pauseTime = 0;
00618 res = _converter->flow(*_stream, data, len, _volL, _volR);
00619 _samplesDecoded += res;
00620 }
00621
00622 return res;
00623 }
00624
00625 }