Page 1 of 1
Waves again
Posted: Wed Sep 03, 2003 4:53 pm
by Megaborsti
Hi,
I asked about wave-files not long ago and wrote the following test-program, but the created file cannot be played with the mediaplayer.
Why not? Can anyone help me?
Code: Select all
CreateFile(0,"wavtest.wav")
WriteString("RIFF")
WriteLong(932)
WriteString("WAVEfmt ")
WriteLong(16)
WriteWord(1)
WriteWord(2)
WriteLong(22050)
WriteLong(44100)
WriteWord(4)
WriteWord(16)
WriteString("data")
WriteLong(880)
For a = 0 To 10
WriteLong(0)
Next
For a = 0 To 100
WriteLong(65536)
WriteLong(-65536)
Next
For a = 0 To 10
WriteLong(0)
Next
Posted: Wed Sep 03, 2003 6:57 pm
by GPI
Maybe this help:
I translatet a programm from Delphi (i think):
It create a wave in the memory and play it.
Code: Select all
Procedure CreateSound(nr,Frequency,Duration,SampleRate);
SoundValue.b
w.f; // omega ( 2 * pi * frequency)
wave_FormatEx.wave_
wave_FormatEx\wFormatTag=#WAVE_FORMAT_PCM;
wave_FormatEx\nChannels =$0001;mono
wave_FormatEx\nSamplesPerSec = SampleRate;
wave_FormatEx\wBitsPerSample = $0008;
wave_FormatEx\nBlockAlign = (wave_FormatEx\nChannels * wave_FormatEx\wBitsPerSample) /8
wave_FormatEx\nAvgBytesPerSec = wave_FormatEx\nSamplesPerSec * wave_FormatEx\nBlockAlign;
wave_FormatEx\cbSize = 0;
DataCount = (Duration * SampleRate)/1000; // sound data
RiffCount = 4+4 +4+ SizeOf(wave_)+4 +4+ DataCount
start=GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT,RiffCount+100)
MS=start
PokeS(MS,"RIFF"):MS+4 ;'RIFF'
PokeL(MS,RiffCount):MS+4 ;file Data size
PokeS(MS,"wave"):MS+4 ;'wave_'
PokeS(MS,"fmt "):MS+4 ;'fmt '
TempInt = SizeOf(wave_);
PokeL(MS,TempInt):MS+4 ;Twave_Format data size
PokeW(MS,wave_FormatEx\wFormatTag):MS+2; wave_FormatEx record
PokeW(MS,wave_FormatEx\nChannels):MS+2
PokeL(MS,wave_FormatEx\nSamplesPerSec):MS+4
PokeL(MS,wave_FormatEx\nAvgBytesPerSec):MS+4
PokeW(MS,wave_FormatEx\nBlockAlign):MS+2
PokeW(MS,wave_FormatEx\wBitsPerSample):MS+2
PokeW(MS,wave_FormatEx\cbSize):MS+2
PokeS(MS,"data"):MS+4 ;'data'
PokeL(MS,DataCount):MS+4 ;sound data size
; {Calculate And write out the tone signal} // now the Data values
w = 2 * 3.1415 * Frequency; omega
For i = 0 To DataCount - 1
SoundValue = 127 + 127 * Sin(i * w / SampleRate);
PokeB(MS,SoundValue):MS+1;
Next
CatchSound(Nr,start)
GlobalFree_(start)
EndProcedure
and it is now part of the jaPBe-IncludePack1
Posted: Thu Sep 04, 2003 6:38 pm
by Froggerprogger
Here one more.
Simply creates a WAV-file with a sinustone.
Code: Select all
;- 04.09.03 by Froggerprogger
;- 04.09.03 by Froggerprogger
;-
;- Tip: You can replace the byte-text-output with the following:
;-
;- WriteLong($46464952) = "RIFF"
;- WriteLong($45564157) = "WAVE"
;- WriteLong($20746D66) = "fmt "
;-
;- You can even use WriteString("RIFF") and WriteString("WAVEfmt "), because PB doesn't write a
;- terminating 0 - but I don't like this way, perhaps it's too easy ;-)
;-
;- For further information on the WAV-format look at: http://www.sonicspot.com/guide/wavefiles.html
#pi = 3.141593 ; pi
#fq = 220 ; frequenz in Hz for sinustone
#samplerate = 44100 ; samplerate
#bitrate = 16 ; Bits per sample, #bitrate Mod 8 must be 0 !
#channels = 2 ; number of channels
#secs = 4 ; time for the sinustone in seconds
#soundfilename.s = "wavtest.wav" ; filename fr the soundfile
avBytesPerSec.l = #channels*#bitrate/8*#samplerate ; calculate the average bytes per second
CreateFile(0, #soundfilename)
WriteByte(Asc("R")) ; here you can use WriteLong($46464952) instead - see the tip on top
WriteByte(Asc("I"))
WriteByte(Asc("F"))
WriteByte(Asc("F"))
WriteLong(36+avBytesPerSec*#secs) ; normally filesize - 8 Bytes, here a bit tricky, fmt-chunk + data-chunk
WriteByte(Asc("W"))
WriteByte(Asc("A"))
WriteByte(Asc("V"))
WriteByte(Asc("E"))
WriteByte(Asc("f"))
WriteByte(Asc("m"))
WriteByte(Asc("t"))
WriteByte(Asc(" "))
WriteLong(16) ; chunk data size
WriteWord(1) ; compression code
WriteWord(#channels) ; number of channels
WriteLong(#samplerate) ; samplerate
WriteLong(avBytesPerSec) ; average bytes per second, here 2(channels)*2(block align)*44100(samplerate)
WriteWord(#bitrate/8*#channels) ; Block Align ('bytes per sample')
WriteWord(#bitrate) ; Bits per sample
WriteByte(Asc("d"))
WriteByte(Asc("a"))
WriteByte(Asc("t"))
WriteByte(Asc("a"))
WriteLong(avBytesPerSec*#secs) ; data chunk size in byes
Global actsamplevalue.w ; for signed RAW data
For acttime = 1 To #samplerate * #secs
For actchannel = 1 To #channels
actsamplevalue = 32767 * Sin(2 * #pi * #fq * acttime / #samplerate)
WriteWord(actsamplevalue)
Next
Next
CloseFile(0)
Posted: Sun Sep 07, 2003 12:51 am
by Dreglor
may i ask how wav files are formated so i can understand this more
Posted: Sun Sep 07, 2003 1:08 am
by freak
@Froggerprogger:
Instead of writing Asc("W"), you can simply write 'W' .
The compiler then inserts the ASCII value for that character in that place.
so do it like:
WriteByte('W')
And this works even with more characters, so instead of doing:
WriteLong($46464952) ; = "RIFF"
You can actually do:
WriteLong('FFIR')
Note, that this must be reversed here, due to the little-endian thingy.
Timo
Posted: Sun Sep 07, 2003 12:06 pm
by Froggerprogger
@freak
Thanks for this! I haven't known, but the 'xxx' is a very cool compiler-feature !
@Dreglor
For example here you'll find information on the possible wav-chunks. The data-chunk is the one storing the uncompressed RAW-data.
http://www.sonicspot.com/guide/wavefiles.html
Posted: Sun Sep 07, 2003 1:09 pm
by Andre
@freak
Thanks for this! I haven't known, but the 'xxx' is a very cool compiler-feature !
Freak, would you write a little extension for the manual about this feature, please ?
Posted: Sun Sep 07, 2003 2:26 pm
by GPI
Andre wrote:@freak
Thanks for this! I haven't known, but the 'xxx' is a very cool compiler-feature !
Freak, would you write a little extension for the manual about this feature, please ?
debug 'A'
debug 'a'
debug 'HA'
debug 'HALL'
'xxxx' is the same like
string.s="xxxx"
debug peekl(@string)
'xx'
string.s="xx"
debug peekw(@string)
'x'
string.s="x"
debug peekb(@string)
debug asc(string)
GPI
Posted: Sun Sep 07, 2003 3:36 pm
by Froggerprogger
But (of course) be careful with the order of the letters:
Code: Select all
;'HALL' is the same like PeekL("LLAH")
Debug 'HALL'
string.s="LLAH"
Debug PeekL(@string)
;'HAL' is the same like PeekL("LAH")
Debug 'HAL'
string.s="LAH"
Debug PeekL(@string)
;'HA' is the same like PeekL("AH")
Debug 'HA'
string.s="AH"
Debug PeekL(@string)
Debug PeekW(@string)
;'H' is (of course) the same like PeekL("H")
Debug 'H'
string.s="H"
Debug PeekL(@string)
Debug PeekW(@string)
Debug PeekB(@string)
Debug Asc(string)