new ALSA audio driver

Archives Forums/Linux Discussion/new ALSA audio driver

skidracer(Posted 2012) [#1]
After failing to get the OSS driver working on latest Ubuntu, have fixed the ALSA driver which seems to work now without problem.

To switch from OSS to ALSA edit freeaudio.mod/freeaudio.bmx in two places:

?Linux
Import "-lasound"
Import "alsadevice.cpp"
'Import "ossdevice.cpp"


and here in the fa_Init method

?Linux
	Select deviceid
		Case 0
			device=OpenALSADevice()
	EndSelect


then replace alsadevice.cpp with following:


// alsadevice.cpp

#ifdef __linux

#include "freeaudio.h"

#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <pthread.h>

#include <alsa/asoundlib.h>

extern "C" audiodevice *OpenALSADevice();

void *audiothread(void *dev);

#define LINUXFRAG 2048

struct alsaaudio:audiodevice{
	pthread_t	audiopthread;
	int			threadid;
	int			running,playing;
	short		*buffer;
	int			buffersize;	//in bytes
	
	int reset(){
		running=1;
		playing=0;
		mix=new mixer(LINUXFRAG);
		mix->freq=44100;
		mix->channels=2;
		buffer=new short[LINUXFRAG];
		buffersize=LINUXFRAG*2;
		pthread_attr_t	attr;
		pthread_attr_init(&attr);
		threadid=pthread_create(&audiopthread,&attr,audiothread,(void*)this);	
		return 0;
	}
	
	int close(){	
		int		timeout;
		running=0;
		timeout=5;
		while (timeout-- && playing) sleep(1);
		return 0;
	}
};


void *audiothread(void *v){
	int						policy;
	sched_param		sched;	
	int						err;
	alsaaudio 		*dev;
	
	pthread_getschedparam(pthread_self(),&policy,&sched);
	sched.sched_priority++;//policy=SCHED_RR;
	pthread_setschedparam(pthread_self(),policy,&sched);	
	dev=(alsaaudio*)v;

	unsigned int val;
	
	snd_pcm_t *fd;
	snd_pcm_uframes_t periodsize;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_hw_params_alloca(&hwparams);
	int output_rate;
	int channels;
	int fragment_size;
	int fragment_count;

	err=snd_pcm_open(&fd, strdup("default"), SND_PCM_STREAM_PLAYBACK, 0);
	if (err<0) return v;

	fragment_size=LINUXFRAG;  //overall buffer size
	fragment_count=2; //2 - 16 fragment count - 2 minimum, the lower it is potentially the lower the latency

//configure device
	if (snd_pcm_hw_params_any(fd, hwparams) < 0) {
		//printf("linuxaudio failed at params any\n");
		return v;
	}	
	if (snd_pcm_hw_params_set_access(fd, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		//printf("linuxaudio failed at set access\n");
		return v;
	}	
	
	if (snd_pcm_hw_params_set_format(fd, hwparams,SND_PCM_FORMAT_S16_LE) < 0) {
		//printf("linuxaudio failed at set format\n");
		return v;
	}
	val = 44100;
	if (snd_pcm_hw_params_set_rate_near(fd, hwparams,&val, 0) < 0) {
		// Try 48KHZ too 
		//printf("linuxaudio - %d HZ not available, trying 48000HZ\n", output_rate);
		val = 48000;
		if (snd_pcm_hw_params_set_rate_near(fd, hwparams,&val, 0) < 0) {
			//printf("linuxaudio failed at setting output rate (%d)\n", output_rate);
			return v;
		}
		dev->mix->freq=val;		
	}
	channels=2;
	if (snd_pcm_hw_params_set_channels(fd, hwparams, channels) < 0) {
		//printf("linuxaudio failed at set channels (%d)\n", channels);
		return v;
	}
	periodsize = (fragment_size) / 4; // bytes -> frames for 16-bit,stereo - should be a minimum of 512
	if (snd_pcm_hw_params_set_period_size_near(fd, hwparams,&periodsize, 0) < 0) {
		//printf("linuxaudio failed at set period size (%d)\n", (int)periodsize);			
		return v;
	}
	val = fragment_count;
	if (snd_pcm_hw_params_set_periods_near(fd, hwparams,&val, 0) < 0) {
		//printf("linuxaudio failed at set periods (%d)\n", val);			
		//should attempt a one by one period increase up to 16?
		return v;
	}
	if (snd_pcm_hw_params(fd, hwparams) < 0) {
		//printf("linuxaudio failed at installing hw params\n");
		return v;
	}
	//loop while playing sound
	dev->playing=1;
	while (dev->playing)
	{
		dev->mix->mix16(dev->buffer);
		if ((snd_pcm_writei (fd, dev->buffer,LINUXFRAG/2)) < 0) {	//Half buffer for two channels?
			//printf ("linuxaudio warning: buffer underrun occurred\n");
			if (snd_pcm_prepare(fd) < 0) {
				//printf ("linuxaudio failed at preparing pcm\n");
				dev->playing=0; //die gracefully
			}
		}	
	}
	snd_pcm_drop(fd);
	snd_pcm_close (fd);
	return 0;
}

audiodevice *OpenALSADevice(){
	return new alsaaudio();
}

#endif



Captain Wicker (crazy hillbilly)(Posted 2012) [#2]
Thank You! Thank You! Thank You skidracer!!!!!! I hope this works! Testing now!!!! :) :) :) :) :) :)

