码迷,mamicode.com
首页 > 其他好文 > 详细

音频文件解析(二):WAV格式文件波形绘制

时间:2015-04-07 17:02:53      阅读:698      评论:0      收藏:0      [点我收藏+]

标签:

  解析WAV头部信息后,接下来就可以根据相关参数和DATA块数据绘制波形.


1.重新编码(转换为8bits,单声道数据)

  Public Function GetFormatData(ByVal pData() As Byte, ByVal pWaveHeader As waveHeaderStructre) As Byte()
        Dim temp As Integer
        Dim data() As Byte = {}
        If pWaveHeader.BitsPerSample = 8 And pWaveHeader.FormatChannels = 1 Then
            ReDim data(pData.Length - 1)
            For i = 0 To data.Length - 1
                data(i) = pData(i)
            Next
        ElseIf pWaveHeader.BitsPerSample = 8 And pWaveHeader.FormatChannels = 2 Then
            ReDim data(pData.Length / 2 - 1)
            For i = 0 To data.Length - 1
                data(i) = pData(i * 2)
            Next
        ElseIf pWaveHeader.BitsPerSample = 16 And pWaveHeader.FormatChannels = 1 Then
            ReDim data(pData.Length / 2 - 1)
            For i = 0 To data.Length - 1
                temp = System.BitConverter.ToInt16(pData, i * 2) / 256 + 127
                temp = IIf(temp > 255, 255, temp)
                temp = IIf(temp < 0, 0, temp)
                data(i) = temp
            Next
        ElseIf pWaveHeader.BitsPerSample = 16 And pWaveHeader.FormatChannels = 2 Then
            ReDim data(pData.Length / 4 - 1)
            For i = 0 To data.Length - 1
                temp = System.BitConverter.ToInt16(pData, i * 4) / 256 + 127
                temp = IIf(temp > 255, 255, temp)
                temp = IIf(temp < 0, 0, temp)
                data(i) = temp
            Next
        End If
        Return data
    End Function

 

2.显示波形

    Public Sub PaintingWave(ByVal pData() As Byte, ByVal pWaveHeader As waveHeaderStructre, ByVal pBox As PictureBox)
        Dim pg As Graphics = pBox.CreateGraphics
        Dim pwidth As Integer = pBox.Width
        Dim pheight As Integer = pBox.Height
        Dim points As New List(Of PointF)
        Dim PImage As Bitmap = New Bitmap(pwidth, pheight)
        pg = Drawing.Graphics.FromImage(PImage)
        For i = 0 To pheight 绘制渐变背景
            pg.DrawLine(New Pen(Color.FromArgb(100 + Math.Abs(i / (pheight / 255) - 128), 0, 0, 0), 1), 0, i, pwidth, i)
        Next
        For i = 0 To pData.Length - 1 波形的离散数据点
            points.Add(New PointF(i * (pwidth / pData.Length), pheight - pData(i) * (pheight / 255)))
        Next
        pg.DrawLines(New Pen(Color.FromArgb(0, 0, 0)), points.ToArray)
        pBox.Image = PImage
        pg.Dispose()
    End Sub

3.完整WAV分析封装类(头部信息解析,重新编码,波形可视化)

示例:

Dim SamplesWave As New WaveClass("F:\Music\李宗盛-山丘.wav")

SamplesWave.PaintWave(PictureBox1)

