'***********************************************************
'*
'*      WAVEFORM CREATOR
'*
'*      realizzato da Andrea Marenghi
'*		(Laser Amiga BBS Milano: 02/27200576)
'*
'***********************************************************

Inizio:
ON ERROR GOTO errore

'PALETTE  3,0,.93,.87
'PALETTE  2,0,0,0
'PALETTE  1,1,.6,1
'PALETTE  0,1,.13,.93

COLOR 0,1
LOCATE 6,28
PRINT "Basic Waveform Creator"
LOCATE 8,28
PRINT "Marenghi Andrea 1988"
LOCATE 10,32
PRINT "Premi un tasto"
GOSUB tasto
CLS
RANDOMIZE TIMER
DIM dati(255)
DIM onda%(255)
DIM prima(255)
DIM note(9)
DIM pref(255)
DIM reverse(255)
DIM doppio(127)
note(0)=130.81
note(1)=146.83
note(2)=261.63
note(3)=293.66
note(4)=329.63
note(5)=523.25
note(6)=587.33
note(7)=659.26
note(8)=1046.5
note(9)=1174.7
FOR s=0 TO 255 
READ pref(s)
NEXT
GOSUB schermo
GOSUB linea
GOTO scelta

REM Da qui iniziano le 10 routines per
REM la definizione dei suoni.

linea:
FOR s=1 TO 255
dati(s)=0
NEXT
GOSUB forma
RETURN

quadrato:
FOR s=0 TO 127
dati(s)=125
NEXT
FOR s=128 TO 255
dati(s)=-126        
NEXT
GOSUB forma
RETURN

diagonale:
FOR s=0 TO 255
dati(s)=s-128
NEXT
GOSUB forma
RETURN

rettangolo:
FOR s=0 TO 230
dati(s)=-126
NEXT
FOR s=231 TO 255
dati(s)=125
NEXT
GOSUB forma
RETURN

triangolo:
FOR s=0 TO 127
dati(s)=s*2-128
NEXT
FOR s=128 TO 255
dati(s)=127-(s-128)*2
NEXT
GOSUB forma
RETURN

rumore:
FOR s=0 TO 255
dati(s)=INT(RND*256-128)
NEXT
GOSUB forma
RETURN

random:
dati(0)=INT(RND*256-128)
FOR s=1 TO 255
dati(s)=dati(s-1)+INT(RND*30)-15
IF dati(s)>127 THEN dati(s)=127
IF dati(s)<-128 THEN dati(s)=128
NEXT
GOSUB forma
RETURN

seno:
FOR s=0 TO 127
dati(s)=INT(SQR(4096-(s-64)^2))
NEXT
FOR s=128 TO 255
dati(s)=-INT(SQR(4096-(s-192)^2))
NEXT
GOSUB forma
RETURN

prefab1:
FOR s=0 TO 63
dati(s)=s*2
NEXT
dati(64)=127
FOR s=65 TO 192
dati(s)=256-2*s
NEXT
FOR s=193 TO 255
dati(s)=(s-255)*2
NEXT
GOSUB forma
RETURN

prefab2:
FOR s=0 TO 255
dati(s)=pref(s)
NEXT 
GOSUB forma 
RETURN

REM data per la prefab2
REM e per i menu

DATA 0,8,15,23,30,37,44,51,57,63,69,74,79
DATA 83,87,91,93,96,98,99,100,100,100
DATA 99,98,97,95,92,89,86,83,79,75,71
DATA 66,62,57,52,48,43,39,34,30,25,21,18
DATA 14,11,8,5,3,0,-1,-3,-4,-5,-5,-6,-6
DATA -5,-4,-3,-1,0,2,3,5,7,9,11,13,15,17
DATA 18,20,21,23,24,25,26,26,27,27,27,27
DATA 27,26,25,24,23,22,20,18,17,15,13,11
DATA 9,7,5,3,1,-1,-3,-5,-6,-8,-9,-10,-11
DATA -12,-12,-13,-13,-13,-13,-13,-12,-11
DATA -11,-10,-8,-7,-6,-4,-3,-2,0,2,3,4,6
DATA 7,8,10,11,11,12,13,13,13,13,13,12,12
DATA 11,10,9,8,6,5,3,1,-1,-3,-5,-7,-9,-11
DATA -13,-15,-17,-18,-20,-22,-23,-24,-25
DATA -26,-27,-27,-27,-27,-27,-26,-26,-25
DATA -24,-23,-21,-20,-18,-17,-15,-13,-11
DATA -9,-7,-5,-3,-2,0,1,3,4,5,5,6,6,5,5
DATA 4,3,1,0,-3,-5,-8,-11,-14,-18,-21,-25
DATA -30,-34,-39,-43,-48,-52,-57,-62,-66
DATA -71,-75,-79,-83,-86,-89,-92,-95,-97
DATA -98,-99,-100,-100,-100,-99,-98,-96
DATA -93,-91,-87,-83,-79,-74,-69,-63,-57
DATA -51,-44,-37,-30,-23,-15,-8,0
DATA " quadrato "
DATA "diagonale "
DATA "rettangolo"
DATA "  random  "
DATA "  rumore  "
DATA "   seno   "
DATA "   linea  "
DATA "triangolo "
DATA " prefab 1 "
DATA " prefab 2 "
DATA "maxvolume "
DATA "minvolume "
DATA "vol.medio "
DATA "piu'volume"
DATA "menovolume"
DATA " riflesso "
DATA " inverso  "
DATA "  doppio  "
DATA "  filtro  "
DATA "distorsore"
DATA " conferma "
DATA " cancella "
DATA "   load   "
DATA "   save   "
DATA "   fine   "

