Make own Echo
#6
Repaired bug: Division by zero

Code: (Select All)
Snd& = _SndOpen("e.mp3")

For Echo = 1 To 4
    Print "Creating Echo level: "; Echo
    _Delay .1
    news& = MakeEcho&(Snd&, 0.05, .5 - Echo / 10)
    _Delay .1
    _SndClose Snd&
    Snd& = news&
Next

'_SndPlay news&

Print "Program create new sound handle ("; news&; " )"

Print " This new handle is not full compatible:"
Print "_SndLen return: "; _SndLen(news&)
Sleep 2
Print "_SndGetPos return: "; _SndGetPos(news&)
Sleep 4
Print "Trying use _SndSetPos to begin this track..."
_SndSetPos news&, 0

Print "SNDGETPOS with _SNDNEW NOT WORK? OK - see row 20 on the screen :)"

PlaySound news&
_SndClose news&

End

Function MakeEcho& (InputSound As Long, SoundDelay As Single, EchoVolume As Single)
    If SoundDelay < 0 Then Print "Error: EchoDelay must be higher than zero.": Exit Function
    If EchoVolume <= 0 Then Print "Error: Echo volume must be higher than zero.": Exit Function
    'EchoVolume in range 0 to 1!

    Dim SourceSound As _MEM
    SourceSound = _MemSound(InputSound&, 0)

    Select Case GetBites(SourceSound)
        Case 1, 2: Multiply = 4
        Case 3: Multiply = 2
        Case 4: Multiply = 1
    End Select

    Select Case SourceSound.TYPE
        Case 260 ' 32-bit floating point
            If SourceSound.ELEMENTSIZE = 4 Then
                SndChanels = 1
            ElseIf SourceSound.ELEMENTSIZE = 8 Then
                SndChanels = 2
            End If
        Case 132 ' 32-bit integer
            If SourceSound.ELEMENTSIZE = 4 Then
                SndChanels = 1
            ElseIf SourceSound.ELEMENTSIZE = 8 Then
                SndChanels = 2
            End If
        Case 130: ' 16-bit integer
            If SourceSound.ELEMENTSIZE = 2 Then
                SndChanels = 1
            ElseIf SourceSound.ELEMENTSIZE = 4 Then
                SndChanels = 2
            End If
        Case 1153: ' 8-bit unsigned integer
            If SourceSound.ELEMENTSIZE = 1 Then
                SndChanels = 1
            ElseIf SourceSound.ELEMENTSIZE = 2 Then
                SndChanels = 2
            End If
    End Select

    Dim As Long i, BB
    Dim As Double sampL, sampL2, sampR, sampR2


    BB& = Multiply * _SndRate * SoundDelay * SndChanels

    Dim TrackTime As _Float

    '   Print "80"
    '   Print "SourceSound.SIZE"; ConvertOffset(SourceSound.SIZE); "SndRate: "; _SndRate; "SourceSound.elementsize"; ConvertOffset(SourceSound.ELEMENTSIZE)

    TrackTime = ConvertOffset(SourceSound.SIZE) \ _SndRate \ ConvertOffset(SourceSound.ELEMENTSIZE) + _Ceil(SoundDelay)


    '  Print "82"
    Print "New track time: "; TrackTime; "[sec]"

    MakeEch& = _SndNew((TrackTime + SoundDelay) * _SndRate, SndChanels, Multiply * 8)


    '    Print MakeEch&, SndChannels, Multiply, _SndLen(InputSound)
    Dim ME As _MEM
    ME = _MemSound(MakeEch&, 0)

    Do Until i >= SourceSound.SIZE - SourceSound.ELEMENTSIZE

        Select Case SndChanels
            Case 1
                Select Case SourceSound.TYPE
                    Case 260: sampL = _MemGet(SourceSound, SourceSound.OFFSET + i, Single) ' 32-bit floating point
                    Case 132: sampL = _MemGet(SourceSound, SourceSound.OFFSET + i, Long) / 2147483648 ' 32-bit integer
                    Case 130: sampL = _MemGet(SourceSound, SourceSound.OFFSET + i, Integer) / 32768 ' 16-bit integer
                    Case 1153: sampL = (_MemGet(SourceSound, SourceSound.OFFSET + i, _Unsigned _Byte) - 128) / 128 ' 8-bit unsigned integer
                End Select
            Case 2
                Select Case SourceSound.TYPE
                    Case 260: sampL = _MemGet(SourceSound, SourceSound.OFFSET + i, Single): sampR = _MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2, Single) ' 32-bit floating point
                    Case 132: sampL = _MemGet(SourceSound, SourceSound.OFFSET + i, Long) / 2147483648: sampR = _MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2, Long) / 2147483648 ' 32-bit integer
                    Case 130: sampL = _MemGet(SourceSound, SourceSound.OFFSET + i, Integer) / 32768: sampR = _MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2, Integer) / 32768 ' 16-bit integer
                    Case 1153: sampL = (_MemGet(SourceSound, SourceSound.OFFSET + i, _Unsigned _Byte) - 128) / 128: sampR = (_MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2, _Unsigned _Byte) - 128) / 128 ' 8-bit unsigned integer
                End Select
        End Select

        If i& > BB& Then
            Select Case SndChanels
                Case 1
                    Select Case SourceSound.TYPE
                        Case 260: sampL2 = _MemGet(SourceSound, SourceSound.OFFSET + i - BB&, Single) ' 32-bit floating point
                        Case 132: sampL2 = _MemGet(SourceSound, SourceSound.OFFSET + i - BB&, Long) / 2147483648 ' 32-bit integer
                        Case 130: sampL2 = _MemGet(SourceSound, SourceSound.OFFSET + i - BB&, Integer) / 32768 ' 16-bit integer
                        Case 1153: sampL2 = (_MemGet(SourceSound, SourceSound.OFFSET + i - BB&, _Unsigned _Byte) - 128) / 128 ' 8-bit unsigned integer
                    End Select
                Case 2
                    Select Case SourceSound.TYPE
                        Case 260: sampL2 = _MemGet(SourceSound, SourceSound.OFFSET + i - BB&, Single): sampR2 = _MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2 - BB&, Single) ' 32-bit floating point
                        Case 132: sampL2 = _MemGet(SourceSound, SourceSound.OFFSET + i - BB&, Long) / 2147483648: sampR2 = _MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2 - BB&, Long) / 2147483648 ' 32-bit integer
                        Case 130: sampL2 = _MemGet(SourceSound, SourceSound.OFFSET + i - BB&, Integer) / 32768: sampR2 = _MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2 - BB&, Integer) / 32768 ' 16-bit integer
                        Case 1153: sampL2 = (_MemGet(SourceSound, SourceSound.OFFSET + i - BB&, _Unsigned _Byte) - 128) / 128: sampR2 = (_MemGet(SourceSound, SourceSound.OFFSET + i + SourceSound.ELEMENTSIZE \ 2 - BB&, _Unsigned _Byte) - 128) / 128 ' 8-bit unsigned integer
                    End Select
            End Select
        End If
        sampL2 = sampL2 * EchoVolume
        sampR2 = sampR2 * EchoVolume

        LeftOut = (sampL * (1 - EchoVolume)) + sampL2
        RightOut = (sampR * (1 - EchoVolume)) + sampR2

        Select Case SndChanels
            Case 1
                Select Case ME.TYPE
                    Case 260: _MemPut ME, ME.OFFSET + i, LeftOut As SINGLE ' 32-bit floating point
                    Case 132: _MemPut ME, ME.OFFSET + i, LeftOut * 2147483648 As LONG ' 32-bit integer
                    Case 130: _MemPut ME, ME.OFFSET + i, LeftOut * 32768 As INTEGER ' 16-bit integer
                    Case 1153: _MemPut ME, ME.OFFSET + i, 128 - (LeftOut * 128) As _UNSIGNED _BYTE ' 8-bit unsigned integer
                End Select
            Case 2
                Select Case ME.TYPE
                    Case 260: _MemPut ME, ME.OFFSET + i, LeftOut As SINGLE: _MemPut ME, ME.OFFSET + i + ME.ELEMENTSIZE \ 2, RightOut As SINGLE ' 32-bit floating point
                    Case 132: _MemPut ME, ME.OFFSET + i, LeftOut * 2147483648 As LONG: _MemPut ME, ME.OFFSET + i + ME.ELEMENTSIZE \ 2, RightOut * 2147483648 As LONG ' 32-bit integer
                    Case 130: _MemPut ME, ME.OFFSET + i, LeftOut * 32768 As INTEGER: _MemPut ME, ME.OFFSET + i + ME.ELEMENTSIZE \ 2, RightOut * 32768 As INTEGER ' 16-bit integer
                    Case 1153: _MemPut ME, ME.OFFSET + i, 128 - (LeftOut * 128) As _UNSIGNED _BYTE: _MemPut ME, ME.OFFSET + i + ME.ELEMENTSIZE \ 2, 128 - (128 * RightOut) As _UNSIGNED _BYTE ' 8-bit unsigned integer
                End Select
        End Select
        i = i + Multiply * 2
    Loop
    MakeEcho& = MakeEch&

    If ME.SIZE Then _MemFree ME
    If SourceSound.SIZE Then _MemFree SourceSound
End Function


Function GetBites (handle As _MEM)
    Select Case handle.TYPE
        Case 260: GetBites = 1 ' 32-bit floating point SINGLE
        Case 132: GetBites = 2 ' 32-bit integer LONG
        Case 130: GetBites = 3 ' 16-bit integer INTEGER
        Case 1153: GetBites = 4 ' 8-bit unsigned integer
    End Select
End Function


Sub PlaySound (handle 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
        Else
            _SndRaw sampL, sampL 'mono = left channel in both speakers
        End If
        i = i + SampleData.ELEMENTSIZE
        Locate 20
        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
Make own Echo - by Petr - 02-24-2023, 07:22 PM
RE: Make own Echo - by bplus - 02-24-2023, 07:48 PM
RE: Make own Echo - by SMcNeill - 02-24-2023, 07:53 PM
RE: Make own Echo - by mnrvovrfc - 02-25-2023, 12:39 AM
RE: Make own Echo - by Petr - 02-25-2023, 07:32 PM
RE: Make own Echo - by Petr - 03-03-2023, 07:00 PM



Users browsing this thread: 1 Guest(s)