WAV-flies

Make a WAV-file

WAV-file format.
We use this information to make 16bit stereo WAV-files.
The following program should be once saved in a file before it is executed.
The file BeatWave.MAV shall be made in the same folder in which the program is saved.
The lines 140 and 150 decide the waves of the left and right channels. The unit of t is the second. The values must fall into the range of -1 to 1. These can be replaced by external functions.
The line 160 designates the duration in seconds.
PLAYSOUND, which plays a sound file, in the line 400 is a original statement of Decimal BASIC for Windows.
DWORD$(n) is an original supplied function that returns the 4 byte image of an integer n.
WORD$(n) is an original supplied function that returns the 2 byte image of an integer n.
DWORD$ and WORD$ are supplied in Ver. 7.4.8 or later.

110 OPTION ARITHMETIC NATIVE
130 LET file$="BeatWave.WAV"
140 DEF wl(t)=SIN(2*PI*440*t) 
150 DEF wr(t)=SIN(2*PI*441*t) 
160 LET duration=5  ! duration in seconds
170 LET fs=44100    ! sampling frequency in Herz
180 LET SIZE=duration*fs
190 OPEN #1: NAME file$
200 ERASE #1
210 PRINT #1: "RIFF";
220 PRINT #1: DWORD$(SIZE*2*2 + 36);
230 PRINT #1: "WAVE";
240 PRINT #1: "fmt ";
250 PRINT #1: DWORD$(16);
260 PRINT #1: WORD$(1);        ! linear PCM
270 PRINT #1: WORD$(2);        ! number of channles
280 PRINT #1: DWORD$(fs);      
290 PRINT #1: DWORD$(fs*2*2);  ! data speed (byte/sec) 
300 PRINT #1: WORD$(2*2);      ! block size 
310 PRINT #1: WORD$(16);       ! bit size
320 PRINT #1: "data";
330 PRINT #1: DWORD$(SIZE*2*2); ! wave data size in bytes
340 FOR i=0 TO SIZE-1 
350    LET t=i/fs
360    PRINT #1: WORD$(ROUND(32767*wl(t)));
370    PRINT #1: WORD$(ROUND(32767*wr(t)));
380 NEXT i
390 CLOSE #1
400 PLAYSOUND file$
410 END

Read a WAV-file

The module WAV, defined in the line 900 or below, reads a WAV-file. It supports linear PCM 16 bit monaural or stereophonic WAV-files.
For the first, we assign the WAV-file with WAV.OPEN.
WAV.READ(L,R) reads a pair of numerical data of the wave. They are gotten not below -1 and below 1. If the wave is monaural, L and R shall be identical.