REM Qui iniziano le routines di gestione
REM delle forme d'onda

loader:
LOCATE 10,24
INPUT"Nome del file? ",l$
IF l$="" THEN GOTO loader
OPEN l$ FOR INPUT AS #2
FOR s=0 TO 255
INPUT# 2,dati(s)
NEXT
CLOSE #2
GOSUB forma
RETURN

saver:
LOCATE 10,24
INPUT"Nome del file ",s$
IF s$="" THEN GOTO saver
OPEN s$ FOR OUTPUT AS #1
FOR s=0 TO 255
WRITE #1,onda%(s)
NEXT
CLOSE #1
GOSUB forma
RETURN

fine:
LOCATE 10,15
PRINT "Grazie per avermi utilizzato!!"
LOCATE 12,22
PRINT "Premi un tasto"
GOSUB tasto
SYSTEM

piuvolume:
FOR s=0 TO 255
dati(s)=dati(s)+5
IF dati(s)>127 THEN dati(s)=127
NEXT
GOSUB forma
RETURN

menovolume:
FOR s=0 TO 255
dati(s)=dati(s)-5
IF dati(s)<-128 THEN dati(s)=-128
NEXT
GOSUB forma
RETURN

maxvolume:
max=dati(0)
FOR s=0 TO 255
IF dati(s)>max THEN max=dati(s)
NEXT
FOR s=0 TO 255
dati(s)=dati(s)+(127-max)
NEXT
GOSUB forma
RETURN

minvolume:
min=dati(0)
FOR s=0 TO 255
IF dati(s)<min THEN min=dati(s)
NEXT
FOR s=0 TO 255
dati(s)=dati(s)-(128+min)
NEXT
GOSUB forma
RETURN

volmedio:
dati(0)=media
FOR s=0 TO 255
media=media+dati(s)
NEXT
media=INT(media/256)
FOR s=0 TO 255
dati(s)=dati(s)-media
IF dati(s)>127 THEN dati(s)=127
IF dati(s)<-128 THEN dati(s)=-128
NEXT
GOSUB forma 
RETURN

riflesso:
FOR s=0 TO 255
dati(s)=-dati(s)
NEXT
GOSUB forma
RETURN

inverso:
FOR s=0 TO 255
reverse(s)=dati(s)
NEXT
rev=255
FOR s=0 TO 255
dati(s)=reverse(rev)
rev=rev-1
NEXT
GOSUB forma
RETURN

distorsore:
FOR s=0 TO 254 STEP 2
dati(s)=dati(s)+1
IF dati(s)>127 THEN dati(s)=127
NEXT
FOR s=1 TO 255 STEP 2
dati(s)=dati(s)-1
IF dati(s)<-128 THEN dati(s)=-128
NEXT
GOSUB forma
RETURN

filtro:
LOCATE 10,31
PRINT "Un attimo,prego"
FOR f=1 TO 20
estremo=dati(0)
FOR s=0 TO 224
dati(s)=INT((dati(s)+dati(s+1))/2)
NEXT
dati(255)=INT((dati(255)+estremo)/2)
NEXT
GOSUB forma
RETURN

doppio:
FOR s=0 TO 127
doppio(s)=INT((dati(2*s)+dati(2*s+1))/2)
dati(s)=doppio(s)
NEXT
FOR s=128 TO 255
dati(s)=doppio(s-128)
NEXT
GOSUB forma
RETURN

