• Hay yoh, person, who are you?

    From brewjay@spamcop.net@21:1/5 to All on Thu Jun 1 13:46:02 2017
    XPost: rec.music.makers.synth

    ' https://soundcloud.com/jay-litwyn/person
    ' It is a two part mixed solo, with a synth lead
    ' having the same tune, parts exchanged:

    ' CC-BY-NC-ND

    ' Name of concert ratio is in throwaway string variable.
    ' Right channel pitch, left channel, length, ratio name:
    DATA 0 , 0 , 15 ,"Jerminal Rest"
    DATA 24 , 12 , 10 ,"Octave"
    DATA 18 , 18 , 10 ,"Unison"
    DATA 16 , 24 , 10 ,"Perfect Fifth, tails in"
    DATA 18 , 18 , 10 ,"Unison"
    DATA 15 , 24 , 10 ,"Minor Sixth, tails in"
    DATA 12 , 18 , 10 ,"Perfect Fifth, tails in"
    DATA 18 , 12 , 10 ,"Perfect Fifth"
    DATA 0 , 0 , 15 ,"Terminal Rest"

    OPTION BASE 1
    DIM TwoPi AS DOUBLE
    DIM pi AS DOUBLE
    DIM temp AS DOUBLE
    DIM BeatsPerSecond AS DOUBLE
    DIM Angle(2) AS DOUBLE
    DIM Velocity(2) AS DOUBLE
    DIM Acceleration(2) AS DOUBLE
    DIM Phase(2) AS DOUBLE
    DIM note(2) AS INTEGER
    DIM LastNote(2) AS INTEGER
    DIM length AS INTEGER
    DIM harmonics(2) AS DOUBLE
    DIM Samples AS LONG
    DIM t AS LONG
    DIM SampleRate AS LONG
    DIM k AS INTEGER
    DIM g AS INTEGER
    DIM amp AS INTEGER
    DIM basis AS INTEGER
    DIM NumHarmonics AS INTEGER
    DIM Sign(2) AS INTEGER
    DIM glide AS INTEGER
    DIM GlideTrim AS LONG
    DIM test AS STRING
    DIM rationame AS STRING
    DIM TerminalAngle(2) AS DOUBLE
    DIM DropAngle(2) AS DOUBLE
    DIM PhaseDir(2) AS DOUBLE

    PRINT
    test = "0"
    ' I frequently flip that.
    NumHarmonics = 2
    BeatsPerSecond = 18#
    pi = 3.141592653589793#
    TwoPi = pi * 2
    SampleRate = 44100

    IF test = "0" THEN
    OPEN "\sox\person.raw" FOR OUTPUT AS #4
    END IF

    ' This is where I write a batch file that assumes where
    ' your FreeBasic and your Sound Exchange are.
    OPEN "person.bat" FOR OUTPUT AS #1
    PRINT #1, "\progra~2\freebasic\fbc -lang qb person.bas"
    PRINT #1, "person.exe"
    PRINT #1, "cd \sox"
    PRINT #1, "sox -c 2 -r"; SampleRate; " -sw person.raw person.wav stat"
    CLOSE #1

    ' Fundamental Frequency of right and left channels.
    harmonics(1) = 8
    harmonics(2) = 8

    FOR k = 1 TO NumHarmonics
    note(k) = 0
    LastNote(k) = 0
    NEXT k

    OPEN "con" FOR APPEND AS #2
    ' Change filename for feedback into this code.

    glide = 30
    100
    FOR g = 1 TO 9
    READ note(1), note(2), length, rationame
    rationame = CHR$(34) + rationame + CHR$(34)
    ' PRINT #2, USING "DATA ###-,###-,###, ,&"; note(1) * 4; note(2)
    * 4; length; rationame
    IF g > 0 THEN
    ' SOUND note(2) * 8, length
    END IF
    IF test = "0" THEN
    IF note(1) = 0 AND LastNote(1) = 0 THEN
    Samples = SampleRate * length / BeatsPerSecond
    GOSUB 300
    GOTO 75
    END IF
    IF note(1) = 0 AND LastNote(1) <> 0 THEN
    GOSUB 250
    FOR k = 1 TO NumHarmonics
    LastNote(k) = note(k)
    NEXT k
    Samples = SampleRate * length / BeatsPerSecond
    GOSUB 300
    GOTO 75
    END IF
    IF LastNote(1) = 0 AND note(1) <> 0 THEN
    FOR k = 1 TO NumHarmonics
    LastNote(k) = note(k)
    NEXT k
    Samples = SampleRate * length / BeatsPerSecond
    GOSUB 275
    GOTO 75
    END IF
    IF note(1) <> 0 AND LastNote(1) <> 0 THEN
    Samples = SampleRate * length / BeatsPerSecond
    / glide
    GlideTrim = Samples
    GOSUB 300
    Samples = SampleRate * length / BeatsPerSecond
    - GlideTrim
    FOR k = 1 TO NumHarmonics
    LastNote(k) = note(k)
    NEXT k
    GOSUB 300
    GOTO 75
    END IF
    END IF

    75 NEXT g
    CLOSE #4

    END

    ' *Neat* Silencer -- finishes a wave like 275 starts one.
    ' When it reaches a peak or a trough, then it cuts amplitude in half
    ' and biases it by half.
    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) = 1
    DropAngle(k) = pi * 2.5
    ELSEIF Angle(k) > pi / 2 THEN
    TerminalAngle(k) = pi * 2.5
    PhaseDir(k) = 0
    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 1
    IF Angle(k) >= DropAngle(k) THEN
    Phase(k) = Phase(k) / 2 + .5
    END IF
    CASE 0
    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(k) * harmonics(k) / SampleRate
    Acceleration(k) = (TwoPi * note(k) * 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
    ' Calculate constants of change for write loop.
    FOR k = 1 TO NumHarmonics
    Velocity(k) = TwoPi * LastNote(k) * harmonics(k) / SampleRate
    Acceleration(k) = (TwoPi * note(k) * harmonics(k) / SampleRate
    - Velocity(k)) / Samples
    NEXT k

    ' Main write loop. Static Phases problem solved at 250.
    FOR t = 1 TO Samples
    FOR k = 1 TO NumHarmonics
    Phase(k) = SIN(Angle(k))
    NEXT k

    GOSUB 400

    FOR k = 1 TO NumHarmonics
    Angle(k) = Angle(k) + Velocity(k)
    Velocity(k) = Velocity(k) + Acceleration(k)
    NEXT k
    NEXT t
    RETURN

    400
    ' Write a sample.
    ' Bayse is on right for a change.
    amp = CINT(Phase(2) * 32000)
    PRINT #4, CHR$(amp AND 255);
    PRINT #4, CHR$((amp AND 65280) / 256);

    amp = CINT(Phase(1) * -32000)
    PRINT #4, CHR$(amp AND 255);
    PRINT #4, CHR$((amp AND 65280) / 256);
    RETURN

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)