OneLoneCoder/olcPixelGameEngine

Bug with stereo in PGEX_Sound ALSA implementation (?)

Opened this issue · 2 comments

Hi, I did done some research about using ALSA and I found something weird with how channels are handled.

At line 707 :

snd_pcm_uframes_t nLeft = m_nBlockSamples;
short *pBlockPos = m_pBlockMemory;
while (nLeft > 0)
{
	int rc = snd_pcm_writei(m_pPCM, pBlockPos, nLeft);
	if (rc > 0)
	{
		pBlockPos += rc * m_nChannels;
			nLeft -= rc;
	}
	if (rc == -EAGAIN) continue;
	if (rc == -EPIPE) // an underrun occured, prepare the device for more data
		snd_pcm_prepare(m_pPCM);
}

snd_pcm_uframes_t doens't refer directly to the number of samples, if we use stereo for instance, we write 2 samples in the block but the snd_pcm_writei function reads both of them at the same time as with stereo a "frame" is 2 samples and we end up reading junk past the buffer... So the fix would be something like snd_pcm_uframes_t nLeft = m_nBlockSamples / m_nChannels;.

Here the block size is set to the number of "frames" so headaches are avoided :
https://gist.github.com/ghedo/963382/815c98d1ba0eda1b486eb9d80d9a91a81d995283

I haven't tested directly with PGE since I fear C++ but it works better in my code, hope it helps in some way.

I tried this as well and it does fix the problem indeed. I couldn't find an answer to this issue until I found this thread. Would be nice to see this fixed in the repository and that you got some recognition before a year has passed.

Yeah, I redone this audio thing a few months ago for my project and it was a pain to debug. Between ALSA not setting the values I was asking, my sound card using 24bits that were sometimes not converted properly from 16bits and weird interactions with other programs... Anyway I think I have it figured out now.