Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mixBus_internal can get stuck in an infinite loop when writesamples is 0 #343

Open
AniCator opened this issue Feb 23, 2022 · 1 comment
Open

Comments

@AniCator
Copy link

AniCator commented Feb 23, 2022

Expected behavior

The function does not get stuck in an infinite loop and the application does not lock up.

Actual behavior

In mixBus_internal, writesamples and outofs can, in rare cases, both be 0; causing the resampling while loop to never finish execution.

Steps to reproduce the problem

I was repeatedly playing a sound over a bus at a regular interval with its rate being adjusted to that of a hailstone sequence.
In some cases it would happen almost immediately, in other cases I had to wait 30 seconds or longer.

I suspect it happens when the playback rate of a sound is near 0.0.

Workaround

I've temporarily just stuck a break in the while loop when writesamples is 0.

// Call resampler to generate the samples, once per channel
if (writesamples)
{
	...
}
else
{
	// NOTE: Breaking here because this thing can get stuck in an infinite loop.
	break;
}

This creates an audible noise whenever the issue occurs but it at least stops my game engine from getting stuck.

SoLoud version, operating system, backend used, any other potentially useful information

Custom fork, branched from main, with the last merged in change being 4d72336a8855f3f421f95ec75cda9062da3fe7eb
From the looks of it, the code in the master branch has not changed in this area since then.

@AniCator
Copy link
Author

The hailstone sequence function in question. SoLoud functions are abstracted away by other classes in my engine.

void HailStone()
{
	static CSound* Bleep = CAssets::Get().CreateNamedSound( "bleep", "Audio/UI/Placeholder/Message.ogg" );
	static SoundInstance BleepInstance = SoundInstance( Bleep );
	static float LastBleep = -1.0f;
	static auto Hailstone = Math::RandomRangeInteger( 1, 20000 );

	if( LastBleep < 0.0f )
	{
		LastBleep = GetCurrentTime();
	}

	const auto BleepDelta = GetCurrentTime() - LastBleep;

	if( Bleep && BleepDelta > 0.15f )
	{
		LastBleep = GetCurrentTime();

		const auto HailstonePrevious = Hailstone;
		if( Hailstone % 2 )
		{
			Hailstone = Hailstone * 3 + 1;
		}
		else
		{
			Hailstone /= 2;
		}

		if( Hailstone <= 1 )
		{
			Hailstone = Math::RandomRangeInteger( 1, 20000 );
		}

		const auto HailstoneDelta = abs( HailstonePrevious - Hailstone );
		const auto Delta = StaticCast<float>( HailstoneDelta ) / 20000.0f;

		auto Spatial = Spatial::CreateUI();
		Spatial.Bus = Bus::Auxilery7;
		Spatial.Rate = Delta * 100.0f;

		if( Spatial.Rate > 0.1f )
		{
			Spatial.Volume = Math::Clamp( Spatial.Rate * 100.0f, 10.0f, 100.0f );

			// BleepInstance.Stop( 0.1f );
			BleepInstance.Start( Spatial );
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant