'
https://soundcloud.com/jay-litwyn/clarity
DATA 2, 5, 13, 34, 89, 144, 377, 1597, 987, 610, 233, 121, 55, 21, 8, 3
DATA 0,9
DATA 43,9,0,3,39,12,26,6,36,9,0,6
DATA 26,9,0,3,36,12,42,6,54,9,0,6
DATA 39,9,0,3,36,12,24,6,32,9,0,6
DATA 24,9,0,3,32,12,39,6,48,9,0,6
DATA 39,9,0,3,36,12,24,6,30,9,0,6
DATA 30,9,0,3,45,12,30,6,40,9,0,6
DATA 50,9,0,3,36,12,0,6,40,12,0,18
DIM NumHarmonics AS INTEGER
NumHarmonics = 16
OPTION BASE 1
DIM harmonics(NumHarmonics) AS DOUBLE
DIM chanamp(2, NumHarmonics) AS DOUBLE
DIM Velocity(NumHarmonics) AS DOUBLE
DIM Acceleration(NumHarmonics) AS DOUBLE
DIM Angle(NumHarmonics) AS DOUBLE
DIM Phase(NumHarmonics) AS DOUBLE
DIM TerminalAngle(NumHarmonics) AS DOUBLE
DIM DropAngle(NumHarmonics) AS DOUBLE
DIM PhaseDir(NumHarmonics) AS INTEGER
DIM sign(NumHarmonics) AS INTEGER
DIM BeatsPerSecond AS DOUBLE
DIM ampleft AS LONG
DIM ampright AS LONG
DIM temp AS DOUBLE
DIM TwoPi AS DOUBLE
DIM SampleRate, t, samples AS LONG
DIM lastnote AS INTEGER
DIM note AS INTEGER
DIM length, glide AS INTEGER
DIM k, g AS INTEGER
DIM Test AS STRING
Test = "0"
pi = 3.141592653589793#
TwoPi = pi * 2
SampleRate = 44100
BeatsPerSecond = 18#
lastnote = 0
OPEN "\sox\clarity.raw" FOR OUTPUT AS #2
OPEN "clarity.bat" FOR OUTPUT AS #1
PRINT #1, "fbc -lang qb clarity.bas"
PRINT #1, "clarity.exe"
PRINT #1, "cd \sox"
PRINT #1, "sox -c 2 -r"; SampleRate; " -sw clarity.raw clarity.wav stat"
CLOSE #1
FOR k = 1 TO NumHarmonics
READ harmonics(k)
Angle(k) = 0
NEXT k
basis = harmonics(5)
ampleft = 60000
ampright = 40000
temp = temp - temp
DropAngle(1) = 1 / NumHarmonics
FOR k = 1 TO NumHarmonics
chanamp(1, k) = ampleft / harmonics(k) * temp
chanamp(2, k) = ampright / harmonics(k) * (1 - temp)
IF k MOD 2 = 0 THEN
chanamp(1, k) = -chanamp(1, k)
ELSE
chanamp(2, k) = -chanamp(2, k)
END IF
temp = temp + DropAngle(1)
harmonics(k) = harmonics(k) * 39.15 / 42
NEXT k
100
FOR g = 1 TO 43
READ note, length
IF g > 0 THEN
' SOUND note * 6, length
END IF
IF Test = "0" THEN
IF note = 0 AND lastnote = 0 THEN
samples = SampleRate * length / BeatsPerSecond
GOSUB 300
GOTO 75
END IF
IF note = 0 AND lastnote <> 0 THEN
GOSUB 250
FOR k = 1 TO NumHarmonics
lastnote = note
NEXT k
samples = SampleRate * length / BeatsPerSecond
GOSUB 300
GOTO 75
END IF
IF note <> 0 AND lastnote = 0 THEN
FOR k = 1 TO NumHarmonics
lastnote = note
NEXT k
samples = SampleRate * length / BeatsPerSecond
GOSUB 275
GOTO 75
END IF
IF note <> 0 AND lastnote <> 0 THEN
IF glide > 0 THEN
samples = SampleRate * length /
BeatsPerSecond / glide
GOSUB 300
samples = SampleRate * length /
BeatsPerSecond - samples
ELSE
samples = SampleRate * length /
BeatsPerSecond
END IF
FOR k = 1 TO NumHarmonics
lastnote = note
NEXT k
GOSUB 300
GOTO 75
END IF
END IF
75 NEXT g
IF Test = "1" THEN END
CLOSE #2
END
250
FOR k = 1 TO NumHarmonics
temp = Angle(k) / TwoPi
Angle(k) = (temp - FIX(temp)) * TwoPi
IF Angle(k) > pi * 3 / 2 THEN
TerminalAngle(k) = pi * 3.5
PhaseDir(k) = 2
DropAngle(k) = pi * 2.5
ELSEIF Angle(k) > pi / 2 THEN
TerminalAngle(k) = pi * 2.5
PhaseDir(k) = 1
DropAngle(k) = pi * 3 / 2
ELSE
TerminalAngle(k) = pi * 3 / 2
PhaseDir(k) = -1
DropAngle(k) = pi / 2
END IF
NEXT k
260
FOR k = 1 TO NumHarmonics
Phase(k) = SIN(Angle(k))
SELECT CASE PhaseDir(k)
CASE 2
IF Angle(k) >= DropAngle(k) THEN
Phase(k) = Phase(k) / 2 + .5
END IF
CASE 1
IF Angle(k) >= DropAngle(k) THEN
Phase(k) = Phase(k) / 2 - .5
END IF
CASE -1
IF Angle(k) >= DropAngle(k) THEN
Phase(k) = Phase(k) / 2 + .5
END IF
END SELECT
IF Angle(k) < TerminalAngle(k) THEN
Angle(k) = Angle(k) + Velocity(k)
ELSE
Angle(k) = TerminalAngle(k)
END IF
NEXT k
GOSUB 400
FOR k = 1 TO NumHarmonics
IF Angle(k) < TerminalAngle(k) THEN GOTO 260
NEXT k
FOR k = 1 TO NumHarmonics
Angle(k) = Angle(k) - Angle(k)
NEXT k
RETURN
275
' This starts a wave from zero, using half the amplitude, a start
' from where sin(angle) = -1, and a bias of half. This cuts
' a leading click that I can hear on some equipment with some tunes.
FOR k = 1 TO NumHarmonics
Velocity(k) = TwoPi * lastnote * harmonics(k) / SampleRate
Acceleration(k) = (TwoPi * note * harmonics(k) / SampleRate - Velocity(k)) / samples
PhaseDir(k) = 1
Angle(k) = 3 / 2 * pi
NEXT k
280
FOR k = 1 TO NumHarmonics
IF PhaseDir(k) = 1 THEN
Phase(k) = SIN(Angle(k)) / 2 + .5
ELSE
Phase(k) = SIN(Angle(k))
END IF
Angle(k) = Angle(k) + Velocity(k)
Velocity(k) = Velocity(k) + Acceleration(k)
NEXT k
samples = samples - 1
GOSUB 400
FOR k = 1 TO NumHarmonics
IF PhaseDir(k) = 1 THEN
Phase(k) = (Phase(k) - .5) * 2
END IF
IF Phase(k) > SIN(Angle(k)) THEN
PhaseDir(k) = -1
END IF
NEXT k
FOR k = 1 TO NumHarmonics
IF PhaseDir(k) = 1 GOTO 280
NEXT k
300
FOR k = 1 TO NumHarmonics
Velocity(k) = TwoPi * lastnote * harmonics(k) / SampleRate
Acceleration(k) = (TwoPi * note * harmonics(k) / SampleRate - Velocity(k)) / samples
NEXT k
FOR t = 1 TO samples
FOR k = 1 TO NumHarmonics
Velocity(k) = Velocity(k) + Acceleration(k)
Angle(k) = Angle(k) + Velocity(k)
Phase(k) = SIN(Angle(k))
NEXT k
GOSUB 400
NEXT t
RETURN
400
ampleft = ampleft - ampleft
ampright = ampright - ampright
FOR k = 1 TO NumHarmonics
ampleft = ampleft + CINT(Phase(k) * chanamp(1, k))
ampright = ampright + CINT(Phase(k) * chanamp(2, k))
NEXT k
PRINT #2, CHR$(ampleft AND 255); CHR$((ampleft AND 65280) / 256);
PRINT #2, CHR$(ampright AND 255); CHR$((ampright AND 65280) / 256);
RETURN
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)