Linux Sound - Alsa
Archives Forums/BlitzMax Bug Reports/Linux Sound - Alsa| 
 | ||
| Hi, In the last version of ubuntu, the OSS support is missing, I have tried to modify freeaudio.mod to support ALSA without results. Does anyone have the same problem ? Regards Inge | 
| 
 | ||
| Yep, it's pretty annoying. One of the users in my forum reckons this script works for him with Irukandji (one of my games): sh -c "<path to Irukandji> && padsp ./Irukandji" It's basically running the game with padsp. Cheers Charlie | 
| 
 | ||
| Yes, I did work with aoss ( ALSA wrapper for OSS applications ) , but I have a delay in sound which is annoying. | 
| 
 | ||
| I've done, BlitzMax working with alsa support. In a few minutes I will send the modifications. We need test it thoroughly to see that everything works fine. | 
| 
 | ||
| Ok Path - mod/pub.mod/freeaudio.mod alsadevice.cpp 
// 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>
#include <alsa/pcm.h>
extern "C" audiodevice *OpenALSADevice();
void *alsaaudiothread(void *dev);
#define LINUXFRAG 2048
struct alsaaudio:audiodevice{
	pthread_t	audiothread;
	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(&audiothread,&attr,alsaaudiothread,(void*)this);	
		return 0;
	}
	
	int close(){	
		int		timeout;
		running=0;
		timeout=5;
		while (timeout-- && playing) sleep(1);
		return 0;
	}
};
void *alsaaudiothread(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 0;
	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 0;
	}	
	if (snd_pcm_hw_params_set_access(fd, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
		//printf("linuxaudio failed at set access\n");
		return 0;
	}	
	
	if (snd_pcm_hw_params_set_format(fd, hwparams,SND_PCM_FORMAT_S16_LE) < 0) {
		//printf("linuxaudio failed at set format\n");
		return 0;
	}
	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 0;
		}
		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 0;
	}
	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 0;
	}
	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 0;
	}
	if (snd_pcm_hw_params(fd, hwparams) < 0) {
		//printf("linuxaudio failed at installing hw params\n");
		return 0;
	}
	//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
