OAL/DS MaxMod Beta Test

BlitzMax Forums/BlitzMax Programming/OAL/DS MaxMod Beta Test

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Guys,

For those interested in the SidPlay streaming, I updated the wrapper to work with v1.22. Copy the following into your Sid.Mod/SidStream.Mod folder:

Sidstream.bmx
SuperStrict 

Rem
bbdoc: SID Stream for MaxMod
End Rem
Module SID.SIDStream

ModuleInfo "Version: 1.05"
ModuleInfo "Name: SID.SIDStream"
ModuleInfo "Description: MaxMod SID streaming player"
ModuleInfo "License: GPL (libsidplay2 is GPL)"
ModuleInfo "Author: gman"
ModuleInfo "Credit: REDi, author of MaxMod (http://www.redi.me.uk/forum/index.php)"
ModuleInfo "History: 2006/7/16 - GG Initial Release"
ModuleInfo "History: 2006/8/1 - REDi Updated for MaxMod v1.9"
ModuleInfo "History: 2006/8/29 - Updated for MaxMod v1.10 by Matt Smith (thank you)"
ModuleInfo "History: 2006/9/5 - Updated for MaxMod v1.11 by REDi (thank you)"
ModuleInfo "History: 2006/10/19 - Recompiled for MaxMod v1.15"
ModuleInfo "History: 2007/02/19 - Recompiled for MaxMod v1.16 by REDi"
ModuleInfo "History: 2008/01/26 - Added Sid for MaxMod v1.22+ by Matt Smith"

Import MAXMOD.AudioStream
Import SID.SIDPlay
Import BRL.Audio

Private
' This adds it to the MaxMod Loader
MaxModLoader.Create(MaxMod_Loader_SID,"SID ~q.sid~q","sid")
Function MaxMod_Loader_SID:TMusic(File:String)
	Local SID:TMusic = SIDStream.Load(File)
	Return SID
EndFunction

Rem
bbdoc: SIDStream (Private - access SidAudioStream instead)
End Rem
Type SIDStream Extends TMusic

	' SIDPlayer pointers
	Field resid:Byte Ptr
	Field tune:Byte Ptr
	Field player:Byte Ptr
	
	Field Track:Short
	Field Bits:Short
	Field Channels:Short
	Field clockSpeed:Int

	Rem
	bbdoc: Loads a SID file and returns an audio sample for playback
	returns: an instance of TAudioSample
	about: Filename => path and name of file to load<BR>
	Track => the track within the file to return a sample for<BR>
	Rate => sample rate to play the sample at<BR>
	format => sample format<BR>
	clockSpeed => SID sample playback clock speed
	EndRem						
	Function Load:SIDStream(FileName:String, Track:Short=1, Rate:Int=44100, format:Int=MM_STEREO16, clockSpeed:Int=SID2_CLOCK_PAL)
			
		Local file:Byte[]=LoadByteArray(FileName)

		Local This:SIDStream = New SIDStream
		
		' make sure we have the file
		If file
			This.clockSpeed=clockSpeed
			
			' load the SID file into the tune
			This.tune=createSidTune()			
			
			If Not This.tune Then RuntimeError "SIDStream.Load(): Unable to create SidTune"
			
			If Not SidTune_Read(This.tune,file,file.length) Then RuntimeError "SIDStream.Load(): Unable To load "+FileName
			file=Null
					
			' select the track within the SID file
			If Not This.SelectTrack(Track) Then RuntimeError "SIDStream.Load(): Unable to select track "+Track
										
			This.channels=sid2_mono
			If format=MM_STEREO8 Or format=MM_STEREO16 Then This.channels=sid2_stereo
		
			' bump down to mono if the sample is mono	
			If This.channels=MM_STEREO8 And Not SidTune_IsStereo(This.tune)
				Select format
					Case MM_STEREO8
						format=MM_MONO8
					Case MM_STEREO16
						format=MM_MONO16
				EndSelect
				This.channels=sid2_mono
			EndIf
			
			This.bits=8
			If format<>MM_MONO8 And format<>MM_STEREO8 Then This.bits=16
		 
			This.STREAM_FORMAT=format
			This.Sample_Rate=Rate
			This.bits=16
		
			' create the ReSIDBuilder
			This.resid=createReSIDBuilder("MaxMod Load SID")
			If Not This.resid Then RuntimeError "SIDStream.Load(): Unable to create ReSIDBuilder"
										
			' create the player for decoding
			This.player=createSidPlay2(This.resid)
			
			' set the player options
			If Not SidPlay2_SetFrequency(This.player,rate) Then RuntimeError "SIDStream.Load(): Unable to set rate "+rate
			If Not SidPlay2_SetBits(This.player,This.bits) Then RuntimeError "SIDStream.Load(): Unable to set bits "+This.bits
			If Not SidPlay2_SetPlayback(This.player,This.channels) Then RuntimeError "SIDStream.Load(): Unable to set format "+format
			If Not SidPlay2_SetClockSpeed(This.player,This.clockSpeed) Then RuntimeError "SIDStream.Load(): Unable to set clockSpeed "+This.clockSpeed
			
			' load the tune into the player
			If SidPlay2_Load(This.player,This.tune)<>0 Then RuntimeError "SIDStream.Load(): Unable to load tune into the player"
			
			Return This					
		Else
			Return Null		
		EndIf	
	EndFunction
	
	Method Play()
		'SidPlay2_Load(player,tune)
		SidPlay2_Play(player,tune,0)
	
	End Method

	Method Stop()
		SidPlay2_Load(player,tune)

	EndMethod

	Rem
	bbdoc: Returns the current track being played
	End Rem
	Method CurrentTrack:Short()
		Return Track
	EndMethod

	Rem
	bbdoc: Returns the total tracks within the SID
	End Rem
	Method GetTrackCount:Short()
		Return SidTuneInfo_songs(SidTune_getInfo(tune))
	EndMethod

	Rem
	bbdoc: Selects a track within the SID to play
	returns: True if successful
	End Rem
	Method SelectTrack:Int(track:Short=1)
		' select the track within the SID file
		Local playing:Int
		If PlayStatus = True Then playing = True
		If SidTune_SelectSong(tune,track)=track Then 
