Make own Echo - Petr - 02-24-2023
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
RE: Make own Echo - bplus - 02-24-2023
Hi Petr,
Do you think this might work with the Text To Speech thing Windows has?
That might be fun!
RE: Make own Echo - SMcNeill - 02-24-2023
(02-24-2023, 07:48 PM)bplus Wrote: Hi Petr,
Do you think this might work with the Text To Speech thing Windows has?
That might be fun!
The Powershell Text to Speech stuff that I did will let you export to a sound file, so I'm certain you could get it working like that, though it might have some load/save/conversion time adding to the overall lag with it.
RE: Make own Echo - mnrvovrfc - 02-25-2023
(02-24-2023, 07:48 PM)bplus Wrote: Do you think this might work with the Text To Speech thing Windows has?
If you're clever enough you could create a QB64PE program that runs the text-to-speech thing (erm, as Steve just said), exports to wave, loads the wave and then uses the code employed in this topic.
Just change the first line of this code to the file that was exported from the text-to-speech thing. The only barrier is being able to use "SHELL" to call Powershell.
RE: Make own Echo - Petr - 02-25-2023
I haven't found a way (only in the paid PowerShell branch) to get the WAV file. The normal redirect character > or >> in the text to speech program for including streams will create an just empty file. Help with this is high appreciated.
RE: Make own Echo - Petr - 03-03-2023
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
|