5565
|
1 ## Copyright (C) 2005 Michael Zeising |
|
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 |
|
7 ## the Free Software Foundation; either version 2, or (at your option) |
|
8 ## any later version. |
|
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 |
|
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 |
|
18 ## 02110-1301, USA. |
|
19 |
|
20 ## -*- texinfo -*- |
|
21 ## @deftypefn {Function File} {} wavwrite(@var{filename}, @var{y}) |
|
22 ## Write @var{y} to the canonical RIFF/WAVE sound file @var{filename}. A sample |
|
23 ## rate of 8000 Hz and 16-bit samples are assumed. Each column of the data |
|
24 ## represents a separate channel. |
|
25 ## |
|
26 ## @deftypefnx {Function File} {} wavwrite(@var{filename}, @var{y}, @var{fs}) |
|
27 ## Set the sample rate to @var{fs} Hz. |
|
28 ## |
|
29 ## @deftypefnx {Function File} {} wavwrite(@var{filename}, @var{y}, @var{fs}, @var{bits}) |
|
30 ## Set the sample rate to @var{fs} Hz and resolution to @var{bits} bits. |
5642
|
31 ## @seealso{wavread} |
5565
|
32 ## @end deftypefn |
|
33 |
|
34 ## Author: Michael Zeising <michael.zeising@stud.uni-erlangen.de> |
|
35 ## Created: 06 December 2005 |
|
36 |
5567
|
37 function wavwrite (filename, y, samples_per_sec, bits_per_sample) |
|
38 |
5565
|
39 BYTEORDER = "ieee-le"; |
|
40 |
5567
|
41 if (nargin < 2 || nargin > 4) |
|
42 usage ("wavwrite (filename, y, samples_per_sec, bits_per_sample)"); |
5565
|
43 endif |
5567
|
44 |
|
45 ## parse arguments |
|
46 if (nargin < 3) |
|
47 warning ("wavwrite: sample rate set to 8000 Hz"); |
|
48 samples_per_sec = 8000; |
|
49 endif |
|
50 |
|
51 if (nargin < 4) |
|
52 warning ("wavwrite: sample resolution set to 16-bit"); |
|
53 bits_per_sample = 16; |
5565
|
54 endif |
|
55 |
5567
|
56 ## determine sample format |
|
57 switch (bits_per_sample) |
5565
|
58 case 8 |
5572
|
59 format = "uint8"; |
5565
|
60 case 16 |
|
61 format = "int16"; |
|
62 case 32 |
|
63 format = "int32"; |
|
64 otherwise |
|
65 error ("wavread: sample resolution not supported"); |
|
66 endswitch |
|
67 |
5567
|
68 ## calculate filesize |
5565
|
69 channels = size(y)(2); |
|
70 n = size(y)(1); |
5567
|
71 |
|
72 ## size of data chunk |
|
73 ck_size = n*channels*(bits_per_sample/8); |
5565
|
74 |
5567
|
75 ## open file for writing binary |
|
76 |
|
77 if (! ischar (filename)) |
|
78 error ("wavwrite: expecting filename to be a character string"); |
|
79 endif |
|
80 |
5565
|
81 [fid, msg] = fopen (filename, "wb"); |
|
82 if (fid < 0) |
|
83 error ("wavwrite: %s", msg) |
|
84 endif |
|
85 |
5567
|
86 ## write RIFF/WAVE header |
5565
|
87 c = 0; |
5567
|
88 c += fwrite (fid, "RIFF", "uchar"); |
|
89 |
|
90 ## file size - 8 |
|
91 c += fwrite (fid, ck_size + 36, "ulong", 0, BYTEORDER); |
|
92 c += fwrite (fid, "WAVEfmt ", "uchar"); |
|
93 |
|
94 ## size of fmt chunk |
|
95 c += fwrite (fid, 16, "ulong", 0, BYTEORDER); |
|
96 |
|
97 ## sample format code (PCM) |
|
98 c += fwrite (fid, 0x0001, "short", 0, BYTEORDER); |
|
99 |
|
100 ## channels |
|
101 c += fwrite (fid, channels, "short", 0, BYTEORDER); |
|
102 |
|
103 ## sample rate |
|
104 c += fwrite (fid, samples_per_sec, "ulong", 0, BYTEORDER); |
|
105 |
|
106 ## bytes per second |
|
107 bps = samples_per_sec*channels*bits_per_sample/8; |
|
108 c += fwrite (fid, bps, "ulong", 0, BYTEORDER); |
|
109 |
|
110 ## block align |
|
111 c += fwrite (fid, channels*bits_per_sample/8, "short", 0, BYTEORDER); |
|
112 |
|
113 c += fwrite (fid, bits_per_sample, "short", 0, BYTEORDER); |
|
114 c += fwrite (fid, "data", "uchar"); |
|
115 c += fwrite (fid, ck_size, "ulong", 0, BYTEORDER); |
5565
|
116 |
|
117 if (c < 25) |
|
118 fclose (fid); |
5567
|
119 error ("wavread: writing to file failed"); |
5565
|
120 endif |
|
121 |
5572
|
122 ## interleave samples |
|
123 yi = reshape (y', n*channels, 1); |
|
124 |
5567
|
125 ## scale samples |
|
126 switch (bits_per_sample) |
5565
|
127 case 8 |
5572
|
128 yi = round (yi*127.5 + 127.5); |
|
129 case 16 |
|
130 yi = floor (yi*32767.5); |
|
131 case 32 |
|
132 yi = floor (yi*2147483647.5); |
5565
|
133 endswitch |
|
134 |
5567
|
135 ## write to file |
5565
|
136 c = fwrite (fid, yi, format, 0, BYTEORDER); |
|
137 |
|
138 fclose (fid); |
|
139 |
|
140 endfunction |