Code archives/Audio/aSound.bb
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| Here is a library I've written for my actual project. In fact, I've needed an easy way to pause a group of sounds without stopping the background music (game pause) and to resume all sounds after. I think this library should help a lot in certain situations and I will surely expand it in the future. If you think it missed inportant functions or have an idea on how to complete this library, explain... Copy then paste this code in a new Blitz document then save as "aSound.bb". Then you'll just have to include this file in your projects. (all functions are hopefully documented) Original page: http://www.kochonet.com/thok/articles.php?lng=en&pg=74 | |||||
; aSound.bb : Advanced Sound Functions for Blitz
; by kochOn - www.kochonet.com
;-----------------------------------------------------------------------------------------------------
; This library exists cause I think there is a lack in Blitz Sound Functions.
; Those functions mainly load sounds with a single channel assigned and let the
; user defining groups of sounds (facility to stop, pause and resume several sounds
; at a time).
Type tASND
Field copy%
Field sound%, channel%, group%
Field vol#, pan#
Field pitched%, pitch%
Field basefreq%, freq%, fscale#
End Type
; aSound_Load%(file$, loop% = False, group% = 0)
;-----------------------------------------------------------------------------------------------------
; Load a sound file in memory
;-----------------------------------------------------------------------------------------------------
; file$ : all accepted blitz sound files
; loop% : optional looping mode (defaut = False)
; group% : optional group (default = 0)
Function aSound_Load%(file$, loop% = False, group% = 0)
Local asnd.tASND = New tASND
asnd\sound = LoadSound(file$)
If asnd\sound = 0 Then Return False
If loop = True Then LoopSound(asnd\sound)
asnd\copy = 0
asnd\group = group
asnd\vol = 1
asnd\pan = 0
asnd\pitched = False
asnd\pitch = 0
asnd\basefreq = False
asnd\freq = 0
asnd\fscale = 1
Return Handle(asnd)
End Function
; aSound_Copy%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Copy a sound previously loaded with aSound_Load
; The copy keep the original behaviors (looping mode, group, volume, panning, pitching, base frequence
; and frequence scaling)
; Use the aSound_Update function to destroy all copies of a deleted sound
; You can copy another copy but each won't work when the parent or the base sound will be deleted
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Copy%(hsnd%)
Local copy.tASND
Local asnd.tASND
Local tmp.tASND
copy = Object.tASND(hsnd)
If copy = Null Then Return False
tmp = copy
While copy\copy <> 0
copy = Object.tASND(copy\copy)
If copy = Null Then Return False
Wend
asnd = New tASND
asnd\copy = Handle(copy)
asnd\sound = 0
asnd\group = tmp\group
asnd\vol = tmp\vol
asnd\pan = tmp\pan
asnd\pitched = tmp\pitched
asnd\pitch = tmp\pitch
asnd\basefreq = tmp\basefreq
asnd\freq = tmp\freq
asnd\fscale = tmp\fscale
Return Handle(asnd)
End Function
; aSound_Replace%(hsnd%, file$, loop% = False)
;-----------------------------------------------------------------------------------------------------
; Replace a previously loaded sound with another sound file (won't work with a copy)
; All modifications made with this sound remains and only the sound file change as for the looping
; mode
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound
; file$ : all accepted blitz sound files
; loop% : optional looping mode for the replacing sound (defaut = False)
Function aSound_Replace%(hsnd%, file$, loop% = False)
Local asnd.tASND, tmp%
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If asnd\copy <> 0 Then Return False
tmp = LoadSound(file$)
If tmp = 0 Then Return False
FreeSound(asnd\sound)
asnd\sound = tmp
If loop = True Then LoopSound(asnd\sound)
Return True
End Function
; aSound_Play%(hsnd%, override% = False)
;-----------------------------------------------------------------------------------------------------
; Play a sound like the original Blitz function but only one at a time. If a sound is already playing
; nothing will happen.
; You can override a playing sound which will stop and replay from the start (no multiple same sounds
; until you make a copy)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; override% : restart the sound on its own channel (default = False)
Function aSound_Play%(hsnd%, override% = False)
Local copy.tASND
Local asnd.tASND
Local tmp%
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If asnd\copy <> 0 Then
copy = Object.tASND(asnd\copy)
If copy = Null Then Return False
tmp = copy\sound
Else
tmp = asnd\sound
EndIf
If override = True Then
If ChannelPlaying(asnd\channel) = True Then StopChannel(asnd\channel)
EndIf
If ChannelPlaying(asnd\channel) = False Then
asnd\channel = PlaySound(tmp)
ChannelVolume(asnd\channel, asnd\vol)
ChannelPan(asnd\channel, asnd\pan)
If asnd\pitched = True Then
ChannelPitch(asnd\channel, asnd\pitch)
EndIf
EndIf
Return True
End Function
; aSound_Volume%(hsnd%, vol#)
;-----------------------------------------------------------------------------------------------------
; Set the volume of a sound (the volume will stay the same until a new aSound_Volume command)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; vol# : the desired amount of volume (0 = min, 1 = max)
Function aSound_Volume%(hsnd%, vol#)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
asnd\vol = vol
ChannelVolume(asnd\channel, vol)
Return True
End Function
; aSound_Pan%(hsnd%, pan#)
;-----------------------------------------------------------------------------------------------------
; Set the panning of a sound (the panning will stay the same until a new aSound_Pan command)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; pan# : the desired panning level (-1 = left, 0 = middle, 1 = right)
Function aSound_Pan%(hsnd%, pan#)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
asnd\pan = pan
ChannelPan(asnd\channel, pan)
Return True
End Function
; aSound_Pitch%(hsnd%, pitch%)
;-----------------------------------------------------------------------------------------------------
; Set the Pitch of a sound (the frequence will stay the same until a new aSound_Pitch command)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; pitch# : the desired frequence (11025, ..., 22050, ..., 44100, ...)
Function aSound_Pitch%(hsnd%, pitch%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
asnd\pitched = True
asnd\pitch = pitch
asnd\fscale = 1
ChannelPitch(asnd\channel, pitch)
Return True
End Function
; aSound_Playing%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Useful to know if a sound is playing (playing = True)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Playing%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
Return ChannelPlaying(asnd\channel)
End Function
; aSound_Stop%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Stop a playing sound
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Stop%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If ChannelPlaying(asnd\channel) Then StopChannel(asnd\channel)
Return True
End Function
; aSound_Pause%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Pause a playing sound (use aSound_Resume to restart the sound from where it has been paused)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Pause%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If ChannelPlaying(asnd\channel) Then PauseChannel(asnd\channel)
Return True
End Function
; aSound_Resume%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Resume a previously paused sound
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Resume%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
ResumeChannel(asnd\channel)
Return True
End Function
; aSound_StopGroup(group%)
;-----------------------------------------------------------------------------------------------------
; Same as aSound_Stop but works for a group of sound
;-----------------------------------------------------------------------------------------------------
; group% : group of sounds to be stopped
Function aSound_StopGroup(group%)
Local asnd.tASND
For asnd = Each tASND
If asnd\group = group Then
If ChannelPlaying(asnd\channel) Then
StopChannel(asnd\channel)
EndIf
EndIf
Next
End Function
; aSound_PauseGroup(group%)
;-----------------------------------------------------------------------------------------------------
; Same as aSound_Pause but works for a group of sound
;-----------------------------------------------------------------------------------------------------
; group% : group of sounds to be paused
Function aSound_PauseGroup(group%)
Local asnd.tASND
For asnd = Each tASND
If asnd\group = group Then
If ChannelPlaying(asnd\channel) Then
PauseChannel(asnd\channel)
EndIf
EndIf
Next
End Function
; aSound_ResumeGroup(group%)
;-----------------------------------------------------------------------------------------------------
; Same as aSound_Resume but works for a group of sound
;-----------------------------------------------------------------------------------------------------
; group% : group of sounds to be resumed
Function aSound_ResumeGroup(group%)
Local asnd.tASND
For asnd = Each tASND
If asnd\group = group Then
ResumeChannel(asnd\channel)
EndIf
Next
End Function
; aSound_StopAll()
;-----------------------------------------------------------------------------------------------------
; Stop all playing sounds
;-----------------------------------------------------------------------------------------------------
Function aSound_StopAll()
Local asnd.tASND
For asnd = Each tASND
If ChannelPlaying(asnd\channel) Then
StopChannel(asnd\channel)
EndIf
Next
End Function
; aSound_PauseAll()
;-----------------------------------------------------------------------------------------------------
; Pause all playing sounds
;-----------------------------------------------------------------------------------------------------
Function aSound_PauseAll()
Local asnd.tASND
For asnd = Each tASND
If ChannelPlaying(asnd\channel) Then
PauseChannel(asnd\channel)
EndIf
Next
End Function
; aSound_ResumeAll()
;-----------------------------------------------------------------------------------------------------
; Resume all previously paused sounds
;-----------------------------------------------------------------------------------------------------
Function aSound_ResumeAll()
Local asnd.tASND
For asnd = Each tASND
ResumeChannel(asnd\channel)
Next
End Function
; aSound_Free%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Free a sound from the memory
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Free%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If asnd\copy = 0 Then FreeSound(asnd\sound)
Delete asnd
Return True
End Function
; aSound_FreeGroup(group%)
;-----------------------------------------------------------------------------------------------------
; Free a group of sounds from the memory
;-----------------------------------------------------------------------------------------------------
; group% : group of sounds to be deleted
Function aSound_FreeGroup(group%)
Local asnd.tASND
For asnd = Each tASND
If asnd\group = group Then
If asnd\copy = 0 Then FreeSound(asnd\sound)
Delete asnd
EndIf
Next
End Function
; aSound_FreeAll(group%)
;-----------------------------------------------------------------------------------------------------
; Free all sounds from the memory
;-----------------------------------------------------------------------------------------------------
Function aSound_FreeAll()
Local asnd.tASND
For asnd = Each tASND
If asnd\copy = 0 Then FreeSound(asnd\sound)
Delete asnd
Next
End Function
; aSound_BaseFreq%(hsnd%, freq%)
;-----------------------------------------------------------------------------------------------------
; As the Blitz LoadSound Function do not permit to know the base frequence of a sample, this is a
; a useful function to set it by yourself.
; Then you could use The aSound_PitchB command which use a scalling factor instead of a pitch
; frequence
; Note that it's important to know and set the good frequence of a sample to avoid surprises
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; freq% : known base frequence of the sample
Function aSound_BaseFreq%(hsnd%, freq%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
asnd\basefreq = True
asnd\freq = freq
asnd\pitched = True
asnd\pitch = Float(freq) * asnd\fscale
ChannelPitch(asnd\channel, freq)
Return True
End Function
; aSound_PitchB%(hsnd%, scale#)
;-----------------------------------------------------------------------------------------------------
; Pitch a sound, which the base frequence has been set, by a scalling factor
; The result is set as the pitch frequence
; Note that using the normal aSound_Pitch command will reset the scalling factor
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; scale# : a scalling factor (2 = base frequence * 2, 0.5 = base frequence / 2)
Function aSound_PitchB%(hsnd%, scale#)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If asnd\basefreq = False Then Return False
asnd\fscale = scale
asnd\pitched = True
asnd\pitch = Float(asnd\freq) * asnd\fscale
ChannelPitch(asnd\channel, asnd\pitch)
Return True
End Function
; aSound_Reset%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Reset all properties of a sound or copy execept for the looping mode
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Reset%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
If ChannelPlaying(asnd\channel) = True Then StopChannel(asnd\channel)
asnd\vol = 1
asnd\pan = 0
asnd\pitched = False
asnd\pitch = 0
asnd\basefreq = False
asnd\freq = 0
asnd\fscale = 1
End Function
; aSound_Update()
;-----------------------------------------------------------------------------------------------------
; Necessary to automatically kill copies depending of a sound or copy that has been deleted
; You can use it in a loop or at the end of a program after the base sounds have been deleted
; Forget it if you don't use sound copies
;-----------------------------------------------------------------------------------------------------
Function aSound_Update()
Local src.tASND
Local asnd.tASND
For asnd = Each tASND
If asnd\copy <> 0 Then
src = Object.tASND(asnd\copy)
If src = Null Then
Delete asnd
EndIf
EndIf
Next
End Function
; aSound_Group%(hsnd%, group%)
;-----------------------------------------------------------------------------------------------------
; Let you set a new or existing group for a sound
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
; group% : new or existing group to assign the sound (can be any positive or negative integer value)
Function aSound_Group%(hsnd%, group%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False
asnd\group = group
Return True
End Function
; aSound_GetVolume$(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Return a string containing the sound volume or "Null" if the sound doesn't exist
; The result should be converted into a float value
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_GetVolume$(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return "Null"
Return Str$(asnd\vol)
End Function
; aSound_GetPan$(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Return a string containing the sound panning level or "Null" if the sound doesn't exist
; The result should be converted into a float value
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_GetPan$(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return "Null"
Return Str$(asnd\pan)
End Function
; aSound_GetPitch$(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Return a string containing the sound pitching frequence or "Null" if the sound doesn't exist
; The result should be converted into an integer value
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_GetPitch$(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return "Null"
If asnd\pitched = False Then Return "Undefined"
Return Str$(asnd\pitch)
End Function
; aSound_GetBaseFreq$(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Return a string containing the sound base frequence, "undefined" or "Null" if the sound doesn't
; exist
; The result should be converted into an integer value
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_GetBaseFreq$(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return "Null"
If asnd\basefreq = False Then Return "Undefined"
Return Str$(asnd\freq)
End Function
; aSound_GetPitchB$(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Return a string containing the sound scalling factor or "Null" if the sound doesn't exists
; The result should be converted into a float value
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_GetPitchB$(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return "Null"
Return Str$(asnd\fscale)
End Function
; aSound_Exists%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Return True if the sound exists False otherwise
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Exists%(hsnd%)
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then Return False Else Return True
End Function
; aSound_Count%()
;-----------------------------------------------------------------------------------------------------
; Return the number of existing sounds after killing unused copies
;-----------------------------------------------------------------------------------------------------
Function aSound_Count%()
Local src.tASND
Local asnd.tASND
Local nb% = 0
For asnd = Each tASND
If asnd\copy <> 0 Then
src = Object.tASND(asnd\copy)
If src = Null Then
Delete asnd
Else
nb = nb + 1
EndIf
Else
nb = nb + 1
EndIf
Next
Return nb
End Function
; aSound_Debug%(hsnd%)
;-----------------------------------------------------------------------------------------------------
; Show properties of a sound in the Debug Window (Debug Mode)
;-----------------------------------------------------------------------------------------------------
; hsnd% : handle of a previously loaded sound or copy
Function aSound_Debug%(hsnd%)
Local src.tASND
Local asnd.tASND
asnd = Object.tASND(hsnd)
If asnd = Null Then DebugLog("Null") : Return False
DebugLog("========================")
DebugLog("handle: " + Str$(Handle(asnd)))
If asnd\copy <> 0 Then
src = Object.tASND(asnd\copy)
If src = Null Then
DebugLog("copy of: unexisting")
Else
DebugLog("copy of: "+ Str$(asnd\copy))
EndIf
EndIf
DebugLog("------------------------")
DebugLog("group: " + Str$(asnd\group))
DebugLog("volume: " + Str$(asnd\vol))
DebugLog("pan: " + Str$(asnd\pan))
If asnd\pitched = True Then
DebugLog("pitch: " + Str$(asnd\pitch))
Else
DebugLog("pitch: not set")
EndIf
DebugLog("------------------------")
If asnd\basefreq = True Then
DebugLog("basefreq: " + Str$(asnd\freq))
DebugLog("fscale: " + Str$(asnd\fscale))
Else
DebugLog("basefreq: not set")
EndIf
Return True
End Function |
Comments
| ||
| I'm curious! The link above goes to a page with another matter. You would have some usu Manual available? or an example of its operation? Thanks! |
| ||
| kochOn's website is long empty now but I remember he had some nice looking games. As far as I can see usage should be the same as the default commands. |
Code Archives Forum