Private cb As ComboBox
Private Const ALTEZZA_TASTI_BIANCHI As Single = 0.35
Private bb As New Byte[3]
Private instrumenta As String[] = ["Acustic Grand Piano", "Bright Acustic Piano", "Electric Grand Piano", "Honky-tonk",
"Electric Piano 1", "Electric Piano 2", "Harpsichord", "Clavinet", "Celesta", "Glockenspiel", "Music Box", "Vibraphone",
"Marimba", "Xylophone", "Tubular Bells", "Dulcimer", "Hammond Organ", "Percussive Organ", "Rock Organ", "Church Organ",
"Reed Organ", "Accordion", "Harmonica", "Tango Accordion", "Acoustic Guitar (nylon)", "Acoustic Guitar (steel)",
"Electric Guitar (jazz)", "Electric Guitar (clean)", "Electric Guitar(muted)", "Overdriven Guitar", "Distortion Guitar",
"Guitar Harmonics", "Acoustic Bass", "Electric Bass (finger)", "Electric Bass (pick)", "Fretless Bass", "Slap Bass 1",
"Slap Bass 2", "Synth Bass 1", "Synth Bass 2", "Violin", "Viola", "Cello", "Contrabass", "Tremolo Strings",
"Pizzicato Strings", "Orchestral Harp", "Timpani", "String Ensemble 1", "String Ensemble 2", "SynthStrings 1",
"SynthStrings 2", "Choir Aahs", "Voice Oohs", "Synth Voice", "Orchestra Hit", "Trumpet", "Trombone", "Tuba", "Muted Trumpet",
"French Horn", "Brass Section", "Synth Brass 1", "Synth Brass 2", "Soprano Sax", "Alto Sax", "Tenor Sax", "Baritone Sax",
"Oboe", "English Horn", "Basson", "Clarinet", "Piccolo", "Flute", "Recorder", "Pan Flute", "Bottle Blow", "Shakuhachi",
"Whistle", "Ocarina", "Lead 1 (square)", "Lead 2 (sawtooth)", "Lead 3 (caliope lead)", "Lead 4 (chiff lead)",
"Lead 5 (charang)", "Lead 6 (voice)", "Lead 7 (fifths)", "Lead 8(brass+lead)", "Pad 1 (new age)", "Pad 2 (warm)",
"Pad 3 (polysynth)", "Pad 4 (choir)", "Pad 5 (bowed)", "Pad 6 (metallic)", "Pad 7 (halo)", "Pad 8 (sweep)", "FX 1 (rain)",
"FX 2 (soundtrack)", "FX 3 (crystal)", "FX 4 (atmosphere)", "FX 5 (brightness)", "FX 6 (goblins)", "FX 7 (echoes)",
"FX 8 (sci-fi)", "Sitar", "Banjo", "Shamisen", "Koto", "Kalimba", "Bagpipe", "Fiddle", "Shanai", "Tinkle Bell", "Agogo",
"Steel Drums", "Woodblock", "Taiko Drum", "Melodic Tom", "Synth Drum", "Reverse Cymbal", "Guitar Fret Noise", "Breath Noise",
"Seashore", "Bird Tweet", "Telephone Ring", "Helicopter", "Applause", "Gunshot"]
Public Sub Form_Open()
With Me
.W = Screen.AvailableWidth * 0.5
.H = Screen.AvailableHeight * 0.2
.Center
End With
CreaClient()
With cb = New ComboBox(Me) As "Combo"
.W = 160
.H = 25
.X = (Me.W * 0.94) - .W
.Y = 0
.List = instrumenta
.Index = 0
End With
CreaTastiera()
End
Private Procedure CreaTastiera()
Dim pn As Panel
Dim neri As New Byte[40]
Dim tasti As Button[]
Dim b, c, n As Byte
With pn = New Panel(Me)
.W = Me.W * 0.88
.H = Me.H * 0.2
.X = (Me.W / 2) - (pn.W / 2)
.Y = Me.H * 0.2
.Border = Border.Sunken
.Background = &8b4513
End With
Repeat
neri[b] = 25 + (12 * b / 5)
neri[b + 1] = 27 + (12 * b / 5)
neri[b + 2] = 30 + (12 * b / 5)
neri[b + 3] = 32 + (12 * b / 5)
neri[b + 4] = 34 + (12 * b / 5)
b += 5
Until b == neri.Count
tasti = New Button[109]
For t As Short = 0 To tasti.Max
With tasti[t] = New Button(Me) As "Tasti"
.W = 0
If t > 23 Then
If neri.Exist(t) Then ' Imposta i tasti neri
.W = Me.W * 0.013
.H = ((Me.H * ALTEZZA_TASTI_BIANCHI) * 66.66) / 100
Select Case t
Case 25 + (12 * n)
.X = tasti[t - 1].X + (((Me.W * 0.025) / 2))
Case 27 + (12 * n)
.X = tasti[t - 1].X + (((Me.W * 0.025) / 2))
Case 30 + (12 * n)
.X = tasti[t - 1].X + (((Me.W * 0.025) / 2))
Case 32 + (12 * n)
.X = tasti[t - 1].X + (((Me.W * 0.025) / 2))
Case 34 + (12 * n)
.X = tasti[t - 1].X + (((Me.W * 0.025) / 2))
Inc n
End Select
.Y = Me.H * 0.375
.Background = Color.Black
.Tag = t
Else
' Imposta i tasti bianchi:
.W = Me.W * 0.018
.H = Me.H * ALTEZZA_TASTI_BIANCHI
.X = (.W * c) + (Me.W / 16)
.Y = Me.H * 0.37
.Background = Color.White
.Tag = t
.Lower
Inc c
Endif
Endif
End With
Next
End
Public Sub Tasti_MouseDown()
bb[0] = 0
bb[1] = Last.Tag
bb[2] = &64
InvioMIDI(bb)
If Last.Background = Color.Black Then Last.Background = Color.DarkGray
Me.Title = "Nota Midi: " & Last.Tag
End
Public Sub Tasti_MouseUp()
bb[0] = 0
bb[1] = Last.Tag
bb[2] = 0
InvioMIDI(bb)
If Last.Background = Color.DarkGray Then Last.Background = Color.Black
Me.Title = Null
End
'''''''''''''''''''''''''''''''''''''''''''''''
Private seq As Pointer
Library "libasound:2"
Public Struct snd_seq_event_t ' Struttura dell'Evento Midi di ALSA
type As Byte
flags As Byte
tag As Byte
queue As Byte
tick_time As Integer
real_time As Integer
source_client As Byte
source_port As Byte
dest_client As Byte
dest_port As Byte
channel As Byte
note As Byte
velocity As Byte
off_velocity As Byte
param As Integer
value As Integer
End Struct
Private Const SND_SEQ_OPEN_OUTPUT As Integer = 1
Private Const SND_SEQ_EVENT_NOTEON As Byte = 6
Private Const SND_SEQ_EVENT_PGMCHANGE As Byte = 11
Private Const SND_SEQ_QUEUE_DIRECT As Byte = 253
' int snd_seq_open (snd_seq_t **handle, const char * name, int streams, int mode)
' Open the ALSA sequencer.
Private Extern snd_seq_open(handle As Pointer, name As String, streams As Integer, mode As Integer) As Integer
' const char * snd_strerror (int errnum)
' Returns the message for an error code.
Private Extern snd_strerror(err As Integer) As String
' int snd_seq_event_output (snd_seq_t *handle, snd_seq_event_t *ev)
' Output an event.
Private Extern snd_seq_event_output(handle As Pointer, ev As Snd_seq_event_t)
' int snd_seq_drain_output (snd_seq_t * seq)
' Drain output buffer to sequencer.
Private Extern snd_seq_drain_output(seq As Pointer) As Integer
' int snd_seq_close (snd_seq_t *handle)
' Close the sequencer.
Private Extern snd_seq_close(handle As Pointer) As Integer
Private Procedure CreaClient()
Dim rit As Integer
rit = snd_seq_open(VarPtr(seq), "default", SND_SEQ_OPEN_OUTPUT, 0)
If rit < 0 Then Error.Raise("Impossibile aprire il subsistema 'seq' di ALSA: " & snd_strerror(rit))
End
Public Sub Combo_Change() ' Imposta lo strumento musicale
Dim evento As New Snd_seq_event_t
With evento
.queue = SND_SEQ_QUEUE_DIRECT
.dest_client = 128
.dest_port = 0
.channel = 0
End With
' Imposta il tipo di strumento musicale mediante il Messaggio Midi "Program-Change":
Messaggio(evento, SND_SEQ_EVENT_PGMCHANGE, [0, 0, 0], cb.Index)
End
Private Procedure InvioMIDI(mid As Byte[])
Dim evento As New Snd_seq_event_t
With evento
.queue = SND_SEQ_QUEUE_DIRECT
.dest_client = 128
.dest_port = 0
.channel = mid[0]
End With
' Imposta il Messaggio Midi "Note-ON":
Messaggio(evento, SND_SEQ_EVENT_NOTEON, mid, 0)
End
Private Procedure Messaggio(ev As Snd_seq_event_t, tipo As Byte, nota As Byte[], strum As Integer)
With ev
.type = tipo
.channel = nota[0]
.note = nota[1]
.velocity = nota[2]
.value = strum
End With
' Inserisce l'Evento di ALSA nel buffer:
snd_seq_event_output(seq, ev)
' Invia l'Evento:
snd_seq_drain_output(seq)
End
Public Sub Form_Close()
snd_seq_close(seq)
End