freeaudio.bmx Module Pub.FreeAudio ModuleInfo "Version: 1.22" ModuleInfo "Author: Simon Armstrong" ModuleInfo "License: Public Domain" ModuleInfo "Copyright: Blitz Research Ltd" ModuleInfo "Modserver: BRL" ModuleInfo "History: 1.22 Release" ModuleInfo "History: Fixed leak with sound recycling" ModuleInfo "History: 1.21 Release" ModuleInfo "History: Fixed reference counting for brl.freeaudioaudio" ModuleInfo "History: 1.20 Release" ModuleInfo "History: Removed duplication of sample memory" ModuleInfo "History: 1.19 Release" ModuleInfo "History: Added DirectSound mode" ModuleInfo "History: 1.18 Release" ModuleInfo "History: added fa_ChannelPosition for live sample generation" ModuleInfo "History: 1.17 Release" ModuleInfo "History: added check for windows playback position overflow" ModuleInfo "History: 1.15 Release" ModuleInfo "History: added low latency windows98 fix" ModuleInfo "History: 1.14 Release" ModuleInfo "History: fixed 1.13 recycling of stopped channels fix" ModuleInfo "History: 1.13 Release" ModuleInfo "History: fixed recycling of stopped channels" ModuleInfo "History: 1.12 Release" ModuleInfo "History: Uses linear interpolation for improved fidelity at low rates" ModuleInfo "History: 1.11 Release" ModuleInfo "History: Fixed freepool sounds Not resetting parameters - thanks To Fetze" ModuleInfo "History: 1.10 Release" ModuleInfo "History: Added ALSA support for Linux courtesy Craig Kiesau" ModuleInfo "History: 1.09 Release" ModuleInfo "History: Improved channel playback timing" ModuleInfo "History: 1.08 Release" ModuleInfo "History: Fixed memory leak in fa_FreeSound()" ModuleInfo "History: 1.07 Release" ModuleInfo "History: Removed output transitions for queued/paused sounds" ModuleInfo "History: 1.06 Release" ModuleInfo "History: Windows device error now silently fails" ModuleInfo "History: 1.05 Release" ModuleInfo "History: Linux version now opens audio device on second thread" ModuleInfo "History: 1.04 Release" ModuleInfo "History: Removed Linux debug output" Import "freeaudio.cpp" Import "freeaudioglue.cpp" ?Win32 Import "dsounddevice.cpp" Import "mmdevice.cpp" Extern "C" Function OpenMultiMediaDevice() Function OpenDirectSoundDevice() End Extern ?MacOS Import "-framework AudioUnit" Import "-framework AudioToolbox" Import "coreaudiodevice.cpp" Extern Function OpenCoreAudioDevice() End Extern ?Linux Import "-lasound" Import "alsadevice.cpp" Import "ossdevice.cpp" Extern "C" Function OpenOSSDevice() Function OpenALSADevice() End Extern ? Extern Const FA_CHANNELSTATUS_FREE=0 Const FA_CHANNELSTATUS_STOPPED=1 Const FA_CHANNELSTATUS_SINGLESHOT=2 Const FA_CHANNELSTATUS_LOOPING=4 Const FA_CHANNELSTATUS_STREAMING=8 Const FA_CHANNELSTATUS_PAUSED=16 Function fa_Reset( audiodevice ) Function fa_Close() Function fa_CreateSound( length,bits,channels,hertz,samples:Byte Ptr=Null,looping=False ) Function fa_WriteSound( sound,samples:Byte Ptr,length ) 'length really neceesary? Function fa_FreeSound( sound ) Function fa_AllocChannel() Function fa_FreeChannel( channel ) Function fa_PlaySound( sound,paused_flag,channel ) Function fa_StopChannel( channel ) Function fa_ChannelStatus( channel ) Function fa_ChannelPosition( channel ) Function fa_SetChannelPaused( channel,paused ) Function fa_SetChannelVolume( channel,volume# ) Function fa_SetChannelRate( channel,pitch# ) Function fa_SetChannelPan( channel,pan# ) Function fa_SetChannelDepth( channel,depth# ) End Extern Function fa_Init( deviceid ) Local device ?Win32 If deviceid device=OpenDirectSoundDevice() Else device=OpenMultiMediaDevice() EndIf ?Linux Select deviceid Case 0 device=OpenOSSDevice() Case 1 device=OpenALSADevice() EndSelect ?MacOS device=OpenCoreAudioDevice() ? Local res=-1 If device res=fa_Reset(device) Return res End Function Path - mod/brl.mod/freeaudioaudio.mod freeaudioaudio.bmx Strict Rem bbdoc: Audio/FreeAudio audio about: The FreeAudio audio module provides FreeAudio drivers for use with the #audio module. End Rem Module BRL.FreeAudioAudio ModuleInfo "Version: 1.13" ModuleInfo "Author: Mark Sibly" ModuleInfo "License: Blitz Shared Source Code" ModuleInfo "Copyright: Blitz Research Ltd" ModuleInfo "Modserver: BRL" ModuleInfo "History: 1.13 Release" ModuleInfo "History: Fixed bug in FreeChannel Playing()" ModuleInfo "History: 1.12 Release" ModuleInfo "History: Added call to fa_FreeChannel to TFreeAudioChannel destructor" ModuleInfo "History: 1.11 Release" ModuleInfo "History: Nudge" ModuleInfo "History: 1.10 Release" ModuleInfo "History: Bumped" ModuleInfo "History: 1.08 Release" ModuleInfo "History: Added src sample reference to TFreeAudioSound" ModuleInfo "History: Channel playing now returns sample playback position" ModuleInfo "History: 1.07 Release" ModuleInfo "History: Added DirectSound driver" ModuleInfo "History: 1.06 Release" ModuleInfo "History: Added Method TFreeAudioChannel.Position" ModuleInfo "History: 1.05 Release" ModuleInfo "History: Mono and 8 bit sample support added" Import BRL.Audio Import Pub.FreeAudio Import Pub.DirectX Private Const CLOG=False Public Type TFreeAudioSound Extends TSound Field fa_sound Method Delete() fa_FreeSound fa_sound If CLOG WriteStdout "Deleted FreeAudio sound "+fa_sound+"~n" End Method Method Play:TFreeAudioChannel( alloced_channel:TChannel ) Local channel:TFreeAudioChannel,fa_channel If alloced_channel channel=TFreeAudioChannel( alloced_channel ) If Not channel Return fa_channel=channel.fa_channel EndIf fa_channel=fa_PlaySound(fa_sound,False,fa_channel) If Not fa_channel Return If channel And channel.fa_channel=fa_channel Return channel Return TFreeAudioChannel.CreateWithChannel( fa_channel ) End Method Method Cue:TFreeAudioChannel( alloced_channel:TChannel ) Local channel:TFreeAudioChannel,fa_channel If alloced_channel channel=TFreeAudioChannel( alloced_channel ) If Not channel Return fa_channel=channel.fa_channel EndIf fa_channel=fa_PlaySound( fa_sound,True,fa_channel ) If Not fa_channel Return If channel And channel.fa_channel=fa_channel Return channel Return TFreeAudioChannel.CreateWithChannel( fa_channel ) End Method Function CreateWithSound:TFreeAudioSound( fa_sound,src:TAudioSample ) Local t:TFreeAudioSound=New TFreeAudioSound t.fa_sound=fa_sound ' t.src=src Return t End Function End Type Type TFreeAudioChannel Extends TChannel Field fa_channel Method Delete() If fa_channel fa_FreeChannel fa_channel End Method Method Stop() fa_StopChannel fa_channel fa_channel=0 End Method Method SetPaused( paused ) fa_SetChannelPaused fa_channel,paused End Method Method SetVolume( volume# ) fa_SetChannelVolume fa_channel,volume End Method Method SetPan( pan# ) fa_SetChannelPan fa_channel,pan End Method Method SetDepth( depth# ) fa_SetChannelDepth fa_channel,depth End Method Method SetRate( rate# ) fa_SetChannelRate fa_channel,rate End Method Method Playing() Local status=fa_ChannelStatus( fa_channel ) If status=FA_CHANNELSTATUS_FREE Return False If status&FA_CHANNELSTATUS_STOPPED Return False If status&FA_CHANNELSTATUS_PAUSED Return False Return True End Method Method Position() Return fa_ChannelPosition( fa_channel ) End Method Function CreateWithChannel:TFreeAudioChannel( fa_channel ) Local t:TFreeAudioChannel=New TFreeAudioChannel t.fa_channel=fa_channel Return t End Function End Type Type TFreeAudioAudioDriver Extends TAudioDriver Method Name$() Return _name End Method Method Startup() If _mode<>-1 Return fa_Init( _mode )<>-1 If fa_Init( 0 )<>-1 Return True ?Win32 Return fa_Init( 1 )<>-1 ? End Method Method Shutdown() fa_Close End Method Method CreateSound:TFreeAudioSound( sample:TAudioSample,flags ) Local channels,bits Select sample.format ?BigEndian Case SF_MONO16LE sample=sample.Convert(SF_MONO16BE) Case SF_STEREO16LE sample=sample.Convert(SF_STEREO16BE) ?LittleEndian Case SF_MONO16BE sample=sample.Convert(SF_MONO16LE) Case SF_STEREO16BE sample=sample.Convert(SF_STEREO16LE) ? End Select Local loop_flag If (flags & 1) loop_flag=-1 channels=ChannelsPerSample[sample.format] If Not channels Return bits=8*BytesPerSample[sample.format]/channels Local fa_sound=fa_CreateSound( sample.length,bits,channels,sample.hertz,sample.samples,loop_flag ) If CLOG WriteStdout "Generated FreeAudio sound "+fa_sound+"~n" Return TFreeAudioSound.CreateWithSound( fa_sound,sample ) End Method Method AllocChannel:TFreeAudioChannel() Local fa_channel=fa_AllocChannel() If fa_channel Return TFreeAudioChannel.CreateWithChannel( fa_channel ) End Method Function Create:TFreeAudioAudioDriver( name$,mode ) Local t:TFreeAudioAudioDriver=New TFreeAudioAudioDriver t._name=name t._mode=mode Return t End Function Field _name$,_mode End Type ?Win32 If DirectSoundCreate TFreeAudioAudioDriver.Create "FreeAudio DirectSound",1 TFreeAudioAudioDriver.Create "FreeAudio Multimedia",0 ?MacOS TFreeAudioAudioDriver.Create "FreeAudio CoreAudio",0 ?Linux ' TFreeAudioAudioDriver.Create "FreeAudio OpenSound System",0 TFreeAudioAudioDriver.Create "FreeAudio ALSA System",1 ? TFreeAudioAudioDriver.Create "FreeAudio",-1 | 
| 
 | ||
| Cool! I'll try to get a chance to look at this over the weekend. What exactly were the changes? Cheers Charlie | 
| 
 | ||
| I have tried this and numerous other posts but still do not have sound with any of my blitzmax applications. I have ubuntu 10.10. Maybe it is this computer? I had another computer with Ubuntu installed, and it worked fine. When I switched computers, it stopped working. I have tried installing all the packages, and this mod. Any other ideas? |