[solved] wave-files (merge)

Just starting out? Need help? Post your questions and find answers here.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: wave-files (merge)

Post by wilbert »

ZX80 wrote:reason: result wav-file will take up a lot of space in memory. I afraid that program will crashed.
That is a very good reason.

If the audio is 22050 Hz, 16 bit mono (which is adequate for speech), 5 minutes of audio would require about 12.6 megabyte of memory.
So I simply assumed memory wouldn't be a problem.
But of course I don't know enough of your program and how much memory the computers have it has to be used on.
Windows (x64)
Raspberry Pi OS (Arm64)
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: wave-files (merge)

Post by ZX80 »

Now the program takes about 50 MB of memory. Resources in DataSection - 500 KB.
AllocateMemory for telegrams - 5MB. And using: UseOGGSoundDecoder(), UsePNGImageEncoder(), UsePNGImageDecoder(), UseJPEGImageDecoder(), UseMD5Fingerprint(), many KeyboardShortcuts and BindEvent!!!

Computer regarding old (winxp). I will not say exactly how much memory. Don't know.

wilbert!
Thank you again for answers. I will think about it a little bit later.

upd:
So I simply assumed memory wouldn't be a problem.
It's not Old School. 48KB on board. :D
(C) 1982 - Sinclair Research Ltd.
User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

Re: wave-files (merge)

Post by CELTIC88 »

hi :D
I think you're looking for that :

Code: Select all

Structure wavfileheader 
  ;// RIFF Header
  riff_header.l; // Contains "RIFF"
  wav_size.l   ; // Size of the wav portion of the file, which follows the first 8 bytes. File size - 8
  Wav_header.l; // Contains "WAVE"
  
  ;// Format Header
  fmt_header.l; // Contains "fmt " (includes trailing space)
  fmt_chunk_size.l; // Should be 16 for PCM
  audio_format.w  ; // Should be 1 for PCM. 3 for IEEE Float
  num_channels.w  ;
  sample_rate.l   ;
  byte_rate.l     ; // Number of bytes per second. sample_rate * num_channels * Bytes Per Sample
  sample_alignment.w; // num_channels * Bytes Per Sample
  bit_depth.w       ; // Number of bits per sample
  
  ;// Data
  data_header.l; // Contains "data"
  data_bytes.l ; // Number of bytes in data. Number of samples * num_channels * sample byte size
               ;// uint8_t bytes[]; // Remainder of wave file is bytes
EndStructure

EnableExplicit

Procedure Wav_OpenFile(sFile.s,*swavfileheader.wavfileheader)
  Protected hFile = ReadFile(#PB_Any,sFile,#PB_File_SharedRead)
  If hFile = 0:ProcedureReturn 0 : EndIf
  ReadData(hFile,*swavfileheader,SizeOf(wavfileheader))
  While *swavfileheader\data_header <> $61746164
    FileSeek(hFile,*swavfileheader\data_bytes,#PB_Relative)
    If ReadData(hFile,@*swavfileheader\data_header,8) = 0 :CloseFile(hFile):ProcedureReturn 0 : EndIf
  Wend
  ProcedureReturn hFile
EndProcedure

Procedure Wav_CreateFile(sFile.s,*swavfileheader.wavfileheader)
  Protected hFile = CreateFile(#PB_Any,sFile)
  If hFile = 0:ProcedureReturn 0 : EndIf
  WriteData(hFile,*swavfileheader,SizeOf(wavfileheader))
  ProcedureReturn hFile
EndProcedure

Structure WavListInfo
  sfilename.s
  Qstartpos.q
  QSize.q
EndStructure

;select wav files
Define sSelectfile.s = OpenFileRequester("Select Wave files..","","Wav file|*.wav",0, #PB_Requester_MultiSelection)
If sSelectfile = "":End 1:EndIf

;get wav header 
Define swavfileheader.wavfileheader
Define hfile = Wav_OpenFile(sSelectfile,swavfileheader)
If hfile = 0:End 2:EndIf
CloseFile(hfile)

Define hfallwav = Wav_CreateFile("allwav.wav",swavfileheader)
If hfallwav = 0:End 3:EndIf

NewList lWavListInfo.WavListInfo()
Define qAllSize.q, pmemoir
While sSelectfile
  hfile = Wav_OpenFile(sSelectfile,swavfileheader)
  pmemoir = AllocateMemory(swavfileheader\data_bytes)
  ReadData(hfile,pmemoir,swavfileheader\data_bytes)
  CloseFile(hfile)
  AddElement(lWavListInfo())
  lWavListInfo()\sfilename = sSelectfile
  lWavListInfo()\QSize = swavfileheader\data_bytes
  lWavListInfo()\Qstartpos = SizeOf(wavfileheader) + qAllSize
  Debug sSelectfile
  Debug "Offset of data : " + qAllSize
  Debug "Size of data : " + swavfileheader\data_bytes
  qAllSize + swavfileheader\data_bytes
  WriteData(hfallwav,pmemoir,swavfileheader\data_bytes)
  sSelectfile = NextSelectedFileName()
Wend

;fix wav header
FileSeek(hfallwav,0)
swavfileheader\wav_size = 36+qAllSize
swavfileheader\data_bytes = qAllSize
WriteData(hfallwav,swavfileheader,SizeOf(wavfileheader))
CloseFile(hfallwav)

;if you want extract a sound from list 
hfile = Wav_OpenFile("allwav.wav",swavfileheader)
;select sound from list
FileSeek(hfile,lWavListInfo()\Qstartpos)
pmemoir = AllocateMemory(lWavListInfo()\QSize + SizeOf(wavfileheader))
ReadData(hfile,pmemoir+ SizeOf(wavfileheader),lWavListInfo()\QSize)
swavfileheader\wav_size = 36+lWavListInfo()\QSize
swavfileheader\data_bytes = lWavListInfo()\QSize
CopyMemory(swavfileheader, pmemoir,SizeOf(wavfileheader))
CloseFile(hfile)

InitSound()
CatchSound(0,pmemoir)
PlaySound(0)
MessageRequester(""," good luck :)")


interested in Cybersecurity..
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: wave-files (merge)

Post by ZX80 »

CELTIC88, good evening.

Code: Select all

I think you're looking for that :
Exactly! This is great/awesome. Thank you so much for your code. You made my day.
Next (2nd stage), I must do it myself. I was interested version which wilbert said. Thank him for it too.
Have a nice day/night. :D
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: wave-files (merge)

Post by ZX80 »

I apologize, but what's wrong

Code: Select all

Structure wavfileheader 
  ;// RIFF Header
  riff_header.l; // Contains "RIFF"
  wav_size.l   ; // Size of the wav portion of the file, which follows the first 8 bytes. File size - 8
  Wav_header.l; // Contains "WAVE"
  
  ;// Format Header
  fmt_header.l; // Contains "fmt " (includes trailing space)
  fmt_chunk_size.l; // Should be 16 for PCM
  audio_format.w  ; // Should be 1 for PCM. 3 for IEEE Float
  num_channels.w  ;
  sample_rate.l   ;
  byte_rate.l     ; // Number of bytes per second. sample_rate * num_channels * Bytes Per Sample
  sample_alignment.w; // num_channels * Bytes Per Sample
  bit_depth.w       ; // Number of bits per sample
  
  ;// Data
  data_header.l; // Contains "data"
  data_bytes.l ; // Number of bytes in data. Number of samples * num_channels * sample byte size
               ;// uint8_t bytes[]; // Remainder of wave file is bytes
EndStructure


EnableExplicit

Structure WavListInfo
  sfilename.s
  Qstartpos.q
  QSize.q
EndStructure



Procedure Wav_OpenFile(sFile.s,*swavfileheader.wavfileheader)
  Protected hFile = ReadFile(#PB_Any,sFile,#PB_File_SharedRead)
  If hFile = 0:ProcedureReturn 0 : EndIf
  ReadData(hFile,*swavfileheader,SizeOf(wavfileheader))
  While *swavfileheader\data_header <> $61746164
    FileSeek(hFile,*swavfileheader\data_bytes,#PB_Relative)
    If ReadData(hFile,@*swavfileheader\data_header,8) = 0 :CloseFile(hFile):ProcedureReturn 0 : EndIf
  Wend
  ProcedureReturn hFile
EndProcedure


;get wav header 
Define swavfileheader.wavfileheader

NewList lWavListInfo.WavListInfo()
Define qAllSize.q, pmemoir, hfile
Define tmp$


If FileSize("list.txt") = -1
  MessageRequester("Information", "list-file not found")
  End
EndIf

If ReadFile(0, "list.txt")
  While Eof(0) = 0
    tmp$ = ReadString(0)
    If FindString(tmp$, "|")
      AddElement(lWavListInfo())
      lWavListInfo()\Qstartpos = Val(StringField(tmp$, 1, "|"))
      lWavListInfo()\QSize = Val(StringField(tmp$, 2, "|"))
    EndIf
  Wend
  CloseFile(0)
Else
  MessageRequester("Information","Couldn't open the db-file!")
EndIf


NewList ToRead()

AddElement(ToRead())
ToRead() = 9
AddElement(ToRead())
ToRead() = 3
AddElement(ToRead())
ToRead() = 1  
AddElement(ToRead())
ToRead() = 10
AddElement(ToRead())
ToRead() = 5
AddElement(ToRead())
ToRead() = 6
AddElement(ToRead())
ToRead() = 7


ForEach ToRead()
  SelectElement(lWavListInfo(), ToRead()-1)
  qAllSize + lWavListInfo()\QSize
Next


;if you want extract a sound from list 
hfile = Wav_OpenFile("allwav.wav",swavfileheader)
pmemoir = AllocateMemory(qAllSize + SizeOf(wavfileheader))
;select sound from list
SelectElement(ToRead(), 0)
SelectElement(lWavListInfo(), ToRead()-1)
FileSeek(hfile,lWavListInfo()\Qstartpos)
ReadData(hfile,pmemoir+ SizeOf(wavfileheader),lWavListInfo()\QSize)

While NextElement(ToRead())
  SelectElement(lWavListInfo(), ToRead()-1)
  FileSeek(hfile,lWavListInfo()\Qstartpos)
  ReadData(hfile,pmemoir+lWavListInfo()\QSize,lWavListInfo()\QSize)
Wend

swavfileheader\wav_size = 36+qAllSize
swavfileheader\data_bytes = qAllSize
CopyMemory(swavfileheader, pmemoir,SizeOf(wavfileheader))
CloseFile(hfile)

InitSound()
CatchSound(0,pmemoir)
PlaySound(0)
MessageRequester(""," good luck :)")
?
User avatar
CELTIC88
Enthusiast
Enthusiast
Posts: 154
Joined: Thu Sep 17, 2015 3:39 pm

Re: wave-files (merge)

Post by CELTIC88 »

:wink:

Code: Select all

Structure wavfileheader 
  ;// RIFF Header
  riff_header.l; // Contains "RIFF"
  wav_size.l   ; // Size of the wav portion of the file, which follows the first 8 bytes. File size - 8
  Wav_header.l ; // Contains "WAVE"
  
  ;// Format Header
  fmt_header.l; // Contains "fmt " (includes trailing space)
  fmt_chunk_size.l; // Should be 16 for PCM
  audio_format.w  ; // Should be 1 for PCM. 3 for IEEE Float
  num_channels.w  ;
  sample_rate.l   ;
  byte_rate.l     ; // Number of bytes per second. sample_rate * num_channels * Bytes Per Sample
  sample_alignment.w; // num_channels * Bytes Per Sample
  bit_depth.w       ; // Number of bits per sample
  
  ;// Data
  data_header.l; // Contains "data"
  data_bytes.l ; // Number of bytes in data. Number of samples * num_channels * sample byte size
               ;// uint8_t bytes[]; // Remainder of wave file is bytes
EndStructure

EnableExplicit

Procedure Wav_OpenFile(sFile.s,*swavfileheader.wavfileheader)
  Protected hFile = ReadFile(#PB_Any,sFile,#PB_File_SharedRead)
  If hFile = 0:ProcedureReturn 0 : EndIf
  ReadData(hFile,*swavfileheader,SizeOf(wavfileheader))
  While *swavfileheader\data_header <> $61746164
    FileSeek(hFile,*swavfileheader\data_bytes,#PB_Relative)
    If ReadData(hFile,@*swavfileheader\data_header,8) = 0 :CloseFile(hFile):ProcedureReturn 0 : EndIf
  Wend
  ProcedureReturn hFile
EndProcedure

Procedure Wav_CreateFile(sFile.s,*swavfileheader.wavfileheader)
  Protected hFile = CreateFile(#PB_Any,sFile)
  If hFile = 0:ProcedureReturn 0 : EndIf
  WriteData(hFile,*swavfileheader,SizeOf(wavfileheader))
  ProcedureReturn hFile
EndProcedure

Structure WavListInfo
  ID.l
  Qstartpos.q
  QSize.q
EndStructure

Procedure Wav_MergeMultiTrackCreate(List slFile.s(), sFile.s) ; only for files have the same format
  If ListSize(slFile()) = 0:ProcedureReturn 0:EndIf
  FirstElement(slFile())
  Protected swavfileheader.wavfileheader
  Protected hfile = Wav_OpenFile(slFile(),swavfileheader)
  If hfile = 0:ProcedureReturn 0:EndIf
  CloseFile(hfile)
  
  Protected hfallwav = Wav_CreateFile(sFile,swavfileheader)
  If hfallwav = 0:ProcedureReturn 0:EndIf
  
  Protected *pWavListInfo.WavListInfo = AllocateMemory(SizeOf(WavListInfo) * ListSize(slFile()))
  Protected *psWavListInfo = *pWavListInfo
  Protected qAllSize.q, pmemoir,Id
  ForEach slFile()
    hfile = Wav_OpenFile(slFile(),swavfileheader)
    pmemoir = AllocateMemory(swavfileheader\data_bytes)
    ReadData(hfile,pmemoir,swavfileheader\data_bytes)
    CloseFile(hfile)
    *pWavListInfo\ID = Id
    *pWavListInfo\QSize = swavfileheader\data_bytes
    *pWavListInfo\Qstartpos = SizeOf(wavfileheader) + qAllSize
    *pWavListInfo + SizeOf(WavListInfo)
    Id + 1
    qAllSize + swavfileheader\data_bytes
    WriteData(hfallwav,pmemoir,swavfileheader\data_bytes)
    FreeMemory(pmemoir)
  Next
  
  WriteData(hfallwav,*psWavListInfo,MemorySize(*psWavListInfo))
  FreeMemory(*psWavListInfo)
  ;fix wav header
  FileSeek(hfallwav,0)
  swavfileheader\wav_size = 36+qAllSize
  swavfileheader\data_bytes = qAllSize
  WriteData(hfallwav,swavfileheader,SizeOf(wavfileheader))
  CloseFile(hfallwav)
EndProcedure

Procedure Wav_MergeMultiTrackPlay( sFile.s, ID.l) ; ID of sound 0 or 1 ..
  Protected swavfileheader.wavfileheader
  Protected hfile = Wav_OpenFile(sFile,swavfileheader)
  FileSeek(hfile,swavfileheader\data_bytes, #PB_Relative)
  Protected pWavListInfo.WavListInfo
  Protected True = 0
  While ReadData(hfile,pWavListInfo,SizeOf(WavListInfo))
    If pWavListInfo\ID = ID
      True= 1
      Break
    EndIf
  Wend
  
  If True = 1
    FileSeek(hfile,pWavListInfo\Qstartpos)
    Protected pmemoir = AllocateMemory(pWavListInfo\QSize + SizeOf(wavfileheader))
    ReadData(hfile,pmemoir+ SizeOf(wavfileheader),pWavListInfo\QSize)
    swavfileheader\wav_size = 36+pWavListInfo\QSize
    swavfileheader\data_bytes = pWavListInfo\QSize
    CopyMemory(swavfileheader, pmemoir,SizeOf(wavfileheader))
    
    InitSound()
    CatchSound(0,pmemoir)
    PlaySound(0)
  EndIf
  
  CloseFile(hfile)
  ProcedureReturn 0
EndProcedure

;select wav files
Define sSelectfile.s = OpenFileRequester("Select Wave files..","","Wav file|*.wav",0, #PB_Requester_MultiSelection)
If sSelectfile = "":End 1:EndIf

NewList slFile.s()
While sSelectfile
  AddElement(slFile())
  slFile() = sSelectfile
  sSelectfile = NextSelectedFileName() 
Wend

Wav_MergeMultiTrackCreate(slFile(),"WavData.Wav")


Wav_MergeMultiTrackPlay("WavData.Wav",4) ; play 4 sound 

MessageRequester("","")








interested in Cybersecurity..
ZX80
Enthusiast
Enthusiast
Posts: 330
Joined: Mon Dec 12, 2016 1:37 pm

Re: wave-files (merge)

Post by ZX80 »

CELTIC88 :!:
good time of day

I just wanted to tell you that my problem is successful solved

and...

Code: Select all

Repeat
  Debug "Thank you so much!!!"
ForEver
Post Reply