100 OPTION ARITHMETIC NATIVE
110 DECLARE EXTERNAL SUB wav.open, wav.read, wav.close
120 DECLARE EXTERNAL NUMERIC wav.size, wav.rate, wav.NChannels
130 DECLARE NUMERIC i,L,R,t,d
140 DECLARE STRING FName$
150 FILE GETNAME FName$, "WAV"
160 CALL wav.open (FName$)
170 PRINT FName$
180 PRINT "Sampling rate in Herz", wav.rate 
190 IF wav.NChannels=1 THEN PRINT "Mono" ELSE PRINT "Stereo"
200 PRINT "Duration in sec.", wav.size / wav.rate
210 LET d=1/32
220 SET WINDOW 0, d , -2, 2
230 FOR i=0  TO wav.size-1
240    LET t = i/wav.rate
250    LET t = MOD(t,d)
260    IF t < 1/wav.rate THEN
270       WAIT DELAY d
280       CLEAR
290       PLOT LINES
300    END if
310    CALL wav.read(L,R)   
320    PLOT LINES :t,L+R;
330 NEXT i 
340 CALL wav.close
350 END
360 
9000 MODULE WAV
9010 MODULE OPTION ARITHMETIC NATIVE
9020 PUBLIC SUB OPEN, READ, CLOSE
9030 PUBLIC NUMERIC  SIZE        ! Number of Samples. size/rate becomes duration
9040 PUBLIC NUMERIC  RATE        ! Sampling rate
9050 PUBLIC NUMERIC  nchannels   ! The number of channels, 1 or 2.
9060 SHARE  STRING FNAME$
9070 SHARE NUMERIC count
9080 SHARE FUNCTION DWORD, INT16
9090 SHARE FUNCTION Chars4$
9100 SHARE CHANNEL #1
9110 LET count=0
9120 
9130 EXTERNAL SUB OPEN(f$)
9140    DECLARE NUMERIC n,id,blocksize
9150    DECLARE STRING s$
9160    OPEN #1: NAME f$, ACCESS INPUT
9170    LET s$=Chars4$
9180    IF s$<>"RIFF" THEN CAUSE EXCEPTION 999
9190    LET n=DWORD     ! The size of the file below
9200    LET s$=Chars4$
9210    IF s$<>"WAVE" THEN CAUSE EXCEPTION 999
9220    LET s$=Chars4$
9230    IF s$<>"fmt " THEN CAUSE EXCEPTION 999
9240    LET n=DWord
9250    IF n<>16 THEN CAUSE EXCEPTION 999
9260    LET id=int16
9270    IF id<>1 THEN CAUSE EXCEPTION 999
9280    LET nchannels =int16    ! The number of channels
9290    LET Rate = dword        ! Sampling rate
9300    LET n=DWORD             ! Data speed
9310    LET BlockSize=int16     ! Block size
9320    LET n=int16             ! 8 or 16
9330    IF n<>16 THEN CAUSE EXCEPTION 998
9340    LET s$=Chars4$
9350    IF s$<>"data" THEN CAUSE EXCEPTION 999
9360    LET SIZE=DWORD/BlockSize  
9370 END SUB
9380  
9390 EXTERNAL SUB READ (L, R)
9400    IF count < SIZE THEN
9410       LET L=int16/2^16
9420       IF nchannels=2 THEN
9430          LET R=int16/2^16
9440       ELSE 
9450          LET R=L
9460       END IF
9470       LET count=count+1
9480    ELSE
9490       CAUSE EXCEPTION 997
9500    END if
9510 END SUB
9520  
9530 EXTERNAL FUNCTION Chars4$
9540    OPTION CHARACTER byte
9550    DECLARE STRING s$
9560    CHARACTER INPUT #1: s$
9570    CHARACTER INPUT #1: s$(2:2)
9580    CHARACTER INPUT #1: s$(3:3)
9590    CHARACTER INPUT #1: s$(4:4)
9600    LET Chars4$=s$
9610 END FUNCTION
9620 
9630 EXTERNAL FUNCTION DWord
9640    OPTION CHARACTER byte
9650    DECLARE NUMERIC n
9660    DECLARE STRING s$
9670    CHARACTER INPUT #1: s$
9680    LET n=ORD(s$)
9690    CHARACTER INPUT #1: s$
9700    LET n=n + ORD(s$)*2^8
9710    CHARACTER INPUT #1: s$
9720    LET n=n + ORD(s$)*2^16
9730    CHARACTER INPUT #1: s$
9740    LET n=n + ORD(s$)*2^24
9750    LET DWord=n
9760 END FUNCTION
9770 
9780 EXTERNAL FUNCTION Int16
9790    OPTION CHARACTER byte
9800    DECLARE NUMERIC n
9810    DECLARE STRING s$
9820    CHARACTER INPUT #1: s$
9830    LET n=ORD(s$)
9840    CHARACTER INPUT #1: s$
9850    LET n=n+ORD(s$)*2^8
9860    IF n>=2^15 THEN LET n=n-2^16
9870    LET int16=n
9880 END FUNCTION
9890 
9900 EXTERNAL SUB CLOSE
9910    CLOSE #1
9920 END SUB
9930 END MODULE 

Supplement

On Windows 95~XP, we use the SoundRecorder of Windows Accessories to make a sound file from the sound source such as a microphone.
We may be able to use on Windows Vista or 7 the following free software.
Re:Sound - 帰ってきた サウンド レコーダー


Back