|
Post by bluatigro on Feb 22, 2022 4:52:35 GMT -5
this is a try at a wav creator i need this to work before i kan try a play it composer program i plan to create muzik and sound efects
'' wav
global rID$ : rID$ = "RIFF"
global rLen ' file size minus 8
global wID$ : wID$ = "WAVE"
global fID$ : fID$ = "fmt "
global fLen : fLen = 16
global FmtTag$ : FmtTag$ = sample$( 1 )
global Channels$ : Channels$ = sample$( 1 ) ' 1 = Mono, 2 = Stereo
global SampleRate : SampleRate = 11025 ' 11025 = 11kHz, 22050 = 22 kHz, etc.
global AvgBytesPerSec ' SampleRate*Channels*BitsPerSample/8
global BlockAlign ' Channels * BitsPerSample/8
global BitsPerSample : BitsPerSample = 16 ' 8, 16, etc.
global dID$ : dID$ = "data"
global dLen ' length in bytes of the sound buffer
global sec : sec = 1
global bufsize : bufsize = SampleRate * sec * 2
global hz : hz = 440
global pi
rLen = 44 + bufsize - 8
AvgBytesPerSec = SampleRate * Channels.struct * BitPerSample / 8
BlockAlign = Channels * BitsPerSample / 8
dLen = bufsize
pi = atn( 1 ) * 4
open "440_1000.wav" for output as #wav
print #wav , rID$ + ul$( rLen ) ;
print #wav , wID$ + fID$ + ul$( fLen );
print #wav , FmtTagS + Channels$ + ul$( SampleRate ) ;
print #wav , ul$( AvgBytesPerSec ) + ul$( BlockAlign ) ;
print #wav , ul$( BitsPerSample ) + dID$ + ul$( dLen ) ;
for i = 1 to bufsize
byte = sin( i * pi * 2 * hz / bufsize ) * 32765
print #wav ; sample$( byte ) ;
next
close #wav
playwave "440_1000.wav"
print "Ready"
end
function sample$( in )
in = in + 32766
low = int( in / 256 ) and 255
hi = ( in - low ) / 256 and 255
sample$ = chr$( low ) + chr$( hi )
end function
function ul$( in )
a = int( in ) and 255
b = int( in / 256 ) and 255
c = int( in / 256 ^ 2 ) and 255
d = int( in / 256 ^ 3 ) and 255
ul$ = chr$(d)+chr$(c)+chr$(b)+chr$(a)
end function
|
|
|
Post by bluatigro on Feb 22, 2022 5:20:15 GMT -5
update : savewav try
'' wav global rID$ : rID$ = "RIFF" global rLen ' file size minus 8 global wID$ : wID$ = "WAVE" global fID$ : fID$ = "fmt " global fLen : fLen = 16 global FmtTag$ : FmtTag$ = sample$( 1 ) global Channels$ : Channels$ = sample$( 1 ) ' 1 = Mono, 2 = Stereo global SampleRate : SampleRate = 11025 ' 11025 = 11kHz, 22050 = 22 kHz, etc. global AvgBytesPerSec ' SampleRate*Channels*BitsPerSample/8 global BlockAlign ' Channels * BitsPerSample/8 global BitsPerSample : BitsPerSample = 16 ' 8, 16, etc. global dID$ : dID$ = "data" global dLen ' length in bytes of the sound buffer
global sec : sec = 1 global bufsize : bufsize = SampleRate * sec * 2 global hz : hz = 440 global pi
rLen = 44 + bufsize - 8 AvgBytesPerSec = SampleRate * Channels.struct * BitPerSample / 8 BlockAlign = Channels * BitsPerSample / 8 dLen = bufsize
pi = atn( 1 ) * 4 sound$ = "" for i = 1 to bufsize byte = sin( i * pi * 2 * hz / bufsize ) * 32765 sound$ = sound$ + sample$( byte ) next
call savewav "440_1000" , sound$
playwave "440_1000.wav" print "Ready" end sub savewav file$ , wav$ ''file$ : name of the wavfile ''wav$ : samples array string rLen = 44 + len( wav$ ) - 8 dLen = len( wav$ ) open file$ + ".wav" for output as #wav print #wav , rID$ + ul$( rLen ) ; print #wav , wID$ + fID$ + ul$( fLen ); print #wav , FmtTagS + Channels$ + ul$( SampleRate ) ; print #wav , ul$( AvgBytesPerSec ) + ul$( BlockAlign ) ; print #wav , ul$( BitsPerSample ) + dID$ + ul$( dLen ) ; print #wav , wav$ close #wav end sub function sample$( in ) in = in + 32766 low = int( in / 256 ) and 255 hi = ( in - low ) / 256 and 255 sample$ = chr$( low ) + chr$( hi ) end function function ul$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 c = int( in / 256 ^ 2 ) and 255 d = int( in / 256 ^ 3 ) and 255 ul$ = chr$(d)+chr$(c)+chr$(b)+chr$(a) end function
|
|
|
Post by bluatigro on Feb 22, 2022 5:36:01 GMT -5
smal error sample$ <> b16$
'' wav global rID$ : rID$ = "RIFF" global rLen ' file size minus 8 global wID$ : wID$ = "WAVE" global fID$ : fID$ = "fmt " global fLen : fLen = 16 global FmtTag$ : FmtTag$ = b16$( 1 ) global Channels$ : Channels$ = b16$( 1 ) ' 1 = Mono, 2 = Stereo global SampleRate : SampleRate = 11025 ' 11025 = 11kHz, 22050 = 22 kHz, etc. global AvgBytesPerSec ' SampleRate*Channels*BitsPerSample/8 global BlockAlign ' Channels * BitsPerSample/8 global BitsPerSample : BitsPerSample = 16 ' 8, 16, etc. global dID$ : dID$ = "data" global dLen ' length in bytes of the sound buffer
global sec : sec = 1 global bufsize : bufsize = SampleRate * sec * 2 global hz : hz = 440 global pi
rLen = 44 + bufsize - 8 AvgBytesPerSec = SampleRate * Channels.struct * BitPerSample / 8 BlockAlign = Channels * BitsPerSample / 8 dLen = bufsize
pi = atn( 1 ) * 4 sound$ = "" for i = 1 to bufsize byte = sin( i * pi * 2 * hz / bufsize ) * 32765 sound$ = sound$ + sample$( byte ) next
call savewav "440_1000" , sound$
playwave "440_1000.wav" print "Ready" end sub savewav file$ , wav$ ''file$ : name of the wavfile ''wav$ : samples array string rLen = 44 + len( wav$ ) - 8 dLen = len( wav$ ) open file$ + ".wav" for output as #wav print #wav , rID$ + ul$( rLen ) ; print #wav , wID$ + fID$ + ul$( fLen ); print #wav , FmtTagS + Channels$ + ul$( SampleRate ) ; print #wav , ul$( AvgBytesPerSec ) + ul$( BlockAlign ) ; print #wav , ul$( BitsPerSample ) + dID$ + ul$( dLen ) ; print #wav , wav$ close #wav end sub function sample$( in ) in = in + 32766 low = int( in / 256 ) and 255 hi = ( in - low ) / 256 and 255 sample$ = chr$( low ) + chr$( hi ) end function function b16$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 b16$ = chr$( b ) + chr$( a ) end function function ul$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 c = int( in / 256 ^ 2 ) and 255 d = int( in / 256 ^ 3 ) and 255 ul$ = chr$(d)+chr$(c)+chr$(b)+chr$(a) end function
|
|
|
Post by tenochtitlanuk on Feb 22, 2022 13:22:44 GMT -5
You've got a 'Channels.struct' in there that I do not understand..
EDIT also a 'BitPerSample' has crept in one line- missing an 's'.
|
|
|
Post by bluatigro on Feb 23, 2022 5:01:10 GMT -5
thanks for spotting that
i chaged the code acordily
error : no sound jet
'' wav global rID$ : rID$ = "RIFF" global rLen ' file size minus 8 global wID$ : wID$ = "WAVE" global fID$ : fID$ = "fmt " global fLen : fLen = 16 global FmtTag$ : FmtTag$ = sample$( 1 ) global Channels$ : Channels$ = sample$( 1 ) ' 1 = Mono, 2 = Stereo global SampleRate : SampleRate = 11025 ' 11025 = 11kHz, 22050 = 22 kHz, etc. global AvgBytesPerSec ' SampleRate*Channels*BitsPerSample/8 global BlockAlign ' Channels * BitsPerSample/8 global BitsPerSample : BitsPerSample = 16 ' 8, 16, etc. global dID$ : dID$ = "data" global dLen ' length in bytes of the sound buffer
global sec : sec = 1 global bufsize : bufsize = SampleRate * sec * 2 global hz : hz = 440 global pi
rLen = 44 + bufsize - 8 AvgBytesPerSec = SampleRate * val( Channels$ ) * BitsPerSample / 8 BlockAlign = val( Channels$ ) * BitsPerSample / 8 dLen = bufsize
pi = atn( 1 ) * 4 sound$ = "" for i = 1 to bufsize byte = sin( i * pi * 2 * hz / bufsize ) * 32765 sound$ = sound$ + sample$( byte ) next
call savewav "440_1000" , sound$
playwave "440_1000.wav" print "Ready" end sub savewav file$ , wav$ ''file$ : name of the wavfile ''wav$ : samples array string rLen = 44 + len( wav$ ) - 8 dLen = len( wav$ ) open file$ + ".wav" for output as #wav print #wav , rID$ + ul$( rLen ) ; print #wav , wID$ + fID$ + ul$( fLen ); print #wav , FmtTag$ + Channels$ + ul$( SampleRate ) ; print #wav , ul$( AvgBytesPerSec ) + ul$( BlockAlign ) ; print #wav , ul$( BitsPerSample ) + dID$ + ul$( dLen ) ; print #wav , wav$ close #wav end sub function sample$( in ) in = in + 32766 low = int( in / 256 ) and 255 hi = ( in - low ) / 256 and 255 sample$ = chr$( low ) + chr$( hi ) end function function ul$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 c = int( in / 256 ^ 2 ) and 255 d = int( in / 256 ^ 3 ) and 255 ul$ = chr$(d)+chr$(c)+chr$(b)+chr$(a) end function
|
|
|
Post by tenochtitlanuk on Feb 23, 2022 11:00:32 GMT -5
I'm suspicious of your 2 and 4 byte routines, but only on a 'pad at present. Examining your code ( to generate the preamble part) in a hex editor shows improbable values. You could look at my code at www.diga.me.uk/makeMusic.html where I essentially cheated, using sections copied from a known-good wav file with just two parts altered, plus my generated wav values. My code on there did basically what you are trying... Can't look at your code in detail until home at the weekend.
EDIT There's also Thomas Watson's wave file creator from 2003! See Alyce Watson's site...
|
|
|
Post by bluatigro on Feb 24, 2022 5:20:34 GMT -5
update :
note$ function added
error : i do not see a wav on disc and the sound playing is a ding
if you see a error please report here and show the corect code sniped
'' wav global rID$ : rID$ = "RIFF" global rLen ' file size minus 8 global wID$ : wID$ = "WAVE" global fID$ : fID$ = "fmt " global fLen : fLen = 16 global FmtTag$ : FmtTag$ = b16$( 1 ) global Channels : Channels = 1 ' 1 = Mono, 2 = Stereo global SampleRate : SampleRate = 11025 ' 11025 = 11kHz, 22050 = 22 kHz, etc. global AvgBytesPerSec ' SampleRate*Channels*BitsPerSample/8 global BlockAlign ' Channels * BitsPerSample/8 global BitsPerSample : BitsPerSample = 16 ' 8, 16, etc. global dID$ : dID$ = "data" global dLen ' length in bytes of the sound buffer
global sec : sec = 1 global bufsize : bufsize = SampleRate * sec * 2 global hz : hz = 440 global pi
rLen = 44 + bufsize - 8 AvgBytesPerSec = SampleRate * Channels * BitPerSample / 8 BlockAlign = Channels * BitsPerSample / 8 dLen = bufsize
pi = atn( 1 ) * 4
call savewav "440_1000" , note$( 440 , 1000 )
playwave "440_1000.wav" notice "Ready" end function note$( hz , ms ) bufsize = int( SampleRate * ms / 1000 * 2 ) sound$ = "" for i = 1 to bufsize byte = sin( i * pi * 2 * hz / bufsize ) * 32765 + 32766 sound$ = sound$ + sample$( byte ) next note$ = sound$ end function sub savewav file$ , wav$ ''file$ : name of the wavfile ''wav$ : samples array string rLen = 44 + len( wav$ ) - 8 dLen = len( wav$ ) open file$ + ".wav" for output as #wav print #wav , rID$ + ul$( rLen ) ; print #wav , wID$ + fID$ + ul$( fLen ); print #wav , FmtTag$ + ul$( Channels ) + ul$( SampleRate ) ; print #wav , ul$( AvgBytesPerSec ) + ul$( BlockAlign ) ; print #wav , ul$( BitsPerSample ) + dID$ + ul$( dLen ) ; print #wav , wav$ close #wav end sub function sample$( in ) low = int( in / 256 ) and 255 hi = ( in - low ) / 256 and 255 sample$ = chr$( low ) + chr$( hi ) end function function b16$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 b16$ = chr$( b ) + chr$( a ) end function function ul$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 c = int( in / 256 ^ 2 ) and 255 d = int( in / 256 ^ 3 ) and 255 ul$ = chr$(d)+chr$(c)+chr$(b)+chr$(a) end function
|
|
|
Post by tenochtitlanuk on Feb 24, 2022 13:11:16 GMT -5
Your ul$ function is bigendian rather than little endian
See the following, with the four bytes in the correct order. There are other problems too. However A file should be appearing, even if not recognised as wav file so not heard. Will try further debugging.
num =11025 ' should give '11 2B 00 00' ( ie littleendian hex '00002B11'), and does...
blua$ =ul$( num ) for k =1 to len( blua$) print right$( "00" +decHex$( asc( mid$( blua$, k, 1))), 2); " "; next k print ""
wait
function ul$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 c = int( in / 256 ^ 2 ) and 255 d = int( in / 256 ^ 3 ) and 255 ul$ = chr$( a) +chr$( b) +chr$( c) +chr$( d) end function
|
|
|
Post by Rod on Feb 24, 2022 14:03:58 GMT -5
Yep, you should really build yourself a .wav header analysis routine because the header is wrong. You have BitPerSample instead of BitsPerSample. The ul$() function is not producing two bytes when it needs to, numbers are not allways 4 bytes. The FmtTag$ is being set to an empty string instead of 1. I think you have forgotten to use b16$() function when required. AudioFormat, No Channels, Blockading and BitsPer Sample are all incorrect.
|
|
|
Post by Rod on Feb 25, 2022 4:02:43 GMT -5
Use this to look at your .wav header to be sure you have sensible values.
filedialog "Open wav file", "*.wav", fileName$ open fileName$ for input as #wav 'the wavfileheader wav$ = Input$(#wav,lof(#wav)) print "ChunkID =";mid$(wav$,1,4) 'always RIFF print "ChunkSize =";value(mid$(wav$,5,4)) print "Format =";mid$(wav$,9,4) print "Sub1ID =";mid$(wav$,13,4) print "Sub1Size =";value(mid$(wav$,17,4)) print "AudioFormat =";value(mid$(wav$,21,2)) print "NumChannels =";value(mid$(wav$,23,2)) print "SampleRate =";value(mid$(wav$,25,4)) print "ByteRate =";value(mid$(wav$,29,4)) print "BlockAlign =";value(mid$(wav$,33,2)) print "bitPerSample=";value(mid$(wav$,35,2)) print "Sub2ID =";mid$(wav$,37,4) print "Sub2Size =";value(mid$(wav$,41,4)) print print "Sound Data" for n= 0 to 20 print value(mid$(wav$,45+n,1)) next wait
function value(x$) select case len(x$) case 1 value = asc(x$) case 2 value=asc(mid$(x$,1,1)) value=value+(asc(mid$(x$,2,1))*256) case 4 value=asc(mid$(x$,1,1)) value=value+(asc(mid$(x$,2,1))*256) value=value+(asc(mid$(x$,3,1))*65536) value=value+(asc(mid$(x$,4,1))*16777216) end select end function
|
|
|
Post by bluatigro on Mar 1, 2022 4:36:56 GMT -5
tenochtitlanuki tryed revere string in ul$() effect : it took verry long to make the wav and it was stil a 'ding'
|
|
|
Post by Rod on Mar 1, 2022 13:08:02 GMT -5
The ding is because the .wav header info is wrong. I have posted code before that creates .wav files. One of the problems I had was that I created a .wav of a precise length. What happened is that the sin wave terminated at a random point. This created a loud crack when the .wav was looped. You look like you complete the sine wave so you have a complete sine wave and a variable time. Once you get the header right you can build on the full sine wave part. So instead of computing many millions of values just calculate one complete sine wave and replicate that by appending it multiple times till you get the length you want. Should speed up creation 100 times plus. My problem code justbasiccom.proboards.com/thread/40/make-noise
|
|
|
Post by tenochtitlanuk on Mar 4, 2022 17:33:24 GMT -5
After much tinkering I've modified your version to work correctly. Unfortunately I added lots of spaces and diagnostic lines- I'll need to remove them for it to be any use.
One important thing was you were generating an offset value rather than the twos complement. This makes a tone but the positive and negative parts swoop down/up to mid-range, rather then up/down from mid-range. You also were generating twice the correct number of samples.
I'm travelling until end of next week- so will post code as soon as I can suitably tidy it.
|
|
|
Post by tenochtitlanuk on Mar 5, 2022 16:24:22 GMT -5
Here's a version which shows the corrections/alterations from your version. The changes are I think all flagged with '<<<<<<< It produces a 'ping' of exponentially decaying 880Hz. Not tested on other sample frequencies or stereo etc....
I'll be posting soon on my LB site a fuller version, including the reason your waveforms would have come out wrong because you missed the need for twos complement.
' ***** bluatigroWorking.bas *****
'Two speed-ups for sine, which is slow and repeatedly used- '1 calculate in advance an array called sine( ) at every 1 degree. ' Use int( ) to find sine() rather than using LB's sin() over and over. '2 work out one complete cycle of your sine wave, then add it multiple times to wav$. ' NB this doesn't work if you are calculating sine waves with decaying amplitudes.
WindowWidth = 650 WindowHeight = 460
nomainwin
' wav file sections.... global rID$ : rID$ = "RIFF" global rLen ' file size minus 8 global wID$ : wID$ = "WAVE" global fID$ : fID$ = "fmt " global fLen : fLen = 16 global FmtTag : FmtTag = 1 'NB I use Channels here not Channels$ '<<<<<<<<<<<< global Channels : Channels = 1 ' 1 = Mono, 2 = Stereo '<<<<<<< global SampleRate : SampleRate = 11025 ' 11025 = 11kHz, 22050 = 22 kHz, etc. global AvgBytesPerSec : AvgBytesPerSec = SampleRate *Channels *BitsPerSample /8 '<<<<<<<< global BlockAlign : BlockAlign = 4 ' BlockAlign = Channels * BitsPerSample / 8 '<<<<<<< global BitsPerSample : BitsPerSample = 16 ' 8, 16, etc. global dID$ : dID$ = "data"
global dLen ' length in bytes of the sound buffer
global sec : sec = 1 global bufsize : bufsize = SampleRate * sec * 2 global hz : hz = 880 global pi
rLen = 44 + bufsize - 8
AvgBytesPerSec = SampleRate * Channels * BitsPerSample / 8'<<<<<<<<< 'BlockAlign = Channels * BitsPerSample / 8'<<<<<<<<< dLen = bufsize
pi = atn( 1 ) * 4 sound$ = ""
for i = 1 to bufsize step 2 '<<<<<<<< 'byte = sin( i * pi * 2 * hz / bufsize ) * 32765'<<<<<<<<<<< byte = (exp( ( 0 -T) /400) *sin( i / bufsize * pi * 2 * hz ) ) * 32765 scan sound$ = sound$ + sample$( byte ) T =T +0.08 ' to make exponential decay next
call savewav "expSin" , sound$'<<<<<<< name change playwave "expSin.wav" notice "Ready" wait
sub savewav file$ , wav$ rLen = 44 + len( wav$) - 8 dLen = len( wav$) open file$ + ".wav" for output as #wav #wav rID$; #wav ul$( rLen); #wav wID$; #wav fID$; #wav ul$( fLen); #wav b16$( FmtTag); '<<<<< #wav b16$( Channels); '<<<<< #wav ul$( SampleRate); #wav ul$( AvgBytesPerSec); #wav b16$( BlockAlign); '<<<<< #wav b16$( BitsPerSample); '<<<<< #wav dID$; #wav ul$( dLen) #wav wav$ close #wav end sub
function sample$( in ) ' <<<<<<<< Your routine produces a weird inverted wave select case in ' This is a twos-complement two-byte that is neeeded case in >=0 in =2^16 -in case in <0 in =0 -in end select low = int( in / 256 ) and 255 hi = ( in - low ) / 256 and 255 sample$ = chr$( low ) + chr$( hi ) end function
function b16$( in ) ' '<<<<<<< New function to generate two byte, lo-hi pairs a = int( in ) and 255 b = int( in / 256 ) and 255 b16$ = chr$( a ) + chr$( b ) end function
function ul$( in ) a = int( in ) and 255 b = int( in / 256 ) and 255 c = int( in / 256 ^ 2 ) and 255 d = int( in / 256 ^ 3 ) and 255 ul$ = chr$( a) +chr$( b) +chr$( c) +chr$( d) '<<<<<< you had wrong way round.. end function
sub printAscii in$ for k =1 to len( in$) print right$( "00" +dechex$( asc( mid$( in$, k, 1))), 2); " "; next k print "" end sub
function asAscii$( in$) asAscii$ ="" for k =1 to len( in$) asAscii$ =asAscii$ +" " +right$( "00" +dechex$( asc( mid$( in$, k, 1))), 2) +" " next k end function
|
|