技术分享
Class WaveClass
    Public waveHeadInf As waveHeaderStructre wav文件头部信息
    Dim fileData() As Byte 文件原始数据
    Public waveData() As Byte DATA块原始数据
    Structure waveHeaderStructre
        RiffChunk
        Dim RIFF As String
        Dim FileSize As UInteger
        Dim WAVE As String
        FormatChunk
        Dim FORMAT As String
        Dim FormatSize As UInteger
        Dim FilePadding As UShort
        Dim FormatChannels As UShort
        Dim SamplesPerSecond As UInteger
        Dim AverageBytesPerSecond As UInteger
        Dim BytesPerSample As UShort
        Dim BitsPerSample As UShort
        Dim FormatExtra As UShort
        FactChunk
        Dim FACT As String
        Dim FactSize As UInteger
        Dim FactInf As UInteger
        DataChunk
        Dim DATA As String
        Dim DataSize As UInteger
    End Structure
    Public Sub New(ByVal FileName As String)
        fileData = My.Computer.FileSystem.ReadAllBytes(FileName) 加载wav文件
        SplitWaveData(fileData) 分析头部,并获取DATA块数据
    End Sub
    Public Sub PaintWave(ByVal pBox As PictureBox, Optional ByVal pData() As Byte = Nothing) 指定PictureBox绘制波形
        If pData Is Nothing Then pData = GetFormatData()
        Dim pg As Graphics = pBox.CreateGraphics
        Dim pwidth As Integer = pBox.Width
        Dim pheight As Integer = pBox.Height
        Dim points As New List(Of PointF)
        Dim PImage As Bitmap = New Bitmap(pwidth, pheight)
        pg = Drawing.Graphics.FromImage(PImage)
        For i = 0 To pheight 绘制渐变背景
            pg.DrawLine(New Pen(Color.FromArgb(100 + Math.Abs(i / (pheight / 255) - 128), 0, 0, 0), 1), 0, i, pwidth, i)
        Next
        For i = 0 To pData.Length - 1 波形的离散数据点
            points.Add(New PointF(i * (pwidth / pData.Length), pheight - pData(i) * (pheight / 255)))
        Next
        pg.DrawLines(New Pen(Color.FromArgb(0, 0, 0)), points.ToArray)
        pBox.Image = PImage
        pg.Dispose()
    End Sub
    Private Sub SplitWaveData(ByVal data As Byte()) 提取wav文件头部信息
        Dim tempIndex As UShort = 0
        waveHeadInf.RIFF = CType(System.Text.Encoding.ASCII.GetChars(data, 0, 4), String)
        waveHeadInf.FileSize = System.BitConverter.ToUInt32(data, 4)
        waveHeadInf.WAVE = CType(System.Text.Encoding.ASCII.GetChars(data, 8, 4), String)
        FormatChunk
        waveHeadInf.FORMAT = CType(System.Text.Encoding.ASCII.GetChars(data, 12, 4), String)
        waveHeadInf.FormatSize = System.BitConverter.ToUInt32(data, 16)
        waveHeadInf.FilePadding = System.BitConverter.ToUInt16(data, 20)
        waveHeadInf.FormatChannels = System.BitConverter.ToUInt16(data, 22)
        waveHeadInf.SamplesPerSecond = System.BitConverter.ToUInt32(data, 24)
        waveHeadInf.AverageBytesPerSecond = System.BitConverter.ToUInt32(data, 28)
        waveHeadInf.BytesPerSample = System.BitConverter.ToUInt16(data, 32)
        waveHeadInf.BitsPerSample = System.BitConverter.ToUInt16(data, 34)
        If waveHeadInf.FormatSize = 18 Then
            waveHeadInf.FormatExtra = System.BitConverter.ToUInt16(data, 36)
        Else
            waveHeadInf.FormatExtra = 0
        End If
        tempIndex = 20 + waveHeadInf.FormatSize
        FactChunk
        waveHeadInf.FACT = CType(System.Text.Encoding.ASCII.GetChars(data, tempIndex, 4), String)
        If waveHeadInf.FACT = "fact" Then
            waveHeadInf.FactSize = System.BitConverter.ToUInt32(data, tempIndex + 4)
            waveHeadInf.FactInf = IIf(waveHeadInf.FactSize = 2, System.BitConverter.ToUInt16(data, tempIndex + 8), System.BitConverter.ToUInt32(data, tempIndex + 8))
            tempIndex = tempIndex + waveHeadInf.FactSize + 8
        Else
            waveHeadInf.FACT = "NULL"
            waveHeadInf.FactSize = 0
            waveHeadInf.FactInf = 0
        End If
        DataChunk
        waveHeadInf.DATA = CType(System.Text.Encoding.ASCII.GetChars(data, tempIndex, 4), String)
        waveHeadInf.DataSize = System.BitConverter.ToUInt32(data, tempIndex + 4)
        tempIndex = tempIndex + 8
        提取DATA数据块
        ReDim waveData(data.Length - tempIndex)
        Array.Copy(data, tempIndex, waveData, 0, data.Length - tempIndex)
    End Sub
    Private Function GetFormatData() As Byte() 重新编码
        Dim temp As Integer
        Dim data() As Byte = {}
        If waveHeadInf.BitsPerSample = 8 And waveHeadInf.FormatChannels = 1 Then
            ReDim data(waveData.Length - 1)
            For i = 0 To data.Length - 1
                data(i) = waveData(i)
            Next
        ElseIf waveHeadInf.BitsPerSample = 8 And waveHeadInf.FormatChannels = 2 Then
            ReDim data(waveData.Length / 2 - 1)
            For i = 0 To data.Length - 1
                data(i) = waveData(i * 2)
            Next
        ElseIf waveHeadInf.BitsPerSample = 16 And waveHeadInf.FormatChannels = 1 Then
            ReDim data(waveData.Length / 2 - 1)
            For i = 0 To data.Length - 1
                temp = System.BitConverter.ToInt16(waveData, i * 2) / 256 + 127
                temp = IIf(temp > 255, 255, temp)
                temp = IIf(temp < 0, 0, temp)
                data(i) = temp
            Next
        ElseIf waveHeadInf.BitsPerSample = 16 And waveHeadInf.FormatChannels = 2 Then
            ReDim data(waveData.Length / 4 - 1)
            For i = 0 To data.Length - 1
                temp = System.BitConverter.ToInt16(waveData, i * 4) / 256 + 127
                temp = IIf(temp > 255, 255, temp)
                temp = IIf(temp < 0, 0, temp)
                data(i) = temp
            Next
        End If
        Return data
    End Function
End Class
View Code

 

音频文件解析(二):WAV格式文件波形绘制

标签:

原文地址:http://www.cnblogs.com/experdot/p/4398705.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!