implemented raw sound looping; some debug output enabled temporarily
svn-id: r9360
This commit is contained in:
parent
0df319e952
commit
d9bd77032a
5 changed files with 52 additions and 16 deletions
|
@ -40,7 +40,7 @@ static inline int16 readSample(const byte *ptr) {
|
|||
|
||||
|
||||
template<bool stereo, bool is16Bit, bool isUnsigned>
|
||||
class LinearMemoryStream : public AudioInputStream {
|
||||
class LinearMemoryStream : public LinearAudioInputStream {
|
||||
protected:
|
||||
const byte *_ptr;
|
||||
const byte *_end;
|
||||
|
@ -58,11 +58,17 @@ public:
|
|||
return val;
|
||||
}
|
||||
bool eof() const {
|
||||
return _end <= _ptr;
|
||||
return _ptr >= _end;
|
||||
}
|
||||
bool isStereo() const {
|
||||
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>
|
||||
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 (is16Bit)
|
||||
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 isUnsigned = (_flags & SoundMixer::FLAG_UNSIGNED) != 0;
|
||||
if (_flags & SoundMixer::FLAG_STEREO) {
|
||||
|
|
|
@ -53,6 +53,11 @@ public:
|
|||
virtual bool eof() const = 0;
|
||||
};
|
||||
|
||||
class LinearAudioInputStream : public AudioInputStream {
|
||||
public:
|
||||
virtual void reset(const byte *data, uint32 len) = 0;
|
||||
};
|
||||
|
||||
class WrappedAudioInputStream : public AudioInputStream {
|
||||
public:
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -67,19 +67,19 @@ class ChannelRaw : public Channel {
|
|||
byte _flags;
|
||||
#ifdef SOX_HACK
|
||||
RateConverter *_converter;
|
||||
AudioInputStream *_input;
|
||||
LinearAudioInputStream *_input;
|
||||
#else
|
||||
uint32 _pos;
|
||||
uint32 _size;
|
||||
uint32 _fpSpeed;
|
||||
uint32 _fpPos;
|
||||
uint32 _realSize, _rate;
|
||||
#endif
|
||||
byte *_loop_ptr;
|
||||
uint32 _loop_size;
|
||||
#endif
|
||||
|
||||
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();
|
||||
|
||||
void mix(int16 *data, uint len);
|
||||
|
@ -272,7 +272,7 @@ int SoundMixer::insertChannel(PlayingSoundHandle *handle, Channel *chan) {
|
|||
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);
|
||||
|
||||
// Prevent duplicate sounds
|
||||
|
@ -282,7 +282,7 @@ int SoundMixer::playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, ui
|
|||
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
|
||||
|
@ -651,7 +651,7 @@ static int16 mixer_element_size[] = {
|
|||
#endif
|
||||
|
||||
/* 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) {
|
||||
_id = id;
|
||||
_ptr = (byte *)sound;
|
||||
|
@ -665,6 +665,23 @@ ChannelRaw::ChannelRaw(SoundMixer *mixer, PlayingSoundHandle *handle, void *soun
|
|||
|
||||
// Get a rate converter instance
|
||||
_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
|
||||
_pos = 0;
|
||||
_fpPos = 0;
|
||||
|
@ -705,9 +722,13 @@ void ChannelRaw::mix(int16 *data, uint len) {
|
|||
|
||||
if (_input->eof()) {
|
||||
// TODO: call drain method
|
||||
// TODO: Looping
|
||||
destroy();
|
||||
return;
|
||||
// Loop if requested
|
||||
if (_loop_ptr) {
|
||||
_input->reset(_loop_ptr, _loop_size);
|
||||
} else {
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const int volume = _mixer->getVolume();
|
||||
|
@ -756,6 +777,9 @@ ChannelStream::ChannelStream(SoundMixer *mixer, PlayingSoundHandle *handle, void
|
|||
|
||||
// Get a rate converter instance
|
||||
_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
|
||||
_flags = flags;
|
||||
_bufferSize = buffer_size;
|
||||
|
|
|
@ -82,7 +82,8 @@ public:
|
|||
~SoundMixer();
|
||||
|
||||
// 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
|
||||
int playMP3(PlayingSoundHandle *handle, File *file, uint32 size);
|
||||
int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration);
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
};
|
||||
|
||||
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) {
|
||||
return new LinearRateConverter(inrate, outrate);
|
||||
//return new ResampleRateConverter(inrate, outrate, 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue