Results 1 to 17 of 17

Thread: [VB6] DirectSound.

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Feb 2015
    Posts
    1,584

    [VB6] DirectSound.


    With Direct3D9 I did the type library and module support functions for DirectSound. The archive contains a type library dsvb.tlb and module DS_Functions.bas. In the future, I add a class module to support asynchronous notification until you can use clsTrickWait.cls. The module DS_Functions contains the following functions:
    • DSCreateSoundBufferFromFile - creates an object with interface IDirectSoundBuffer8 from a file. Supported only WAVE and MP3 files is. MP3 files can contain only the ID3v1 and ID3v2 tags, any other may not be recognized/will not work. Too long (by time) files are not supported. For streaming you need to write streaming decoding based on the function code DSCreateSoundBufferFromMemory;
    • DSCreateSoundBufferFromMemory - the same, but instead of the file is passed a pointer to the data file in memory and size.


    Also in the archive contains an example of a player that implements some methods IDirectSoundBuffer8 interface (volume, pan, frequency, effects). TLB especially did not well tested, so something may not work. If something is not working please write here.

    Download latest version.
    Attached Files Attached Files

  2. #2
    PowerPoster
    Join Date
    Feb 2017
    Posts
    2,266

    Re: [VB6] DirectSound.

    Hello The Trick.
    I want to report that I tested it and I get error 7 "Out of memory" at the line:

    Code:
    ReDim Preserve buffer(outSize - 1)
    of the function DSCreateSoundBufferFromMemory.

    (I needed to remove some error handling to get to the error line)

    I tested it with a Mp3 file that its size is 36 MB and has 26 minutes of audio.
    It is trying to redim the byte array buffer to 250435583.

    I have only 1 GB of physical RAM (on XP SP3) but that was never a problem to reproduce audio.

    PS: sometimes I'm glad that I'm working in a such old machine, I'm permanently testing all for the worst case!
    Last edited by Eduardo-; Jun 29th, 2017 at 05:36 PM.

  3. #3

  4. #4
    PowerPoster
    Join Date
    Feb 2017
    Posts
    2,266

    Re: [VB6] DirectSound.

    Ok, The trick.

  5. #5
    PowerPoster
    Join Date
    Sep 2012
    Posts
    2,070

    Re: [VB6] DirectSound.

    Quote Originally Posted by Eduardo- View Post
    Hello The Trick.
    I want to report that I tested it and I get error 7 "Out of memory" at the line:

    Code:
    ReDim Preserve buffer(outSize - 1)
    of the function DSCreateSoundBufferFromMemory.

    (I needed to remove some error handling to get to the error line)

    I tested it with a Mp3 file that its size is 36 MB and has 26 minutes of audio.
    It is trying to redim the byte array buffer to 250435583.

    I have only 1 GB of physical RAM (on XP SP3) but that was never a problem to reproduce audio.

    PS: sometimes I'm glad that I'm working in a such old machine, I'm permanently testing all for the worst case!
    Hi Eduardo-, I met the same problem as you. Have you solved your problem using circular buffer?

  6. #6
    PowerPoster
    Join Date
    Feb 2017
    Posts
    2,266

    Re: [VB6] DirectSound.

    Quote Originally Posted by dreammanor View Post
    Hi Eduardo-, I met the same problem as you. Have you solved your problem using circular buffer?
    No, I did what I needed to do at that time in another way (opening the mp3 file in Windows Media Player).

  7. #7
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    Im testing this code, and it works well, except for this mp3.
    its a small mp3, 390 bytes, the mp3 works in media player / directshow, but not with this code.
    it gives me error when I try to load it (automation)
    all other mp3 I have works well.
    anyone have a clue why?
    Attached Files Attached Files

  8. #8

  9. #9
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    that worked well.
    so I just change to:
    desc.dwFlags = DSBCAPS_CTRLVOLUME
    since I will only use the volume nothing else.

    thanks The trick!

    I have now changed directshow to directsound in my game.
    now I can make 1 big file containing all the small sounds!

    edit:
    Just looking through the code:
    IsBadReadPtr: https://docs.microsoft.com/en-us/win...e-isbadreadptr
    it says its obsolete.
    Last edited by baka; Apr 15th, 2020 at 08:58 AM.

  10. #10

  11. #11
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    so, I have done a lot of changes, this to load from an Offset and also to create multiple sounds from 1 source.

    I create 3 functions instead of 1, the first one:

    Code:
    Private Sub DSCreateOpen(ByRef strFileName$)
        Dim hFile       As Long
        Dim hMap        As Long
        
        hFile = CreateFile(StrPtr(strFileName), GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
        bufSize = GetFileSize(hFile, ByVal 0)
        hMap = CreateFileMapping(hFile, ByVal 0&, PAGE_READONLY, 0, 0, 0): CloseHandle hFile
        buflpData = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0):           CloseHandle hMap
    End Sub
    the next function is used to create IDirectSoundBuffer , and can be called multiple times if needed:
    Public variables: buflpData, bufSize, buffer(), lpData and bufDesc

    Code:
    Private Function DSCreateSoundBufferFromMemory(Optional ByVal Offset&, Optional ByVal szData&) As IDirectSoundBuffer
    lpData = buflpData + Offset
    If szData = 0 Then szData = bufSize
    (just the important part, the rest is like the original)

    and the last function is to remove the Public buffer and to Unmap
    Code:
    Private Sub DSCreateClose()
        Erase buffer
        UnmapViewOfFile lpData
    End Sub
    This is how I use it (to load 1 mp3)
    Code:
    DSCreateOpen strFileName
    Set Media.sb = DSCreateSoundBufferFromMemory
    Media.sb.setVolume Volume
    Media.Loaded = True
    DSCreateClose
    This to load multiple mp3 inside 1 file:
    Code:
    DSCreateOpen Root & "\ui\ui_sound.dat"
    For forI = 0 To SoundMax
        Set Sounds(forI).sb = DSCreateSoundBufferFromMemory(Offset, BS.SoundLen(forI))
        Sounds(forI).sb.setVolume sVolume
        Sounds(forI).Loaded = True
        Offset = Offset + BS.SoundLen(forI)
    Next forI
    DSCreateClose
    and this to create multiple "sb" from 1 sound:
    Code:
    DSCreateOpen Root & "ui\ui_sound.dat"
    Set Hits(Id).channel(0).sb = DSCreateSoundBufferFromMemory(BS.Sfx(forJ).Pos, BS.Sfx(forJ).Size)
    For forI = 1 To 4
       ds.CreateSoundBuffer bufDesc, Hits(Id).channel(forI).sb, ByVal 0&
       Hits(Id).channel(forI).sb.Lock 0, 0, ptr, bufDesc.dwBufferBytes, 0, 0, DSBLOCK_ENTIREBUFFER
       memcpy ByVal ptr, buffer(0), bufDesc.dwBufferBytes
       Hits(Id).channel(forI).sb.Unlock ptr, bufDesc.dwBufferBytes, 0, 0
    Next forI
    DSCreateClose

    everything works, but Im not sure its the best way,
    - first the "offset", right now I read the entire file, the Offset will jump ahead to a position in the memory address.
    what I want is to read "only" the part of the file that are used, but I dont know how, everything I tried resulted in crash or not working!

    - second is the "multiple" creating, is there any other way? or is that the right way to add the same sounds multiple times from 1 source?
    (I create 5 hit-sounds so when I hit many monsters theres multiple hit-sounds not just one)
    Last edited by baka; Apr 17th, 2020 at 08:54 AM.

  12. #12

    Thread Starter
    Frenzied Member
    Join Date
    Feb 2015
    Posts
    1,584

    Re: [VB6] DirectSound.

    everything works, but Im not sure its the best way,
    - first the "offset", right now I read the entire file, the Offset will jump ahead to a position in the memory address.
    what I want is to read "only" the part of the file that are used, but I dont know how, everything I tried resulted in crash or not working!
    You can map the only the needed part of the file (see dwFileOffsetLow in MapViewOfFile function). Note it should be multiple to memory allocation granularity. The better way is to encapsulate the logic to a class. You could also use no file mapping at all just read the content thru ReadFile. (FileMapping was added in order to make the same logic of opening a file either from a physical file or memory.

    second is the "multiple" creating, is there any other way? or is that the right way to add the same sounds multiple times from 1 source?
    (I create 5 hit-sounds so when I hit many monsters theres multiple hit-sounds not just one)
    IDirectSound8:uplicateSoundBuffer creates the buffer which uses the data from the passed parameter (no data duplication occurs).

  13. #13
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    ah thanks a lot! I now use _lopen and _llseek and it works well!

    here's the code if anyone else want to use it: (its a class, and u need to call Init first)

    Code:
    Dim ds                  As DirectSound8
    Dim format              As MPEGLAYER3WAVEFORMAT
    Dim dstFormat           As WAVEFORMATEX
    Dim acmHdr              As ACMSTREAMHEADER
    Dim bufDesc             As DSBUFFERDESC
    
    Sub init(ByVal hWnd&)
        Dim b As curBuffer
    
        Set ds = New DirectSound8
        ds.Initialize ByVal 0
        ds.SetCooperativeLevel hWnd, DSSCL_NORMAL
        b.b(0) = 450377142658.6656@:    b.b(1) = 900743977448.248@:     b.b(2) = 1351114248211.6672@
        b.b(3) = 1801487954948.9248@:   b.b(4) = 2702228496423.3344@:   b.b(5) = 3602975909897.8496@
        b.b(6) = 4503737067267.712@:    b.b(7) = 18941235272.0895@:     b.b(8) = 4735201446.045@
        b.b(9) = 10307921515.2@:        b.b(10) = 13743895348.4@:       b.b(11) = 3435973838.4@
        memcpy Constants.bitrate(0, 1), b.b(0), 96
        With format
            .wFormatTag = WAVE_FORMAT_MPEGLAYER3
            .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES
            .wBitsPerSample = 0
            .nBlockAlign = 1
            .nFramesPerBlock = 1
            .nCodecDelay = 0
            .fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF
            .wID = MPEGLAYER3_ID_MPEG
        End With
        With dstFormat
            .cbSize = Len(dstFormat)
            .wBitsPerSample = 16
            .wFormatTag = WAVE_FORMAT_PCM
        End With
        acmHdr.cbStruct = Len(acmHdr)
        bufDesc.dwFlags = DSBCAPS_CTRLVOLUME
        bufDesc.dwSize = Len(bufDesc)
        bufDesc.lpwfxFormat = VarPtr(dstFormat)
    End Sub
    
    Private Sub Class_Terminate()
        Set ds = Nothing
    End Sub
    
    Function DSReadFile(ByRef FileName$, Optional ByVal Offset&, Optional ByVal FileSize&) As IDirectSoundBuffer
        Dim hFile       As Long
        Dim b()         As Byte
        Dim buffer()    As Byte
        Dim L           As Long
        Dim D           As Long
        Dim ptr         As Long
        Dim hStream     As Long
        Dim index       As Long
        Dim AcmSize     As Long
        Dim AcmTotal    As Long
            
        hFile = lOpen(FileName, 0)
        If FileSize = 0 Then FileSize = GetFileSize(hFile, ByVal 0)
        If Offset > 0 Then llseek hFile, Offset, FILE_BEGIN
        ReDim b(FileSize - 1)
        lread hFile, b(0), FileSize
        lclose hFile
        
        D = FileSize - 128
        If b(D) = &H54 And b(D + 1) = &H41 And b(D + 2) = &H47 Then FileSize = FileSize - 128
        If b(0) = &H49 And b(1) = &H44 And b(2) = &H33 Then
            If b(5) And &H10 Then FileSize = FileSize - 10
            hFile = b(6) * &H200000
            hFile = hFile Or (b(7) * &H4000&)
            hFile = hFile Or (b(8) * &H80&)
            hFile = hFile Or b(9)
            hFile = hFile + 10
            L = L + hFile
            FileSize = FileSize - hFile
        Else
            D = FileSize - 10
            If b(D) = &H33 And b(D + 1) = &H44 And b(D + 2) = &H49 Then
                hFile = b(D + 6) * &H200000
                hFile = hFile Or (b(D + 7) * &H4000&)
                hFile = hFile Or (b(D + 8) * &H80&)
                hFile = hFile Or b(D + 9)
                FileSize = FileSize - hFile - 20
            End If
        End If
        
        Do
            If b(L) = &HFF And (b(L + 1) And &HE0) = &HE0 Then
                D = (b(L + 1) And &H18) \ 8
                With format
                    If D = 3 Then
                        .nAvgBytesPerSec = Constants.bitrate(0, (b(L + 2) And &HF0) \ &H10)
                        .nSamplesPerSec = Constants.smprate(0, (b(L + 2) And &HC) \ &H4)
                    Else
                        .nAvgBytesPerSec = Constants.bitrate(1, (b(L + 2) And &HF0) \ &H10)
                        If D = 2 Then .nSamplesPerSec = Constants.smprate(1, (b(L + 2) And &HC) \ &H4) Else .nSamplesPerSec = Constants.smprate(2, (b(L + 2) And &HC) \ &H4)
                    End If
                    If D = 3 Then
                        .nBlockSize = Int(144000 * .nAvgBytesPerSec / .nSamplesPerSec) + CInt((b(L + 2) And &H2) \ 2)
                    Else
                        .nBlockSize = Int(72000 * .nAvgBytesPerSec / .nSamplesPerSec) + CInt((b(L + 2) And &H2) \ 2)
                    End If
                    .nChannels = -(((b(L + 3) And &HC0) \ 64) <> 3) + 1
                    .nAvgBytesPerSec = .nAvgBytesPerSec * 128
                End With
                Exit Do
            End If
            L = L + 1
            FileSize = FileSize - 1
        Loop
        With dstFormat
            .nChannels = format.nChannels
            .nSamplesPerSec = format.nSamplesPerSec
            .nBlockAlign = (.wBitsPerSample \ 8) * .nChannels
            .nAvgBytesPerSec = .nBlockAlign * .nSamplesPerSec
        End With
    
        acmStreamOpen hStream, 0, format, dstFormat, ByVal 0&, ByVal 0&, ByVal 0&, 0
        Do While FileSize > 0
            acmStreamSize hStream, FileSize, AcmSize, ACM_STREAMSIZEF_SOURCE
            AcmTotal = AcmTotal + AcmSize
            ReDim Preserve buffer(AcmTotal - 1)
            With acmHdr
                .lppbDst = VarPtr(buffer(index))
                .lppbSrc = VarPtr(b(L))
                .cbDstLength = AcmSize
                .cbSrcLength = FileSize
            End With
            acmStreamPrepareHeader hStream, acmHdr, 0
            acmStreamConvert hStream, acmHdr, ACM_STREAMCONVERTF_BLOCKALIGN
            acmStreamUnprepareHeader hStream, acmHdr, 0
            FileSize = FileSize - acmHdr.cbSrcLengthUsed
            L = L + acmHdr.cbSrcLengthUsed
            index = index + acmHdr.cbDstLengthUsed
        Loop
        acmStreamClose hStream, 0
        bufDesc.dwBufferBytes = index
        ds.CreateSoundBuffer bufDesc, DSReadFile, ByVal 0&
        DSReadFile.Lock 0, 0, ptr, index, 0, 0, DSBLOCK_ENTIREBUFFER
        memcpy ByVal ptr, buffer(0), index
        DSReadFile.Unlock ptr, index, 0, 0
    End Function
    Last edited by baka; Apr 17th, 2020 at 01:52 PM.

  14. #14
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    ok, another problem, that I can not recreate (since its working for me), but theres one user that can not use it.
    the reason is: acmStreamSize
    that is not returning the right size, so its impossible to continue.
    it could be a "codec" problem, that is missing on the system.

    I read in the internet that if that person doesn't have the right codec in the "list" it will not work,
    so I wonder, how to check if the person have WAVE_FORMAT_PCM and/or WAVE_FORMAT_MPEGLAYER3

  15. #15
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    ok, I found this: http://www.vbforums.com/showthread.p...Codec-question

    and running that project, I get:
    Code:
    Microsoft IMA ADPCM CODEC
    Microsoft CCITT G.711 A-Law and u-Law CODEC
    Microsoft GSM 6.10 Audio CODEC
    Microsoft ADPCM CODEC
    Fraunhofer IIS MPEG Layer-3 Codec (decode only)
    Microsoft PCM Converter
    so, Microsoft PCM Converter should work with WAVE_FORMAT_PCM
    and Fraunhofer IIS MPEG Layer-3 Codec should work with WAVE_FORMAT_MPEGLAYER3

    but how do I know that?

    Im asking that person to check what codecs he has in his computer.
    edit;
    that user tried that program and the result is:
    Code:
    Microsoft IMA ADPCM CODEC
    Microsoft CCITT G.711 A-Law and u-Law CODEC
    Microsoft GSM 6.10 Audio CODEC
    Microsoft ADPCM CODEC
    Microsoft PCM Converter
    that means Fraunhofer IIS MPEG Layer-3 Codec is missing.

    what can be done?
    instruction to install the codec?
    include the codec with the program?
    some other solution?
    Last edited by baka; May 11th, 2020 at 02:15 PM.

  16. #16
    Frenzied Member
    Join Date
    Dec 2014
    Posts
    1,051

    Re: [VB6] DirectSound.

    a solution would be to encode the mp3 to pcm and save them in a file.
    this is possible with small mp3, sound-effects.
    I have around 50 sound-effects, 161kb in size total, in pcm format I get 2.3MB total, its acceptable size.
    but background music would increase size too much, since most of the time mp3>pcm would increase around 15x.

    using ADPCM CODEC could also be another way, convert .mp3 to .wav, would increase size 2.5x, still too much.

    I tried using ADPCM wav directly into the directsound8, it start playing but not the right speed, I can't change much in dstFormat,
    no changes helps, and most of the time it crashes on me. so I suppose only PCM works.

  17. #17

Tags for this Thread

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