Results 1 to 2 of 2

Thread: Sound Help

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Jun 2012
    Posts
    20

    Sound Help

    i am trying make software which plays different frequency sound.My problem is that out of three sound first two plays very fast and third plays for longer time.The code for the program is below
    can anybody help?
    HTML Code:
    Option Explicit
    '
    ' DirectSound access
    Dim DX As DirectX8
    Dim DS As DirectSound8
    Dim dsToneBuffer As DirectSoundSecondaryBuffer8
    Dim desc As DSBUFFERDESC
    '
    ' Global variables
    Const PI = 3.14159265358979
    Const SRATE = 44100             ' Sampling Rate
    Const DUR = 5                ' Tone duration
    Const FREQUENCY = 240              ' Tone frequency
    Dim sbuf(0 To DUR * SRATE) As Integer
    
    Public Sub Command1_Click()
    Dim sc(3) As Double
    Static J As Integer
    Dim FREQ As Integer
    
    
    sc(1) = 1
    sc(2) = 2
    sc(3) = 2.5
    For J = 1 To 3
    FREQ = FREQUENCY * sc(J)
    Call createtone(FREQ, DUR)
    ' play the tone
    dsToneBuffer.Play DSBPLAY_DEFAULT
    Next J
    
    End Sub
    
    Private Sub Form_Load()
    '
    ' initialise DirectSound
    Set DX = New DirectX8
    Set DS = DX.DirectSoundCreate("")
    DS.SetCooperativeLevel Me.hWnd, DSSCL_NORMAL
    '
    ' create a buffer
    desc.fxFormat.nFormatTag = WAVE_FORMAT_PCM
    desc.fxFormat.nSize = 0
    desc.fxFormat.lExtra = 0
    desc.fxFormat.nChannels = 1
    desc.fxFormat.lSamplesPerSec = SRATE
    desc.fxFormat.nBitsPerSample = 16
    desc.fxFormat.nBlockAlign = 2
    desc.fxFormat.lAvgBytesPerSec = 2 * SRATE
    desc.lFlags = 0
    desc.lBufferBytes = 2 * DUR * SRATE
    Set dsToneBuffer = DS.CreateSoundBuffer(desc)
    End Sub
    Public Sub createtone(FREQ As Integer, DUR As Integer)
    
    ' create a tone
    Dim I
    For I = 0 To DUR * SRATE
        sbuf(I) = 10000 * Sin(2 * PI * FREQ * I / SRATE)
    Next I
    '
    ' copy tone to buffer
    dsToneBuffer.WriteBuffer 0, 2 * DUR * SRATE, sbuf(0), DSBLOCK_DEFAULT
    
    
    '
    End Sub
    

  2. #2
    New Member WindozeNT's Avatar
    Join Date
    Jun 2012
    Location
    Middle of nowhere
    Posts
    10

    Re: Sound Help

    This revised code will play all 3 tones at roughly the same speed:
    Code:
    Option Explicit
    
    ' DirectSound access
    Dim DX As DirectX8
    Dim DS As DirectSound8
    Dim dsToneBuffer As DirectSoundSecondaryBuffer8
    Dim desc As DSBUFFERDESC
    
    ' Global variables
    Const PI = 3.14159265358979
    Const SRATE = 44100             ' Sampling Rate
    Const DUR = 5                ' Tone duration
    Const FREQUENCY = 240              ' Tone frequency
    Dim sbuf() As Integer
    
    Public Sub Command1_Click()
    Dim sc(4) As Double
    Static J As Integer
    Dim FREQ As Integer
    
    sc(1) = 1
    sc(2) = 2
    sc(3) = 2.5
    
    For J = 1 To 4
     ReDim sbuf(0 To (DUR * J) * SRATE)
     FREQ = FREQUENCY * sc(J)
     Call createtone(FREQ, DUR, J)
     dsToneBuffer.Play DSBPLAY_DEFAULT ' play the tone
    Next J
    
    DoEvents
    dsToneBuffer.Stop
    End Sub
    
    Private Sub Form_Load()
    ' initialise DirectSound
    Set DX = New DirectX8
    Set DS = DX.DirectSoundCreate("")
    DS.SetCooperativeLevel Me.hWnd, DSSCL_NORMAL
    
    ' create a buffer
    desc.fxFormat.nFormatTag = WAVE_FORMAT_PCM
    desc.fxFormat.nSize = 0
    desc.fxFormat.lExtra = 0
    desc.fxFormat.nChannels = 1
    desc.fxFormat.lSamplesPerSec = SRATE
    desc.fxFormat.nBitsPerSample = 16
    desc.fxFormat.nBlockAlign = 2
    desc.fxFormat.lAvgBytesPerSec = 2 * SRATE
    desc.lFlags = 0
    desc.lBufferBytes = 2 * (DUR * 4) * SRATE
    Set dsToneBuffer = DS.CreateSoundBuffer(desc)
    End Sub
    
    Public Sub createtone(FREQ As Integer, DUR As Integer, CV As Integer)
    ' create a tone
    Dim I
    For I = 0 To (DUR * CV) * SRATE
        sbuf(I) = 10000 * Sin(2 * PI * FREQ * I / SRATE)
    Next I
    
    ' copy tone to buffer
    dsToneBuffer.WriteBuffer 0, 2 * (DUR * CV) * SRATE, sbuf(0), DSBLOCK_DEFAULT
    End Sub
    What I did was I converted sbuf to a dynamic array and resized it when a new tone played. The tone buffer length is changed to the value of DUR times the current index of the tone being played (represented as J in the For loop and as CV in the function). Although there are 3 tones being played, the buffer is resized for 4, with the 4th buffer being reserved for a null tone (keeping tone 3 from being longer than the others; notice that I didn't set sc(4)?) then after the For loop is done I told DirectSound to stop playing. However, it seems that after 10 plays, DirectX glitches out and skips over the first tone after each subsequent play starting at 11 plays.
    Hope this helps!
    Last edited by WindozeNT; Jul 5th, 2012 at 06:12 AM. Reason: Slightly reformatted

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