-->fsampling = 22050; // sampling frequency
-->t = 0 : 1/fsampling : 1; // one second at this frequency
-->sinwav = sin (2 * %pi * 500 * t); // a wave at 500 Hz
-->savewave ('beep.wav',sinwav,fsampling); // saves as beep.wav
Writing Wave file: Microsoft PCM format, 1 channel, 22050 samp/sec
44100 byte/sec, 2 block align, 16 bits/samp
Finished writing Wave file, 44102 data bytes
Once wav file has been created, we can hear it with any media player. Now we are going to recover the wave. We could do that with the command `loadwave', but we are going to load the wave from the file directly to show how different types can be loaded.
Wav files are formed by a header part and a data part. As the header part includes binary data with different characteristics, it can be appropriate to read data of different types. The header of a wav file is composed of the following fields
| Field | bytes | format | contains |
| 1 | 0...3 | str4 | "RIFF" in ASCII |
| 2 | 4...7 | int4 | Total bytes minus 8 |
| 3 | 8...15 | str4 | "WAVEfmt" Eigth character is a space |
| 4 | 16...19 | int4 | 16 for PCM format |
| 5 | 20...21 | int2 | 1 for PCM format |
| 6 | 22...23 | int2 | channels |
| 7 | 24...27 | int4 | sampling frequency |
| 8 | 28...31 | int4 | bytes per second |
| 9 | 32...33 | int2 | bytes by capture |
| 10 | 34...35 | int2 | bits per sample |
| 11 | 36:39 | str4 | "data" |
| 12 | 40:43 | int4 | bytes in data |
fid = mopen('beep.wav', 'rb'); // opens file to read in binary
ID = mget (4, 'c', fid); // RIFF
ID = ascii (ID); // conversion to ASCII format
Size = mget (1, 'ui', fid); // total bytes minus 8
typ = mget (8, 'c', fid); // WAVEfmt_
typ = ascii (typ); // conversion to ASCII format
PCM = mget (1, 'ui', fid); // 16
PCM2 = mget (1, 'us', fid); // 1
nchannels = mget (1, 'us', fid); // number of channels
fsampling2 = mget (1, 'ui', fid); // sampling frequency
nbbytes = mget ( 1, 'ui', fid); // bytes per second
nbytescap = mget ( 1, 'us', fid); // bytes by capture
nbytessamp = mget ( 1, 'us', fid); // bytes per sample
worddata = mget (4, 'c', fid ); // data in ASCII format
worddata = ascii (worddata); // conversion to ASCII format
bytesindata = mget (1, 'ul', fid); // bytes in data
With this information, we can read the file
wave = mget ( bytesindata / nbytescap , 's', fid); //reads data mclose(fid)We can plot the curve and see that everything was OK.
The source code we can see in `macros/sound/wavread.sci' that the way Scilab does this is much safer (it checks inputs and the internal structure of the file). Our goal was not to build a robust routine but to understand how we can read different values from a file that includes binary and ASCII data and that contains in the header the information of the structure utilized to store data.
But what can a clinical neurophysiologist do with wav files?
Besides learning to read and write different types of data, there are several things that could be useful:
-->t = 0: (1/10) : (8*60*60); // eighth hours at 10 samples per second
-->resp= sin ( 2 * %pi * (1/4) * t); // respirogram at a frequency of 1/4
-->savewave('beep2.wav',resp,10000); // saved as if it had been sampled at 10000
Writing Wave file: Microsoft PCM format, 1 channel, 10000 samp/s
20000 byte/sec, 2 block align, 16 bits/samp
Finished writing Wave file, 576002 data bytes
One hour of recording (36000 data) can be heard in 3.6 seconds and eight hours of recording can be heard in about 30 seconds. With a monotonous respiration at 15/minute we would hear a monotonous tone of 250 Hz. On the contrary, a modification of the amplitude, as can be seen in apneas or hypopneas, can be heard in a very quick way.
We are habituated to "see" neurophysiological signals and the eye is an organ specialized in parallel processing of information, but we can hear neurophysiological signals too and the ability of audition to discriminate signal from noise or to distinguish the frequency components can be useful too.