Public Class frmSounder
#Region "Enumeratori / Strutture"
'Nome delle note
Public Enum NomeNota
_Do = -9
Re = -7
Mi = -5
Fa = -4
Sol = -2
La = 0
Si = 2
Pausa = -32000
End Enum
'Nome delle alterazioni
Public Enum Alterazione
Doppio_Dieses = 2
Diesis = 1
Bequadro = 0
Bemolle = -1
Doppio_Bemolle = -2
End Enum
'Nome delle ottave
Public Enum Ottava
Prima = -36
Seconda = -24
Terza = -12
Centrale = 0
Quinta = 12
Sesta = 24
Settima = 36
End Enum
'Nomi delle figure musicali, in funzione di una fusa
Public Enum Figura
Breve = 256
Semibreve = 128
Minima = 64
Semiminima = 32
Croma = 16
Semicroma = 8
Biscroma = 4
Semibiscroma = 2
Fusa = 1
End Enum
'Indicazione di tempo
Public Structure Tempo
Dim Fig As Figura
Dim Battiti As Byte
Sub New(ByVal F As Figura, ByVal b As Byte)
Fig = F
Battiti = b
End Sub
Shadows Function ToString() As String
Return Fig.ToString + " = " + Battiti.ToString
End Function
End Structure
'Una nota
Public Structure Nota
Dim Nome As NomeNota
Dim Alt As Alterazione
Dim Ott As Ottava
Dim Fig As Figura
Dim Punti As Byte
Sub New(ByVal n As NomeNota, ByVal a As Alterazione, ByVal o As Ottava, ByVal f As Figura, ByVal p As Byte)
Nome = n
Alt = a
Ott = o
Fig = f
Punti = p
End Sub
Shadows Function ToString() As String
Return Nome.ToString.Replace("_", "") + ToStr(Alt)
End Function
Function GetArrayName() As String()
Dim S() As String = { _
Nome.ToString.Replace("_", "") + ToStr(Alt), _
Fig.ToString + " " + New String(".", Punti), _
Ott.ToString}
Return S
End Function
'Restituisce il coefficiente di moltiplicazione della lunghezza di una nota con un dato numero di punti
Public Function GetCoef() As Single
Select Case Punti
Case 0
Return 1
Case 1
Return 1.5
Case 2
Return 1.75
Case 3
Return 1.975
End Select
End Function
'Frequenza di una nota, in hertz
Public Function GetFreq() As Single
If Nome = NomeNota.Pausa Then
Return 0
End If
Dim C As Single
C = (Nome + Alt + Ott) / 12
Return 440 * (2 ^ C)
End Function
'Lunghezza di una nota, in millisecondi
Public Function GetLength(ByVal T As Tempo) As Single
Dim C As Single = 60000 / T.Battiti
Return C * (Fig * GetCoef()) / T.Fig
End Function
'Suona la nota
Public Sub Play()
Dim F, L As Int32
F = GetFreq()
L = GetLength(Time)
Beep(F, L)
End Sub
End Structure
#End Region
#Region "Metodi"
Declare Function Beep Lib "kernel32.dll" (ByVal dwFreq As Integer, ByVal dwDuration As Integer) As Boolean
Public Shared Function ToStr(ByVal Alt As Alterazione) As String
Select Case Alt
Case Alterazione.Bemolle
Return "b"
Case Alterazione.Bequadro
Return ""
Case Alterazione.Diesis
Return "#"
Case Alterazione.Doppio_Bemolle
Return "bb"
Case Alterazione.Doppio_Dieses
Return "##"
End Select
Return ""
End Function
Function GetObject() As ListViewItem
Dim L As ListViewItem
If tabInsert.SelectedIndex = 0 Then
Dim N As New Nota
Select Case cmbNome.SelectedItem
Case "Do"
N.Nome = NomeNota._Do
Case "Re"
N.Nome = NomeNota.Re
Case "Mi"
N.Nome = NomeNota.Mi
Case "Fa"
N.Nome = NomeNota.Fa
Case "Sol"
N.Nome = NomeNota.Sol
Case "La"
N.Nome = NomeNota.La
Case "Si"
N.Nome = NomeNota.Si
Case "Pausa"
N.Nome = NomeNota.Pausa
End Select
N.Alt = 2 - cmbAlt.SelectedIndex
N.Ott = (cmbOtt.SelectedIndex - 3) * 12
N.Punti = nudPunti.Value
N.Fig = 2 ^ (8 - cmbFig.SelectedIndex)
L = New ListViewItem(N.GetArrayName)
L.Tag = N
Else
Dim T As New Tempo
T.Fig = 2 ^ (8 - cmbTimeFig.SelectedIndex)
T.Battiti = nudBattiti.Value
L = New ListViewItem(T.ToString)
L.Tag = T
End If
Return L
End Function
#End Region
#Region "Variabili globali / Costanti"
Public Shared Time As New Tempo(Figura.Semiminima, 120)
#End Region
Private Sub frmSounder_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub cmdAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdd.Click
lstNote.Items.Add(GetObject)
End Sub
Private Sub cmdInsert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdInsert.Click
If lstNote.SelectedIndices.Count > 0 Then
lstNote.Items.Insert(lstNote.SelectedIndices(0), GetObject)
Else
MsgBox("Selezionare un elemento!", MsgBoxStyle.Exclamation)
End If
End Sub
Private Sub cmdChange_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdChange.Click
If lstNote.SelectedIndices.Count > 0 Then
Dim L As ListViewItem = GetObject()
lstNote.Items(lstNote.SelectedIndices(0)).Text = L.Text
lstNote.Items(lstNote.SelectedIndices(0)).Tag = L.Tag
Else
MsgBox("Selezionare un elemento!", MsgBoxStyle.Exclamation)
End If
End Sub
Private Sub cmdRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRemove.Click
If lstNote.SelectedIndices.Count > 0 Then
lstNote.Items.RemoveAt(lstNote.SelectedIndices(0))
Else
MsgBox("Selezionare un elemento!", MsgBoxStyle.Exclamation)
End If
End Sub
Private Sub cmdPlay_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPlay.Click
Dim L As ListViewItem
Dim N As Nota
Time = New Tempo(Figura.Semiminima, 120)
For I As Int32 = 0 To lstNote.Items.Count - 1
L = lstNote.Items(I)
If TypeOf L.Tag Is Nota Then
N = L.Tag
N.Play()
Else
Time = L.Tag
End If
Next
End Sub
Private Sub cmdClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClear.Click
lstNote.Items.Clear()
End Sub
Private Sub cmdBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseSave.Click
Dim S As New SaveFileDialog
S.Filter = "File di notazione|*.mus"
If S.ShowDialog = Windows.Forms.DialogResult.OK Then
txtDirSave.Text = S.FileName
End If
End Sub
Private Sub cmdBrowseLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseLoad.Click
Dim O As New OpenFileDialog
O.Filter = "File di notazione|*.mus"
If O.ShowDialog = Windows.Forms.DialogResult.OK Then
txtDirLoad.Text = O.FileName
End If
End Sub
Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click
Try
Dim W As New IO.StreamWriter(txtDirSave.Text)
Dim L As ListViewItem
Dim N As Nota
Dim T As Tempo
Dim S As String
For I As Int32 = 0 To lstNote.Items.Count - 1
L = lstNote.Items(I)
If TypeOf L.Tag Is Nota Then
N = L.Tag
S = N.Nome & "|" & N.Alt & "|" & N.Ott & "|" & N.Fig & "|" & N.Punti
Else
Time = L.Tag
T = L.Tag
S = T.Fig & "|" & T.Battiti
End If
W.Write(S + ";")
Application.DoEvents()
Next
W.Close()
MsgBox("File salvato!", MsgBoxStyle.Information)
Catch Ex As Exception
MsgBox("Impossibile salvare il file!", MsgBoxStyle.Exclamation)
End Try
End Sub
Private Sub cmdLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLoad.Click
Try
Dim R As New IO.StreamReader(txtDirLoad.Text)
Dim L As ListViewItem
Dim N As Nota
Dim T As Tempo
Dim S, All(), Tag() As String
S = R.ReadToEnd
R.Close()
All = S.Split(";")
For I As Int32 = 0 To UBound(All)
If All(I) = "" Then
Continue For
End If
Tag = All(I).Split("|")
If Tag.Length = 5 Then
N = New Nota(CInt(Tag(0)), CInt(Tag(1)), CInt(Tag(2)), CInt(Tag(3)), CInt(Tag(4)))
L = New ListViewItem(N.GetArrayName)
L.Tag = N
Else
T = New Tempo(CInt(Tag(0)), CInt(Tag(1)))
L = New ListViewItem(T.ToString)
L.Tag = T
End If
lstNote.Items.Add(L)
Application.DoEvents()
Next
Catch Ex As Exception
MsgBox("Impossibile caricare il file!", MsgBoxStyle.Exclamation)
End Try
End Sub
End Class