comparison scripts/audio/wavread.m @ 5567:80e629357483

[project @ 2005-12-07 06:31:28 by jwe]
author jwe
date Wed, 07 Dec 2005 06:31:28 +0000
parents 2f5d0d8a7f13
children c45cf76df06f
comparison
equal deleted inserted replaced
5566:2f5d0d8a7f13 5567:80e629357483
16 ## along with Octave; see the file COPYING. If not, write to the Free 16 ## along with Octave; see the file COPYING. If not, write to the Free
17 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 ## 02110-1301, USA. 18 ## 02110-1301, USA.
19 19
20 ## -*- texinfo -*- 20 ## -*- texinfo -*-
21 ## @deftypefn {Function File} {} @var{y} = wavread(@var{filename}) 21 ## @deftypefn {Function File} {@var{y}} = wavread (@var{filename})
22 ## Load the RIFF/WAVE sound file @var{filename}, returning the samples in vector 22 ## Load the RIFF/WAVE sound file @var{filename}, and return the samples
23 ## @var{y}. If the file contains multichannel data, then @var{y} is a matrix with the 23 ## in vector @var{y}. If the file contains multichannel data, then
24 ## channels represented as columns. 24 ## @var{y} is a matrix with the channels represented as columns.
25 ## 25 ##
26 ## @deftypefnx {Function File} {} [@var{y},@var{Fs},@var{bits}] = wavread(@var{filename}) 26 ## @deftypefnx {Function File} {[@var{y}, @var{Fs}, @var{bits}]} = wavread (@var{filename})
27 ## Additionally return the sample rate (@var{fs}) in Hz and the number of bits 27 ## Additionally return the sample rate (@var{fs}) in Hz and the number of bits
28 ## per sample (@var{bits}). 28 ## per sample (@var{bits}).
29 ## 29 ##
30 ## @deftypefnx {Function File} {} [...] = wavread(@var{filename},@var{n}) 30 ## @deftypefnx {Function File} {[@dots{}]} = wavread (@var{filename}, @var{n})
31 ## Read only the first @var{n} samples from each channel. 31 ## Read only the first @var{n} samples from each channel.
32 ## 32 ##
33 ## @deftypefnx {Function File} {} [...] = wavread(@var{filename},[@var{n1} @var{n2}]) 33 ## @deftypefnx {Function File} {[@dots{}]} = wavread(@var{filename},[@var{n1} @var{n2}])
34 ## Read only samples @var{n1} through @var{n2} from each channel. 34 ## Read only samples @var{n1} through @var{n2} from each channel.
35 ## 35 ##
36 ## @deftypefnx {Function File} {} [@var{samples} @var{channels}] = wavread(@var{filename},'size') 36 ## @deftypefnx {Function File} {[@var{samples}, @var{channels}]} = wavread (@var{filename}, "size")
37 ## Return the number of samples (@var{n}) and channels (@var{ch}) instead of the 37 ## Return the number of samples (@var{n}) and channels (@var{ch})
38 ## audio data. 38 ## instead of the audio data.
39 ##
40 ## @end deftypefn 39 ## @end deftypefn
41 ## 40 ##
42 ## @seealso{wavwrite} 41 ## @seealso{wavwrite}
43 42
44 ## Author: Michael Zeising <michael.zeising@stud.uni-erlangen.de> 43 ## Author: Michael Zeising <michael.zeising@stud.uni-erlangen.de>
45 ## Created: 06 December 2005 44 ## Created: 06 December 2005
46 45
47 function [y, samplesPerSec, bitsPerSample] = wavread (filename, param) 46 function [y, samples_per_sec, bits_per_sample] = wavread (filename, param)
47
48 FORMAT_PCM = 0x0001; # PCM (8/16/32 bit) 48 FORMAT_PCM = 0x0001; # PCM (8/16/32 bit)
49 FORMAT_IEEE_FLOAT = 0x0003; # IEEE float (32/64 bit) 49 FORMAT_IEEE_FLOAT = 0x0003; # IEEE float (32/64 bit)
50 FORMAT_ALAW = 0x0006; # 8-bit ITU-T G.711 A-law (not yet supported) 50 FORMAT_ALAW = 0x0006; # 8-bit ITU-T G.711 A-law (not yet supported)
51 FORMAT_MULAW = 0x0007; # 8-bit ITU-T G.711 µ-law (not yet supported) 51 FORMAT_MULAW = 0x0007; # 8-bit ITU-T G.711 µ-law (not yet supported)
52 FORMAT_IMA_ADPCM = 0x0011; # IMA/ADPCM 4:1 compression (not yet supported) 52 FORMAT_IMA_ADPCM = 0x0011; # IMA/ADPCM 4:1 compression (not yet supported)
53 BYTEORDER = "ieee-le"; 53 BYTEORDER = "ieee-le";
54 54
55 if (nargin < 1 || nargin > 2)
56 usage ("wavread (filename, param)");
57 endif
58
55 # open file for binary reading 59 # open file for binary reading
60
61 if (! ischar (filename))
62 error ("wavwrite: expecting filename to be a character string");
63 endif
64
56 [fid, msg] = fopen (filename, "rb"); 65 [fid, msg] = fopen (filename, "rb");
57 if (fid < 0) 66 if (fid < 0)
58 error ("wavread: %s", msg) 67 error ("wavread: %s", msg)
59 endif 68 endif
60 69
61 # check for RIFF/WAVE header 70 ## check for RIFF/WAVE header
62 ckID = char (fread (fid, 4))'; # chunk ID: "RIFF" 71 ck_id = char (fread (fid, 4))';
63 fseek (fid, 4, SEEK_CUR); 72 fseek (fid, 4, SEEK_CUR);
64 WAVEID = char (fread (fid, 4))'; # WAVE ID: "WAVE" 73 wave_id = char (fread (fid, 4))';
65 if ((ckID ~= "RIFF") || (WAVEID ~= "WAVE")) 74 if (ck_id != "RIFF" || wave_id != "WAVE")
66 fclose (fid); 75 fclose (fid);
67 error ("wavread: file contains no RIFF/WAVE signature"); 76 error ("wavread: file contains no RIFF/WAVE signature");
68 endif 77 endif
69 78
70 # find format chunk within the next 256 (4*64) bytes 79 ## find format chunk within the next 256 (4*64) bytes
71 i = 1; 80 i = 1;
72 while 1 81 while (true)
73 if (char (fread (fid, 4))' == "fmt ") 82 if (char (fread (fid, 4))' == "fmt ");
74 break 83 break;
75 endif 84 endif
76 if (i++ == 64) 85 if (i++ == 64)
77 fclose (fid); 86 fclose (fid);
78 error ("wavread: file contains no format chunk") 87 error ("wavread: file contains no format chunk");
79 endif 88 endif
80 endwhile 89 endwhile
81 90
82 ckSize = fread (fid, 1, "ulong", 0, BYTEORDER); # format chunk size 91 ## format chunk size
83 92 ck_size = fread (fid, 1, "ulong", 0, BYTEORDER);
84 formatTag = fread (fid, 1, "short", 0, BYTEORDER); # sample format code 93
85 if ((formatTag ~= FORMAT_PCM) && (formatTag ~= FORMAT_IEEE_FLOAT)) 94 ## sample format code
95 format_tag = fread (fid, 1, "short", 0, BYTEORDER);
96 if (format_tag != FORMAT_PCM && format_tag != FORMAT_IEEE_FLOAT)
86 fclose (fid); 97 fclose (fid);
87 error ("wavread: sample format %#x is not supported", formatTag) 98 error ("wavread: sample format %#x is not supported", format_tag);
88 endif 99 endif
89 100
90 channels = fread (fid, 1, "short", 0, BYTEORDER); # number of interleaved channels 101 ## number of interleaved channels
91 samplesPerSec = fread (fid, 1, "ulong", 0, BYTEORDER); # sample rate 102 channels = fread (fid, 1, "short", 0, BYTEORDER);
103
104 ## sample rate
105 samples_per_sec = fread (fid, 1, "ulong", 0, BYTEORDER);
106
107 ## bits per sample
92 fseek (fid, 6, SEEK_CUR); 108 fseek (fid, 6, SEEK_CUR);
93 bitsPerSample = fread (fid, 1, "short", 0, BYTEORDER); # bits per sample 109 bits_per_sample = fread (fid, 1, "short", 0, BYTEORDER);
94 # ignore the rest of the chunk 110
95 fseek (fid, ckSize-16, SEEK_CUR); 111 ## ignore the rest of the chunk
96 112 fseek (fid, ck_size-16, SEEK_CUR);
97 # find data chunk 113
114 ## find data chunk
98 i = 1; 115 i = 1;
99 while 1 116 while (true)
100 if (char (fread(fid, 4))' == "data") 117 if (char (fread (fid, 4))' == "data")
101 break 118 break;
102 endif 119 endif
103 if (i++ == 64) 120 if (i++ == 64)
104 fclose (fid); 121 fclose (fid);
105 error ("wavread: file contains no data chunk") 122 error ("wavread: file contains no data chunk");
106 endif 123 endif
107 end 124 end
108 125
109 ckSize = fread (fid, 1, "ulong", 0, BYTEORDER); # data chunk size 126 ## data chunk size
110 127 ck_size = fread (fid, 1, "ulong", 0, BYTEORDER);
111 # determine sample data type 128
112 if (formatTag == FORMAT_PCM) 129 ## determine sample data type
113 switch bitsPerSample 130 if (format_tag == FORMAT_PCM)
131 switch bits_per_sample
114 case 8 132 case 8
115 format = "int8"; 133 format = "int8";
116 case 16 134 case 16
117 format = "int16"; 135 format = "int16";
118 case 32 136 case 32
119 format = "int32"; 137 format = "int32";
120 otherwise 138 otherwise
121 fclose (fid); 139 fclose (fid);
122 error ("wavread: %d bits sample resolution is not supported with PCM", bitsPerSample); 140 error ("wavread: %d bits sample resolution is not supported with PCM", bits_per_sample);
123 endswitch 141 endswitch
124 else 142 else
125 switch bitsPerSample 143 switch (bits_per_sample)
126 case 32 144 case 32
127 format = "float32"; 145 format = "float32";
128 case 64 146 case 64
129 format = "float64"; 147 format = "float64";
130 otherwise 148 otherwise
131 fclose (fid); 149 fclose (fid);
132 error ("wavread: %d bits sample resolution is not supported with IEEE float", bitsPerSample); 150 error ("wavread: %d bits sample resolution is not supported with IEEE float", bits_per_sample);
133 endswitch 151 endswitch
134 endif 152 endif
135 153
136 # parse arguments 154 ## parse arguments
137 if (exist ("param","var") < 1) 155 if (nargin == 1)
138 length = inf; 156 length = inf;
139 else 157 else
140 if (size(param)(2) == 1) # number of samples is given 158 if (size (param, 2) == 1)
159 ## number of samples is given
141 length = param * channels; 160 length = param * channels;
142 elseif (size(param)(2) == 2) # sample range is given 161 elseif (size (param, 2) == 2)
143 if fseek(fid, param(1) * channels * (bitsPerSample/8), SEEK_CUR) < 0 162 ## sample range is given
144 warning ("wavread: seeking failed") 163 if (fseek (fid, param(1) * channels * (bits_per_sample/8), SEEK_CUR) < 0)
164 warning ("wavread: seeking failed");
145 endif 165 endif
146 length = (param(2)-param(1)) * channels; 166 length = (param(2)-param(1)) * channels;
147 elseif ((size (param)(2) == 4) && (char(param) == "size")) # size of the file is requested 167 elseif (size (param, 2) == 4 && char (param) == "size")
148 fclose (fid); 168 ## size of the file is requested
149 y = [ckSize/channels/bitsPerSample/8 channels]; 169 fclose (fid);
170 y = [ck_size/channels/bits_per_sample/8, channels];
150 return 171 return
151 else 172 else
152 fclose (fid); 173 fclose (fid);
153 error ("wavread: invalid argument 2"); 174 error ("wavread: invalid argument 2");
154 endif 175 endif
155 endif 176 endif
156 177
157 # read samples 178 ## read samples
158 [yi, n] = fread (fid, length, format, 0, BYTEORDER); 179 [yi, n] = fread (fid, length, format, 0, BYTEORDER);
159 180
160 fclose (fid); 181 fclose (fid);
161 182
162 if (formatTag == FORMAT_PCM) 183 if (format_tag == FORMAT_PCM)
163 # normalize samples 184 ## normalize samples
164 switch bitsPerSample 185 switch (bits_per_sample)
165 case 8 186 case 8
166 yi = (yi - 127)/127; # 8-bit samples are unsigned 187 yi = (yi - 127)/127; # 8-bit samples are unsigned
167 case {16,32} 188 case {16, 32}
168 yi = yi/((2 ** bitsPerSample) / 2 - 1); 189 yi = yi/((2 ** bits_per_sample) / 2 - 1);
169 endswitch 190 endswitch
170 endif 191 endif
171 192
172 # deinterleave 193 ## deinterleave
173 y = []; 194 ## y = [];
174 for (i = 1:channels) 195 ## for i = 1:channels
175 y = [y yi(i:channels:n)]; 196 ## y = [y, yi(i:channels:n)];
176 endfor 197 ## endfor
198
199 nr = numel (yi) / channels;
200 y = reshape (yi, channels, nr)';
177 201
178 endfunction 202 endfunction