Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

sound.h

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * Additional copyright for this file:
 * Copyright (C) 1994-1998 Revolution Software Ltd.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-11-1/engines/sword2/sound.h $
 * $Id: sound.h 30944 2008-02-23 22:50:18Z sev $
 */

/*****************************************************************************
 *          SOUND.H           Sound engine
 *
 *          SOUND.CPP Contains the sound engine, fx & music functions
 *          Some very 'sound' code in here ;)
 *
 *          (16Dec96 JEL)
 *
 ****************************************************************************/

#ifndef SWORD2_SOUND_H
#define SWORD2_SOUND_H

#include "common/file.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"

// Max number of sound fx
#define MAXMUS 2

// Max number of fx in queue at once
#define FXQ_LENGTH 32

#define BUFFER_SIZE 4096

namespace Sword2 {

enum {
      kCLUMode = 1,
      kMP3Mode,
      kVorbisMode,
      kFlacMode
};

enum {
      kLeadInSound,
      kLeadOutSound
};

enum {
      // These three types correspond to types set by the scripts
      FX_SPOT           = 0,
      FX_LOOP           = 1,
      FX_RANDOM   = 2,

      // These are used for FX queue bookkeeping
      FX_SPOT2    = 3,
      FX_LOOPING  = 4
};

// Sound defines

enum {
      RDSE_SAMPLEFINISHED           = 0,
      RDSE_SAMPLEPLAYING            = 1,
      RDSE_FXTOCLEAR                = 0,        // Unused
      RDSE_FXCACHED                 = 1,        // Unused
      RDSE_FXSPOT             = 0,
      RDSE_FXLOOP             = 1,
      RDSE_FXLEADIN                 = 2,
      RDSE_FXLEADOUT                = 3,
      RDSE_QUIET              = 1,
      RDSE_SPEAKING                 = 0
};

class CLUInputStream : public Audio::AudioStream {
private:
      Common::File *_file;
      bool _firstTime;
      uint32 _file_pos;
      uint32 _end_pos;
      int16 _outbuf[BUFFER_SIZE];
      byte _inbuf[BUFFER_SIZE];
      const int16 *_bufferEnd;
      const int16 *_pos;

      uint16 _prev;

      void refill();

      inline bool eosIntern() const {
            return _pos >= _bufferEnd;
      }

public:
      CLUInputStream(Common::File *file, int size);
      ~CLUInputStream();

      int readBuffer(int16 *buffer, const int numSamples);

      bool endOfData() const  { return eosIntern(); }
      bool isStereo() const   { return false; }
      int getRate() const     { return 22050; }
};

struct SoundFileHandle {
      Common::File file;
      uint32 *idxTab;
      uint32 idxLen;
      uint32 fileSize;
      uint32 fileType;
      volatile bool inUse;
};

class MusicInputStream : public Audio::AudioStream {
private:
      int _cd;
      SoundFileHandle *_fh;
      uint32 _musicId;
      Audio::AudioStream *_decoder;
      int16 _buffer[BUFFER_SIZE];
      const int16 *_bufferEnd;
      const int16 *_pos;
      bool _remove;
      uint32 _numSamples;
      uint32 _samplesLeft;
      bool _looping;
      int32 _fading;
      int32 _fadeSamples;
      bool _paused;

      void refill();

      inline bool eosIntern() const {
            if (_looping)
                  return false;
            return _remove || _pos >= _bufferEnd;
      }

public:
      MusicInputStream(int cd, SoundFileHandle *fh, uint32 musicId, bool looping);
      ~MusicInputStream();

      int readBuffer(int16 *buffer, const int numSamples);

      bool endOfData() const  { return eosIntern(); }
      bool isStereo() const   { return _decoder->isStereo(); }
      int getRate() const     { return _decoder->getRate(); }

      int getCD()       { return _cd; }

      void fadeUp();
      void fadeDown();

      bool isReady()          { return _decoder != NULL; }
      int32 isFading()  { return _fading; }

      bool readyToRemove();
      int32 getTimeRemaining();
};

class Sound : public Audio::AudioStream {
private:
      Sword2Engine *_vm;

      Common::Mutex _mutex;

      Audio::SoundHandle _mixerSoundHandle;
      Audio::SoundHandle _leadInHandle;
      Audio::SoundHandle _leadOutHandle;

      struct FxQueueEntry {
            Audio::SoundHandle handle;    // sound handle
            uint32 resource;        // resource id of sample
            byte *data;             // pointer to WAV data
            uint32 len;             // WAV data length
            uint16 delay;                 // cycles to wait before playing (or 'random chance' if FX_RANDOM)
            uint8 volume;                 // sound volume
            int8 pan;               // sound panning
            uint8 type;             // FX_SPOT, FX_RANDOM, FX_LOOP
      };

      FxQueueEntry _fxQueue[FXQ_LENGTH];

      void triggerFx(uint8 i);

      bool _reverseStereo;

      bool _speechMuted;
      bool _fxMuted;
      bool _musicMuted;

      bool _speechPaused;
      bool _fxPaused;
      bool _musicPaused;

      int32 _loopingMusicId;

      Audio::SoundHandle _soundHandleSpeech;

      MusicInputStream *_music[MAXMUS];
      SoundFileHandle _musicFile[MAXMUS];
      SoundFileHandle _speechFile[MAXMUS];

      int16 *_mixBuffer;
      int _mixBufferLen;

public:
      Sound(Sword2Engine *vm);
      ~Sound();

      // AudioStream API

      int readBuffer(int16 *buffer, const int numSamples);
      bool isStereo() const { return false; }
      bool endOfData() const;
      int getRate() const { return 22050; }

      // End of AudioStream API

      void clearFxQueue(bool killMovieSounds);
      void processFxQueue();

      void setReverseStereo(bool reverse);
      bool isReverseStereo() const { return _reverseStereo; }

      void muteSpeech(bool mute);
      bool isSpeechMute() const { return _speechMuted; }

      void muteFx(bool mute);
      bool isFxMute() const { return _fxMuted; }

      void muteMusic(bool mute) { _musicMuted = mute; }
      bool isMusicMute() const { return _musicMuted; }

      void setLoopingMusicId(int32 id) { _loopingMusicId = id; }
      int32 getLoopingMusicId() const { return _loopingMusicId; }

      void pauseSpeech();
      void unpauseSpeech();

      void pauseFx();
      void unpauseFx();

      void pauseMusic();
      void unpauseMusic();

      void pauseAllSound();
      void unpauseAllSound();

      void playMovieSound(int32 res, int type);

      void queueFx(int32 res, int32 type, int32 delay, int32 volume, int32 pan);
      int32 playFx(FxQueueEntry *fx);
      int32 playFx(Audio::SoundHandle *handle, byte *data, uint32 len, uint8 vol, int8 pan, bool loop, Audio::Mixer::SoundType soundType);
      int32 stopFx(int32 i);
      int32 setFxIdVolumePan(int32 id, int vol, int pan = 255);

      int32 getSpeechStatus();
      int32 amISpeaking();
      int32 playCompSpeech(uint32 speechId, uint8 vol, int8 pan);
      int32 stopSpeech();

      int32 streamCompMusic(uint32 musicId, bool loop);
      void stopMusic(bool immediately);
      int32 musicTimeRemaining();
};

} // End of namespace Sword2

#endif

Generated by  Doxygen 1.6.0   Back to index