Audio: Remove all traces of rubberband

We will not be using librubberband for in place
pitch shifting. RMXP "shifts" PCM based audio
by just playing it back slower/faster, which
OpenAL takes care of for us. A native midi backend
will be able to effortlessly pitch shift by
multiplying note pitches, should we ever get one.

I have been chasing this ghost for way too long.
This commit is contained in:
Jonas Kulla 2013-12-04 14:49:35 +01:00
parent e26d0366f1
commit a817b31e7c
1 changed files with 33 additions and 154 deletions

View File

@ -48,81 +48,6 @@
#define SE_SOURCES 6 #define SE_SOURCES 6
#define SE_CACHE_MEM (10*1024*1024) // 10 MB #define SE_CACHE_MEM (10*1024*1024) // 10 MB
static void genFloatSamples(int sampleCount, int sdlFormat, const void *in, float *out)
{
(void) genFloatSamples;
int i = sampleCount;
/* Convert from the possible fixed point
* formats to [-1;1] floats */
switch (sdlFormat)
{
case AUDIO_U8 :
{
const uint8_t *_in = static_cast<const uint8_t*>(in);
while (i--)
out[i] = (((float) _in[i] / 255.f) - 0.5) * 2;
break;
}
case AUDIO_S8 :
{
const int8_t *_in = static_cast<const int8_t*>(in);
while (i--)
out[i] = (float) _in[i] / 128.f; // ???
break;
}
case AUDIO_U16LSB :
{
const uint16_t *_in = static_cast<const uint16_t*>(in);
while (i--)
out[i] = (((float) _in[i] / 65536.f) - 0.5) * 2;
break;
}
case AUDIO_U16MSB :
{
const int16_t *_in = static_cast<const int16_t*>(in);
while (i--)
{
int16_t swp = SDL_Swap16(_in[i]);
out[i] = (((float) swp / 65536.f) - 0.5) * 2;
}
break;
}
case AUDIO_S16LSB :
{
const int16_t *_in = static_cast<const int16_t*>(in);
while (i--)
out[i] = (float) _in[i] / 32768.f; // ???
break;
}
case AUDIO_S16MSB :
{
const int16_t *_in = static_cast<const int16_t*>(in);
while (i--)
{
int16_t swp = SDL_Swap16(_in[i]);
out[i] = (float) swp / 32768.f;
}
break;
}
qDebug() << "Unhandled sample format";
default: Q_ASSERT(0); // XXX
}
}
static uint8_t formatSampleSize(int sdlFormat) static uint8_t formatSampleSize(int sdlFormat)
{ {
switch (sdlFormat) switch (sdlFormat)
@ -183,10 +108,8 @@ static const int streamBufSize = 32768;
struct SoundBuffer struct SoundBuffer
{ {
/* Filename, pitch. /* Uniquely identifies this or equal buffer */
* Uniquely identifies this or equal buffer */ QByteArray key;
typedef QPair<QByteArray, int> Key;
Key key;
AL::Buffer::ID alBuffer; AL::Buffer::ID alBuffer;
@ -229,7 +152,7 @@ struct SoundBuffer
struct SoundEmitter struct SoundEmitter
{ {
IntruList<SoundBuffer> buffers; IntruList<SoundBuffer> buffers;
QHash<SoundBuffer::Key, SoundBuffer*> bufferHash; QHash<QByteArray, SoundBuffer*> bufferHash;
/* Byte count sum of all cached / playing buffers */ /* Byte count sum of all cached / playing buffers */
uint32_t bufferBytes; uint32_t bufferBytes;
@ -239,10 +162,6 @@ struct SoundEmitter
/* Index of next source to be used */ /* Index of next source to be used */
int srcIndex; int srcIndex;
#ifdef RUBBERBAND
std::vector<float> floatBuf;
#endif
SoundEmitter() SoundEmitter()
: bufferBytes(0), : bufferBytes(0),
srcIndex(0) srcIndex(0)
@ -252,9 +171,6 @@ struct SoundEmitter
alSrcs[i] = AL::Source::gen(); alSrcs[i] = AL::Source::gen();
atchBufs[i] = 0; atchBufs[i] = 0;
} }
#ifdef RUBBERBAND
floatBuf.resize(streamBufSize/4);
#endif
} }
~SoundEmitter() ~SoundEmitter()
@ -268,7 +184,7 @@ struct SoundEmitter
SoundBuffer::deref(atchBufs[i]); SoundBuffer::deref(atchBufs[i]);
} }
QHash<SoundBuffer::Key, SoundBuffer*>::iterator iter; QHash<QByteArray, SoundBuffer*>::iterator iter;
for (iter = bufferHash.begin(); iter != bufferHash.end(); ++iter) for (iter = bufferHash.begin(); iter != bufferHash.end(); ++iter)
delete iter.value(); delete iter.value();
} }
@ -278,8 +194,9 @@ struct SoundEmitter
int pitch) int pitch)
{ {
float _volume = clamp<int>(volume, 0, 100) / 100.f; float _volume = clamp<int>(volume, 0, 100) / 100.f;
float _pitch = clamp<int>(pitch, 50, 150) / 100.f;
SoundBuffer *buffer = allocateBuffer(filename, pitch); SoundBuffer *buffer = allocateBuffer(filename);
int soundIndex = srcIndex++; int soundIndex = srcIndex++;
if (srcIndex > SE_SOURCES-1) if (srcIndex > SE_SOURCES-1)
@ -297,11 +214,9 @@ struct SoundEmitter
atchBufs[soundIndex] = SoundBuffer::ref(buffer); atchBufs[soundIndex] = SoundBuffer::ref(buffer);
AL::Source::attachBuffer(src, buffer->alBuffer); AL::Source::attachBuffer(src, buffer->alBuffer);
AL::Source::setVolume(src, _volume);
#ifndef RUBBERBAND AL::Source::setVolume(src, _volume);
AL::Source::setPitch(src, clamp<int>(pitch, 50, 150) / 100.f); AL::Source::setPitch(src, _pitch);
#endif
AL::Source::play(src); AL::Source::play(src);
} }
@ -313,26 +228,9 @@ struct SoundEmitter
} }
private: private:
#ifdef RUBBERBAND SoundBuffer *allocateBuffer(const QByteArray &filename)
void ensureFloatBufSize(uint32_t size)
{ {
if (size <= floatBuf.size()) SoundBuffer *buffer = bufferHash.value(filename, 0);
return;
floatBuf.resize(size);
}
#endif
SoundBuffer *allocateBuffer(const QByteArray &filename,
int pitch)
{
#ifndef RUBBERBAND
pitch = 100;
#endif
SoundBuffer::Key soundKey(filename, pitch);
SoundBuffer *buffer = bufferHash.value(soundKey, 0);
if (buffer) if (buffer)
{ {
@ -364,34 +262,15 @@ private:
uint8_t sampleSize = formatSampleSize(sampleHandle->actual.format); uint8_t sampleSize = formatSampleSize(sampleHandle->actual.format);
uint32_t sampleCount = decBytes / sampleSize; uint32_t sampleCount = decBytes / sampleSize;
uint32_t actSampleSize;
#ifdef RUBBERBAND
actSampleSize = sizeof(float);
#else
actSampleSize = sampleSize;
#endif
buffer = new SoundBuffer; buffer = new SoundBuffer;
buffer->key = soundKey; buffer->key = filename;
buffer->bytes = actSampleSize * sampleCount; buffer->bytes = sampleSize * sampleCount;
ALenum alFormat = chooseALFormat(actSampleSize, sampleHandle->actual.channels); ALenum alFormat = chooseALFormat(sampleSize, sampleHandle->actual.channels);
#ifdef RUBBERBAND
/* Fill float buffer */
ensureFloatBufSize(sampleCount);
genFloatSamples(sampleCount, sampleHandle->actual.format,
sampleHandle->buffer, floatBuf.data());
// XXX apply stretcher
/* Upload data to AL */
AL::Buffer::uploadData(buffer->alBuffer, alFormat, floatBuf.data(),
buffer->bytes, sampleHandle->actual.rate);
#else
AL::Buffer::uploadData(buffer->alBuffer, alFormat, sampleHandle->buffer, AL::Buffer::uploadData(buffer->alBuffer, alFormat, sampleHandle->buffer,
buffer->bytes, sampleHandle->actual.rate); buffer->bytes, sampleHandle->actual.rate);
#endif
Sound_FreeSample(sampleHandle); Sound_FreeSample(sampleHandle);
uint32_t wouldBeBytes = bufferBytes + buffer->bytes; uint32_t wouldBeBytes = bufferBytes + buffer->bytes;
@ -409,7 +288,7 @@ private:
SoundBuffer::deref(last); SoundBuffer::deref(last);
} }
bufferHash.insert(soundKey, buffer); bufferHash.insert(filename, buffer);
buffers.prepend(buffer->link); buffers.prepend(buffer->link);
bufferBytes = wouldBeBytes; bufferBytes = wouldBeBytes;
@ -457,12 +336,9 @@ struct SDLSoundSource : ALDataSource
SDLSoundSource(const std::string &filename, SDLSoundSource(const std::string &filename,
uint32_t maxBufSize, uint32_t maxBufSize,
bool looped, bool looped)
float pitch)
: looped(looped) : looped(looped)
{ {
(void) pitch;
const char *extension; const char *extension;
shState->fileSystem().openRead(ops, shState->fileSystem().openRead(ops,
filename.c_str(), filename.c_str(),
@ -505,8 +381,6 @@ struct SDLSoundSource : ALDataSource
if (sample->flags & SOUND_SAMPLEFLAG_ERROR) if (sample->flags & SOUND_SAMPLEFLAG_ERROR)
return ALDataSource::Error; return ALDataSource::Error;
// XXX apply stretcher here
AL::Buffer::uploadData(alBuffer, alFormat, sample->buffer, decoded, alFreq); AL::Buffer::uploadData(alBuffer, alFormat, sample->buffer, decoded, alFreq);
if (sample->flags & SOUND_SAMPLEFLAG_EOF) if (sample->flags & SOUND_SAMPLEFLAG_EOF)
@ -644,8 +518,7 @@ struct ALStream
} }
} }
void open(const std::string &filename, void open(const std::string &filename)
float pitch)
{ {
checkStopped(); checkStopped();
@ -657,7 +530,7 @@ struct ALStream
case Stopped: case Stopped:
closeSource(); closeSource();
case Closed: case Closed:
openSource(filename, pitch); openSource(filename);
} }
state = Stopped; state = Stopped;
@ -730,6 +603,11 @@ struct ALStream
AL::Source::setVolume(alSrc, value); AL::Source::setVolume(alSrc, value);
} }
void setPitch(float value)
{
AL::Source::setPitch(alSrc, value);
}
State queryState() State queryState()
{ {
checkStopped(); checkStopped();
@ -754,15 +632,10 @@ private:
delete source; delete source;
} }
void openSource(const std::string &filename, void openSource(const std::string &filename)
float pitch)
{ {
source = new SDLSoundSource(filename, streamBufSize, looped, pitch); source = new SDLSoundSource(filename, streamBufSize, looped);
needsRewind = false; needsRewind = false;
#ifndef RUBBERBAND
AL::Source::setPitch(alSrc, pitch);
#endif
} }
void stopStream() void stopStream()
@ -1084,19 +957,25 @@ struct AudioStream
return; return;
} }
/* Requested audio file is different from current one */
bool diffFile = (filename != current.filename);
switch (sState) switch (sState)
{ {
case ALStream::Paused : case ALStream::Paused :
case ALStream::Playing : case ALStream::Playing :
stream.stop(); stream.stop();
case ALStream::Stopped : case ALStream::Stopped :
if (diffFile)
stream.close(); stream.close();
case ALStream::Closed : case ALStream::Closed :
if (diffFile)
stream.open(filename);
break; break;
} }
stream.open(filename, _pitch);
setBaseVolume(_volume); setBaseVolume(_volume);
stream.setPitch(_pitch);
current.filename = filename; current.filename = filename;
current.volume = _volume; current.volume = _volume;