implemented raw sound looping; some debug output enabled temporarily

svn-id: r9360
This commit is contained in:
Max Horn 2003-08-01 12:49:24 +00:00
parent 0df319e952
commit d9bd77032a
5 changed files with 52 additions and 16 deletions

View file

@ -40,7 +40,7 @@ static inline int16 readSample(const byte *ptr) {
template<bool stereo, bool is16Bit, bool isUnsigned> template<bool stereo, bool is16Bit, bool isUnsigned>
class LinearMemoryStream : public AudioInputStream { class LinearMemoryStream : public LinearAudioInputStream {
protected: protected:
const byte *_ptr; const byte *_ptr;
const byte *_end; const byte *_end;
@ -58,11 +58,17 @@ public:
return val; return val;
} }
bool eof() const { bool eof() const {
return _end <= _ptr; return _ptr >= _end;
} }
bool isStereo() const { bool isStereo() const {
return stereo; return stereo;
} }
void reset(const byte *data, uint32 len) {
_ptr = data;
_end = data + len;
if (stereo) // Stereo requires even sized data
assert(len % 2 == 0);
}
}; };
@ -413,7 +419,7 @@ void VorbisInputStream::refill() {
template<bool stereo> template<bool stereo>
static AudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned) { static LinearAudioInputStream *makeLinearInputStream(const byte *ptr, uint32 len, bool is16Bit, bool isUnsigned) {
if (isUnsigned) { if (isUnsigned) {
if (is16Bit) if (is16Bit)
return new LinearMemoryStream<stereo, true, true>(ptr, len); return new LinearMemoryStream<stereo, true, true>(ptr, len);
@ -444,7 +450,7 @@ static WrappedAudioInputStream *makeWrappedInputStream(uint32 len, bool is16Bit,
} }
AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len) { LinearAudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len) {
const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0; const bool is16Bit = (_flags & SoundMixer::FLAG_16BITS) != 0;
const bool isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0; const bool isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0;
if (_flags & SoundMixer::FLAG_STEREO) { if (_flags & SoundMixer::FLAG_STEREO) {

View file

@ -53,6 +53,11 @@ public:
virtual bool eof() const = 0; virtual bool eof() const = 0;
}; };
class LinearAudioInputStream : public AudioInputStream {
public:
virtual void reset(const byte *data, uint32 len) = 0;
};
class WrappedAudioInputStream : public AudioInputStream { class WrappedAudioInputStream : public AudioInputStream {
public: public:
virtual void append(const byte *data, uint32 len) = 0; virtual void append(const byte *data, uint32 len) = 0;
@ -118,7 +123,7 @@ public:
AudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len); LinearAudioInputStream *makeLinearInputStream(byte _flags, const byte *ptr, uint32 len);
WrappedAudioInputStream *makeWrappedInputStream(byte _flags, uint32 len); WrappedAudioInputStream *makeWrappedInputStream(byte _flags, uint32 len);

View file

@ -67,19 +67,19 @@ class ChannelRaw : public Channel {
byte _flags; byte _flags;
#ifdef SOX_HACK #ifdef SOX_HACK
RateConverter *_converter; RateConverter *_converter;
AudioInputStream *_input; LinearAudioInputStream *_input;
#else #else
uint32 _pos; uint32 _pos;
uint32 _size; uint32 _size;
uint32 _fpSpeed; uint32 _fpSpeed;
uint32 _fpPos; uint32 _fpPos;
uint32 _realSize, _rate; uint32 _realSize, _rate;
#endif
byte *_loop_ptr; byte *_loop_ptr;
uint32 _loop_size; uint32 _loop_size;
#endif
public: public:
ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id); ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd);
~ChannelRaw(); ~ChannelRaw();
void mix(int16 *data, uint len); void mix(int16 *data, uint len);
@ -272,7 +272,7 @@ int SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) {
return index; return index;
} }
int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id) { int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd) {
StackLock lock(_mutex); StackLock lock(_mutex);
// Prevent duplicate sounds // Prevent duplicate sounds
@ -282,7 +282,7 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui
return -1; return -1;
} }
return insertChannel(handle, new ChannelRaw(this, handle, sound, size, rate, flags, id)); return insertChannel(handle, new ChannelRaw(this, handle, sound, size, rate, flags, id, loopStart, loopEnd));
} }
#ifdef USE_MAD #ifdef USE_MAD
@ -651,7 +651,7 @@ static int16 mixer_element_size[] = {
#endif #endif
/* RAW mixer */ /* RAW mixer */
ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id) ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id, uint32 loopStart, uint32 loopEnd)
: Channel(mixer, handle) { : Channel(mixer, handle) {
_id = id; _id = id;
_ptr = (byte *)sound; _ptr = (byte *)sound;
@ -665,6 +665,23 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun
// Get a rate converter instance // Get a rate converter instance
_converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo()); _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo());
printf(" data has %d bits and is %s\n",
((flags & SoundMixer::FLAG_16BITS) ? 16 : 8),
((flags & SoundMixer::FLAG_UNSIGNED) ? "unsigned" : "signed"));
if (flags & SoundMixer::FLAG_LOOP) {
if (loopEnd == 0) {
_loop_ptr = _ptr;
_loop_size = size;
} else {
assert(loopStart < loopEnd && loopEnd <= size);
_loop_ptr = _ptr + loopStart;
_loop_size = loopEnd - loopStart;
}
} else {
_loop_ptr = 0;
_loop_size = 0;
}
#else #else
_pos = 0; _pos = 0;
_fpPos = 0; _fpPos = 0;
@ -705,9 +722,13 @@ void ChannelRaw::mix(int16 *data, uint len) {
if (_input->eof()) { if (_input->eof()) {
// TODO: call drain method // TODO: call drain method
// TODO: Looping // Loop if requested
destroy(); if (_loop_ptr) {
return; _input->reset(_loop_ptr, _loop_size);
} else {
destroy();
return;
}
} }
const int volume = _mixer->getVolume(); const int volume = _mixer->getVolume();
@ -756,6 +777,9 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void
// Get a rate converter instance // Get a rate converter instance
_converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo()); _converter = makeRateConverter(rate, mixer->getOutputRate(), _input->isStereo());
printf(" data has %d bits and is %s\n",
((flags & SoundMixer::FLAG_16BITS) ? 16 : 8),
((flags & SoundMixer::FLAG_UNSIGNED) ? "unsigned" : "signed"));
#else #else
_flags = flags; _flags = flags;
_bufferSize = buffer_size; _bufferSize = buffer_size;

View file

@ -82,7 +82,8 @@ public:
~SoundMixer(); ~SoundMixer();
// start playing a raw sound // start playing a raw sound
int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id = -1); int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags,
int id = -1, uint32 loopStart = 0, uint32 loopEnd = 0);
#ifdef USE_MAD #ifdef USE_MAD
int playMP3(PlayingSoundHandle *handle, File *file, uint32 size); int playMP3(PlayingSoundHandle *handle, File *file, uint32 size);
int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration); int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration);

View file

@ -94,7 +94,7 @@ public:
}; };
static inline RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo) { static inline RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo) {
// printf("makeRateConverter: inrate %d, outrate %d\n", inrate, outrate); printf("makeRateConverter: inrate %d, outrate %d, %s\n", inrate, outrate, (stereo ? "stereo" : "mono"));
if (inrate != outrate) { if (inrate != outrate) {
return new LinearRateConverter(inrate, outrate); return new LinearRateConverter(inrate, outrate);
//return new ResampleRateConverter(inrate, outrate, 1); //return new ResampleRateConverter(inrate, outrate, 1);