DATA 2,3,5,11,13,23,29,31
' Parallel Harmonics
DATA 46,2,44,1,58,2,52,1,29,3,46,2,0,1
DATA 31,2,23,1,35,2,26,1,29,3,23,2,0,1
DATA 42,2,31,1,36,2,24,1,31,3,36,2,0,1
DATA 39,2,33,1,29,2,36,1,44,3,33,2,0,1
DATA 46,2,44,1,58,2,52,1,58,3,46,2
' I can't tell you anything about composition.
' It's all trial and error in a terminal series of whole numbered
ratios.
' For you this is code to play with.
' For me this is an archive and witnesses, if not inspection and
' promotion.
' Notice that all of my harmonics are factors in my notes.
' This version of my linear tuning synthesizer leaves out variable
' glides, because this tune actually sounds quite decent to me
' with NO glide, but at least it doesn't hav "silence in the sky",
' like previous versions did. You might need to remove some
' line breaks if you know this language and hav sound exchange.
OPTION BASE 1
DIM Velocity(8) AS DOUBLE
DIM acceleration(8) AS DOUBLE
DIM Angle(8) AS DOUBLE
DIM AmpLeft AS DOUBLE
DIM AmpRight AS DOUBLE
DIM AmpLeftDivisor AS DOUBLE
DIM AmpRightDivisor AS DOUBLE
DIM TwoPi AS DOUBLE
DIM pi AS DOUBLE
DIM FlipStart AS DOUBLE
DIM basis, note, length, glide AS DOUBLE
DIM samples, samplerate, Amp AS LONG
DIM g AS INTEGER
DIM k, t, lastnote AS INTEGER
DIM SignLeft, SignRight, harmonics(8) AS INTEGER
DIM test AS STRING
basis = 5
FOR k = 1 TO 8
READ harmonics(k)
NEXT k
test = "0"
' Make that zero when you are prepared to write the wav data file,
' which requires "Sound Exchange" to be in your \sox directory.
pi = 3.141592653589793#
TwoPi = pi + pi
samplerate = 44100
lastnote = 0
Angle = 0
AmpLeftDivisor = 4 / 1.06
AmpRightDivisor = 4.01
IF test <> "1" THEN
OPEN "\sox\lohruh.bat" FOR OUTPUT AS #1
OPEN "\sox\lohruh.raw" FOR OUTPUT AS #2
END IF
100
FOR g = 1 TO 34
READ note, length
SOUND note * basis, length
IF test = "0" THEN
IF note = 0 THEN
GOSUB 250
lastnote = note
samples = samplerate * length / 6
GOSUB 300
GOTO 75
END IF
IF lastnote = 0 THEN
lastnote = note
samples = samplerate * length / 6
GOSUB 300
GOTO 75
END IF
IF note <> 0 AND lastnote <> 0 THEN
samples = 147
GOSUB 300
samples = samplerate * length / 6
lastnote = note
GOSUB 300
GOTO 75
END IF
END IF
75 NEXT g
IF test = "1" THEN
END
ELSE
' Wait for amplitude to zip and add 2s terminal silence.
GOSUB 250
FOR k = 1 TO samplerate * 2
PRINT #2, CHR$(255) + CHR$(127);
NEXT k
print "Here, I try to write a batch file that
executes sox."
PRINT #1, "sox -c 2 -r 44100 -uw lohruh.raw -sw lohruh.wav stat"
CLOSE #1, #2
END
END IF
250
' Zip amplitude when lastnote is zero.
IF AmpLeft = 0 THEN SignLeft = 0
IF AmpLeft > 0 THEN SignLeft = 1
IF AmpLeft < 0 THEN SignLeft = -1
AmpLeft = AmpLeft - AmpLeft
FOR k = 1 TO 7 STEP 2
AmpLeft = AmpLeft + SIN(Angle(k))
Angle(k) = Angle(k) + Velocity(k)
NEXT k
' If the sign changes, then SignLeft becomes zero and stays that way.
IF AmpLeft > 0 AND SignLeft = -1 OR AmpLeft < 0 AND SignLeft = 1 OR
SignLeft = 0 THEN
AmpLeft = 0
END IF
Amp = (AmpLeft / AmpLeftDivisor + 1) * 32767.5
PRINT #2, CHR$(Amp AND 255);
PRINT #2, CHR$((Amp AND 65280) / 256);
' Halt right channel when amplitude crosses zero.
IF AmpRight = 0 THEN SignRight = 0
IF AmpRight > 0 THEN SignRight = 1
IF AmpRight < 0 THEN SignRight = -1
AmpRight = AmpRight - AmpRight
FOR k = 2 TO 8 STEP 2
AmpRight = AmpRight + SIN(Angle(k))
Angle(k) = Angle(k) + Velocity(k)
NEXT k
' If the sign changes, then SignRight becomes zero and stays that way.
IF AmpRight > 0 AND SignRight = -1 OR AmpRight < 0 AND SignRight = 1
OR SignRight = 0 THEN
AmpRight = 0
END IF
Amp = (AmpRight / AmpRightDivisor + 1) * 32767.5
PRINT #2, CHR$(Amp AND 255);
PRINT #2, CHR$((Amp AND 65280) / 256);
IF AmpLeft <> 0 OR AmpRight <> 0 GOTO 250
FlipStart = pi * g
FOR k = 1 TO 8
Angle(k) = FlipStart
NEXT k
' Inverts phase after a pause.
RETURN
300
FOR k = 1 TO 8
Velocity(k) = TwoPi * lastnote * harmonics(k) / samplerate
acceleration(k) = (TwoPi * note * harmonics(k) / samplerate -
Velocity(k)) / samples
NEXT k
FOR t = 1 TO samples
AmpLeft = AmpLeft - AmpLeft
FOR k = 1 TO 7 STEP 2
AmpLeft = AmpLeft + SIN(Angle(k))
NEXT k
Amp = (AmpLeft / AmpLeftDivisor + 1) * 32767.5
PRINT #2, CHR$(Amp AND 255);
PRINT #2, CHR$((Amp AND 65280) / 256);
AmpRight = AmpRight - AmpRight
FOR k = 2 TO 8 STEP 2
AmpRight = AmpRight + SIN(Angle(k))
NEXT k
Amp = (AmpRight / AmpRightDivisor + 1) * 32767.5
PRINT #2, CHR$(Amp AND 255);
PRINT #2, CHR$((Amp AND 65280) / 256);
FOR k = 1 TO 8
Angle(k) = Angle(k) + Velocity(k)
Velocity(k) = Velocity(k) + acceleration(k)
NEXT k
NEXT t
RETURN
I call it "Lohruh, Regruntled", and I might delete "Lohruh" if it gets
(and sticks at) a better rating. Right now, that would be easy,
because neither is rated.
I changed my output to 16 signed bits, so it's a touch better than the
15 unsigned bits I was using. I should be able to use 16 unsigned
bits, but for some reason, sound exchange doubles them and "wraps"
them downward. I also added several harmonics that are exponents of of
prime-numbered factors in my frequencies, which are all multiplied by
those factors. Perhaps I can divide my notes by their factors for
complex harmony. So, my data for harmonics is now:
' DATA 2,64,243,3,5,625,343,7,11,121,169,13
That goes left, right, left... With a few transforms, it sounds a lot
like bells in a complex arrangement of harmony. In order, I used a
delay of 2s with 25% feedback, then chorus, flanger, and reverb
(170ms, a bit longer than a beat) effects. All effects made with
almost no dry signal (and very little base). It was also two seconds
longer than the orijinal recording (delay does that, and scratches out
a leading 2s).
So, I mixed THAT highly transormed signal with the oriJinal at 1:1.
_______
<a href="http://www.mynumo.com/SherLok/">GrayvYard Mushruumz</a>, home
of about ten imaJinary people with one voice.