Mercurial > hg > octave-nkf
annotate scripts/audio/wavwrite.m @ 14138:72c96de7a403 stable
maint: update copyright notices for 2012
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 02 Jan 2012 14:25:41 -0500 |
parents | e9c23efe6fff |
children | 9a7f73fc304f |
rev | line source |
---|---|
14138
72c96de7a403
maint: update copyright notices for 2012
John W. Eaton <jwe@octave.org>
parents:
13764
diff
changeset
|
1 ## Copyright (C) 2005-2012 Michael Zeising |
5565 | 2 ## |
3 ## This file is part of Octave. | |
4 ## | |
5 ## Octave is free software; you can redistribute it and/or modify it | |
6 ## under the terms of the GNU General Public License as published by | |
7016 | 7 ## the Free Software Foundation; either version 3 of the License, or (at |
8 ## your option) any later version. | |
5565 | 9 ## |
10 ## Octave is distributed in the hope that it will be useful, but | |
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 ## General Public License for more details. | |
14 ## | |
15 ## You should have received a copy of the GNU General Public License | |
7016 | 16 ## along with Octave; see the file COPYING. If not, see |
17 ## <http://www.gnu.org/licenses/>. | |
5565 | 18 |
19 ## -*- texinfo -*- | |
10793
be55736a0783
Grammarcheck the documentation from m-files.
Rik <octave@nomad.inbox5.com>
parents:
10549
diff
changeset
|
20 ## @deftypefn {Function File} {} wavwrite (@var{y}, @var{filename}) |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
21 ## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{Fs}, @var{filename}) |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
22 ## @deftypefnx {Function File} {} wavwrite (@var{y}, @var{Fs}, @var{bps}, @var{filename}) |
6985 | 23 ## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename} |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
24 ## with sample rate @var{Fs} and bits per sample @var{bps}. The |
6985 | 25 ## default sample rate is 8000 Hz with 16-bits per sample. Each column |
26 ## of the data represents a separate channel. | |
5642 | 27 ## @seealso{wavread} |
5565 | 28 ## @end deftypefn |
29 | |
7117 | 30 ## Author: Michael Zeising <michael@michaels-website.de> |
5565 | 31 ## Created: 06 December 2005 |
32 | |
6985 | 33 function wavwrite (y, varargin) |
5567 | 34 |
5565 | 35 BYTEORDER = "ieee-le"; |
6985 | 36 |
5567 | 37 if (nargin < 2 || nargin > 4) |
6046 | 38 print_usage (); |
5565 | 39 endif |
5567 | 40 |
6985 | 41 ## Defaults. |
42 samples_per_sec = 8000; | |
43 bits_per_sample = 16; | |
44 | |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
45 filename = varargin{end}; |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
46 if (nargin > 2) |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
47 samples_per_sec = varargin{1}; |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
48 if (nargin > 3) |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
49 bits_per_sample = varargin{2}; |
6985 | 50 endif |
51 endif | |
52 | |
6304 | 53 ## test arguments |
54 if (columns (y) < 1) | |
55 error ("wavwrite: Y must have at least one column"); | |
56 endif | |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
57 if (columns (y) > 0x7FFF) |
6304 | 58 error ("wavwrite: Y has more than 32767 columns (too many for a WAV-file)"); |
59 endif | |
60 | |
5567 | 61 ## determine sample format |
62 switch (bits_per_sample) | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
63 case 8 |
5572 | 64 format = "uint8"; |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
65 case 16 |
5565 | 66 format = "int16"; |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
67 case 32 |
5565 | 68 format = "int32"; |
69 otherwise | |
6304 | 70 error ("wavwrite: sample resolution not supported"); |
5565 | 71 endswitch |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
72 |
5567 | 73 ## calculate filesize |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
74 [n, channels] = size (y); |
5567 | 75 |
76 ## size of data chunk | |
77 ck_size = n*channels*(bits_per_sample/8); | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
78 |
5567 | 79 if (! ischar (filename)) |
11472
1740012184f9
Use uppercase for variable names in error() strings to match Info documentation. Only m-files done.
Rik <octave@nomad.inbox5.com>
parents:
10793
diff
changeset
|
80 error ("wavwrite: expecting FILENAME to be a character string"); |
5567 | 81 endif |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
82 |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
83 ## open file for writing binary |
5565 | 84 [fid, msg] = fopen (filename, "wb"); |
85 if (fid < 0) | |
8664 | 86 error ("wavwrite: %s", msg); |
5565 | 87 endif |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
88 |
5567 | 89 ## write RIFF/WAVE header |
5565 | 90 c = 0; |
5567 | 91 c += fwrite (fid, "RIFF", "uchar"); |
92 | |
93 ## file size - 8 | |
6304 | 94 c += fwrite (fid, ck_size + 36, "uint32", 0, BYTEORDER); |
5567 | 95 c += fwrite (fid, "WAVEfmt ", "uchar"); |
96 | |
97 ## size of fmt chunk | |
6304 | 98 c += fwrite (fid, 16, "uint32", 0, BYTEORDER); |
5567 | 99 |
100 ## sample format code (PCM) | |
6304 | 101 c += fwrite (fid, 1, "uint16", 0, BYTEORDER); |
5567 | 102 |
103 ## channels | |
6304 | 104 c += fwrite (fid, channels, "uint16", 0, BYTEORDER); |
5567 | 105 |
106 ## sample rate | |
6304 | 107 c += fwrite (fid, samples_per_sec, "uint32", 0, BYTEORDER); |
5567 | 108 |
109 ## bytes per second | |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
110 byteps = samples_per_sec*channels*bits_per_sample/8; |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
111 c += fwrite (fid, byteps, "uint32", 0, BYTEORDER); |
5567 | 112 |
113 ## block align | |
6304 | 114 c += fwrite (fid, channels*bits_per_sample/8, "uint16", 0, BYTEORDER); |
5567 | 115 |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
116 c += fwrite (fid, bits_per_sample, "uint16", 0, BYTEORDER); |
5567 | 117 c += fwrite (fid, "data", "uchar"); |
6304 | 118 c += fwrite (fid, ck_size, "uint32", 0, BYTEORDER); |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
119 |
5565 | 120 if (c < 25) |
121 fclose (fid); | |
6304 | 122 error ("wavwrite: writing to file failed"); |
5565 | 123 endif |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
124 |
5572 | 125 ## interleave samples |
126 yi = reshape (y', n*channels, 1); | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
127 |
5567 | 128 ## scale samples |
129 switch (bits_per_sample) | |
5565 | 130 case 8 |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
131 yi = round (yi*128 + 128); |
5572 | 132 case 16 |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
133 yi = round (yi*32768); |
5572 | 134 case 32 |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
135 yi = round (yi*2147483648); |
5565 | 136 endswitch |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
137 |
5567 | 138 ## write to file |
5565 | 139 c = fwrite (fid, yi, format, 0, BYTEORDER); |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
140 |
5565 | 141 fclose (fid); |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
142 |
5565 | 143 endfunction |
6304 | 144 |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
145 |
13764
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
146 %!shared fname |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
147 %! fname = tmpnam (); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
148 |
6304 | 149 %!test |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
150 %! A = [-1:0.1:1; -1:0.1:1]; |
13764
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
151 %! wavwrite (A, fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
152 %! [B, samples_per_sec, bits_per_sample] = wavread (fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
153 %! assert (A,B, 1/2^15); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
154 %! assert (samples_per_sec, 8000); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
155 %! assert (bits_per_sample, 16); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
156 %! unlink (fname); |
6304 | 157 % |
158 %!test | |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
159 %! A = [-1:0.1:1; -1:0.1:1]; |
13764
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
160 %! wavwrite (A, 4000, fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
161 %! [B, samples_per_sec, bits_per_sample] = wavread (fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
162 %! assert (A,B, 1/2^15); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
163 %! assert (samples_per_sec, 4000); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
164 %! assert (bits_per_sample, 16); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
165 %! unlink (fname); |
6304 | 166 % |
167 %!test | |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
168 %! A = [-1:0.1:1; -1:0.1:1]; |
13764
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
169 %! wavwrite (A, 4000, 8, fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
170 %! [B, samples_per_sec, bits_per_sample] = wavread (fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
171 %! assert (A,B, 1/128); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
172 %! assert (samples_per_sec, 4000); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
173 %! assert (bits_per_sample, 8); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
174 %! unlink (fname); |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
175 % |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
176 %!test |
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
177 %! A = [-2:2]; |
13764
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
178 %! wavwrite (A, fname); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
179 %! B = wavread (fname); |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
180 %! B *= 32768; |
13764
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
181 %! assert (B, [-32768 -32768 0 32767 32767]); |
e9c23efe6fff
wavwrite.m: Use temporary filename in %!tests rather than hardcoded one.
Rik <octave@nomad.inbox5.com>
parents:
12701
diff
changeset
|
182 %! unlink (fname); |
12701
de3e90a420e3
Overhaul wavwrite, wavread and fix normalization problem (Bug #33420).
Rik <octave@nomad.inbox5.com>
parents:
11587
diff
changeset
|
183 |