Code archives/Audio/Read wave and write to bb data file
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| This is a 2-part code entry. It is designed to pack any wave sounds inside a blitz executable and then write them with data labels. The first part is to read wave files and write the data to a bb data file. The second is to read the data (as an include) and write the wave file. You can read/write various samplerates and in 8 or 16-bit quality. there is some kind of issue when using 8-bit waves as source, but it still works. There is an end of data signature fourcc "end " to avoid out of data errors. I decided this was better than trying to calculate it. edit: i have updated this to check the values written are never the fourcc "end ", so it should work 100% of the time now. | |||||
;Read Wave Write Data, on 19/9/06
Graphics 640,480,0,2
SetBuffer BackBuffer()
fileout$="temp.bb"
filein$="yourname.wav" ;wave in
ok=ReadWaveWriteData(filein$,fileout$,12000) ;comprate
chnsnd=PlayMusic(filein$) ;play wave in
;Main loop
While Not KeyHit(1)
Cls
Text 0,0,"ok="+ok+" filein="+filein$+" fileout$="+fileout$
Flip
Wend
;Functions
Function ReadWaveWriteData(filein$,fileout$,comprate)
;Read a wave file and write data to bb file
;filein$=wave file, fileout$=bb file, comprate=compression rate
;From PureBasic CodeArchiv, by Froggerprogger on 4/9/03
Local rfile,datasize,pcm,channels,samplesps,avgbytesps,blockalign,bps
Local mssize,wfile,time,side,value,lastms,mstime,x,integer
If filein$="" Then Return False ;fail code
rfile=ReadFile(filein$)
If Not rfile Then Return False ;read fail
;RIFF Chunk, Resource Interchange File Format
If ReadInt(rfile)<>MakeFourCC("R","I","F","F") ;dwChunkID, "RIFF"
CloseFile rfile : Return False ;not riff file
EndIf
datasize=ReadInt(rfile) ;dwChunkSize, filesize-8
If ReadInt(rfile)<>MakeFourCC("W","A","V","E") ;dwTypeID, "WAVE"
CloseFile rfile : Return False ;not wave file
EndIf
;Format Chunk, RIFF Subchunk
If ReadInt(rfile)<>MakeFourCC("f","m","t"," ") ;dwChunkID, "fmt "
CloseFile rfile : Return False ;not PCM format
EndIf
datasize=ReadInt(rfile) ;dwChunkSize, sizeof(PCMWAVEFORMAT)
;PCMWAVEFORMAT structure, uncompressed wave data
pcm=ReadShort(rfile) ;wFormatTag, WAVE_FORMAT_PCM=1
channels=ReadShort(rfile) ;wChannels, mono=1/stereo=2
samplesps=ReadInt(rfile) ;dwSamplesPerSec, samplerate in hertz
avgbytesps=ReadInt(rfile) ;dwAvgBytesPerSec
blockalign=ReadShort(rfile) ;wBlockAlign, bytes per sample
bps=ReadShort(rfile) ;wBitsPerSample, PCM=8/16
;Data Chunk, RIFF Subchunk
SeekFile(rfile,20+datasize)
If ReadInt(rfile)<>MakeFourCC("d","a","t","a") ;dwChunkID, "data"
CloseFile rfile : Return False ;not PCM data
EndIf
datasize=ReadInt(rfile) ;dwChunkSize, sizeof(DataSamples)
;calculate compressed size, make sure value not too big
mssize=(datasize*(comprate/1000))/((samplesps/1000)*blockalign)
;Write fileout.bb
If fileout$="" Then Return False ;fail code
wfile=WriteFile(fileout$)
If Not wfile Then Return False ;write fail
;write title comment, wave data label and data command
WriteStringAscii(wfile,";"+fileout$)
WriteByte wfile,13 : WriteByte wfile,10 ;newline
WriteByte wfile,13 : WriteByte wfile,10 ;newline
WriteStringAscii(wfile,"."+Left(filein$,Len(filein$)-4))
WriteStringAscii(wfile,"_"+Right(filein$,3))
WriteByte wfile,13 : WriteByte wfile,10 ;newline
WriteStringAscii(wfile,"Data ")
WriteValueAscii(wfile,mssize) ;first value is compressed size
;Data Samples
While time<datasize
;read value according to bits per sample
For side=1 To channels
If bps=8
value=ReadByte(rfile) ;range 0..255
Else
value=ReadShort(rfile) ;range -32767..32767
value=value/256 ;convert short to byte
If value<128 Then value=value+128 Else value=value-128
EndIf
Next
;calculate compressed time interval, make sure value not too big
lastms=mstime
mstime=(time*(comprate/1000))/((samplesps/1000)*blockalign)
If lastms<>mstime ;time reached, write integer
If x=0 Then integer=integer Or value ;set bytes to integer
If x=1 Then integer=integer Or (value Shl 8)
If x=2 Then integer=integer Or (value Shl 16)
If x=3 Then integer=integer Or (value Shl 24)
If x=3 ;write integer, make sure not fourcc "end "
If integer=MakeFourCC("e","n","d"," ") Then integer=integer+1
WriteByte wfile,Asc(",")
WriteValueAscii(wfile,integer)
EndIf
x=x+1 : If x>3 Then x=0 : integer=0 ;reset
EndIf
time=time+blockalign
Wend
If x>0 ;last integer not aligned
WriteByte wfile,Asc(",")
WriteValueAscii(wfile,integer)
EndIf
;write end fourcc and end comment
WriteByte wfile,Asc(",")
WriteValueAscii(wfile,MakeFourCC("e","n","d"," ")) ;avoid out of data
WriteByte wfile,13 : WriteByte wfile,10 ;newline
WriteStringAscii(wfile,";end "+Left(filein$,Len(filein$)-4))
WriteStringAscii(wfile,"_"+Right(filein$,3))
CloseFile rfile
CloseFile wfile
Return True ;success code
End Function
Function MakeFourCC(c0$,c1$,c2$,c3$)
Return (Asc(c0$)+(Asc(c1$) Shl 8)+(Asc(c2$) Shl 16)+(Asc(c3$) Shl 24))
End Function
Function WriteValueAscii(file,value)
;file=file handle, value=byte/short/integer
Local ascii$,i,char$
ascii$=Str(value)
For i=1 To Len(ascii$)
char$=Mid(ascii$,i,1)
WriteByte(file,Asc(char$))
Next
End Function
Function WriteStringAscii(file,ascii$)
;file=file handle, ascii$=ascii string
Local i,char$
For i=1 To Len(ascii$)
char$=Mid(ascii$,i,1)
WriteByte(file,Asc(char$))
Next
End Function |
Comments
| ||
| This is the second part. It writes waves from the data labels. |
Code Archives Forum