mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-29 05:03:29 +00:00
70bae60c44
svn-id: r26595
201 lines
5.0 KiB
C++
201 lines
5.0 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2004 Ivan Dubrov
|
|
* Copyright (C) 2004-2006 The ScummVM project
|
|
*
|
|
* 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$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#ifndef GOB_SOUND_H
|
|
#define GOB_SOUND_H
|
|
|
|
#include "common/mutex.h"
|
|
#include "sound/audiostream.h"
|
|
#include "sound/mixer.h"
|
|
|
|
namespace Gob {
|
|
|
|
enum SoundType {
|
|
SOUND_SND,
|
|
SOUND_ADL
|
|
};
|
|
|
|
enum SoundSource {
|
|
SOUND_FILE,
|
|
SOUND_TOT,
|
|
SOUND_EXT
|
|
};
|
|
|
|
class SoundDesc {
|
|
public:
|
|
int16 _repCount;
|
|
int16 _frequency;
|
|
int16 _flag;
|
|
int16 _id;
|
|
|
|
byte *getData() { return _dataPtr; }
|
|
uint32 size() { return _size; }
|
|
bool empty() { return !_dataPtr; }
|
|
bool isId(int16 id) { return _dataPtr && _id == id; }
|
|
SoundType getType() { return _type; }
|
|
|
|
void set(SoundType type, SoundSource src, byte *data, uint32 dSize);
|
|
void load(SoundType type, SoundSource src, byte *data, uint32 dSize);
|
|
void free();
|
|
void convToSigned();
|
|
|
|
// Which fade out length to use when the fade starts half-way through?
|
|
int16 calcFadeOutLength(int16 frequency) {
|
|
return (10 * (_size / 2)) / frequency;
|
|
}
|
|
uint32 calcLength(int16 repCount, int16 frequency, bool fade) {
|
|
uint32 fadeSize = fade ? _size / 2 : 0;
|
|
return ((_size * repCount - fadeSize) * 1000) / frequency;
|
|
}
|
|
|
|
SoundDesc() : _data(0), _dataPtr(0), _size(0), _type(SOUND_SND),
|
|
_source(SOUND_FILE), _repCount(0), _frequency(0),
|
|
_flag(0), _id(0) {}
|
|
~SoundDesc() { free(); }
|
|
|
|
private:
|
|
byte *_data;
|
|
byte *_dataPtr;
|
|
uint32 _size;
|
|
|
|
SoundType _type;
|
|
SoundSource _source;
|
|
|
|
void loadSND(byte *data, uint32 dSize);
|
|
void loadADL(byte *data, uint32 dSize);
|
|
};
|
|
|
|
class Snd : public Audio::AudioStream {
|
|
public:
|
|
char _playingSound;
|
|
|
|
Snd(GobEngine *vm);
|
|
~Snd();
|
|
|
|
void speakerOn(int16 frequency, int32 length);
|
|
void speakerOff();
|
|
void speakerOnUpdate(uint32 milis);
|
|
void stopSound(int16 fadeLength, SoundDesc *sndDesc = 0);
|
|
|
|
bool loadSample(SoundDesc &sndDesc, const char *fileName);
|
|
void freeSample(SoundDesc &sndDesc);
|
|
void playSample(SoundDesc &sndDesc, int16 repCount,
|
|
int16 frequency, int16 fadeLength = 0);
|
|
|
|
void playComposition(int16 *composition, int16 freqVal,
|
|
SoundDesc *sndDescs = 0, int8 sndCount = 60);
|
|
void stopComposition();
|
|
void setRepeating(int32 repCount);
|
|
void waitEndPlay(bool interruptible = false, bool stopComp = true);
|
|
|
|
static void convToSigned(byte *buffer, int length) {
|
|
while (length-- > 0)
|
|
*buffer++ ^= 0x80;
|
|
}
|
|
|
|
int readBuffer(int16 *buffer, const int numSamples);
|
|
bool isStereo() const { return false; }
|
|
bool endOfData() const { return _end; }
|
|
bool endOfStream() const { return false; }
|
|
int getRate() const { return _rate; }
|
|
|
|
protected:
|
|
// TODO: This is a very primitive square wave generator. The only thing it
|
|
// has in common with the PC speaker is that it sounds terrible.
|
|
// Note: The SCUMM code has a PC speaker implementations; maybe it could be
|
|
// refactored to be reusable by all engines. And DosBox also has code
|
|
// for emulating the PC speaker.
|
|
class SquareWaveStream : public Audio::AudioStream {
|
|
private:
|
|
uint _rate;
|
|
bool _beepForever;
|
|
uint32 _periodLength;
|
|
uint32 _periodSamples;
|
|
uint32 _remainingSamples;
|
|
uint32 _mixedSamples;
|
|
int16 _sampleValue;
|
|
|
|
public:
|
|
SquareWaveStream();
|
|
|
|
void playNote(int freq, int32 ms, uint rate);
|
|
void update(uint32 milis);
|
|
void stop(uint32 milis);
|
|
|
|
int readBuffer(int16 *buffer, const int numSamples);
|
|
|
|
bool isStereo() const { return false; }
|
|
bool endOfData() const { return false; }
|
|
bool endOfStream() const { return false; }
|
|
int getRate() const { return _rate; }
|
|
};
|
|
|
|
SquareWaveStream _speakerStream;
|
|
Audio::SoundHandle _speakerHandle;
|
|
uint32 _speakerStartTimeKey;
|
|
|
|
Audio::SoundHandle *_activeHandle;
|
|
Audio::SoundHandle _compositionHandle;
|
|
|
|
SoundDesc *_compositionSamples;
|
|
int8 _compositionSampleCount;
|
|
int16 _composition[50];
|
|
int8 _compositionPos;
|
|
|
|
Audio::SoundHandle _handle;
|
|
Common::Mutex _mutex;
|
|
SoundDesc *_curSoundDesc;
|
|
bool _end;
|
|
int8 *_data;
|
|
uint32 _length;
|
|
uint32 _rate;
|
|
int32 _freq;
|
|
int32 _repCount;
|
|
|
|
uint32 _offset;
|
|
uint32 _offsetFrac;
|
|
uint32 _offsetInc;
|
|
uint32 _offsetIncFrac;
|
|
|
|
int16 _cur;
|
|
int16 _last;
|
|
|
|
bool _fade;
|
|
int32 _fadeVol;
|
|
int32 _fadeVolStep;
|
|
uint8 _fadeLength;
|
|
uint32 _fadeSamples;
|
|
uint32 _curFadeSamples;
|
|
|
|
GobEngine *_vm;
|
|
|
|
void setSample(SoundDesc &sndDesc, int16 repCount,
|
|
int16 frequency, int16 fadeLength);
|
|
void checkEndSample();
|
|
void nextCompositionPos();
|
|
};
|
|
|
|
} // End of namespace Gob
|
|
|
|
#endif // GOB_SOUND_H
|