That's an amazing effect. I ran a mp3 song through it and noticed the amplitude of the terrain suddenly increased significantly while the sound remained relatively the same. Must have been picking up something subtle in the encoding...
Yes, this is because it is used to visualize the line every 8192th audio sample. Then the line is moved one step closer in the Z axis (it has a higher coordinate number, the nearest visible one is -1, 0 is no longer invisible and 1 is basically in front of the monitor). For a finer display, I had each sample drawn, it's this source code, the edit is on line 39. Still, not every sample will be rendered now. Why?
In order to render virtually every sound sample, you must first determine in how many frames per second the program will run.
Suppose you set 50 frames per second for smooth graphics. For sound, this means 44100 (SNDRATE) / 50 samples per second, that is 882 samples. But that also means overwriting 882 values in memory 50 times per second.
In this program, this is solved by not tracking exactly where you ended up rendering. Simply take the current position of the sound and load more samples from it. Therefore, it can easily happen that some samples simply fall out before the whole thing is rendered.
Under line 61, the program solves normal 2D graphics for blinking background circles.
This source code try use "every" sample:
'sky texture
Texture2 = NewImage(255, 255, 32)
Dest Texture2
Line (diY
+ 20, diY
+ 20)-(235 - diY
, 235 - diY
), RGBA32
(67, 100, 255 - diY
, 255 - diY
), B
Circle (127, 127), 100 + diY
, RGBA32
(155 - diY
, diY
/ 2, 20 + diY
, 155 - diY
) 'earth texture
Texture = NewImage(255, 255, 32)
Dest Texture
Line (diY
+ 20, diY
+ 20)-(235 - diY
, 235 - diY
), RGB32
(diY
, 0, 0), B
Dest 0
Dim As Float IL
, IR
, IntensityLeft
, IntensityRight
Dim As Unsigned Byte Rc
, Gc
, Bc
SND = SndOpen("bb.mp3") ' <----------------- insert here your sound file name!
VOL = 10
SndVol SND, VOL / 20
L = MemSound(SND, 1)
R = MemSound(SND, 2)
DW = DesktopWidth
DH = DesktopHeight
HT = CopyImage(Texture, 33)
HT2 = CopyImage(Texture2, 33)
FreeImage Texture
FullScreen
SndPlay SND
Do Until Position
>= L.SIZE
- 882 'CHANGED ShiftIt = 89
Swap M3D
(rows
, ShiftIt
), M3D
(rows
, ShiftIt
+ 1) Swap M2D
(rows
, ShiftIt
), M2D
(rows
, ShiftIt
+ 1) ShiftIt = ShiftIt - 1
Depth = 0
Do Until Depth
= 180 ' This fill 3D visualisation in X axis. One sample is long 2 bytes, one row is 90 points long. This fill 90 points. M3D
(ra
, 0) = MemGet
(L
, L.OFFSET
+ Position
+ Depth
, Integer) / 32768 * 1.7 M2D
(ra
, 0) = MemGet
(R
, R.OFFSET
+ Position
+ Depth
, Integer) / 32768 * 1.7 Depth = Depth + 2 ' This is byte counter and now use all samples not every 8192th as in previous case (first source code in this thread)
ra = ra + 1
ra = 0
HX = -45 + X
HX2 = HX + 1
HZ = -89 + Z
HZ2 = HZ + 1
HY1 = -3 + M3D(X, Z): HY2 = -3 + M3D(X + 1, Z): HY3 = -3 + M3D(X, Z + 1): HY4 = -3 + M3D(X + 1, Z + 1)
HY11 = 3 - M2D(X, Z): HY12 = 3 - M2D(X + 1, Z): HY13 = 3 - M2D(X, Z + 1): HY14 = 3 - M2D(X + 1, Z + 1)
MapTriangle
(0, 0)-(255, 0)-(0, 255), HT
To(HX
, HY1
, HZ
)-(HX2
, HY2
, HZ
)-(HX
, HY3
, HZ2
), 0, Smooth MapTriangle
(255, 0)-(0, 255)-(255, 255), HT
To(HX2
, HY2
, HZ
)-(HX
, HY3
, HZ2
)-(HX2
, HY4
, HZ2
), 0, Smooth MapTriangle
(0, 0)-(255, 0)-(0, 255), HT2
To(HX
, HY11
, HZ
)-(HX2
, HY12
, HZ
)-(HX
, HY13
, HZ2
), 0, Smooth MapTriangle
(255, 0)-(0, 255)-(255, 255), HT2
To(HX2
, HY12
, HZ
)-(HX
, HY13
, HZ2
)-(HX2
, HY14
, HZ2
), 0, Smooth
'----------------------------------------------------------------------------------------------------------- CIRCLES --------------------------------------------------------------
FillCache = 0
IntensityLeft = 0
IntensityRight = 0
IntensityLeft
= IntensityLeft
+ Abs(MemGet
(L
, L.OFFSET
+ Position
+ FillCache
, Integer) / 32768) IntensityRight
= IntensityRight
+ Abs(MemGet
(R
, R.OFFSET
+ Position
+ FillCache
, Integer) / 32768) FillCache = FillCache + 2
IL = IntensityLeft / 2 ' recalc values as decimal
IR = IntensityRight / 2
CLL = 0
If IL
> 4.41 Then LightsL
(CLL
) = 255 Else LightsL
(CLL
) = IL
* 57 IL = IL - 4.41
CLL = CLL + 1
MAX CLL, 10
CLR = 0
If IR
> 4.41 Then LightsR
(CLR
) = 255 Else LightsR
(CLR
) = IR
* 57 IR = IR - 4.41
CLR = CLR + 1
MAX CLR, 10
IL = 0
IR = 0
Rc = 0: Gc = 255: Bc = 0
Rc = 255: Gc = 255: Bc = 0
Rc = 255: Gc = 0: Bc = 0
CircleFill
Width / 2 - 50 - DL
* 80, Height
/ 2, 30, &HFF000000 CircleFill
Width / 2 - 50 - DL
* 80, Height
/ 2, 30, RGBA32
(Rc
, Gc
, Bc
, LightsL
(DL
)) CircleFill
Width / 2 + 50 + DL
* 80, Height
/ 2, 30, &HFF000000 CircleFill
Width / 2 + 50 + DL
* 80, Height
/ 2, 30, RGBA32
(Rc
, Gc
, Bc
, LightsR
(DL
)) Display
Limit 50
Position = SndGetPos(SND) * SndRate * 2
' CX = center x coordinate
' CY = center y coordinate
' R = radius
' C = fill color
RadiusError = -Radius
X = Radius
Y = 0
Line (CX
- X
, CY
)-(CX
+ X
, CY
), C
, BF
RadiusError = RadiusError + Y * 2 + 1
Line (CX
- Y
, CY
- X
)-(CX
+ Y
, CY
- X
), C
, BF
Line (CX
- Y
, CY
+ X
)-(CX
+ Y
, CY
+ X
), C
, BF
X = X - 1
RadiusError = RadiusError - X * 2
Y = Y + 1
Line (CX
- X
, CY
- Y
)-(CX
+ X
, CY
- Y
), C
, BF
Line (CX
- X
, CY
+ Y
)-(CX
+ X
, CY
+ Y
), C
, BF
Due to the adjustment, I also had to adjust the rendering of the circles. This brought a noticeable increase in speed (not so many shades are used anymore, only about 5 for the color intensity of the circle)