Loadsound()/Playsound() problem (Solved).

Just starting out? Need help? Post your questions and find answers here.
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Loadsound()/Playsound() problem (Solved).

Post by DK_PETER »

Hey..
Are there any special criterias for wav files, when using LoadSound()/Playsound()?
Below link contains 3 wav files. While all three plays nicely in mediaplayer, files 1.wav and 3.wav will fail using LoadSound()

I could convert 1.wav and 3.wav to make them work, but I would like to know why they fail.
The problem has been present for a long time and is still present in PB 5.31 B3.

https://www.dropbox.com/s/wi8cp1lrh05yz ... s.zip?dl=0

TIA.

Edit: Fix by infratec should be implemented by PB team.
Last edited by DK_PETER on Wed Oct 22, 2014 11:55 am, edited 1 time in total.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
es_91
Enthusiast
Enthusiast
Posts: 242
Joined: Thu Jan 27, 2011 12:00 pm
Location: DE

Re: Loadsound()/Playsound() problem with specific wav files?

Post by es_91 »

Hi.

I am not sure if I can help you. I toyed around with .wav files half a year ago and I found that the loading algorithms can be very sensitive with the header. You should learn about the header of RIFF-WAVE files and check if they are correct. It is a bit complicated but that should be the clean way.

http://en.wikipedia.org/wiki/WAV

The german Wikipedia gives a clean list of header parts:

http://de.wikipedia.org/wiki/RIFF_WAVE# ... CM-Formats

Maybe you can read it. If not, i could provide a translation. Wanted?
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Loadsound()/Playsound() problem with specific wav files?

Post by DK_PETER »

@es_91
Thanks for trying to help.
No translation is necessary, I appreciate the offer, though. :-)
I've been fiddling with the wav format myself and I know, that the two of them isn't excatly follows the
default standard. I've gotten past the problem by either converting the specific wav file or by using
LoadMovie()/PlayMovie(), which plays all the wav files nicely.

Code: Select all

Properties for each wav file:

General                        : 1.wav
Format                         : Wave
File size                      : 442 KiB
Duration                       : 5s 102ms
Overall bit rate mode          : Constant
Overall bit rate               : 710 Kbps
Producer                       : Pro Tools
Description                    : COUGAR_2 GAIN
Encoded date                   : 2004-08-27 18:49:04
Producer_Reference             : kR1vmQas3CY3

Audio
Format                         : PCM
Format settings, Endianness    : Little
Format settings, Sign          : Signed
Codec ID                       : 1
Duration                       : 5s 102ms
Bit rate mode                  : Constant
Bit rate                       : 705.6 Kbps
Channel(s)                     : 1 channel
Sampling rate                  : 44.1 KHz
Bit depth                      : 16 bits
Stream size                    : 440 KiB (99%)

-----------------------------------------------------
General
Complete name                  : E:\2.wav
Format                         : Wave
File size                      : 88.3 KiB
Duration                       : 2s 49ms
Overall bit rate mode          : Constant
Overall bit rate               : 353 Kbps
Audio
Format                         : PCM
Format settings, Endianness    : Little
Format settings, Sign          : Signed
Codec ID                       : 1
Duration                       : 2s 49ms
Bit rate mode                  : Constant
Bit rate                       : 352.8 Kbps
Channel(s)                     : 1 channel
Sampling rate                  : 22.05 KHz
Bit depth                      : 16 bits
Stream size                    : 88.2 KiB (100%)

-----------------------------------------------------
General                        : 3.wav
Format                         : Wave
File size                      : 602 KiB
Duration                       : 3s 486ms
Overall bit rate mode          : Constant
Overall bit rate               : 1 414 Kbps
Producer                       : Pro Tools
Description                    : SNAKE_H2.1-GAIN_01-01
Encoded date                   : 1904-01-01 04:09:42
Producer_Reference             : kGaaoOyigAVh

Audio
Format                         : PCM
Format settings, Endianness    : Little
Format settings, Sign          : Signed
Codec ID                       : 1
Duration                       : 3s 486ms
Bit rate mode                  : Constant
Bit rate                       : 1 411.2 Kbps
Channel(s)                     : 2 channels
Sampling rate                  : 44.1 KHz
Bit depth                      : 16 bits
Stream size                    : 601 KiB (100%)

------------------------------------------------------
So...My question is:
What is the criteria for LoadSound()? I got a lot of effect files,
which are just like file 1 and 3.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Loadsound()/Playsound() problem with specific wav files?

Post by Joris »

Your tree wave files seems to be correct (played them within CoolEdit).
So I think you should report this as a bug.

(Always better to add a sample source code too.)
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Loadsound()/Playsound() problem with specific wav files?

Post by DK_PETER »

Joris wrote:Your tree wave files seems to be correct (played them within CoolEdit).
So I think you should report this as a bug.
(Always better to add a sample source code too.)
Thanks for checking - and you're right...Code example has been added to the archive.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
infratec
Always Here
Always Here
Posts: 6874
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Loadsound()/Playsound() problem with specific wav files?

Post by infratec »

Hi,

I noticed that some players can not handle when the data chunk is not directly after the fmt chunk.
Which is the case for your 1 and 3 file.

Bernd
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Loadsound()/Playsound() problem with specific wav files?

Post by DK_PETER »

infratec wrote:Hi,
I noticed that some players can not handle when the data chunk is not directly after the fmt chunk.
Which is the case for your 1 and 3 file.
Bernd
Yeah..I've noticed the same. It's a minority of players, which can't handle it (Codec specific?). But recently I've stumbled into a
lot of files, which have the same format as 1 and 3. Especially when it comes to effects.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
infratec
Always Here
Always Here
Posts: 6874
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Loadsound()/Playsound() problem with specific wav files?

Post by infratec »

Hi,

a bug fix, save it as LoadSoundWav.pbi

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf

Structure RIFFStructure
  Riff.a[4]
  Length.l
  Wave.a[4]
EndStructure

Structure chunkStructure
  Signature.a[4]
  Length.l
EndStructure

Structure fmtStructure
  fmt.a[4]
  Length.l
  Format.u
  Channels.u
  SampleRate.l
  BytesPerSecond.l
  BlockAlign.u
  BitsPerSample.u
EndStructure

Structure dataStructure
  dataChunk.a[4]
  Length.l
 
  dataBytes.a[0]
EndStructure


