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