I need to merge several sound files into one. Assume that all files have the same format. I read this topic and want to use code written by infratec. Here is a non-working example(very dirty), but it shows what I want to do (based on code by infratec):
Code: Select all
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
Structure properties
begin_position.q
size.q
EndStructure
#HeaderSize = 44 ; standard size for wav-file header
Global OutputFile.s = "c:\base.wav" ; result file
Global size_of_data.q
Global NewList DATABase.properties()
Procedure.i LoadSoundWav(Filename$)
Protected.i 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)
resultfile_size.q = FileSize(OutputFile)
If resultfile_size =-1
CreateFile(99, OutputFile)
WriteData(99, *WAVBuffer, #HeaderSize) ; write original header
; CloseFile(99)
Else
OpenFile(99, OutputFile)
FileSeek(99, 40)
WriteData(99, @size_of_data, 4) ; change size of data (position: 4 Bytes after 'data')
FileSeek(99, Lof(99)) ; the same as #PB_File_Append
EndIf
size_of_data + PeekL(*WAVBuffer+#HeaderSize-4) ; how to sum bytes here ???
WriteData(99, *WAVBuffer + #HeaderSize, *RiffPtr\Length + 8 - #HeaderSize)
CloseFile(99)
AddElement(DATABase())
If resultfile_size
DATABase()\begin_position = resultfile_size
Else
DATABase()\begin_position = #HeaderSize
EndIf
DATABase()\size = *RiffPtr\Length + 8 - #HeaderSize
EndIf
EndIf
FreeMemory(*WAVBuffer)
EndIf
FreeMemory(*ReadBuffer)
EndIf
EndIf
EndProcedure
For i=1 To 3
LoadSoundWav("c:\"+Str(i)+".wav")
Next i
; now I want to get a second sound from the base
SelectElement(DATABase(), 1)
OpenFile(99, OutputFile)
*Header = AllocateMemory(#HeaderSize)
ReadData(99, *Header, #HeaderSize)
FileSeek(99, DATABase()\begin_position)
_DATA = DATABase()\size
*ReadBuffer = AllocateMemory(_DATA)
ReadData(99, *ReadBuffer, _DATA)
CloseFile(99)
; create a new file
OpenFile(99, "c:\taste.wav")
WriteData(99, *Header, #HeaderSize-4)
WriteData(99, @_DATA, 4) ; ??? hex()
WriteData(99, *ReadBuffer, _DATA)
CloseFile(99)
FreeMemory(*Header)
FreeMemory(*ReadBuffer)