DDRM
Administrator
member is offline


Gender: 
Posts: 321
|
 |
Making a WAV file in memory
« Thread started on: Feb 16th, 2018, 3:32pm » |
|
Hi Folks,
I wanted to be able to make and modify a WAV file in memory. Here's some code to do that. The first section sets up the header etc, and then the second bit writes data (a sinusoidal wave of the specified frequency) to the left and right channels, with a variable delay between them, which makes the sound appear to move.
The top bit might be useful to others: the second part just makes it do something, but probably isn't interesting to anyone else...
Best wishes,
D
Code:SND_MEMORY = 4
Duration%=1000 :REM duration of sound in ms
SampleRate%=44100
nChannels%=2
BitsPerSample%=16
BytesPerSample%=nChannels%*BitsPerSample%/8
ByteRate%=SampleRate%*BytesPerSample%
DataSize%=Duration%*ByteRate%/1000
DIM wavbit% DataSize%+44 :REM Reserve enough space for our sound sample plus the header
REM Write the header
!wavbit%=&46464952 :REM "RIFF"
wavbit%!4=DataSize%+36 :REM Remaining file size
wavbit%!8=&45564157 :REM "WAVE"
wavbit%!12=&20746D66:REM "fmt "
wavbit%!16=16 :REM Size of format block
wavbit%!20=1 :REM type of format - 1 is PCM
wavbit%!22=nChannels%
wavbit%!24=SampleRate%
wavbit%!28=ByteRate%
wavbit%!32=BytesPerSample%
wavbit%!34=BitsPerSample%
wavbit%!36=&61746164:REM "data"
wavbit%!40=DataSize%:REM Remaining file size (data size)
D%=wavbit%+44 :REM Start of data block
freq%=440 :REM Required frequency
beeplength%=800 :REM Duration of beep in samples - if SampleRate%=40000, each represents 25 µs
lamp%=10000 :REM amplitude (loudness) for left channel - between 0 and 32767
ramp%=10000 :REM amplitude (loudness) for right channel - between 0 and 32767
loff%=0 :REM delay on left channel, in samples - if SampleRate%=40000, each represents 25 µs
roff%=0 :REM delay on right channel, in samples - if SampleRate%=40000, each represents 25 µs
FOR x%=-40 TO 40 STEP 4
IF x%<0 THEN loff%=-x% ELSE roff%=x%
REM IF x%<0 THEN lamp%=10000+(x%*1000):ramp%=10000 ELSE ramp%=10000-(x%*1000):lamp%=10000
PROCFillData(D%,freq%,lamp%,ramp%,loff%,roff%,beeplength%)
SYS "PlaySound",wavbit%,0,SND_MEMORY
WAIT 1
NEXT x%
END
:
DEFPROCFillData(d%,f%,lamp%,ramp%,loff%,roff%,beeplength%)
LOCAL t%,tl%,tr%,s%,sl%,sr%,nsamples%
f%*=2*PI
nsamples%=Duration%*SampleRate%/1000
FOR t%=0 TO nsamples%
tl%=t%-loff%
tr%=t%-roff%
IF tl%>=0 AND tl%<beeplength% THEN sl%=lamp%*SIN(f%*(t%-loff%)/SampleRate%) ELSE sl%=0
IF tr%>=0 AND tr%<beeplength% THEN sr%=ramp%*SIN(f%*(t%-roff%)/SampleRate%) ELSE sr%=0
s%=sr%*2^16 + sl%
ENDIF
!(d%+t%*BytesPerSample%)=s%
NEXT t%
ENDPROC
|