Code: Select all
Structure Sample
l.w
r.w
EndStructure
Procedure UpdateWaveImage(PBImage, *SampleData.Sample, SampleCount)
Protected.i Width, Height, X, VOffsetL, VOffsetR, Mul
Protected.i SamplesPerPixel, Sample
Protected.w MinL, MaxL, MinR, MaxR
Protected.w MinL_, MaxL_, MinR_, MaxR_
If *SampleData And SampleCount
StartDrawing(ImageOutput(PBImage))
Width = OutputWidth() : Height = OutputHeight()
VOffsetL = Height >> 2 : VOffsetR = VOffsetL + Height >> 1
Mul = (VOffsetL * $19999) >> 16
Box(0, 0, Width, Height, $ffe0e0e0)
Line(0, VOffsetL, Width, 1, $ffa0a0a0)
Line(0, VOffsetR, Width, 1, $ffa0a0a0)
SamplesPerPixel = (SampleCount + Width - 1) / Width
MinL = $7fff : MaxL = $8000 : MinR = $7fff : MaxR = $8000
MinL_ = $8000 : MaxL_ = $7fff : MinR_ = $8000 : MaxR_ = $7fff
While SampleCount
If *SampleData\l < MinL : MinL = *SampleData\l : ElseIf *SampleData\l > MaxL : MaxL = *SampleData\l : EndIf
If *SampleData\r < MinR : MinR = *SampleData\r : ElseIf *SampleData\r > MaxR : MaxR = *SampleData\r : EndIf
*SampleData + 4
Sample + 1 : SampleCount - 1
If Sample = SamplesPerPixel Or SampleCount = 0
MinL = (MinL * Mul) >> 16 : MaxL = (MaxL * Mul) >> 16
MinR = (MinR * Mul) >> 16 : MaxR = (MaxR * Mul) >> 16
If MinL_ > MaxL : LineXY(X, VOffsetL - MinL_, X, VOffsetL - MaxL, $ffff8000) : EndIf
If MaxL_ < MinL : LineXY(X, VOffsetL - MaxL_, X, VOffsetL - MinL, $ffff8000) : EndIf
If MinR_ > MaxR : LineXY(X, VOffsetR - MinR_, X, VOffsetR - MaxR, $ffff8000) : EndIf
If MaxR_ < MinR : LineXY(X, VOffsetR - MaxR_, X, VOffsetR - MinR, $ffff8000) : EndIf
LineXY(X, VOffsetL - MinL, X, VOffsetL - MaxL, $ffff8000)
LineXY(X, VOffsetR - MinR, X, VOffsetR - MaxR, $ffff8000)
MinL_ = MinL : MaxL_ = MaxL : MinR_ = MinR : MaxR_ = MaxR
MinL = $7fff : MaxL = $8000 : MinR = $7fff : MaxR = $8000
X + 1 : Sample = 0
EndIf
Wend
StopDrawing()
EndIf
EndProcedure
BASS_Init(-1, 44100, 0, 0, #Null)
Channel.l = BASS_StreamCreateFile(#False, @"Test.mp3", 0, 0, #BASS_STREAM_PRESCAN|#BASS_STREAM_DECODE|#BASS_UNICODE)
Length.q = BASS_ChannelGetLength(Channel, #BASS_POS_BYTE)
Dim Buffer.Sample(Length >> 2)
BASS_ChannelGetData(Channel, @Buffer(), Length)
OpenWindow(0, 0, 0, 620, 320, "Waveform", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
WaveImage = CreateImage(#PB_Any, 8192, 256)
UpdateWaveImage(WaveImage, @Buffer(), Length >> 2)
ScrollAreaGadget(0, 10, 10, 600, 300, ImageWidth(WaveImage), ImageHeight(WaveImage), 10, #PB_ScrollArea_Center)
ImageGadget(1, 0, 0, 600, 300, ImageID(WaveImage))
CloseGadgetList()
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Make sure to compile with debugger disabled or it will be slow.
It could be made much faster using asm but not everyone likes that. So far it's PB code only.
By Creating a different size image, or altering the starting point and sample count for the UpdateWaveImage procedure, you can change the output.