Beispiel #1
0
	int Soloud::play(AudioSource &aSound, float aVolume, float aPan, int aPaused, int aBus)
	{
		if (aSound.mFlags & AudioSource::SINGLE_INSTANCE)
		{
			// Only one instance allowed, stop others
			stopSound(aSound);
		}

		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = findFreeVoice();
		if (ch < 0) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return -1;
		}
		if (!aSound.mAudioSourceID)
		{
			aSound.mAudioSourceID = mAudioSourceID;
			mAudioSourceID++;
			aSound.mSoloud = this;
		}
		mVoice[ch] = aSound.createInstance();
		mVoice[ch]->mAudioSourceID = aSound.mAudioSourceID;
		mVoice[ch]->mBusHandle = aBus;
		mVoice[ch]->init(mPlayIndex, aSound.mBaseSamplerate, aSound.mChannels, aSound.mFlags);

		mPlayIndex++;

		if (aPaused)
		{
			mVoice[ch]->mFlags |= AudioSourceInstance::PAUSED;
		}

		setVoicePan(ch, aPan);
		setVoiceVolume(ch, aVolume);
		setVoiceRelativePlaySpeed(ch, 1);

		int i;
		for (i = 0; i < FILTERS_PER_STREAM; i++)
		{
			if (aSound.mFilter[i])
			{
				mVoice[ch]->mFilter[i] = aSound.mFilter[i]->createInstance();
			}
		}

		int scratchneeded = SAMPLE_GRANULARITY * mVoice[ch]->mChannels;

		mVoice[ch]->mResampleData[0]->mBuffer = new float[scratchneeded];
		mVoice[ch]->mResampleData[1]->mBuffer = new float[scratchneeded];

		// First buffer will be overwritten anyway; the second may be referenced by resampler
		memset(mVoice[ch]->mResampleData[0]->mBuffer, 0, sizeof(float) * scratchneeded);
		memset(mVoice[ch]->mResampleData[1]->mBuffer, 0, sizeof(float) * scratchneeded);

		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);

		int handle = getHandleFromVoice(ch);
		return handle;
	}	
	// Remove all non-active voices from group
	void Soloud::trimVoiceGroup(handle aVoiceGroupHandle)
	{
		if (!isVoiceGroup(aVoiceGroupHandle))
			return;
		int c = aVoiceGroupHandle & 0xfff;

		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		// empty group
		if (mVoiceGroup[c][1] == 0)
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}

		unsigned int i;
		for (i = 1; i < mVoiceGroup[c][0]; i++)
		{
			if (mVoiceGroup[c][i] == 0)
			{
				if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
				return;
			}
			
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			while (!isValidVoiceHandle(mVoiceGroup[c][i])) // function locks mutex, so we need to unlock it before the call
			{
				if (mLockMutexFunc) mLockMutexFunc(mMutex);
				unsigned int j;
				for (j = i; j < mVoiceGroup[c][0] - 1; j++)
				{
					mVoiceGroup[c][j] = mVoiceGroup[c][j + 1];
					if (mVoiceGroup[c][j] == 0)
						break;
				}
				mVoiceGroup[c][mVoiceGroup[c][0] - 1] = 0;				
				if (mVoiceGroup[c][i] == 0)
				{
					if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
					return;
				}
			}
		}
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
	void Soloud::stopAll()
	{
		int i;
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		for (i = 0; i < VOICE_COUNT; i++)
		{
			stopVoice(i);
		}
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
Beispiel #4
0
	void Soloud::stop(int aVoiceHandle)
	{
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			return;
		}
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		stopVoice(ch);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
	// Destroy a voice group. 
	result Soloud::destroyVoiceGroup(handle aVoiceGroupHandle)
	{
		if (!isVoiceGroup(aVoiceGroupHandle))
			return INVALID_PARAMETER;
		int c = aVoiceGroupHandle & 0xfff;
		
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		delete[] mVoiceGroup[c];
		mVoiceGroup[c] = NULL;
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
		return SO_NO_ERROR;
	}
Beispiel #6
0
	void Soloud::seek(int aVoiceHandle, float aSeconds)
	{
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->seek(aSeconds, mScratch, mScratchSize);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
	// Add a voice handle to a voice group
	result Soloud::addVoiceToGroup(handle aVoiceGroupHandle, handle aVoiceHandle)
	{
		if (!isVoiceGroup(aVoiceGroupHandle))
			return INVALID_PARAMETER;
		
		// Don't consider adding invalid voice handles as an error, since the voice may just have ended.
		if (!isValidVoiceHandle(aVoiceHandle))
			return SO_NO_ERROR;

		trimVoiceGroup(aVoiceGroupHandle);
		
		int c = aVoiceGroupHandle & 0xfff;
		unsigned int i;

		if (mLockMutexFunc) mLockMutexFunc(mMutex);

		for (i = 1; i < mVoiceGroup[c][0]; i++)
		{
			if (mVoiceGroup[c][i] == aVoiceHandle)
			{
				if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
				return SO_NO_ERROR; // already there
			}

			if (mVoiceGroup[c][i] == 0)
			{
				mVoiceGroup[c][i] = aVoiceHandle;
				mVoiceGroup[c][i + 1] = 0;
				
				if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
				return SO_NO_ERROR;
			}
		}
		
		// Full group, allocate more memory
		unsigned int * n = new unsigned int[mVoiceGroup[c][0] * 2 + 1];
		if (n == NULL)
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return OUT_OF_MEMORY;
		}
		for (i = 0; i < mVoiceGroup[c][0]; i++)
			n[i] = mVoiceGroup[c][i];
		n[n[0]] = aVoiceHandle;
		n[n[0]+1] = 0;
		n[0] *= 2;
		delete[] mVoiceGroup[c];
		mVoiceGroup[c] = n;
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
		return SO_NO_ERROR;
	}
	// Is this voice group empty?
	bool Soloud::isVoiceGroupEmpty(handle aVoiceGroupHandle)
	{
		// If not a voice group, yeah, we're empty alright..
		if (!isVoiceGroup(aVoiceGroupHandle))
			return 1;
		trimVoiceGroup(aVoiceGroupHandle);
		int c = aVoiceGroupHandle & 0xfff;

		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		bool res = mVoiceGroup[c][1] == 0;
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);

		return res;
	}
	// Is this handle a valid voice group?
	bool Soloud::isVoiceGroup(handle aVoiceGroupHandle)
	{
		if ((aVoiceGroupHandle & 0xfffff000) != 0xfffff000)
			return 0;
		unsigned int c = aVoiceGroupHandle & 0xfff;
		if (c >= mVoiceGroupCount)
			return 0;

		if (mLockMutexFunc) mLockMutexFunc(mMutex);		
		bool res = mVoiceGroup[c] != NULL;		
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);

		return res;
	}
	void Soloud::stopAudioSource(AudioSource &aSound)
	{
		if (aSound.mAudioSourceID)
		{
			if (mLockMutexFunc) mLockMutexFunc(mMutex);
			
			int i;
			for (i = 0; i < VOICE_COUNT; i++)
			{
				if (mVoice && mVoice[i] && mVoice[i]->mAudioSourceID == aSound.mAudioSourceID)
				{
					stopVoice(i);
				}
			}
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
		}
	}
	void Soloud::scheduleStop(handle aVoiceHandle, time aTime)
	{
		if (aTime <= 0)
		{
			stop(aVoiceHandle);
			return;
		}
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->mStopScheduler.set(1, 0, aTime, mVoice[ch]->mStreamTime);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
	void Soloud::oscillateRelativePlaySpeed(handle aVoiceHandle, float aFrom, float aTo, time aTime)
	{
		if (aTime <= 0 || aTo == aFrom)
		{
			setRelativePlaySpeed(aVoiceHandle, aTo);
			return;
		}
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->mRelativePlaySpeedFader.setLFO(aFrom, aTo, aTime, mVoice[ch]->mStreamTime);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
Beispiel #13
0
	void Soloud::schedulePause(int aVoiceHandle, float aTime)
	{
		if (aTime <= 0)
		{
			setPause(aVoiceHandle, 1);
			return;
		}
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->mPauseScheduler.set(1, 0, aTime, mVoice[ch]->mStreamTime);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
Beispiel #14
0
	void Soloud::oscillatePan(int aVoiceHandle, float aFrom, float aTo, float aTime)
	{
		if (aTime <= 0 || aTo == aFrom)
		{
			setPan(aVoiceHandle, aTo);
			return;
		}

		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->mPanFader.setLFO(aFrom, aTo, aTime, mVoice[ch]->mStreamTime);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
Beispiel #15
0
	void Soloud::fadeRelativePlaySpeed(int aVoiceHandle, float aTo, float aTime)
	{
		float from = getRelativePlaySpeed(aVoiceHandle);
		if (aTime <= 0 || aTo == from)
		{
			setRelativePlaySpeed(aVoiceHandle, aTo);
			return;
		}
		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->mRelativePlaySpeedFader.set(from, aTo, aTime, mVoice[ch]->mStreamTime);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
	void Soloud::fadePan(handle aVoiceHandle, float aTo, time aTime)
	{
		float from = getPan(aVoiceHandle);
		if (aTime <= 0 || aTo == from)
		{
			setPan(aVoiceHandle, aTo);
			return;
		}

		if (mLockMutexFunc) mLockMutexFunc(mMutex);
		int ch = getVoiceFromHandle(aVoiceHandle);
		if (ch == -1) 
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return;
		}
		mVoice[ch]->mPanFader.set(from, aTo, aTime, mVoice[ch]->mStreamTime);
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
	}
	// Create a voice group. Returns 0 if unable (out of voice groups / out of memory)
	handle Soloud::createVoiceGroup()
	{
		if (mLockMutexFunc) mLockMutexFunc(mMutex);

		unsigned int i;
		// Check if there's any deleted voice groups and re-use if found
		for (i = 0; i < mVoiceGroupCount; i++)
		{
			if (mVoiceGroup[i] == NULL)
			{
				mVoiceGroup[i] = new unsigned int[16];
				if (mVoiceGroup[i] == NULL)
				{
					if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
					return 0;
				}
				mVoiceGroup[i][0] = 16;
				mVoiceGroup[i][1] = 0;
				if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
				return 0xfffff000 | i;
			}		
		}
		if (mVoiceGroupCount == 4096)
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return 0;
		}
		unsigned int oldcount = mVoiceGroupCount;
		if (mVoiceGroupCount == 0)
		{
			mVoiceGroupCount = 4;
		}
		mVoiceGroupCount *= 2;
		unsigned int **vg = new unsigned int * [mVoiceGroupCount];
		if (vg == NULL)
		{
			mVoiceGroupCount = oldcount;
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return 0;
		}
		for (i = 0; i < oldcount; i++)
		{
			vg[i] = mVoiceGroup[i];
		}

		for (; i < mVoiceGroupCount; i++)
		{
			vg[i] = NULL;
		}

		delete[] mVoiceGroup;
		mVoiceGroup = vg;
		i = oldcount;
		mVoiceGroup[i] = new unsigned int[17];
		if (mVoiceGroup[i] == NULL)
		{
			if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
			return 0;
		}
		mVoiceGroup[i][0] = 16;
		mVoiceGroup[i][1] = 0;
		if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex);
		return 0xfffff000 | i;
	}