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:
		
							parent
							
								
									e26d0366f1
								
							
						
					
					
						commit
						a817b31e7c
					
				
					 1 changed files with 33 additions and 154 deletions
				
			
		
							
								
								
									
										185
									
								
								src/audio.cpp
									
										
									
									
									
								
							
							
						
						
									
										185
									
								
								src/audio.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue