Tag: bugs

Raspberry Pi Sound issues- trying to fix it

Raspberry Pi Sound issues- trying to fix it

Loudpeaker
Image by OpenClipart-Vectors from Pixabay

In working through my Linux/Raspberry Pi eBook(Yes – the second eBook!), I’m up to the chapter where sounds are introduced using the SDL_mixer library. And I’ve hit two sets of problems.

It sometimes refuses to initialize the sound code.  This code below hits the LogError line:

	int success=Mix_OpenAudio(22050, AUDIO_S16LSB, 2, 8192);
	if (success==-1 ) {
		LogError("InitSetup failed to init audio");
	}

The other day it was working but not today. Now I have updated the Pi’s code (sudo apt update etc) but I wouldn’t have expected that to break it. I’ve been looking on the internet and find the whole thing a bit complicated.

I’ve got my Pi running 64-bit Raspberry Pi OS. I’ve changed the output device to headphones which plug into the headphone socket. If I run the VLC media player and tell it to play into the headphones, it will happily play the .wav files I’ve got for the asteroids game.

But if I run speaker-test, a terminal application with this command line

speaker-test -c2 -twav -l7 plughw:1,0

I get

speaker-test 1.2.4

Playback device is default
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Setting of hwparams failed: Invalid argument

By running this command:

aplay -L

I got 71 lines of output but of these these below are the most important

output
hw:CARD=Headphones,DEV=0
    bcm2835 Headphones, bcm2835 Headphones

and the speaker-test command using the device parameter –Dhw:Headphones now worked. I’ve highlighted the bits in the aplay output needed to identify the device.

The new command  is

speaker-test -c2 -twav -l7 -Dhw:Headphones

I can now hear a female voice saying front left then front right a few times in my headphones.

So my Pi’s sound device is working; I just have to figure why SDL_mixer isn’t always. I’ll keep looking.

And the second problem which only occurs when the mixer is working, is when you play a lot of sounds. The PlayASound() function checks the result. On Windows it never had a problem but on Raspberry Pi, when you blow up a lot of asteroids say at one time, it plays a number of explosions then returns an error for each explosion after that. I think there’s only so many channels; that’s an easy fix; just ignore the error and return as if it succeeded.

To brace or not to brace

To brace or not to brace

Abstract programming picture
Image by Gerd Altmann from Pixabay

This isn’t exactly confined to C, in fact it applies to many programming languages where braces or curly brackets {like this} are optional after an if. It even applies to Pascal with Begin ends which are optional after an if.

You can have the first or the second as shown below.

if (expressions) 
  DoSomething;

if (expression {
  DoSomething;
}

I saw a recent example where the DoSomething was a logging expression which the compiler optimised away so the if, which lacked braces applied to the next statement. As the if was only true on rare occasions. It meant that that statement which should have been run every time was only run on those rare occasions.

So the prevailing wisdom and one that I entirely agree with is that you should always use braces. If you don’t you risk accidentally introducing bugs like this.

Note. that link is to a discussion on the C programming Subreddit (on Reddit.com).

.

Fun with Raspberry Pi 4

Fun with Raspberry Pi 4

Bugs!
Image by Ron van den Berg from Pixabay

So it turned up and I setup things up similar to the 3B+. My interest was in seeing what frame rate it can manage compared to the 27 FPS that the 3B+ managed.

When I eventually got Clang, VS Code etc. installed and setup, compiled etc. it crashed just like it did on the 3B+ when first run. And again it failed to load the am2.msk file; I will really have to figure out what’s going on there. But also it would now not load the a1.png image. This is the one with the 24 x 280 x 280 asteroid images.

SDL provides a function SDL_GetError so I added that to the output when an image file fails to load. The error message that came back was Texture dimensions are limited to 4096×4096. Now this is weird for this Pi has 4 GB of RAM (the 3B+ has 1GB) and is outputting on the same 24″ monitor that the 3B+ used as well. Now it’s true that the a1.png file has dimensions of 6,720 x 64, so I can understand why that would cause grief but not why it worked on the 3B+. I suspect it has to do with RAM being allocated between the GPU and CPU so I’ll check that out.

I also installed Clang-6.0 to try that. On the Pi, installing clang defaults to Clang-7 (they changed the name so it no longer has a .0 on the end!). The release notes for Clang-7 suggested a possibility to do with abi incompatibility between Clang-7 and earlier versions. Bit of a longshot but I thought, that might explain the fail to load am2.msk file but no joy.

Well there’s nothing like juicy tender bugs to get my teeth into… the battle is on.

And the bug is fixed

And the bug is fixed

Showing the comparison of two sources and tracking a bug downHow did I fix it? Did I spend hours debugging, poring over every line? No. I woke up in the middle of the night and thought about it and remembered that

I’d had a similar bug in this chapter when working on the original Ebook.

Stupidly I’d put the fix in the sources for the next chapter (44) but hadn’t applied it to the sources in the chapter where it had occurred (42). So I fired up my favourite code comparison tool (Devart Code Compare) and looked for differences between the source files for each chapter.

This was in the function AddObjectToCells and is part of the collision detection. It’s when an asteroid or player ship is partly on screen and calculating the cell coordinates that the object lies over. The fix was just adding these two lines so it doesn’t try and access the cells array with negative indices.

if (cellx < 0) cellx = 0;
if (celly < 0) celly = 0;
Bugs and crashes!

Bugs and crashes!

A bug!
Image by Ronny Overhate from Pixabay

I’m up to chapter 42 in the Linux e-book. The rest have gone very smoothly though I’m still unable to debug either on my Hyper-V Ubuntu or my Ubuntu running laptop. Both still have the same problem XDG_RUNTIME_DIR not set in the environment.

I’ve been reading up on that and it seems if you switch into root and the value of the environment variable $XAUTHORITY is blank then that is the problem.

My error logging is picking up problems with sound channels not playing. I think the problem is, when I hit the b key to make lots of asteroids explode, it uses up all available sound channels and there’s still explosions happening.  Not really a problem.

But to cap it all, there is a segmentation error happening with a core dump. A segfault which kills the program. But it’s not related to the sound problem. I’ve proved that by commenting out the entire PlayASound function. It now looks like this which I call the sound of silence.

void PlayASound(int soundindex) {
	//int success=Mix_PlayChannel(-1, sounds[soundindex], 0);
	//if (success == -1) {
	//	LogError2("Mix_PlayChannel failed to play audio sound #",SDL_ltoa(soundindex,buffer,10));
	//}
}

So without being able to run the program in a debugger, I’m forced to start putting in lots of logging calls and figure out where the segfault happens that way. It’s an effective way of finding bugs BUT it’s not the fastest! I have also enabled apport to try and get the crash files created in /var/crash so that may be a faster way forward.

Once I have fixed the segmentation fault, I’ll upload the fixed code to Github. It’ll be somewhere in the new code added between chapter 37 and chapter 42, to do with collision detection. Time to put on a deerstalker hat!