_SndOpenRaw bug? SOLVED!
#1
Hello. Working with the new excellent _SndNew command, I discovered that _SndGetPos can't find the time in the track that is created by the _SndNew command, so I played that field with the _SndRaw command, which already has a perfectly fixed stereo. On this occasion, I discovered that the SndLen command works as it should only if _SndRaw does not have a third parameter used for a pointer to _SndOpenRaw. If the third parameter is used, then _SndLen does not work as it should and in that case the sound will be stored in memory faster than expected. I also found that when using the third parameter of the _SndRaw command, the difficulty increases sharply, and then (on my weak laptop, it is enough in the attached program on line 53 to disable the condition of printing to the screen at every thousandth step, and the sound is played as jerking and tearing, simply unlistenable ). But if the third parameter of _SndRaw is not used, you can print to the screen at every step and everything runs perfectly.

Code: (Select All)
'example show _SNDOPENRAW bug
Screen _NewImage(800, 600, 32)
test& = _SndOpen("0.mp3")
Print "Track lenght:"; _SndLen(test&)
Dim As Long RawS
RawS = _SndOpenRaw

Print "In this source code: First try this, PlaySound calculate correct time and _SndRawLen works correctly."
Print "Then comment row 10, 45, 48 and uncomment row 11, 46, 49 and run program again."
PlaySound test&, 1 '
'PlaySound test&, RawS

Sub PlaySound (handle As Long, RAWSND As Long)
    Dim SampleData As _MEM
    Dim channels As _Unsigned _Byte
    Dim sampL As Single, sampR As Single
    Dim i As _Offset

    channels = SndChannels(handle)

    SampleData = _MemSound(handle, 0)
    If SampleData.SIZE = 0 Then
        Print "PlaySound: Sample data array is empty."
        Exit Sub
    End If

    Do Until i = SampleData.SIZE - SampleData.ELEMENTSIZE
        Select Case channels
            Case 1
                Select Case SampleData.TYPE
                    Case 260: sampL = _MemGet(SampleData, SampleData.OFFSET + i, Single) ' 32-bit floating point
                    Case 132: sampL = _MemGet(SampleData, SampleData.OFFSET + i, Long) / 2147483648 ' 32-bit integer
                    Case 130: sampL = _MemGet(SampleData, SampleData.OFFSET + i, Integer) / 32768 ' 16-bit integer
                    Case 1153: sampL = (_MemGet(SampleData, SampleData.OFFSET + i, _Unsigned _Byte) - 128) / 128 ' 8-bit unsigned integer
                End Select
            Case 2
                Select Case SampleData.TYPE
                    Case 260: sampL = _MemGet(SampleData, SampleData.OFFSET + i, Single): sampR = _MemGet(SampleData, SampleData.OFFSET + i + SampleData.ELEMENTSIZE / 2, Single) ' 32-bit floating point
                    Case 132: sampL = _MemGet(SampleData, SampleData.OFFSET + i, Long) / 2147483648: sampR = _MemGet(SampleData, SampleData.OFFSET + i + SampleData.ELEMENTSIZE / 2, Long) / 2147483648 ' 32-bit integer
                    Case 130: sampL = _MemGet(SampleData, SampleData.OFFSET + i, Integer) / 32768: sampR = _MemGet(SampleData, SampleData.OFFSET + i + SampleData.ELEMENTSIZE / 2, Integer) / 32768 ' 16-bit integer
                    Case 1153: sampL = (_MemGet(SampleData, SampleData.OFFSET + i, _Unsigned _Byte) - 128) / 128: sampR = (_MemGet(SampleData, SampleData.OFFSET + i + SampleData.ELEMENTSIZE / 2, _Unsigned _Byte) - 128) / 128 ' 8-bit unsigned integer
                End Select
        End Select
        If channels Mod 2 = 0 Then
            _SndRaw sampL, sampR 'stereo
            '_SndRaw sampL, sampR, RAWSND 'stereo
        Else
            _SndRaw sampL, sampL 'mono = left channel in both speakers
            ' _SndRaw sampL, sampL, RAWSND 'mono = left channel in both speakers
        End If
        i = i + SampleData.ELEMENTSIZE
        Locate 20
        If i Mod 1000 = 0 Then Print "PlaySound: Track time:"; CSng(ConvertOffset(i / SampleData.ELEMENTSIZE) / _SndRate); "[sec]    "
        Do Until _SndRawLen < 0.1: Loop
    Loop
    _MemFree SampleData
End Sub

Function ConvertOffset&& (value As _Offset)
    $Checking:Off
    Dim m As _MEM 'Define a memblock
    m = _Mem(value) 'Point it to use value
    $If 64BIT Then
            'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
            _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
    $Else
        'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
        _MemGet m, m.OFFSET, temp& 'Like this
        ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
    $End If
    _MemFree m 'Free the memblock
    $Checking:On
End Function

' This function returns the number of sound channels for a valid sound "handle"
' Note that we are assuming that the sound can have at most 2 channels
' In reality miniaudio can handle sounds with more than 2 channels
' 2 = stereo, 1 = mono, 0 = error
Function SndChannels~%% (handle As Long)
    Dim SampleData As _MEM
    ' Check if the sound is valid
    SampleData = _MemSound(handle, 0)
    If SampleData.SIZE = 0 Then
        Print "SndChannels: MemSound return ZERO for audio data size!"
        Exit Function
    End If

    ' Check the data type and then decide if the sound is stereo or mono
    Select Case SampleData.TYPE
        Case 260 ' 32-bit floating point
            If SampleData.ELEMENTSIZE = 4 Then
                SndChannels = 1
            ElseIf SampleData.ELEMENTSIZE = 8 Then
                SndChannels = 2
            End If
        Case 132 ' 32-bit integer
            If SampleData.ELEMENTSIZE = 4 Then
                SndChannels = 1
            ElseIf SampleData.ELEMENTSIZE = 8 Then
                SndChannels = 2
            End If
        Case 130: ' 16-bit integer
            If SampleData.ELEMENTSIZE = 2 Then
                SndChannels = 1
            ElseIf SampleData.ELEMENTSIZE = 4 Then
                SndChannels = 2
            End If
        Case 1153: ' 8-bit unsigned integer
            If SampleData.ELEMENTSIZE = 1 Then
                SndChannels = 1
            ElseIf SampleData.ELEMENTSIZE = 2 Then
                SndChannels = 2
            End If
    End Select
    _MemFree SampleData
End Function


Reply


Messages In This Thread
_SndOpenRaw bug? SOLVED! - by Petr - 03-03-2023, 06:30 PM
RE: _SndOpenRaw bug? - by DSMan195276 - 03-03-2023, 09:41 PM
RE: _SndOpenRaw bug? - by Petr - 03-03-2023, 10:04 PM



Users browsing this thread: 3 Guest(s)