Procedure.i LoadSoundWav(Sound.i, Filename$)
 
  Protected.i Result, File, FileSize
  Protected Chunk$
  Protected *ReadBuffer, *WAVBuffer
  Protected *RiffPtr.RIFFStructure
  Protected *chunkPtr.chunkStructure
  Protected *fmtPtr.fmtStructure
  Protected *dataPtr.dataStructure
 
 
  File = ReadFile(#PB_Any, Filename$)
  If File
   
    FileSize = Lof(File)
    *ReadBuffer = AllocateMemory(FileSize)
    If *ReadBuffer
     
      *WAVBuffer = AllocateMemory(FileSize)
      If *WAVBuffer
       
        If ReadData(File, *ReadBuffer, FileSize) = FileSize
         
          *RiffPtr = *ReadBuffer
          If PeekS(@*RiffPtr\Riff, 4, #PB_Ascii) = "RIFF" And *RiffPtr\Length = FileSize - 8 And PeekS(@*RiffPtr\Wave, 4, #PB_Ascii) = "WAVE"
            ;Debug "Header Ok"
           
            CopyMemory(*RiffPtr, *WAVBuffer, SizeOf(RIFFStructure))
           
           
            *chunkPtr = *ReadBuffer + SizeOf(RIFFStructure)
           
            Repeat
              ; check for data chunk
           
              Chunk$ = PeekS(@*chunkPtr\Signature, 4, #PB_Ascii)
           
              ;Debug "Chunk: " + Chunk$
             
              Select Chunk$
                Case "fmt "
                  *fmtPtr = *chunkPtr
                  CopyMemory(*fmtPtr, *WAVBuffer + SizeOf(RIFFStructure), *fmtPtr\Length + 8)
                  
                Case "data"
                  *dataPtr = *chunkPtr
                  CopyMemory(*dataPtr, *WAVBuffer + SizeOf(RIFFStructure) + *fmtPtr\Length + 8, *dataPtr\Length + 8)
                 
              EndSelect
             
              *chunkPtr + 8 + *chunkPtr\Length
             
            Until *chunkPtr >= *ReadBuffer + *RiffPtr\Length
           
           
            *RiffPtr = *WAVBuffer
            PokeL(@*RiffPtr\Length, SizeOf(RIFFStructure) - 8 + *fmtPtr\Length + 8 + *dataPtr\Length + 8)
            
;             CreateFile(99, "new.wav")
;             WriteData(99, *WAVBuffer, *RiffPtr\Length + 8)
;             CloseFile(99)
            
            Result = CatchSound(Sound, *WAVBuffer, *RiffPtr\Length + 8)
           
          EndIf
         
        EndIf
       
        FreeMemory(*WAVBuffer)
      EndIf
     
      FreeMemory(*ReadBuffer)
    EndIf
   
  EndIf
 
  ProcedureReturn Result
 
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
 
Define Filename$

InitSound()

Filename$ = OpenFileRequester("Choose a wav file", "", "wav|*.wav", 0)
If Filename$
  If LoadSoundWav(0, Filename$)
    PlaySound(0)
    While SoundStatus(0) = #PB_Sound_Playing
      Delay(10)
    Wend
  Else
    Debug "Error"
  EndIf
EndIf
CompilerEndIf
I extract the RIFF header, the fmt and the data chunk.

Bernd
Last edited by infratec on Sun Jan 18, 2015 10:10 pm, edited 1 time in total.
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Loadsound()/Playsound() problem with specific wav files?

Post by DK_PETER »

@infratech
Wonderful, just wonderful!!

It works with all my effect files :-)
An nice way to solve an annoying problem.
I appreciate your effort very much. (Big thanks).

Best regards
Peter
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: Loadsound()/Playsound() problem (Solved).

Post by heartbone »

infratech, I have some files that I'd love to be able to play using your converter.
6 .wavs in a .zip
Converting a 57 KB .ogg (sourced from midi playback) into a .wav using different formats yields these various file sizes
IMA ADPCM 11.025 kHz, 4 Bit, Mono 16 KB DECENT
MICROSOFT ADPCM 11.025 kHz, 4 Bit, Mono 16 KB DECENT
GSM 6.10 11.025 kHz, Mono 8 KB THE SOUND IS A BIT TOO MUDDY
MPEG Layer-3 16 kBit/s, 12,000 Hz, Mono 8 KB THE BEST BANG FOR THE BUCK BY FAR
MPEG Layer-3 56 kBit/s, 24,000 Hz, Stereo 28.0 KB INCLUDED FOR COMPARISON
PCM 8.000 kHz, 16 Bit, Mono 179 KB OINK, OINK
The only .wav format of the ones shown above that PureBasic will play is the (apparently uncompressed) PCM format.
infratech, I would love to use your fix but the only file above that works with your code is the one using the PCM format, which already worked.
For the others, execution fails at the statement

Code: Select all

Result = CatchSound(Sound, *WAVBuffer, *RiffPtr\Length + 8)
[ERROR] Invalid memory access. (read error at address 2407689146)
So would it be correct for me to deduce that this playback problem isn't a chunk alignment issue, and that you wouldn't be able to make your fix work with the other .wav file formats?
Keep it BASIC.
infratec
Always Here
Always Here
Posts: 6874
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Loadsound()/Playsound() problem (Solved).

Post by infratec »

I'll have a look.

Bernd
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: Loadsound()/Playsound() problem (Solved).

Post by heartbone »

I thank you kind sir for taking the time to look at this.

If you can come up with something that I can use to allow me to include that flourish, then if anyone ever asks me what I used to build the program, I'd be obliged to mention your fix along with PureBasic.
At this point my executable is 829 KB and using the PCM wav is out of the question if I intend to deliver a less than 1 MB final executable.
If I see that finishing the implementation will put me over the desired 1 MB limit, (my best guess is 50-50 at this point), then I'll go ahead and use that large PCM file.
But if I can squeeze the entire program in under a megabyte without that unnecessary flourish, then that sound won't make it.
Whereas an 8 KB .wav file, plus your code fix, would make the desired flourish much more likely to be included in a 1 MB executable.

In my opinion one of PureBasic strengths is the small executable file size.
If I can deliver a fully working, non-trivial three player networked game in less than 1 megabyte, then that might garner some deserved notice.
Keep it BASIC.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4663
Joined: Sun Apr 12, 2009 6:27 am

Re: Loadsound()/Playsound() problem (Solved).

Post by RASHAD »

Hi heartbone
Simple one for windows

Code: Select all

Filename$ = OpenFileRequester("Choose a wav file", "", "wav|*.wav", 0)
If Filename$
    PlaySound_(Filename$,0,#SND_FILENAME |#SND_NODEFAULT  ) 
EndIf
Egypt my love
infratec
Always Here
Always Here
Posts: 6874
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Loadsound()/Playsound() problem (Solved).

Post by infratec »

Hi heartbone,

I found a bug in my code when not using PCM files.
I corrected it above.
But ...

It does not solve your problem, because, according to the help, PB WAV can only play PCM files.
So Rashads way is the only solution for you.
If you need a crossplatform solution: pack the files and unpack them in memory.

Bernd
User avatar
heartbone
Addict
Addict
Posts: 1058
Joined: Fri Apr 12, 2013 1:55 pm
Location: just outside of Ferguson

Re: Loadsound()/Playsound() problem (Solved).

Post by heartbone »

RASHAD wrote:Hi heartbone
Simple one for windows

Code: Select all

Filename$ = OpenFileRequester("Choose a wav file", "", "wav|*.wav", 0)
If Filename$
    PlaySound_(Filename$,0,#SND_FILENAME |#SND_NODEFAULT  ) 
EndIf
So it is! :D
That works great in Windows®, thanks a lot RASHAD.
edit: Then again... the suggested methods for controlling the volume seems to be rather involved to outright primitive.
My app saves the user's volume setting and expects to use it during this playback. A relatively blaring intro is not a deal breaker however, so I doubt if I'll go in and rewrite the wav file on the fly just to change the volume when needed.
infratec wrote:If you need a crossplatform solution: pack the files and unpack them in memory.
Thanks for the suggestion infratec.
I am using IncludeBinary and unpacking the data on the fly into a temp file in order to play it using Windows® PlaySound_ function.
Therefore in Linux the .wav file is already in memory, yet I still don't understand how to play it from there. :?:
Last edited by heartbone on Mon Jan 19, 2015 8:27 pm, edited 2 times in total.
Keep it BASIC.
Post Reply