annotate scripts/audio/wavread.m @ 5565:2eeed655e801

[project @ 2005-12-06 20:38:20 by jwe]
author jwe
date Tue, 06 Dec 2005 20:38:21 +0000
parents
children 2f5d0d8a7f13
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5565
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
1 ## Copyright (C) 2005 Michael Zeising
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
2 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
3 ## This file is part of Octave.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
4 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
5 ## Octave is free software; you can redistribute it and/or modify it
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
6 ## under the terms of the GNU General Public License as published by
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
7 ## the Free Software Foundation; either version 2, or (at your option)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
8 ## any later version.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
9 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
10 ## Octave is distributed in the hope that it will be useful, but
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
13 ## General Public License for more details.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
14 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
15 ## You should have received a copy of the GNU General Public License
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
16 ## along with Octave; see the file COPYING. If not, write to the Free
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
17 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
18 ## 02110-1301, USA.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
19
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
20 ## -*- texinfo -*-
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
21 ## @deftypefn {Function File} {} @var{y} = wavread(@var{filename})
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
22 ## Load the RIFF/WAVE sound file @var{filename}, returning the samples in vector
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
23 ## @var{y}. If the file contains multichannel data, then @var{y} is a matrix with the
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
24 ## channels represented as columns.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
25 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
26 ## @deftypefnx {Function File} {} [@var{y},@var{Fs},@var{bits}] = wavread(@var{filename})
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
27 ## Additionally return the sample rate (@var{fs}) in Hz and the number of bits
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
28 ## per sample (@var{bits}).
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
29 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
30 ## @deftypefnx {Function File} {} [...] = wavread(@var{filename},@var{n})
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
31 ## Read only the first @var{n} samples from each channel.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
32 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
33 ## @deftypefnx {Function File} {} [...] = wavread(@var{filename},[@var{n1} @var{n2}])
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
34 ## Read only samples @var{n1} through @var{n2} from each channel.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
35 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
36 ## @deftypefnx {Function File} {} [@var{samples} @var{channels}] = wavread(@var{filename},'size')
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
37 ## Return the number of samples (@var{n}) and channels (@var{ch}) instead of the
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
38 ## audio data.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
39 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
40 ## @end deftypefn
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
41 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
42 ## @seealso{wavwrite}
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
43
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
44 ## Author: Michael Zeising <michael.zeising@stud.uni-erlangen.de>
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
45 ## Created: 06 December 2005
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
46
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
47 function [y, samplesPerSec, bitsPerSample] = wavread (filename, param)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
48 FORMAT_PCM = 0x0001; # PCM (8/16/32 bit)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
49 FORMAT_IEEE_FLOAT = 0x0003; # IEEE float (32/64 bit)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
50 FORMAT_ALAW = 0x0006; # 8-bit ITU-T G.711 A-law (not yet supported)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
51 FORMAT_MULAW = 0x0007; # 8-bit ITU-T G.711 ยต-law (not yet supported)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
52 FORMAT_IMA_ADPCM = 0x0011; # IMA/ADPCM 4:1 compression (not yet supported)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
53 BYTEORDER = "ieee-le";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
54
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
55 # open file for binary reading
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
56 [fid, msg] = fopen (filename, "rb");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
57 if (fid < 0)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
58 error ("wavread: %s", msg)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
59 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
60
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
61 # check for RIFF/WAVE header
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
62 ckID = char (fread (fid, 4))'; # chunk ID: "RIFF"
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
63 fseek (fid, 4, SEEK_CUR);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
64 WAVEID = char (fread (fid, 4))'; # WAVE ID: "WAVE"
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
65 if ((ckID ~= "RIFF") || (WAVEID ~= "WAVE"))
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
66 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
67 error ("wavread: file contains no RIFF/WAVE signature");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
68 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
69
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
70 # find format chunk within the next 256 (4*64) bytes
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
71 i = 1;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
72 while 1
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
73 if (char (fread (fid, 4))' == "fmt ")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
74 break
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
75 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
76 if (i++ == 64)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
77 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
78 error ("wavread: file contains no format chunk")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
79 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
80 endwhile
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
81
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
82 ckSize = fread (fid, 1, "ulong", 0, BYTEORDER); # format chunk size
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
83
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
84 formatTag = fread (fid, 1, "short", 0, BYTEORDER); # sample format code
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
85 if ((formatTag ~= FORMAT_PCM) && (formatTag ~= FORMAT_IEEE_FLOAT))
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
86 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
87 error ("wavread: sample format %#x is not supported", formatTag)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
88 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
89
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
90 channels = fread (fid, 1, "short", 0, BYTEORDER); # number of interleaved channels
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
91 samplesPerSec = fread (fid, 1, "ulong", 0, BYTEORDER); # sample rate
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
92 fseek (fid, 6, SEEK_CUR);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
93 bitsPerSample = fread (fid, 1, "short", 0, BYTEORDER); # bits per sample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
94 # ignore the rest of the chunk
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
95 fseek (fid, ckSize-16, SEEK_CUR);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
96
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
97 # find data chunk
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
98 i = 1;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
99 while 1
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
100 if (char (fread(fid, 4))' == "data")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
101 break
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
102 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
103 if (i++ == 64)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
104 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
105 error ("wavread: file contains no data chunk")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
106 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
107 end
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
108
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
109 ckSize = fread (fid, 1, "ulong", 0, BYTEORDER); # data chunk size
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
110
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
111 # determine sample data type
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
112 if (formatTag == FORMAT_PCM)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
113 switch bitsPerSample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
114 case 8
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
115 format = "int8";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
116 case 16
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
117 format = "int16";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
118 case 32
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
119 format = "int32";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
120 otherwise
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
121 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
122 error ("wavread: %d bits sample resolution is not supported with PCM", bitsPerSample);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
123 endswitch
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
124 else
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
125 switch bitsPerSample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
126 case 32
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
127 format = "float32";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
128 case 64
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
129 format = "float64";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
130 otherwise
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
131 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
132 error ("wavread: %d bits sample resolution is not supported with IEEE float", bitsPerSample);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
133 endswitch
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
134 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
135
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
136 # parse arguments
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
137 if (exist ("param","var") < 1)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
138 length = inf;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
139 else
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
140 if (size(param)(2) == 1) # number of samples is given
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
141 length = param * channels;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
142 elseif (size(param)(2) == 2) # sample range is given
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
143 if fseek(fid, param(1) * channels * (bitsPerSample/8), SEEK_CUR) < 0
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
144 warning ("wavread: seeking failed")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
145 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
146 length = (param(2)-param(1)) * channels;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
147 elseif ((size (param)(2) == 4) && (char(param) == "size")) # size of the file is requested
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
148 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
149 y = [ckSize/channels/bitsPerSample/8 channels];
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
150 return
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
151 else
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
152 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
153 error ("wavread: invalid argument 2");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
154 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
155 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
156
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
157 # read samples
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
158 [yi, n] = fread (fid, length, format, 0, BYTEORDER);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
159
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
160 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
161
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
162 if (formatTag == FORMAT_PCM)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
163 # normalize samples
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
164 switch bitsPerSample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
165 case 8
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
166 yi = (yi - 127)/127; # 8-bit samples are unsigned
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
167 case {16,32}
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
168 yi = yi/((2 ** bitsPerSample) / 2 - 1);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
169 endswitch
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
170 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
171
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
172 # deinterleave
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
173 y = [];
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
174 for (i = 1:channels)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
175 y = [y yi(i:channels:n)];
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
176 endfor
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
177
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
178 endfunction
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
179 ## Copyright (C) 2005 Michael Zeising
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
180 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
181 ## This file is part of Octave.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
182 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
183 ## Octave is free software; you can redistribute it and/or modify it
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
184 ## under the terms of the GNU General Public License as published by
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
185 ## the Free Software Foundation; either version 2, or (at your option)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
186 ## any later version.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
187 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
188 ## Octave is distributed in the hope that it will be useful, but
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
189 ## WITHOUT ANY WARRANTY; without even the implied warranty of
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
190 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
191 ## General Public License for more details.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
192 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
193 ## You should have received a copy of the GNU General Public License
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
194 ## along with Octave; see the file COPYING. If not, write to the Free
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
195 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
196 ## 02110-1301, USA.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
197
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
198 ## -*- texinfo -*-
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
199 ## @deftypefn {Function File} {} wavwrite(@var{filename}, @var{y})
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
200 ## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}. A sample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
201 ## rate of 8000 Hz and 16-bit samples are assumed. Each column of the data
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
202 ## represents a separate channel.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
203 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
204 ## @deftypefnx {Function File} {} wavwrite(@var{filename}, @var{y}, @var{fs})
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
205 ## Set the sample rate to @var{fs} Hz.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
206 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
207 ## @deftypefnx {Function File} {} wavwrite(@var{filename}, @var{y}, @var{fs}, @var{bits})
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
208 ## Set the sample rate to @var{fs} Hz and resolution to @var{bits} bits.
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
209 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
210 ## @end deftypefn
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
211 ##
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
212 ## @seealso{wavread}
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
213
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
214 ## Author: Michael Zeising <michael.zeising@stud.uni-erlangen.de>
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
215 ## Created: 06 December 2005
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
216
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
217 function wavwrite (filename, y, samplesPerSec, bitsPerSample)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
218 BYTEORDER = "ieee-le";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
219
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
220 # parse arguments
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
221 if (exist ("samplesPerSec","var") < 1)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
222 warning ("wavwrite: sample rate set to 8000 Hz")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
223 samplesPerSec = 8000;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
224 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
225 if (exist ("bitsPerSample","var") < 1)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
226 warning ("wavwrite: sample resolution set to 16-bit")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
227 bitsPerSample = 16;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
228 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
229
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
230 # determine sample format
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
231 switch bitsPerSample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
232 case 8
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
233 format = "int8";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
234 case 16
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
235 format = "int16";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
236 case 32
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
237 format = "int32";
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
238 otherwise
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
239 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
240 error ("wavread: sample resolution not supported");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
241 endswitch
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
242
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
243 # calculate filesize
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
244 channels = size(y)(2);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
245 n = size(y)(1);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
246
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
247 ckSize = n*channels*(bitsPerSample/8); # size of data chunk
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
248
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
249 # open file for writing binary
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
250 [fid, msg] = fopen (filename, "wb");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
251 if (fid < 0)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
252 error ("wavwrite: %s", msg)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
253 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
254
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
255 # write RIFF/WAVE header
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
256 c = 0;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
257 c += fwrite (fid, "RIFF", "uchar");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
258 c += fwrite (fid, ckSize + 36, "ulong", 0, BYTEORDER); # file size - 8
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
259 c += fwrite (fid, "WAVEfmt ", "uchar");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
260 c += fwrite (fid, 16, "ulong", 0, BYTEORDER); # size of fmt chunk
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
261 c += fwrite (fid, 0x0001, "short", 0, BYTEORDER); # sample format code (PCM)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
262 c += fwrite (fid, channels, "short", 0, BYTEORDER); # channels
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
263 c += fwrite (fid, samplesPerSec, "ulong", 0, BYTEORDER); # sample rate
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
264 c += fwrite (fid, samplesPerSec*channels*bitsPerSample/8, "ulong", 0, BYTEORDER); # bytes per second
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
265 c += fwrite (fid, channels*bitsPerSample/8, "short", 0, BYTEORDER); # block align
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
266 c += fwrite (fid, bitsPerSample, "short", 0, BYTEORDER); # bits/sample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
267 c += fwrite (fid, "data", "uchar");
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
268 c += fwrite (fid, ckSize, "ulong", 0, BYTEORDER); # size of data chunk
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
269
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
270 if (c < 25)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
271 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
272 error ("wavread: writing to file failed")
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
273 endif
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
274
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
275 # scale samples
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
276 switch bitsPerSample
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
277 case 8
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
278 y = floor (y*127 + 127);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
279 case {16,32}
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
280 y = floor (y*((2 ** bitsPerSample) / 2 - 1));
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
281 endswitch
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
282
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
283 # interleave samples
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
284 l = n*channels;
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
285 for (i = 1:channels)
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
286 yi(i:channels:l) = y(:,i);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
287 endfor
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
288
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
289 # write to file
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
290 c = fwrite (fid, yi, format, 0, BYTEORDER);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
291
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
292 fclose (fid);
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
293
2eeed655e801 [project @ 2005-12-06 20:38:20 by jwe]
jwe
parents:
diff changeset
294 endfunction