'			If playing Then Stop
			SidPlay2_Load(player,tune)
			Self.Track=track
'			If playing Then Play
			Return True
		Else
			Return False
		EndIf
	EndMethod

	Method Delete()
		' cleanup the libsidplay objects
		deleteSidPlay2(player)
		deleteSidTune(tune)
		deleteReSIDBuilder(resid)	
	EndMethod
	
	' this method gets called when the buffer needs filling
	Method FillBuffer(SoundData:Int,Length:Int)
		If Not Length Return
		Global count:Int
		If Not SidPlay2_Play(player,Short Ptr(SoundData),Length) Then RuntimeError "SIDStream.FillBuffer(): Unable to process sample data"
		count:+Length												
	EndMethod
	
EndType

'Internal properties
Global myStream:SIDStream	
Global myChannel:TChannel
Global paused:Byte

Public
Rem
bbdoc: SidAudioStream
about: A wrapper of the REDi's MaxMod 1.22+ Streamer to play c64 SIDs via gman's SidPlay module.
End Rem
Type SidAudioStream
	
	Rem
	bbdoc: A wrapper to load and play SID files
	returns: status of load
	about: filename => path and name of file to load<BR>
	track => the track within the SID to play<BR>
	playOnLoad => automatically starts the track once sid is loaded
	hertz => audio playback hertz<BR>
	volume => audio playback volume<BR>
	EndRem						
	Method Load:Byte(filename:String,track:Short=1,playOnLoad:Byte=True,volume:Float=1.0,hertz:Float=1.0)
		'Load music and prepare to stream it
		myStream = SIDStream(LoadMusic(filename))
		If (myStream)
			'Validate track and select
			If (track < 1 Or track > GetTrackCount()) Then track = 1
			
			'Load channel (stop for now)
			myChannel = CreateAudioStream(myStream)
			Stop()
			
			'Set other properties
			SetHertz(hertz)
			SetVolume(volume)

			'Select track and play
			SelectTrack(track)
			If (playOnLoad) Then Play()

			'Success
			Return True
			
		Else
			'Failure
			Return False
			
		End If
		
	End Method
	
	Rem
	bbdoc: Plays the current track
	End Rem
	Method Play()
		'Is player paused?, if restart and exit
		If (paused) Then
			myChannel.SetPaused(False)
			Return
			
		End If
		
		'Is channel already playing?, if so exit
		If (myChannel.Playing()) Then Return

		'Start current track
		myChannel = CreateAudioStream(myStream)
		paused = False
		
	End Method
	
	Rem
	bbdoc: Stops the current track
	End Rem
	Method Stop()
		myStream.Stop
		myChannel.Stop
		paused = False
		
	End Method
	
	Rem
	bbdoc: Pauses the current track
	End Rem
	Method Pause()
		myChannel.SetPaused(True)
		paused = True

	End Method
	
	rem
	bbdoc: Restarts the current track from the beginning
	end rem
	Method Restart()
		Stop()
		Play()
		
	End Method
	
	rem
	bbdoc: Determines if the current track is paused 
	endrem
	Method IsPaused:Byte()
		Return paused
		
	End Method
	
	Rem
	bbdoc: Returns the total tracks within the SID
	End Rem
	Method GetTrackCount:Short()
		Return myStream.GetTrackCount()
		
	End Method
	
	Rem
	bbdoc: Returns the current track being played
	End Rem
	Method CurrentTrack:Short()
		Return myStream.CurrentTrack()
		
	End Method
	
	Rem
	bbdoc: Selects a track within the SID to play
	returns: True if successful
	End Rem
	Method SelectTrack:Int(track:Short=1)
		Return myStream.SelectTrack(track)
		
	End Method
	
	Rem
	bbdoc: Sets SID audio playback hertz
	End Rem
	Method SetHertz(Hertz:Float)
		myChannel.SetRate(Hertz)
		
	End Method
	
	Rem
	bbdoc: Sets SID audio playback volume
	End Rem
	Method SetVolume(Volume:Float)
		myChannel.SetVolume(Volume)
		
	End Method
	
	Rem
	bbdoc: Disposes the Audio object
	End Rem
	Method Dispose()
		'Free sid channel
		myChannel.Stop
		myChannel = Null
		
		'Free sid stream
		myStream.Free()
		myStream = Null
		
	End Method
	