cancella:
FOR s=0 TO 255
dati(s)=prima(s)
NEXT
GOSUB forma
RETURN

forma:
LINE (64,6)-(576,134),2,bf
FOR s=0 TO 255
prima(s)=onda%(s)
onda%(s)= dati(s)
PSET(64+2*s,70-onda%(s)/2)
NEXT
WAVE 0,onda%
RETURN

REM Qui iniziano le routines
REM di gestione schermo e menu

schermo:
FOR y=0 TO 4
FOR x=0 TO 512 STEP 128
READ scelte$
LOCATE 19+y
PRINT PTAB (x+20);scelte$;
NEXT
NEXT
LOCATE 18,22
PRINT "DO1 RE1 DO2 RE2 MI2 DO3 RE3 MI3 DO4 RE4"
FOR f=143 TO 183 STEP 8                   
LINE (0,f)-(640,f),3
NEXT
FOR x=128 TO 512 STEP 128
LINE (x,143)-(x,183),3
NEXT
FOR y=6 TO 134 STEP 16
LINE (58,y)-(582,y),3
NEXT
FOR f=164 TO 484 STEP 32
LINE (f,134)-(f,143),2
NEXT
RETURN

leggimouse:
selezione=0
WHILE selezione=0
WHILE MOUSE(0)>0
WEND
WHILE MOUSE(0)=0
WEND
x=MOUSE(1)
orizz=INT(x/128)
y=MOUSE(2)
vert=INT((y-143)/8)
IF vert=0 THEN
selezione=5*orizz+1
ELSEIF vert=1 THEN
selezione=5*orizz+2
ELSEIF vert=2 THEN
selezione=5*orizz+3
ELSEIF vert=3 THEN
selezione=5*orizz+4
ELSEIF vert=4 THEN
selezione=5*orizz+5
ELSE
selezione=0
IF x>63 AND x<576 AND y>6 AND y<135 THEN
s=INT((x-64)/2)
PSET (64+2*s,70-INT(dati(s))/2),2
dati(s)=(70-y)*2
PSET (64+2*s,70-INT(dati(s))/2)
END IF
IF y>134 AND y<143 AND x>164 AND x<484 THEN
SOUND note(INT((x-164)/32)),1,200,0
END IF
END IF
WEND
RETURN

scelta:
selezione=0
WHILE selezione<>25
GOSUB leggimouse
IF selezione=1 THEN
GOSUB quadrato
ELSEIF selezione=2 THEN
GOSUB seno
ELSEIF selezione=3 THEN
GOSUB maxvolume
ELSEIF selezione=4 THEN
GOSUB riflesso
ELSEIF selezione=5 THEN
GOSUB forma
ELSEIF selezione=6 THEN
GOSUB diagonale
ELSEIF selezione=7 THEN
GOSUB linea
ELSEIF selezione=8 THEN
GOSUB minvolume
ELSEIF selezione=9 THEN
GOSUB inverso
ELSEIF selezione=10 THEN
GOSUB cancella
ELSEIF selezione=11 THEN
GOSUB rettangolo
ELSEIF selezione=12 THEN
GOSUB triangolo
ELSEIF selezione=13 THEN 
GOSUB volmedio
ELSEIF selezione=14 THEN
GOSUB doppio
ELSEIF selezione=15 THEN
GOSUB loader
ELSEIF selezione=16 THEN
GOSUB random
ELSEIF selezione=17 THEN
GOSUB prefab1
ELSEIF selezione=18 THEN
GOSUB piuvolume
ELSEIF selezione=19 THEN
GOSUB filtro
ELSEIF selezione=20 THEN
GOSUB saver
ELSEIF selezione=21 THEN
GOSUB rumore
ELSEIF selezione=22 THEN
GOSUB prefab2
ELSEIF selezione=23 THEN
GOSUB menovolume
ELSEIF selezione=24 THEN
GOSUB distorsore
END IF
WEND
GOTO fine

tasto:
a$=INKEY$
IF a$="" THEN GOTO tasto
RETURN

errore:
IF ERR=53 THEN
LINE (64,6)-(576,134),2,bf
LOCATE 10,30
PRINT "Questo file non esiste!!"
LOCATE 12,34
PRINT " premi un tasto"
GOSUB tasto
LINE (64,6)-(576,134),2,bf
RESUME leggimouse
ELSE
LOCATE 10,23
PRINT "C'e' un errore!!!!!!"
LOCATE 12,23
PRINT "Mi dispiace!"
END 
END IF

