Phoenix 3.5.0 bug? - Solved, just diference! - Petr - 02-19-2023
Hello. I found a MemSound bug (see attached test program) that makes Phoenix 3.5.0 MemSound unable to be used properly and causing my programs to crash, unlike QB64 2.02. The attached program exactly shows the occurrence of the error.
Code: (Select All) $NoPrefix
s = SndOpen("0.mp3")
Dim As MEM l, r
l = MemSound(s, 1)
r = MemSound(s, 2)
Print "MemSound bug"
Print
Print "Value returned for left audio channel:"; l.SIZE
Print "Value returned for right audio channel:"; r.SIZE
chan& = SndLen(s) * 2 * SndRate
If l.SIZE = r.SIZE And r.SIZE = chan& Then Print "All ok!": End
Print "the size of the ONE audio track channel, that is expected:"; chan&
Print "Value returned with SndOpen:"; s;
If s > 0 Then Print "[correct audio file]" Else Print "[unsupported audio file]"
Print
Print "press key for try play this file"
Sleep
SndPlay s
If SndPlaying(s) Then Print "Both channels playing, bug is not in SndOpen." Else Print "Bug is in SndOpen"
'wroted in Phoenix IDE 3.5.0
RE: Phoenix 3.5.0 bug? - a740g - 02-19-2023
(02-19-2023, 04:25 PM)Petr Wrote: Hello. I found a MemSound bug (see attached test program) that makes Phoenix 3.5.0 MemSound unable to be used properly and causing my programs to crash, unlike QB64 2.02. The attached program exactly shows the occurrence of the error.
Code: (Select All) $NoPrefix
s = SndOpen("0.mp3")
Dim As MEM l, r
l = MemSound(s, 1)
r = MemSound(s, 2)
Print "MemSound bug"
Print
Print "Value returned for left audio channel:"; l.SIZE
Print "Value returned for right audio channel:"; r.SIZE
chan& = SndLen(s) * 2 * SndRate
If l.SIZE = r.SIZE And r.SIZE = chan& Then Print "All ok!": End
Print "the size of the ONE audio track channel, that is expected:"; chan&
Print "Value returned with SndOpen:"; s;
If s > 0 Then Print "[correct audio file]" Else Print "[unsupported audio file]"
Print
Print "press key for try play this file"
Sleep
SndPlay s
If SndPlaying(s) Then Print "Both channels playing, bug is not in SndOpen." Else Print "Bug is in SndOpen"
'wroted in Phoenix IDE 3.5.0
This is working for me @Petr.
However, there has been a slight change in the behavior of _MemSound since we moved to the miniaudio backend. The wiki link has all the details and new examples. But to put this briefly, line "r.SIZE" will always return 0 since miniaudio internally uses interleaved audio for multi-channel sounds. Hence, the "All ok!" text will never print.
RE: Phoenix 3.5.0 bug? - Petr - 02-19-2023
Ok then write me how to get the audio data for the right channel. Also try to play the acquired music data for the left channel. It caused the program to crash. Don't tell me you've made changes to MemSound that would cause incompatibility. I couldn't find any such change on Wiki.
then try this:
Code: (Select All) $NoPrefix
s = SndOpen("0.mp3")
Dim As MEM l, r
Dim done As Long, m As Integer
l = MemSound(s, 1)
Do Until done = l.SIZE
MemGet l, l.OFFSET + done, m
done = done + 2
SndRaw m / 32768
Loop
It's entirely possible that I've missed something, so I'll ask you for a valid link to a real working use of memsound. Thank you.
In the attached screenshot, look at the numeric values returned. Even if you got it right, I absolutely do not understand the difference between the correctly calculated expected data size and what it returns for the left channel. And try playing the audio for the left channel.
RE: Phoenix 3.5.0 bug? - Petr - 02-19-2023
Good. I kicked it now. Phoenix seems to have a much better level of oversampling. So I want to confirm only one thing, but it is essential. Are the samples in the MEM array organized in order Left, Right, Left, Right...? So MemSound with a parameter of 1 will return the entire sound array for both channels?
I also found out, and I'm thrilled and thank you very much, that SndRaw is now fixed in Phoenix and actually plays in stereo! Here is a test program that opened my eyes.
Code: (Select All) $NoPrefix
Dim s As Long
s = SndOpen("0.mp3")
Dim As MEM l, r
Dim done As Long
Dim m2 As Single '4 byte long, so 32bit sound!
Dim m As Single
l = MemSound(s, 1)
If l.ELEMENTSIZE <> 8 Then Print "This program play just 32 bit songs.": End
Do Until done = l.SIZE - 8
MemGet l, l.OFFSET + done, m
MemGet l, l.OFFSET + done + 4, m2
done = done + 8
SndRaw m, m2
Loop
'wroted in Phoenix 3.5.0
I will change the name of the thread.
RE: Phoenix 3.5.0 bug? - a740g - 02-19-2023
Code: (Select All) OPTION _EXPLICIT
PRINT "Loading...";
DIM Song AS LONG
Song = _SNDOPEN("STARDUST.MOD") ' Replace file name with your sound file
IF Song < 1 THEN
PRINT "Failed to load sound!"
END
END IF
PRINT "Done!"
DIM Channels AS _UNSIGNED _BYTE
Channels = SndChannels(Song)
IF Channels > 0 THEN
PRINT "The sound has"; Channels; "channels."
ELSE
PRINT "An error occurred."
END
END IF
DIM AS LONG i, rawSnd
rawSnd = _SNDOPENRAW
IF rawSnd < 1 THEN
PRINT "Failed to open sound pipe!"
END
END IF
FOR i = 0 TO Channels - 1
PRINT "Queueing channel"; i; "...";
PlaySoundChannel Song, i, rawSnd
PRINT "Done!"
PRINT "Waiting for playback to finish...";
DO WHILE _SNDRAWLEN(rawSnd) > 0 'Finish any left over queued sound!
SLEEP 1
LOOP
PRINT "Done!"
NEXT
_SNDCLOSE rawSnd
_SNDCLOSE Song 'closing the sound releases the mem blocks
END
' Here chan starts from 0
' So, chan 0 is the first channel, 1 the next one and so on
' rs is the raw sound handle
SUB PlaySoundChannel (handle AS LONG, chan AS _UNSIGNED _BYTE, rs AS LONG)
DIM AS _UNSIGNED _INTEGER64 i, sz, es, ofs
DIM SampleData AS _MEM
DIM channels AS _UNSIGNED _BYTE
DIM samp AS SINGLE
channels = SndChannels(handle)
SampleData = _MEMSOUND(handle, 0)
IF SampleData.SIZE = 0 THEN
EXIT SUB
END IF
$IF 64BIT THEN
sz = _CV(_UNSIGNED _INTEGER64, _MK$(_OFFSET, SampleData.SIZE)) ' sz is the total size of the sound in bytes
es = _CV(_UNSIGNED _INTEGER64, _MK$(_OFFSET, SampleData.ELEMENTSIZE))
$ELSE
sz = _CV(_Unsigned long, _MK$(_Offset, SampleData.SIZE)) ' sz is the total size of the sound in bytes
es = _CV(_Unsigned long, _MK$(_Offset, SampleData.ELEMENTSIZE))
$END IF
ofs = es \ channels
FOR i = 0 TO sz - es STEP es
IF SampleData.TYPE = 260 THEN ' 32-bit floating point
samp = _MEMGET(SampleData, SampleData.OFFSET + i + (chan * ofs), SINGLE)
ELSEIF SampleData.TYPE = 132 THEN ' 32-bit integer
samp = _MEMGET(SampleData, SampleData.OFFSET + i + (chan * ofs), LONG) / 2147483648
ELSEIF SampleData.TYPE = 130 THEN ' 16-bit integer
samp = _MEMGET(SampleData, SampleData.OFFSET + i + (chan * ofs), INTEGER) / 32768
ELSEIF SampleData.TYPE = 1153 THEN ' 8-bit unsigned integer
samp = (_MEMGET(SampleData, SampleData.OFFSET + i + (chan * ofs), _UNSIGNED _BYTE) - 128) / 128
END IF
IF chan MOD 2 = 0 THEN
_SNDRAW samp, 0, rs
ELSE
_SNDRAW 0, samp, rs
END IF
NEXT
END SUB
' 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
EXIT FUNCTION
END IF
' Check the data type and then decide if the sound is stereo or mono
IF SampleData.TYPE = 260 THEN ' 32-bit floating point
IF SampleData.ELEMENTSIZE = 4 THEN
SndChannels = 1
ELSEIF SampleData.ELEMENTSIZE = 8 THEN
SndChannels = 2
END IF
ELSEIF SampleData.TYPE = 132 THEN ' 32-bit integer
IF SampleData.ELEMENTSIZE = 4 THEN
SndChannels = 1
ELSEIF SampleData.ELEMENTSIZE = 8 THEN
SndChannels = 2
END IF
ELSEIF SampleData.TYPE = 130 THEN ' 16-bit integer
IF SampleData.ELEMENTSIZE = 2 THEN
SndChannels = 1
ELSEIF SampleData.ELEMENTSIZE = 4 THEN
SndChannels = 2
END IF
ELSEIF SampleData.TYPE = 1153 THEN ' 8-bit unsigned integer
IF SampleData.ELEMENTSIZE = 1 THEN
SndChannels = 1
ELSEIF SampleData.ELEMENTSIZE = 2 THEN
SndChannels = 2
END IF
END IF
END FUNCTION
Here you go @Petr. Hope this will help.
RE: Phoenix 3.5.0 bug? - Petr - 02-19-2023
I tried it and it ended up with an error.
RE: Phoenix 3.5.0 bug? - a740g - 02-19-2023
Quote:Good. I kicked it now. Phoenix seems to have a much better level of oversampling. So I want to confirm only one thing, but it is essential. Are the samples in the MEM array organized in order Left, Right, Left, Right...? So MemSound with a parameter of 1 will return the entire sound array for both channels?
Yes. They are interleaved. LRLR... for stereo sounds.
Quote:I also found out, and I'm thrilled and thank you very much, that SndRaw is now fixed in Phoenix and actually plays in stereo! Here is a test program that opened my eyes.
Yes. That bug was really annoying. But it is fixed now. I discovered it while writing my MOD re-player using _SNDRAW and then I discovered your posts about it in the old forums.
You've been away from the scene for a while. Nice to see you are back.
RE: Phoenix 3.5.0 bug? - a740g - 02-19-2023
You are using the 32-bit version of QB64-PE. Sorry, I did not pay much attention to what it would do when compiled with the 32-bit version of QB64-PE.
The code should run correctly if you compile with the 64-bit version of QB64-PE though.
Update: I fixed my code above for 32-bit QB64-PE. It should work correctly now.
RE: Phoenix 3.5.0 bug? - Petr - 02-19-2023
It works now. I will study it. Thank you.
RE: Phoenix 3.5.0 bug? - a740g - 02-20-2023
(02-19-2023, 07:06 PM)Petr Wrote: I tried it and it ended up with an error.
(02-19-2023, 07:43 PM)Petr Wrote: It works now. I will study it. Thank you.
@Petr there was a bug. More like a typo inside the PlaySoundChannel FOR loop that I corrected. The updated code is in the same post.
|