2. Modul MFCC - Appendix (610.1Kb)
LAMPIRAN I
LISTING PROGRAM
1. Modul MySql
Imports MySql.Data.MySqlClient Module ModuleMySql Dim Strcon As String = "server=localhost;user=root;database=piano;port=3306;password=;" Dim conn As MySqlConnection Sub hubungkan() Try conn = New MySqlConnection(Strcon) conn.Open() Catch ex As Exception MessageBox.Show("Koneksi Gagal : " & ex.Message) End Try End Sub Function lookup(ByVal strquery As String) As DataTable hubungkan() Dim hasil As New DataTable Dim cmd As MySqlCommand = New MySqlCommand(strquery, conn) Dim rdr As MySqlDataReader = cmd.ExecuteReader hasil.Load(rdr) rdr.Close() conn.Close() Return hasil End Function Function query(ByVal strquery As String) As String Try hubungkan() Dim hasil As New DataTable Dim cmd As MySqlCommand = New MySqlCommand(strquery, conn) conn.Close() Catch ex As Exception conn.Close() Return "Gagal : " & ex.Message End Try Return "Berhasil" End Function End Module
2. Modul MFCC Imports System.Collections.Generic Imports System.Text Module ModuleMFCC Private Function my_rint(x As Double) As Integer If 2 * x = CDbl(Math.Round(2 * x)) Then x += 0.0001 End If Return CInt(Math.Truncate(Math.Round(x))) End Function Public Function DCremoval(ByVal signal As Double()) As Double() Dim hasil(signal.Length - 1) As Double Dim avg As Double = signal.Average For i As Integer = 0 To signal.Length - 1 hasil(i) = signal(i) - avg Next Return hasil End Function Public Function EmpFiltering(ByVal signal As Double()) As Double() Dim alpha As Double = -0.97 Dim hasil(signal.Length - 1) As Double For i As Integer = 1 To signal.Length - 2 hasil(i) = signal(i) + signal(i - 1) * alpha Next hasil(0) = signal(0) Return hasil End Function Public Function mfcc(ByRef signal As Double()) As Double() Dim lowestFrequency As Double = 133.3333 Dim linearFilters As Double = 13 Dim linearSpacing As Double = 66.66666666 Dim logFilters As Double = 27 Dim logSpacing As Double = 1.0711703 Dim fftSize As Double = 512 Dim cepstralCoefficients As Double = 13 Dim windowSize As Double = 256 Dim samplingRate As Double = 44100 Dim totalFilters As Double Dim mfccFilterWeights As Double() Dim freqs As Double() Dim triangleHeight As Double() Dim lower As Double() Dim upper As Double() Dim center As Double() Dim fftFreqs As Double() Dim hamWindow As Double() Dim mfccDCTMatrix As Double() Dim preEmphasized As Double() Dim first As Double Dim last As Double Dim fftData As Double() Dim empreinte As Double() Dim maxi As Double Dim earMag As Double()
Dim ceps As Double() Dim loga As Double Dim windowStep As Double Dim cols As Double Dim frameRate As Double = 100 Dim i As Integer, j As Integer, k As Integer signal = DCremoval(signal) preEmphasized = EmpFiltering(signal) totalFilters = linearFilters + logFilters freqs = New Double(CInt(Math.Truncate(totalFilters)) + 1) {} For i = 0 To linearFilters - 1 freqs(i) = lowestFrequency + i * linearSpacing Next For i = CInt(Math.Truncate(linearFilters)) To CInt(Math.Truncate(totalFilters)) + 1 freqs(i) = freqs(CInt(Math.Truncate(linearFilters)) - 1) * Math.Pow(logSpacing, i - linearFilters + 1) Next lower = New Double(CInt(Math.Truncate(totalFilters)) - 1) {} upper = New Double(CInt(Math.Truncate(totalFilters)) - 1) {} center = New Double(CInt(Math.Truncate(totalFilters)) - 1) {} triangleHeight = New Double(CInt(Math.Truncate(totalFilters)) - 1) {} fftData = New Double(CInt(Math.Truncate(fftSize)) - 1) {} For i = 0 To CInt(Math.Truncate(totalFilters)) - 1 lower(i) = freqs(i) Next For i = 1 To CInt(Math.Truncate(totalFilters)) center(i - 1) = freqs(i) Next For i = 2 To CInt(Math.Truncate(totalFilters)) + 1 upper(i - 2) = freqs(i) Next mfccFilterWeights = New Double(CInt(Math.Truncate(totalFilters * fftSize)) - 1) {} For i = 0 To totalFilters - 1 triangleHeight(i) = 2 / (upper(i) - lower(i)) Next fftFreqs = New Double(CInt(Math.Truncate(fftSize)) - 1) {} For i = 0 To fftSize - 1 fftFreqs(i) = (i / fftSize) * samplingRate Next For i = 0 To totalFilters - 1 For j = 0 To CInt(Math.Truncate(fftSize)) - 1 If (fftFreqs(j) > lower(i)) AndAlso (fftFreqs(j) <= center(i)) Then mfccFilterWeights(CInt(Math.Truncate(fftSize)) * i + j) = triangleHeight(i) * (fftFreqs(j) - lower(i)) / (center(i) - lower(i)) End If If (fftFreqs(j) > center(i)) AndAlso (fftFreqs(j) < upper(i)) Then mfccFilterWeights(CInt(Math.Truncate(fftSize)) * i + j) = (triangleHeight(i) * (fftFreqs(j) - lower(i)) / (center(i) - lower(i))) + (triangleHeight(i) * (upper(i) - fftFreqs(j)) / (upper(i) - center(i))) End If Next Next hamWindow = New Double(CInt(Math.Truncate(windowSize)) - 1) {} For i = 0 To windowSize - 1 hamWindow(i) = 0.54 - 0.46 * Math.Cos(2 * Math.PI * i / windowSize) Next mfccDCTMatrix = New Double(CInt(Math.Truncate(cepstralCoefficients
- totalFilters)) - 1) {} For i = 0 To cepstralCoefficients - 1 For j = 0 To totalFilters - 1 mfccDCTMatrix(j * CInt(Math.Truncate(cepstralCoefficients))
- i) = 1 / Math.Sqrt(totalFilters / 2) * Math.Cos(i * (2 * j + 1) * Math.PI / 2 / totalFilters) Next Next For i = 0 To totalFilters - 1 mfccDCTMatrix(i * CInt(Math.Truncate(cepstralCoefficients))) *= 1 / Math.Sqrt(2) Next earMag = New Double(CInt(Math.Truncate(totalFilters)) - 1) {} windowStep = samplingRate / frameRate cols = CInt(Math.Truncate((1024 - windowSize) / windowStep)) ceps = New Double(CInt(Math.Truncate(8 * cols * linearFilters)) - 1) {} For i = 0 To cols - 1
first = i * windowStep + 1 last = first + windowSize - 1 For j = 0 To fftSize - 1 fftData(j) = 0 Next For j = 0 To windowSize - 1 fftData(j) = preEmphasized(CInt(my_rint(first + j - 1))) * hamWindow(j) Next Dim fftMag As Double() = AlgoritmaFft.Calculate(signal) For j = 0 To totalFilters - 1 loga = 0 For k = 0 To fftSize - 1 loga += fftMag(k) * mfccFilterWeights(k + j * CInt(Math.Truncate(fftSize))) Next earMag(j) = Math.Log10(loga) Next
For j = 0 To linearFilters - 1 loga = 0 For k = 0 To totalFilters - 1 loga += earMag(k) * mfccDCTMatrix(j + k * CInt(Math.Truncate(linearFilters))) Next ceps(j + i * CInt(Math.Truncate(linearFilters))) = loga Next Next empreinte = New Double(11) {} For i = 1 To 12 empreinte(i - 1) = (ceps(i) + ceps(i + 13) + ceps(i + 26) + ceps(i + 39) + ceps(i + 52) + ceps(i + 65)) Next maxi = 0 For i = 0 To 11 If maxi * maxi < empreinte(i) * empreinte(i) Then maxi = empreinte(i) End If Next For i = 0 To 11 empreinte(i) = (empreinte(i) / Math.Abs(maxi)) * 2 Next Return empreinte End Function End Module
3. Modul FFT
Public NotInheritable Class AlgoritmaFft Private Sub New() End Sub Public Shared Function Calculate(x As Double()) As Double() Dim length As Integer Dim bitsInLength As Integer If x.Length > 1 AndAlso (x.Length And (x.Length - 1)) = 0 Then length = x.Length bitsInLength = Log2(length) - 1 Else bitsInLength = Log2(x.Length) length = 1 << bitsInLength End If
Dim data As ComplexNumber() = New ComplexNumber(length - 1) {} For i As Integer = 0 To x.Length - 1 Dim j As Integer = ReverseBits(i, bitsInLength) data(j) = New ComplexNumber(x(i)) Next For i As Integer = 0 To bitsInLength - 1 Dim m As Integer = 1 << i Dim n As Integer = m * 2 Dim alpha As Double = -(2 * Math.PI / n) For k As Integer = 0 To m - 1 Dim oddPartMultiplier As ComplexNumber = New ComplexNumber(0, alpha * k).PoweredE() Dim j As Integer = k While j < length Dim evenPart As ComplexNumber = data(j) Dim oddPart As ComplexNumber = oddPartMultiplier * data(j + m) data(j) = evenPart + oddPart data(j + m) = evenPart - oddPart j += n End While Next Next Dim spectrogram As Double() = New Double(length - 1) {} For i As Integer = 0 To spectrogram.Length - 1 spectrogram(i) = data(i).AbsPower2() Next Return spectrogram End Function Private Shared Function Log2(n As Integer) As Integer Dim i As Integer = 0 While n > 0 i += 1 n >>= 1 End While Return i End Function Private Shared Function ReverseBits(n As Integer, bitsCount As Integer) As Integer Dim reversed As Integer = 0 For i As Integer = 0 To bitsCount - 1 Dim nextBit As Integer = n And 1 n >>= 1 reversed <<= 1 reversed = reversed Or nextBit Next Return reversed End Function
End Class
4. Modul Suara
Imports NAudio.Wave Module ModuleSuara Function ekstraksisignaldigital(namafile As String) As Double() Dim tmp As Integer = 0 Dim x As Integer = 0 Dim xx As Double = 0.0 Dim tmpxy As New List(Of Double()) Dim fr As IO.StreamReader = New IO.StreamReader(namafile) Dim signal() As Double Using wfr As New WaveFileReader(namafile) Using ws As WaveStream = WaveFormatConversionStream.CreatePcmStream(wfr) Using baStream As WaveStream = New BlockAlignReductionStream(ws) Dim format As New WaveFormat(baStream.WaveFormat.SampleRate, baStream.WaveFormat.BitsPerSample, baStream.WaveFormat.Channels) Dim buffer1 As Byte() = New Byte(baStream.WaveFormat.BitsPerSample / 8 - 1) {} Dim SampleRate = baStream.WaveFormat.SampleRate Dim wavFormat = baStream.WaveFormat Dim bytesRead As Integer = 0 Dim previousPosition As Long = 0 Dim currentValue As Double Dim avg As Double = 0 ReDim signal(baStream.Length) Dim i As Integer = 0 While baStream.Position < baStream.Length bytesRead = baStream.Read(buffer1, 0, baStream.WaveFormat.BitsPerSample / 8) If baStream.WaveFormat.BitsPerSample / 8 > 1 Then currentValue = 100.0 * BitConverter.ToInt16(buffer1, 0) / Short.MaxValue Else currentValue = 100.0 * 255 * (buffer1(0) - 128) / Short.MaxValue End If If Not x = 0 And (x Mod 5 = 0) Then If Not CInt(currentValue) * -1 = 0 Then tmpxy.Add(New Double() {x, CInt(currentValue) * -1 + 150, x - 1, tmp * -1 + 150}) End If End If xx += 0.02 x = CInt(xx) signal(i) = currentValue avg += currentValue i += 1 End While avg /= baStream.Length End Using End Using End Using Return signal End Function Function potongsuara(ByVal signal As Double(), ByVal tampil As Boolean, ByVal x As Integer) As List(Of Double()) Dim hasil As New List(Of Double()) Dim awal As Integer = -1, akhir As Integer = -1 Dim potong As New List(Of Integer) Dim count As Integer = 0 For i As Integer = 0 To signal.Count - 2 If Not (signal(i) >= -5 And signal(i) <= 5) Then Dim tmphasil(x) As Double For j As Integer = 0 To x - 1 If i + j > signal.Count - 1 Then Exit For End If tmphasil(j) = signal(i + j) Next hasil.Add(tmphasil) i += x End If Next If tampil Then For k As Integer = 0 To hasil.Count - 1 Dim p As Integer = 1000 Dim a As New Form a.Width = 500 a.Height = 500 a.Show() Dim g As Graphics g = a.CreateGraphics Dim penn As New System.Drawing.Pen(Brushes.Black, 5) g.DrawLine(penn, New Point(0, 250), New Point(500, 250)) penn = New System.Drawing.Pen(Brushes.Red, 1) Dim l As Integer = 0 Dim tot As Double = 0 For i As Integer = 0 To hasil(k).Length - 1 Step p l += 1 tot = 0 For j As Integer = i To i + p tot += hasil(k)(i) Next tot = CInt(tot / p) If tot > 0 Then g.DrawLine(penn, New Point(l, 250), New Point(l, (250 + tot))) Else g.DrawLine(penn, New Point(l, (250 + tot)), New Point(l, 250)) End If Application.DoEvents()
Next Next End If Return hasil End Function End Module
5. Modul LVQ
Module LVQ Dim listdata As DataTable Dim a As New List(Of data) Dim maxEpoh As Integer = 5 Dim alpha As Double = 0.02 Dim jumlahvektor As Integer = 11 Dim LR As Double = 0.00005 Structure data Dim vektor() As Double Dim jenis As String Dim idjenis As Integer End Structure Public Sub AmbilData() Try listdata = lookup("SELECT jenisnada, v.`id`, `v1`, `v2`, `v3`, `v4`, `v5`, `v6`, `v7`, `v8`, `v9`, `v10`, `v11`, `v12`, `hasildari` FROM `vektor` v INNER JOIN jenisnada j on v.jenisnada=j.id") a.Clear() Dim ab As data For i As Integer = 0 To listdata.Rows.Count - 1 ab.jenis = listdata.Rows(i)(0) Dim nilaiv(11) As Double For j As Integer = 0 To jumlahvektor nilaiv(j) = CDbl(listdata.Rows(i)(j + 2)) Next ab.vektor = nilaiv ab.idjenis = listdata.Rows(i)(1) a.Add(ab) Next Catch MessageBox.Show("Database Tidk bisa diproses", "Database Error", _ MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End End Try End Sub Public Function pelatihan(ByVal vektor As Double()) As String
AmbilData() Dim j As Integer Dim bobotinput() As Double, nilaibanding() As Double Dim hasil As Double Dim min As Double = 100 Dim flag = 0 j = 0 bobotinput = vektor Dim Wbaru As String = "" Do flag += 1 For i As Integer = 0 To a.Count - 1 nilaibanding = a(i).vektor hasil = 0 For z As Integer = 0 To jumlahvektor hasil += Math.Abs(Math.Pow((bobotinput(z) - nilaibanding(z)), 2)) Next hasil = Math.Sqrt(hasil) If hasil < min Then min = hasil j = i End If Next Wbaru = "" nilaibanding = a(j).vektor For z As Integer = 0 To jumlahvektor Wbaru &= nilaibanding(z) + alpha * (bobotinput(z) - nilaibanding(z)) & "|" Next LR = alpha * LR Loop While flag <= maxEpoh Dim _mfcc = Wbaru.Split("|") query("insert into vektor(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,jenisnada,hasildari) values(" & _mfcc(0) & "," & _mfcc(1) & "," & _mfcc(2) & "," & _mfcc(3) & "," & _mfcc(4) & "," & _mfcc(5) & "," & _mfcc(6) & "," & _mfcc(7) & "," & _mfcc(8) & "," & _mfcc(9) & "," & _mfcc(10) & "," & _mfcc(11) & "," & a(j).jenis & ",'Pelatihan')") Return a(j).jenis End Function
Public Function pengenalan(ByVal vektor As Double()) As String AmbilData() Dim j As Integer Dim bobotinput() As Double, nilaibanding() As Double Dim hasil As Double Dim flag = 0 Dim min As Double = 100 bobotinput = vektor j = 0 For i As Integer = 0 To a.Count - 1 nilaibanding = a(i).vektor hasil = 0 For z As Integer = 0 To jumlahvektor hasil += Math.Abs(Math.Pow((bobotinput(z) - nilaibanding(z)), 2)) Next hasil = Math.Sqrt(hasil) If hasil < min Then min = hasil j = i End If Next Return a(j).jenis End Function End Module
6. Modul Cetak Partitur
Module CetakKeImage Function getGambarNotBalok(i As Integer) As Bitmap Select Case i + 1 Case 1 Return New Bitmap(My.Resources._do) Case 2 Return New Bitmap(My.Resources.re) Case 3 Return New Bitmap(My.Resources.mi) Case 4 Return New Bitmap(My.Resources.fa) Case 5 Return New Bitmap(My.Resources.sol) Case 6 Return New Bitmap(My.Resources.la) Case 7 Return New Bitmap(My.Resources.si) Case Else Return New Bitmap(My.Resources.do_) End Select End Function
Sub cetaknotbalok(ByVal notbalok() As Integer, ByVal dest As String) Dim height As Integer = 254 Dim width As Integer = 31 Dim x As Integer = 31 Dim y As Integer = 254 If notbalok.Count < 10 Then width *= notbalok.Count Else width = 310 height *= Math.Ceiling(notbalok.Count / 10) End If Dim kanvas As Bitmap Dim gr As Graphics kanvas = New Bitmap(width, height) gr = Graphics.FromImage(kanvas) Dim x1 As Integer = 0 Dim y1 As Integer = 0 For j As Integer = 0 To notbalok.Count - 1 gr.DrawImage(getGambarNotBalok(notbalok(j)), x1, y1) If j Mod 10 = 0 And Not j = 0 Then x1 = 0 y1 += y Else x1 += x End If Next kanvas.Save(dest) End Sub End Module