OGG audio sample loader for use with OpenAL library

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Axeman
User
User
Posts: 40
Joined: Mon Nov 03, 2003 5:34 am

OGG audio sample loader for use with OpenAL library

Post by Axeman »

It would be great if PureBasic had functionality added for loading an OpenAL compatible audio sample as a mono file using the supported audio formats in PureBasic (OGG, etc).

An example of what I'm talking about can be found in the 'LoadAudioSample()' function from BlitzMax ( https://blitzmax.org/ ). The source code for the audio sample library is available in the BlitzMax IDE's help files at: Projects > Modules Source > brl.mod > audiosample.mod

The reason that I'd like this is that I have an old OpenAL wrapper library for BlitzMax and the MiniB3D renderer that I'm currently attempting to port to PureBasic (since PureBasic's 3D sound library is utterly useless).

I already have fully tested code to setup OpenAL and have ported some of my BlitzMax code, but I've hit a snag with the sound loader functionality. It relies on the audio sample library function 'LoadAudioSample()' from BlitzMax to provide an audio sample to pass to OpenAL. It also makes use of the audio sample object's 'Convert' method and 'format' field to convert stereo formats to mono.

Here's an example from my BlizMax code showing how the 'LoadAudioSample()' function, the 'Convert' method, and the 'format' field are used when loading an audio sample and passing it to OpenAL.

Code: Select all

Function Load:T3DSound( filepath_:String, reuse_existing_sound:Int = False )
		' Loads a sound intended for playback with 3D positioning.
		' The 'filepath' parameter should be the string filepath of the sound file to be loaded.
		' The 'reuse_existing_sound' determines whether an existing sound object is reused if the filepath matches
		' the path of an already loaded sound file. True = Re-use. False = Don't re-use (default).
		' Note that if 'reuse_existing_sound' is set to True then the sound object will be locked and must be unlocked before
		' it can be freed.
		' Returns a T3DSound object, or a Null value if the sound file could not be loaded.
		' Note that only mono sounds should be used for 3D sounds. Other formats will be converted to mono automatically.
				
		Local sound:T3DSound
		
		If reuse_existing_sound Then sound = T3DSound( MapValueForKey( T3DSound.map, filepath_ )	)
		
		' Load a new sound if an existing one is not being re-used.
		If sound = Null
		
			Local sample:TAudioSample
			Local alfmt:Int
			sample = LoadAudioSample( filepath_ )
			
			' Return a Null value if the sound could not be loaded.
			If Not sample Return Null
			
			' Create a new T3DSound object.
			sound = New T3DSound
			If T3DSound.ALContext Then alGenBuffers 1, Varptr sound.buffer
			sound.link = ListAddLast:TLink( T3DSound.list, sound )
			
			' Check if the sound needs converting to a mono format and convert it if necessary.
			Select sample.format
				Case SF_MONO8
					alfmt=AL_FORMAT_MONO8
				Case SF_MONO16LE
					alfmt=AL_FORMAT_MONO16
					?BigEndian
						sample=sample.Convert( SF_MONO16BE )
					?
				Case SF_MONO16BE
					alfmt=AL_FORMAT_MONO16
					?LittleEndian
						sample=sample.Convert( SF_MONO16LE )
					?
				Case SF_STEREO8
					alfmt=AL_FORMAT_STEREO8
				Case SF_STEREO16LE
					alfmt=AL_FORMAT_STEREO16
					?BigEndian
						sample=sample.Convert( SF_STEREO16BE )
					?
				Case SF_STEREO16BE
					alfmt=AL_FORMAT_STEREO16
					?LittleEndian
						sample=sample.Convert( SF_STEREO16LE )
					?
			End Select
		
			' Store the audio data in a buffer.
			alBufferData sound.buffer, alfmt, sample.samples, sample.length * BytesPerSample[ sample.format ], sample.hertz
		
			' Add the sound object pointer to the T3DSound map with the filepath acting as the key.
			MapInsert( T3DSound.map, filepath_, sound )
			
			' Store the filepath so that it can be used as a map key when this object is removed from the sound hashmap.
			sound.filepath = filepath_
		
		EndIf
		
		' Lock the sound if sound resources are being actively managed.
		If reuse_existing_sound Then sound.Lock()
		
		Return sound
End Function
User avatar
Keya
Addict
Addict
Posts: 1828
Joined: Thu Jun 04, 2015 7:10 am

Re: OGG audio sample loader for use with OpenAL library

Post by Keya »

It seems you're already aware of this and just not happy with it for some reason, but just in case you're not, Purebasic already has an OGG decoder, see UseOGGSoundDecoder()
Axeman
User
User
Posts: 40
Joined: Mon Nov 03, 2003 5:34 am

Re: OGG audio sample loader for use with OpenAL library

Post by Axeman »

Hi Keya. The UseOGGSoundDecoder() function just enables the use of the OGG codec when loading sound files. What I need is a function for loading a sound file that also provides an address for the sound buffer, the size of the data in the sound buffer, an ID for the sound format (for conversion to mono), and a function to convert from one format (stereo) to another (mono). You can see an example usage in the BlitzMax code that I added to my original post.

Basically I need similar functionality to what BlitMax provides in its audio samples mod library, so that I can pass the sound data to OpenAL.

I can probably do the conversion stuff myself using the BlitMax audio sample code as a reference, which means that I just need to get the sound buffer address, the buffer size, and the sound format ID.
Post Reply