Make own Echo
#1
Hello. I wrote a function that you just push a music file, set the echo length and volume (in the range from 0 to 1) and the program will generate a new sound straight away. I used _SndNew for this.



Code: (Select All)
Snd& = _SndOpen("SongEight.mod")

For Echo = 1 To 3
    Print "Creating Echo level: "; Echo
    _Delay .1
    news& = MakeEcho&(Snd&, Echo / 10, .85)
    _Delay .1
    _SndClose Snd&
    Snd& = _SndCopy(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






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
    '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
                SndChannels = 1
            ElseIf SourceSound.ELEMENTSIZE = 8 Then
                SndChannels = 2
            End If
        Case 132 ' 32-bit integer
            If SourceSound.ELEMENTSIZE = 4 Then
                SndChannels = 1
            ElseIf SourceSound.ELEMENTSIZE = 8 Then
                SndChannels = 2
            End If
        Case 130: ' 16-bit integer
            If SourceSound.ELEMENTSIZE = 2 Then
                SndChannels = 1
            ElseIf SourceSound.ELEMENTSIZE = 4 Then
                SndChannels = 2
            End If
        Case 1153: ' 8-bit unsigned integer
            If SourceSound.ELEMENTSIZE = 1 Then
                SndChannels = 1
            ElseIf SourceSound.ELEMENTSIZE = 2 Then
                SndChannels = 2
            End If
    End Select

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


    BB& = Multiply * _SndRate * SoundDelay * SndChannels

    Dim TrackTime As _Float

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

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

    MakeEch& = _SndNew((TrackTime + SoundDelay) * _SndRate, SndChannels, 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 SndChannels
            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 SndChannels
                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 SndChannels
            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& = _SndCopy(MakeEch&)
    _SndClose 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, rs 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, rs 'stereo
        Else
            _SndRaw sampL, sampL, rs 'mono = left channel in both speakers
        End If
        i = i + SampleData.ELEMENTSIZE
    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


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: 4 Guest(s)