Code: Select all
new names for existing functions
SetSoundFrequency(Sound, Frequency) (instead of SoundFrequency)
SetSoundPan(Sound, Pan) (instead of SoundPan)
SetSoundVolume(Sound, Volume) (instead of SoundVolume)
of course the Get recurring functions
GetSoundFrequency(Sound)
GetSoundPan(Sound)
GetSoundVolume(Sound)
time functions (in milliseconds)
SeSoundPosition(Sound, Position)
GetSoundPosition(Sound)
SoundLength(Sound) ;depends on frequency
SoundRealLength(Sound)
playing functions
PauseSound(Sound)
ResumeSound(Sound) ;do not play if stopped ?
SoundStatus(Sound)
and status constants
#PB_Sound_Stopped
#PB_Sound_Playing
#PB_Sound_Paused
maybe a flag for LoadSound ?
Something like #PB_Sound_Music for streaming
Code: Select all
Structure WAVEFORMATEX Extends WAVEFORMAT
nBitsPerSample.l
EndStructure
Structure DSBCAPS
dwSize.l
dwFlags.l
dwBufferBytes.l
dwUnlockTransferRate.l
dwPlayCpuOverhead.l
EndStructure
Procedure.l SoundID(Sound.l)
Protected *SoundID.Long
*SoundID = IsSound(Sound)
If *SoundID
*SoundID = *SoundID\l
EndIf
ProcedureReturn *SoundID
EndProcedure
Procedure.l GetSoundFrequency(Sound.l)
Protected Frequency.l
Protected *SoundID.Long
Protected Buffer.IDirectSoundBuffer
*SoundID = IsSound(Sound)
If *SoundID
Buffer = *SoundID\l
EndIf
If Buffer
Buffer\GetFrequency(@Frequency)
EndIf
ProcedureReturn Frequency
EndProcedure
Procedure.l GetSoundPosition(Sound.l)
Protected Position.q
Protected Frequency.l
Protected *SoundID.Long
Protected Format.WAVEFORMATEX
Protected Buffer.IDirectSoundBuffer
*SoundID = IsSound(Sound)
If *SoundID
Buffer = *SoundID\l
EndIf
If Buffer
Buffer\GetCurrentPosition(@Position, #Null)
Buffer\GetFrequency(@Frequency)
Buffer\GetFormat(Format, SizeOf(WAVEFORMATEX), #Null)
Format\nBitsPerSample / 8
EndIf
If Frequency And Format\nChannels And Format\nBitsPerSample
Position * 1000 ;milliseconds
Position / Format\nChannels
Position / Format\nBitsPerSample
Position / Frequency
Else
Position = -1
EndIf
ProcedureReturn Position
EndProcedure
Procedure.l SoundLength(Sound.l)
Protected Length.q
Protected Frequency.l
Protected *SoundID.Long
Protected Caps.DSBCAPS
Protected Format.WAVEFORMATEX
Protected Buffer.IDirectSoundBuffer
*SoundID = IsSound(Sound)
If *SoundID
Buffer = *SoundID\l
EndIf
If Buffer
Caps\dwSize = SizeOf(DSBCAPS)
Buffer\GetCaps(Caps)
Buffer\GetFrequency(@Frequency)
Buffer\GetFormat(Format, SizeOf(WAVEFORMATEX), #Null)
Length = Caps\dwBufferBytes
Format\nBitsPerSample / 8
EndIf
If Length And Frequency And Format\nChannels And Format\nBitsPerSample
Length * 1000 ;milliseconds
Length / Format\nChannels
Length / Format\nBitsPerSample
Length / Frequency
Else
Length = -1
EndIf
ProcedureReturn Length
EndProcedure
Procedure.l SoundRealLength(Sound.l)
Protected Length.q
Protected *SoundID.Long
Protected Caps.DSBCAPS
Protected Format.WAVEFORMATEX
Protected Buffer.IDirectSoundBuffer
*SoundID = IsSound(Sound)
If *SoundID
Buffer = *SoundID\l
EndIf
If Buffer
Caps\dwSize = SizeOf(DSBCAPS)
Buffer\GetCaps(Caps)
Buffer\GetFormat(Format, SizeOf(WAVEFORMATEX), #Null)
Length = Caps\dwBufferBytes
Format\nBitsPerSample / 8
EndIf
If Length And Format\nSamplesPerSec And Format\nChannels And Format\nBitsPerSample
Length * 1000 ;milliseconds
Length / Format\nChannels
Length / Format\nBitsPerSample
Length / Format\nSamplesPerSec
Else
Length = -1
EndIf
ProcedureReturn Length
EndProcedure
InitSound()
UseOGGSoundDecoder()
If OpenWindow(0, 0, 0, 270, 160, "Sound Enhancement", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
;fixed font gadgets
TextGadget(0, 10, 10, 250, 20, "", #PB_Text_Right)
TextGadget(1, 10, 40, 250, 20, "", #PB_Text_Right)
TextGadget(2, 10, 70, 250, 20, "", #PB_Text_Right)
TextGadget(3, 10, 100, 250, 20, "", #PB_Text_Right)
For i = 0 To 3
SetGadgetFont(i, GetStockObject_(#ANSI_FIXED_FONT))
Next i
;updates the gadgets
SetTimer_(WindowID(0), 1, 50, 0)
;loads a sound ^_^
Repeat
file$ = OpenFileRequester("Open a music file", "", "Music file | *.wav;*.ogg", 0)
LoadSound(0, file$)
Until IsSound(0)
;length a position depend on Frequency
;you can try it a bit faster ;)
SoundFrequency(0, GetSoundFrequency(0) * 1.5)
;length is unsigned long so a quad is more simple
;than using the "length & $FFFFFFFF" trick
length.q = SoundRealLength(Sound.l)
mil = length % 1000
length / 1000
sec = length % 60
min = length / 60
;display the real length
Text$ = Str(min) + ":" + RSet(Str(sec), 2, "0") + ":" + RSet(Str(mil/10), 2, "0")
SetGadgetText(3, "Real length -> " + Text$)
length.q = SoundLength(Sound.l)
mil = length % 1000
length / 1000
sec = length % 60
min = length / 60
;display the length
Text$ = Str(min) + ":" + RSet(Str(sec), 2, "0") + ":" + RSet(Str(mil/10), 2, "0")
SetGadgetText(2, "Length -> " + Text$)
;progressbar from pos 0 to length/1000
ProgressBarGadget(4, 10, 130, 250, 20, 0, length, #PB_ProgressBar_Smooth)
;here we go
PlaySound(0)
start = ElapsedMilliseconds()
Repeat
Event = WaitWindowEvent()
If Event = #WM_TIMER
;display the software position
pos.q = ElapsedMilliseconds() - start
SetGadgetText(0, Hex(pos))
mil = pos % 1000
pos / 1000
sec = pos % 60
min = pos / 60
Text$ = Str(min) + ":" + RSet(Str(sec), 2, "0") + ":" + RSet(Str(mil/10), 2, "0")
SetGadgetText(1, "Software position -> " + Text$)
;display the hardware position
pos.q = GetSoundPosition(0)
SetGadgetText(0, Hex(pos))
mil = pos % 1000
pos / 1000
sec = pos % 60
min = pos / 60
Text$ = Str(min) + ":" + RSet(Str(sec), 2, "0") + ":" + RSet(Str(mil/10), 2, "0")
SetGadgetText(0, "Hardware position -> " + Text$)
;update progressbar from hardware pos/1000
SetGadgetState(4, pos)
EndIf
Until Event = #PB_Event_CloseWindow
EndIf