EDIT: No Luck! :(

Last edited 2012


dawlane(Posted 2012) [#3]
Nice one skid works well so far with Ubuntu 12.04(64bit) so should work with 32bit as well.

@Captain Wicker:Was the Ubuntu install a clean or was it an upgrade?

Last edited 2012


Captain Wicker (crazy hillbilly)(Posted 2012) [#4]
Was the Ubuntu install a clean

Yep! :D


dawlane(Posted 2012) [#5]
@Captain Wicker: Which method did you use to set up the build environment for BMax and what architecture is the installation as some of the old tutorials will not work correctly for 12.04 (I've done an updated version with a little explanation of whats the difference is between the last 64bit version and the new one). I don't even know if a chroot environment will work correctly as that tutorial was created when 32bit support on a 64bit install was sketchy.


Captain Wicker (crazy hillbilly)(Posted 2012) [#6]
Which method did you use to set up the build environment for BMax

I extracted the BlitzMax folder to my desktop. Is this not right? Does BlitzMax work 'out-of-the-box' in Linux Mint? What is the difference?


dawlane(Posted 2012) [#7]
I extracted the BlitzMax folder to my desktop. Is this not right?
BMax can be extracted to any location. If you extracted it to any other place than your home folder or it's sub folders then you would have to set the file permissions. By build environment I mean all the dependencies; as I've noticed in a few other posts that you have links to some of the old tutorials for previous version of Ubuntu and by rights are out of date.
Does BlitzMax work 'out-of-the-box' in Linux Mint?
I'm not familiar with Linux Mint but as it's based on Debian and appears to use the repositories of Ubuntu so it should work out of the box (unless your using the 64bit version then more work is required look for the post BlitzMax on Ubuntu 12.04) and I have tested Linux Mint-MATE-64bit(13) in Virtual box. The only exception so far was getting sound working. As skid says getting it to work with the OSS driver is a lost cause so the ALSA driver should now be used as the default.
I got sound working by editing the freeaudio.bmx file in pub.mod/freeaudio.mod to read
?Linux
Import "-lasound"
Import "alsadevice.cpp"
'Import "ossdevice.cpp"
Extern "C"
'Function OpenOSSDevice()
Function OpenALSADevice()
End Extern

and modified the Select deviceid in the Linux section in the Function fa_Init( deviceid ) of the same file with the alteration above.
Then I renamed the file alsadevice.cpp by adding _bak to the end. I then used maxide to create a new empty file saving it as alsadevice.cpp in pub.mod/freeaudio.mod and then copying the cpp code above and pasting it to the empty file before saving it again. It was just a case of rebuilding all the modules and testing the sample.


Captain Wicker (crazy hillbilly)(Posted 2012) [#8]
On Ubuntu, is it supposed to freeze after rebuilding modules when compiling alsadevice.cpp?


dawlane(Posted 2012) [#9]
On Ubuntu, is it supposed to freeze after rebuilding modules when compiling alsadevice.cpp?
No. If I remember some else posted about this problem in skid's other topic on the pulse audio driver. Turns out they copied and pasted to the MaxIDE first and then saved it when they should have created an empty file then saved it as alsadevice.cpp and then reopening the file to do the copy and past before re-saving it.

Last edited 2012


Captain Wicker (crazy hillbilly)(Posted 2012) [#10]
It works now all of the sudden!!!! :)
I started all over with your instructions and works great! thank you so much!!!! :D


Captain Wicker (crazy hillbilly)(Posted 2012) [#11]
wanted to confirm that it is working now on Ubuntu 12.04 LTS


Richard Betson(Posted 2012) [#12]
Awesome. :)

Works on debian 6.0 squeeze i386.

Thanks,


Captain Wicker (crazy hillbilly)(Posted 2012) [#13]
Shouldn't somebody sticky this thread?


dawlane(Posted 2012) [#14]
It shouldn't need to be a sticky. It should have been added as an update.


Captain Wicker (crazy hillbilly)(Posted 2012) [#15]
It should have been added as an update.

agreed


Tachyon(Posted 2013) [#16]
When I try to rebuild the modules, I get:

Compile Error 23: fatal error: freeaudio.h: No such file or directory

It's stopping on the line:

#include "freeaudio.h"

in alsadevice.cpp


Derron(Posted 2013) [#17]
what says "locate freeaudio.h" ? do you have it somewhere in a reachable path?

bye
Ron


Brucey(Posted 2013) [#18]
freeaudio is in Pub, as far as I remember.


Tachyon(Posted 2013) [#19]
Looks like in my frustration to get sound working, I was looking in the wrong folders and altered something I shouldn't have.

Fresh BlitzMax install, followed instructions closely, sound now works fine.

Thank you, guys!


Tachyon(Posted 2013) [#20]
Oh, and what is the most favoured sound driver on Linux: ALSA, Pulse, or OpenAL?


Derron(Posted 2013) [#21]
Ubuntubased installations will use "PulseAudio".

OpenAL has to get installed first to work.

ALSA is used by older DE or ones that dislike PA.
Also you have good chances to get problems with multiple apps trying to output sound with ALSA.


bye
Ron


pmc(Posted 2013) [#22]
The module builds for me (Mint 11, 64-bit), but linking doesn't seem to work.

/usr/bin/ld: skipping incompatible /usr/lib/libasound.so when searching for -lasound
/usr/bin/ld: skipping incompatible /usr/lib/libasound.a when searching for -lasound
/usr/bin/ld: skipping incompatible /usr/lib/libasound.so when searching for -lasound
/usr/bin/ld: skipping incompatible /usr/lib/libasound.a when searching for -lasound
/usr/bin/ld: cannot find -lasound

Is this a 32-bit/64-bit problem? I have all the ALSA libraries installed including libasound2 and libasound2-dev.


dawlane(Posted 2013) [#23]
Is this a 32-bit/64-bit problem? I have all the ALSA libraries installed including libasound2 and libasound2-dev.
It always has been a problem. Even now it's still an issue for some distributions.

There are two version of any development package. One 32bit and one 64bit.
Which of these gets installed depends on which architecture you Linux OS is built for.

So on a 64bit OS, the default will be to install the 64bit version. If you need to install the 32bit version you had to add :i386 on the end (and sometime the 32bit repositories) or down load the 32bit standard library separately (libasound2:i386) or as part of the ia32-multilib package and make a link to it.

The problem is as the the repositories for Mint 11 have closed you will have to go looking for the 32bit version of libasound2. You don't need the 32bit development version as the 64bit header file should be the same in both the 32bit and 64bit.

Once you have the 32bit libasound package then you can try and force an install or extract any file with libasound.so in their name to /usr/lib32.
And if need be create a link to libasound.so.2 somewhere in your system search path to those files that were extracted.


pmc(Posted 2013) [#24]
Hey... thanks man. This taught me alot.

I went and got a copy of libasound2_1.0.24.1-0ubuntu5_i386.deb to get the lib from, but then when I checked /usr/lib32 it was already there! No need to install it. I just need to get MaxIDE to use it.

How do I update my search path so that it'll be found? LD_LIBRARY_PATH was empty so I set it to /usr/lib32 but it didn't work. If I can simply tell MaxIDE to use the the 32-bit libs and not mess with the rest of my config, that would be ideal (i.e., I don't want no trouble with the rest of my apps).

I think when I go the newest Mint -- which is very soon now that I'm starting to have package trouble -- I'm going 32-bit altogether. This isn't my first go-round with forcing architectures and disassembling packages to get the PC work.


dawlane(Posted 2013) [#25]
If the ia-32libs package is installed and the MaxIDE works then then the path is already set up.

The system search path is set to look in a number of places. Some common locations are.
/usr/bin
/usr/lib
/usr/lib32 <----- Only found on 64bit systems when any 32bit library package is installed and defined in /etc/ld.so.conf
/usr/local/bin
/usr/local/share

To add a path there are a number of ways to do it but the recommended way is to add as a variable in the hidden file .profile in the user's home directory.
e.g
PATH="$HOME/BlitzMax:$HOME/BlitzMax/bin:$PATH"
LD_LIBRARY_PATH="/usr/lib32/:$LD_LIBRARY_PATH"

The other is directly editing the PATH found in /etc/environment or one of the files in /etc/ld.so.conf.

In /usr/lib32 there should be....
libasound.a <---- This is the old static link version of the library
libasound.so <---- This is a link to libasound.so.2 (and the one that the BlitzMax compiiler is looking for).
libasound.so.2 <---- This is a link to libasound.so.2.0.0
libasound.so.2.0.0 <---- This is the shared library

libasound.la <---- This is a script used by libtool and is found in the development package. You could try and copy it over to /usr/lib32 and do a bit of editing.

My advice is...
In stead of trying to get software to work on a operating system that is no longer being supported. It would have been better spending the time and effort in just backing up all the important data to an external storage device or another partition/hard drive and doing a clean install with a later version. You could have been up and running again within a few hours.

You should only install a 64bit OS if you have more than 4GB of memory installed and would like to use it or you intend to target both 32bit and 64bit systems as it's easier to set up and test on a 64bit build environment with support of 32bit binaries than trying to build and test 64bit binaries on a 32bit system. You can build the binaries of a 32bit system but you wouldn't be able to test them.

I made it easy to set up BlitzMax on many versions of Linux (32bit and 64bit) by writing a script to handle much of the dependencies and set up installation as I got tired of doing it by hand.


pmc(Posted 2013) [#26]
Sorry for the late response dawlane.

I tried setting paths in both .profile and via a shell (and then launching MaxIDE from the command line in that shell). No go. Same error. I'll keep dorking with it when I get more time.

I will accelerate my "OS upgrade" project as you suggest, but it isn't really 3-hours. I have alot of reconfiguration work to do to restore my environment.

My PC is 8-gigs RAM. I have no need to build 64-bit binaries. Actually, my final executables are intended for Windows so my final builds will always be in Windows. I just work in Linux on a day-to-day basis and would prefer that everything work normally. I only went Linux-64bit because I figured it'd handle things better. I think I'll be better off with a 32-bit OS next time...

I appreciate your assistance. This is what I get for insisting on running as much open source software as possible. I always learn alot, but it always takes some work too...


Armitage 1982(Posted 2014) [#27]
Thanks for this patch Simon.
Some users reported weird music pitch while good SFX output but at least no more crash on this version.
Anyway the PulseAudio hack and this ALSA fix works great on my Mint 12.

I went niggling Monkeycoders to see if we could not officialize this patch (which is always better than the default one). I'm gonna get my *ss beaten, but I do not care :D
Hope it will be fixed for the next BlitzMax users at the very least.


So much troubles for just sounds...


Derron(Posted 2014) [#28]
To get that fixed you will have to directly write to Mark S. so he gets his hands on this ... else it will be hidden under dust within the next months. I had to be obstinate too to get that comments-bug fixed which lead to the latest release.

bye
Ron


skidracer(Posted 2014) [#29]
That post on monkeycoder will not make any sense to mark, you don't even link to the relevant threads.