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