Results 1 to 2 of 2

Thread: Creating .wav files - getting "clicks"

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Oct 2008
    Location
    Midwest Region, United States
    Posts
    3,574

    Creating .wav files - getting "clicks"

    All,

    I am creating some sounds using the following code (got the basis of it from this forum):

    Code:
    Option Explicit
    
    Private Incr As Integer
    Private I As Integer
    Private fName As String
    Private Buff(0 To 44100) As Integer
    Private Const SND_ASYNC = &H1
    Private Const SND_FILENAME = &H20000
    Private Declare Function PlaySound Lib "winmm.dll" _
        Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
    
    Private Type tWAVEFORMATEX
        wFormatTag As Integer
        nChannels As Integer
        nSamplesPerSec As Long
        nAvgBytesPerSec As Long
        nBlockAlign As Integer
        wBitsPerSample As Integer
        cbSize As Integer
        ExtraData(1 To 32) As Byte ' makes the structure 50 bytes long
    End Type
    
    Private Type FileHeader
        lRiff As Long
        lFileSize As Long
        lWave As Long
        lFormat As Long
        lFormatLength As Long
    End Type
    
    Private Type WaveFormat
        wFormatTag As Integer
        nChannels As Integer
        nSamplesPerSec As Long
        nAvgBytesPerSec As Long
        nBlockAlign As Integer
        wBitsPerSample As Integer
    End Type
    
    Private Type ChunkHeader
        lType As Long
        lLen As Long
    End Type
    
    Private Sub cmdNote_Click(Index As Integer)
        Dim I As Integer
        Incr = txtFreq.Text
        Select Case Index
            Case 0
                GenerateTone 261.63, Buff, 1
                fName = "c:\wave262.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 1
                GenerateTone 293.66, Buff, 1
                fName = "c:\wave294.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 2
                GenerateTone 329.63, Buff, 1
                fName = "c:\wave330.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 3
                GenerateTone 349.23, Buff, 1
                fName = "c:\wave349.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 4
                GenerateTone 392, Buff, 1
                fName = "c:\wave392.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 5
                GenerateTone 440, Buff, 1
                fName = "c:\wave440.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 6
                GenerateTone 493.88, Buff, 1
                fName = "c:\wave494.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 7
                GenerateTone 523.25, Buff, 1
                fName = "c:\wave523.wav"
                SaveWaveFile fName, Buff
                PlaySound fName, ByVal 0&, SND_FILENAME Or SND_ASYNC
            Case 99
                Timer1.Enabled = True
        End Select
        
    End Sub
    
    Private Sub GenerateTone(ByVal Frequency As Single, _
        intBuff() As Integer, Optional Amplitude As Single = 1, _
        Optional SamplesPerSec As Long = 44100, _
        Optional startPos As Long = 0, Optional Length As Long = -1)
        
        Dim K As Long, V1 As Double
        Const Pi As Double = 3.14159265358979
        V1 = SamplesPerSec / (Pi * 2 * Frequency)
        'If Length = -1 Then Length = UBound(intBuff) - startPos
        Length = 5512
        For K = startPos To startPos + Length
            intBuff(K) = CInt(Fix(Sin(K / V1) * (32766.5 * Amplitude)))
        Next K
    End Sub
    
    Private Sub SaveWaveFile(ByVal WaveFileName As String, _
        ByRef buffer() As Integer, Optional SamplesPerSec As Long = 44100)
        Dim wF As tWAVEFORMATEX
        wF.wFormatTag = 1
        wF.nChannels = 1
        wF.wBitsPerSample = 16
        wF.nSamplesPerSec = SamplesPerSec
        wF.nBlockAlign = (wF.wBitsPerSample * wF.nChannels) / 8
        wF.nAvgBytesPerSec = wF.nSamplesPerSec * wF.nBlockAlign
        Open WaveFileName For Binary Access Write Lock Write As #1
            WaveWriteHeader 1, wF
            Put #1, , buffer
            WaveWriteHeaderEnd 1
        Close #1
    End Sub
    
    Private Sub WaveWriteHeader(ByVal OutFileNum As Integer, _
        WaveFmt As tWAVEFORMATEX)
            
        Dim Header As FileHeader
        Dim HdrFormat As WaveFormat
        Dim Chunk As ChunkHeader
        
        With Header
            .lRiff = &H46464952
            .lFileSize = 0
            .lWave = &H45564157
            .lFormat = &H20746D66
            .lFormatLength = Len(HdrFormat)
        End With
        
        With HdrFormat
            .wFormatTag = WaveFmt.wFormatTag
            .nChannels = WaveFmt.nChannels
            .nSamplesPerSec = WaveFmt.nSamplesPerSec
            .nAvgBytesPerSec = WaveFmt.nAvgBytesPerSec
            .nBlockAlign = WaveFmt.nBlockAlign
            .wBitsPerSample = WaveFmt.wBitsPerSample
        End With
        
        Chunk.lType = &H61746164
        Chunk.lLen = 0
        
        Put #OutFileNum, 1, Header
        Put #OutFileNum, , HdrFormat
        Put #OutFileNum, , Chunk
    End Sub
    
    Private Sub WaveWriteHeaderEnd(ByVal OutFileNum As Integer)
        Dim Header As FileHeader
        Dim HdrFormat As WaveFormat
        Dim Chunk As ChunkHeader
        Dim Lng As Long
        
        Lng = LOF(OutFileNum)
        Put #OutFileNum, 5, Lng
        Lng = LOF(OutFileNum) - (Len(Header) + Len(HdrFormat) + Len(Chunk))
        Put #OutFileNum, Len(Header) + Len(HdrFormat) + 5, Lng
    End Sub
    
    Private Sub Timer1_Timer()
        If I > 7 Then
            Timer1.Enabled = False
            I = 0
            Exit Sub
        End If
        cmdNote_Click (I)
        I = I + 1
        
    End Sub
    When I play back the sounds (in particular the 8 notes in succession, middle C on up...), I get nasty clicks. I've read a few posts on how to avoid that, but have not had any luck.

    Can anyone help me make the clicks go away?

    Thanks!

    Bryce

  2. #2
    Fanatic Member technorobbo's Avatar
    Join Date
    Dec 2008
    Location
    Chicago
    Posts
    864

    Re: Creating .wav files - getting "clicks"

    Clicks aren't that big of a mystery -they're are cause by a sudden change in the amplitude of the wave. Audible Sound waves are relatively slow and a slight variance of a sine wave comes off as a dissonant irritation.

    The pops you are experiencing are caused by the wave form ending in a sudden and unnatural manner. The proper way to end it is to create a fade out.

    When I wrote the mini Synth program that you reference it was to demonstrate how to create the sound so I didn't put too much time and effort into how to play consecutive sounds.

    After I received your PM I rewrote the synth program and re-uploaded it.

    I changed over to direct sound in order to create multiple buffers. And added a timer for fading out the sounds in a more natural manner.

    The Idea is that when a key is released that buffer starts fading. If you click another key the program finds a silent buffer to play the new note.

    Is used the setfrequency command to make the note playing faster. When you click on create sound -4 waves get created 10 semitones apart from each other. Each of the 4 waves gets stored into 3 buffers to allow for quick playing.

    The in between notes are created by adjusting the playback frequency.
    each semitone is exactly the 12th root of 2 times the frequency of the next lower note. In the program that's defined by 2^(1/12). The frequencies are precalculated stored in the key (commandbutton) tags.

    Sounds confusing but it's not the programs kinda small.

    http://www.vbforums.com/showthread.p...15#post3480515
    Have Fun,

    TR
    _____________________________
    Check out my Alpha DogFighter2D Game Demo and Source code. Direct Download:http://home.comcast.net/~technorobbo/Alpha.zip or Read about it in the forum:http://www.vbforums.com/showthread.php?t=551700. Now in 3D!!! http://home.comcast.net/~technorobbo/AlPha3D.zip or read about it in the forum: http://www.vbforums.com/showthread.php?goto=newpost&t=552560 and IChessChat3D internet chess game

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width