This is a BASIC program I wrote for use with RENOISE. It invents a single track with random note commands and other things. Technically, it invents a XML-like file that is copied into the Windows clipboard and that could be pasted into a track in RENOISE.
After the program is compiled and run, it will bring about a window with a black background… there is no output displayed. But you should have this program and RENOISE running in your Windows system session. You run this program, then quickly switch to RENOISE and find an empty track, then press [CTRL][V] or choose “Paste” from the Edit menu.
I spent the longest making sure the formatting (spaces) of the clipboard data went down correctly.
This was written for QB64, which is a stupendous effort by Galleon. It was based on QBASIC but meant to work on 32-bit and 64-bit systems.
Download (freeware):
http://www.qb64.net/forum/index.php?board=2.0
Caveats:
(1) The program assumes 128 rows in a pattern, and only one note column and only one effect column. I’m sorry, I had to make it as simple as possible.
(2) The panning commands aren’t accounted for. It would be fairly easy to include that capability – but the logic in the program gets tricky around line 44!
(3) The subprogram section which starts with the line label “putinnotes” is where the program could be customized to the user’s taste, that is, how to insert note commands, effect commands etc. The routine actually in the program just chooses every 4th row and decides whether or not it should have a note command. If so, it probably gives it a volume command too, and much less often, an offset command. A few rows after that, a NOTE-OFF is inserted. Only instrument #00 is used in the routine.
I might as well break down the user-defined type which handles the tracker pattern data. It’s really straightforward:
s(i).noat Note number (0-127)
s(i).nstru Instrument number *
s(i).vol Volume column
s(i).dlay Delay column
s(i).efn The pattern effect number (gapper, offset etc.) *
s(i).efv The pattern effect value
- Neither the instrument number nor the pattern effect number should be -1. That’s the value used by the program to compare to see if there’s anything in a certain row.
(4) The QB64 compiler is slow, yes I know, but otherwise I could have written this in PureBASIC, and I’m much less comfortable using that other product (it’s not even installed in my computers anymore). QB64 is also peculiar about where a *.EXE file it created could be placed in the system. But the best part about this is that it could be customized! You would have to know how to program in BASIC, though. But changing things could be rewarding…
“Legal” stuff: if you use this program and the QB64 compiler, I’m not responsible for your system’s performance, or your inability to use the programs etc.
I give away the source code so that a few people using RENOISE could get creative. It’s not meant at all to be a prank or something else that should have disgusted someone. This is a program that I wrote, I don’t have to rip off anyone else for anything because I programmed in BASIC on a PC since 1989 and have spent many years refining text-processing routines. You could see that this program doesn’t do 3D graphics or sound or anything like that. Basically it does what I just said, text processing, but it required a nifty feature (copying data to the Windows clipboard).
ONE MORE THING: This program was meant to be used with RENOISE v2.0 and later (because of the delay column).
Enjoy!
Francisco
March 20, 2010
DEFINT A-Z
const NUMROW = 128
TYPE trakhtype
noat AS INTEGER
nstru AS INTEGER
vol AS INTEGER
dlay AS INTEGER
efn AS INTEGER
efv AS INTEGER
END TYPE
DIM s(1 TO Numrow) AS trakhtype
lf$ = CHR$(10)
cr$ = CHR$(13)
'lf$ = CHR$(13) + CHR$(10) 'FOR TESTING PURPOSES ONLY
qu$ = CHR$(34)
o$ = ""
RANDOMIZE
GOSUB initrows
GOSUB putinnotes
o$ = o$ + "<?xml version=" + qu$ + "1.0" + qu$ + " encoding=" + qu$ + "UTF-8" + qu$ + "?>" + lf$
o$ = o$ + "<patternclipboard.blockbuffer doc_version=" + qu$ + " qu>" + slf$(2)<br>
o$ = o$ + "<trackcolumns>" + slf$(2)<br>
o$ = o$ + "<trackcolumn>" + slf$(2)<br>
o$ = o$ + "<trackcolumn>" + slf$(2)<br>
o$ = o$ + "<lines>" + slf$(2)<br>
<br>
FOR i = 1 TO Numrow<br>
<br>
IF s(i).nstru <> -1 THEN<br>
o$ = o$ + "<line index=" + qu$ + LTRIM$(STR$(i - 1)) + qu$ + ">" + slf$(2)<br>
o$ = o$ + "<notecolumns>" + slf$(2)<br>
o$ = o$ + "<notecolumn>" + slf$(2)<br>
o$ = o$ + "<note>" + notenum2name$(s(i).noat) + "</note>" + slf$(0)<br>
o$ = o$ + "<instrument>" + duohex$(s(i).nstru) + "</instrument>"<br>
IF s(i).vol > 0 THEN<br>
o$ = o$ + slf$(0) + "<volume>" + duohex$(s(i).vol) + "</volume>"<br>
IF s(i).dlay > 0 THEN<br>
o$ = o$ + slf$(0) + "<delay>" + duohex$(s(i).dlay) + "</delay>" + slf$(-2)<br>
ELSE<br>
o$ = o$ + slf$(-2)<br>
END IF<br>
ELSE<br>
o$ = o$ + slf$(-2)<br>
END IF<br>
o$ = o$ + "</notecolumn>" + slf$(-2)<br>
o$ = o$ + "</notecolumns>" + slf$(-2)<br>
o$ = o$ + "</line>" + slf$(0)<br>
ELSEIF s(i).noat = 255 THEN<br>
o$ = o$ + "<line index=" + qu$ + LTRIM$(STR$(i - 1)) + qu$ + ">" + slf$(2)<br>
o$ = o$ + "<notecolumns>" + slf$(2)<br>
o$ = o$ + "<notecolumn>" + slf$(2)<br>
o$ = o$ + "<note>OFF</note>" + slf$(-2)<br>
o$ = o$ + "</notecolumn>" + slf$(-2)<br>
o$ = o$ + "</notecolumns>" + slf$(-2)<br>
o$ = o$ + "</line>" + slf$(0)<br>
ELSE<br>
o$ = o$ + "<line index=" + qu$ + LTRIM$(STR$(i - 1)) + qu$ + "></line>"<br>
IF i = Numrow THEN<br>
o$ = o$ + slf$(-2)<br>
ELSE<br>
o$ = o$ + slf$(0)<br>
END IF<br>
END IF<br>
<br>
NEXT i<br>
<br>
o$ = o$ + "</lines>" + slf$(0)<br>
o$ = o$ + "<columntype>NoteColumn</columntype>" + slf$(-2)<br>
o$ = o$ + "</trackcolumn>" + slf$(0)<br>
o$ = o$ + "<trackcolumn>" + slf$(2)<br>
o$ = o$ + "<lines>" + slf$(2)<br>
<br>
FOR i = 1 TO Numrow<br>
IF s(i).efn <> -1 THEN<br>
o$ = o$ + "<line index=" + qu$ + LTRIM$(STR$(i - 1)) + qu$ + ">" + slf$(2)<br>
o$ = o$ + "<effectcolumns>" + slf$(2)<br>
o$ = o$ + "<effectcolumn>" + slf$(2)<br>
o$ = o$ + "<value>" + duohex$(s(i).efv) + "</value>" + slf$(0)<br>
o$ = o$ + "<number>" + duohex$(s(i).efn) + "</number>" + slf$(-2)<br>
o$ = o$ + "</effectcolumn>" + slf$(-2)<br>
o$ = o$ + "</effectcolumns>" + slf$(-2)<br>
o$ = o$ + "</line>" + slf$(0)<br>
ELSE<br>
o$ = o$ + "<line index=" + qu$ + LTRIM$(STR$(i - 1)) + qu$ + "></line>"<br>
IF i = Numrow THEN<br>
o$ = o$ + slf$(-2)<br>
ELSE<br>
o$ = o$ + slf$(0)<br>
END IF<br>
END IF<br>
NEXT i<br>
<br>
o$ = o$ + "</lines>" + slf$(0)<br>
o$ = o$ + "<columntype>EffectColumn</columntype>" + slf$(-2)<br>
o$ = o$ + "</trackcolumn>" + slf$(-2)<br>
o$ = o$ + "</trackcolumn>" + slf$(-2)<br>
o$ = o$ + "</trackcolumns>" + slf$(-2)<br>
o$ = o$ + "</patternclipboard.blockbuffer>" + lf$
_CLIPBOARD$ = o$
pend:
END
'******************************
'put in notes routine goes here
'******************************
putinnotes:
vl$ = "46844682646824866468264866824"
vll = LEN(vl$)
m1 = 1
m2 = 1
FOR j = 1 TO Numrow - 4 STEP 4
IF RND > .667 THEN
k = j + INT(RND * 3 + 1)
s(j).noat = 48
s(j).vol = VAL("&H" + MID$(vl$, m1, 1) + "0")
IF s(j).vol >= 128 THEN s(j).vol = 0
m1 = m1 + 1
IF m1 > vll THEN m1 = 1
s(j).nstru = 0
IF RND > .85 THEN
s(j).dlay = &H80
ELSEIF RND > .75 THEN
s(j).efn = 9
s(j).efv = VAL("&H" + MID$(vl$, m2, 1) + "0")
m2 = m2 + 1
IF m2 > vll THEN m2 = 1
END IF
s(k).noat = 255
END IF
NEXT j
RETURN
initrows:
FOR i = 1 TO Numrow
s(i).noat = 0
s(i).nstru = -1
s(i).vol = 0
s(i).dlay = 0
s(i).efn = -1
s(i).efv = 0
NEXT i
RETURN
'---------------------------------------------------------------------------
'SUBs
'---------------------------------------------------------------------------
FUNCTION notenum2name$ (num)
oc = FIX(num / 12)
semit = num MOD 12
SELECT CASE semit
CASE 0: a$ = "C-"
CASE 1: a$ = "C#"
CASE 2: a$ = "D-"
CASE 3: a$ = "D#"
CASE 4: a$ = "E-"
CASE 5: a$ = "F-"
CASE 6: a$ = "F#"
CASE 7: a$ = "G-"
CASE 8: a$ = "G#"
CASE 9: a$ = "A-"
CASE 10: a$ = "A#"
CASE 11: a$ = "B-"
END SELECT
a$ = a$ + CHR$(48 + oc)
notenum2name$ = a$
END FUNCTION
FUNCTION duohex$ (decnum)
a$ = HEX$(decnum)
IF decnum < 16 THEN a$ = "0" + a$
duohex$ = a$
END FUNCTION
FUNCTION slf$ (indent) STATIC
stb = stb + indent
IF stb < 0 THEN stb = 0
a$ = lf$ + SPACE$(stb)
slf$ = a$
END FUNCTION