EndType



The following example shows you how to use the mod:
' load.bmx

Strict 
Framework BRL.GLMax2D 
Import SID.SIDStream
Graphics 800,600,0 

'Set audio driver
'SetAudioDriver("DirectSound")

'Create sid audio stream object
Local sas:SidAudioStream = New SidAudioStream
sas.Load(RequestFile("Load a sid file"))

Local Pitch# = 1
Repeat 

	Cls 
	DrawText "  ESCAPE = Exit",5,5
	DrawText "   SPACE = Play",5,20
	DrawText "       S = Stop",5,35
	DrawText "       R = Restart",5,50
	DrawText "       P = Pause",5,65
	DrawText " UP/DOWN = Pitch",5,80
	
	DrawText "   PITCH = "+Pitch,5,125

	DrawText "TOTAL TRACKS = "+sas.GetTrackCount(),5,170
	DrawText "       TRACK = "+sas.CurrentTrack(),5,185
	DrawText "  LEFT/RIGHT = Select Track",5,200
	
	If KeyHit(KEY_S) 	 Then sas.Stop()
	If KeyHit(KEY_SPACE) Then sas.Play()
	If KeyHit(KEY_P) 	 Then sas.Pause()
	If KeyHit(KEY_R) 	 Then sas.Restart()
	If KeyDown(KEY_UP)	 Then Pitch:+0.001 ; sas.SetHertz(Pitch)
	If KeyDown(KEY_DOWN) Then Pitch:-0.001 ; sas.SetHertz(Pitch)
	If KeyHit(KEY_LEFT)  Then sas.SelectTrack(sas.CurrentTrack()-1)
	If KeyHit(KEY_RIGHT) Then sas.SelectTrack(sas.CurrentTrack()+1)

	Flip True
	
Until KeyDown(KEY_ESCAPE)

'Tidyup
sas.Dispose()
End



Thanks again to REDi and GMan for the original mods.