BBC BASIC for Windows
Programming >> Sound, Music and Video >> Making a WAV file in memory
http://bb4w.conforums.com/index.cgi?board=multimedia&action=display&num=1518798743

Making a WAV file in memory
Post by DDRM 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