comparison toolboxes/mp3readwrite/mp3write.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e9a9cd732c1e
1 function mp3write(D,SR,NBITS,FILE,OPTIONS)
2 % MP3WRITE Write MP3 file by use of external binary
3 % MP3WRITE(Y,FS,NBITS,FILE) writes waveform data Y to mp3-encoded
4 % file FILE at sampling rate FS using bitdepth NBITS.
5 % The syntax exactly mirrors WAVWRITE. NBITS must be 16.
6 % MP3WRITE(Y,FS,FILE) assumes NBITS is 16
7 % MP3WRITE(Y,FILE) further assumes FS = 8000.
8 %
9 % MP3WRITE(..., OPTIONS) specifies additional compression control
10 % options as a string passed directly to the lame encoder
11 % program; default is '--quiet -h' for high-quality model.
12 %
13 % Example:
14 % To convert a wav file to mp3 (assuming the sample rate is
15 % supported):
16 % [Y,FS] = wavread('piano.wav');
17 % mp3write(Y,FS,'piano.mp3');
18 % To force lame to use 160 kbps (instead of default 128 kbps)
19 % with the default filename extension (mp3):
20 % mp3write(Y,FS,'piano','--quiet -h -b 160');
21 %
22 % Note: The actual mp3 encoding is done by an external binary,
23 % lame, which is available for multiple platforms. Usable
24 % binaries are available from:
25 % http://labrosa.ee.columbia.edu/matlab/mp3read.html
26 %
27 % Note: MP3WRITE will use the mex file popenw, if available, to
28 % open a pipe to the lame encoder. Otherwise, it will have to
29 % write a large temporary file, then execute lame on that file.
30 % popenw is available at:
31 % http://labrosa.ee.columbia.edu/matlab/popenrw.html
32 % This is a nice way to save large audio files as the
33 % incremental output of your code, but you'll have to adapt the
34 % central loop of this function (rather than using it directly).
35 %
36 % See also: mp3read, wavwrite, popenw.
37
38 % 2005-11-10 Original version
39 % 2007-02-04 Modified to exactly match wavwrite syntax, and to
40 % automatically find architecture-dependent binaries.
41 % 2007-07-26 Writing of stereo files via tmp file fixed (thx Yu-ching Lin)
42 %
43 % $Header: /Users/dpwe/matlab/columbiafns/RCS/mp3write.m,v 1.2 2007/07/26 15:09:16 dpwe Exp $
44
45 % find our baseline directory
46 [path] = fileparts(which('mp3write'));
47
48 % %%%%% Directory for temporary file (if needed)
49 % % Try to read from environment, or use /tmp if it exists, or use CWD
50 tmpdir = getenv('TMPDIR');
51 if isempty(tmpdir) || exist(tmpdir,'file')==0
52 tmpdir = '/tmp';
53 end
54 if exist(tmpdir,'file')==0
55 tmpdir = '';
56 end
57 % ensure it exists
58 %if length(tmpdir) > 0 && exist(tmpdir,'file')==0
59 % mkdir(tmpdir);
60 %end
61
62 %%%%%% Command to delete temporary file (if needed)
63 rmcmd = 'rm';
64
65 %%%%%% Location of the binary - attempt to choose automatically
66 %%%%%% (or edit to be hard-coded for your installation)
67 ext = lower(computer);
68 if ispc
69 ext = 'exe';
70 rmcmd = 'del';
71 end
72 lame = fullfile(path,['lame.',ext]);
73
74 %%%% Process input arguments
75 % Do we have NBITS?
76 mynargin = nargin;
77 if ischar(NBITS)
78 % NBITS is a string i.e. it's actually the filename
79 if mynargin > 3
80 OPTIONS = FILE;
81 end
82 FILE = NBITS;
83 NBITS = 16;
84 % it's as if NBITS had been specified...
85 mynargin = mynargin + 1;
86 end
87
88 if mynargin < 5
89 OPTIONS = '--quiet -h'; % -h means high-quality psych model
90 end
91
92 [nr, nc] = size(D);
93 if nc < nr
94 D = D';
95 [nr, nc] = size(D);
96 end
97 % Now rows are channels, cols are time frames (so interleaving is right)
98
99 %%%%% add extension if none (like wavread)
100 [path,file,ext] = fileparts(FILE);
101 if isempty(ext)
102 FILE = [FILE, '.mp3'];
103 end
104
105 nchan = nr;
106 nfrm = nc;
107
108 if nchan == 1
109 monostring = ' -m m';
110 else
111 monostring = '';
112 end
113
114 lameopts = [' ', OPTIONS, monostring, ' '];
115
116 %if exist('popenw') == 3
117 if length(which('popenw')) > 0
118
119 % We have the writable stream process extensions
120 cmd = ['"',lame,'"', lameopts, '-r -s ',num2str(SR),' - "',FILE,'"'];
121
122 p = popenw(cmd);
123 if p < 0
124 error(['Error running popen(',cmd,')']);
125 end
126
127 % We feed the audio to the encoder in blocks of <blksize> frames.
128 % By adapting this loop, you can create your own code to
129 % write a single, large, MP3 file one part at a time.
130
131 blksiz = 10000;
132
133 nrem = nfrm;
134 base = 0;
135
136 while nrem > 0
137 thistime = min(nrem, blksiz);
138 done = popenw(p,32767*D(:,base+(1:thistime)),'int16be');
139 nrem = nrem - thistime;
140 base = base + thistime;
141 %disp(['done=',num2str(done)]);
142 end
143
144 % Close pipe
145 popenw(p,[]);
146
147 else
148 disp('Warning: popenw not available, writing temporary file');
149
150 tmpfile = fullfile(tmpdir,['tmp',num2str(round(1000*rand(1))),'.wav']);
151
152 wavwrite(D',SR,tmpfile);
153
154 cmd = ['"',lame,'"', lameopts, '"',tmpfile, '" "', FILE, '"'];
155
156 mysystem(cmd);
157
158 % Delete tmp file
159 mysystem([rmcmd, ' "', tmpfile,'"']);
160
161 end
162
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 function w = mysystem(cmd)
165 % Run system command; report error; strip all but last line
166 [s,w] = system(cmd);
167 if s ~= 0
168 error(['unable to execute ',cmd,' (',w,')']);
169 end
170 % Keep just final line
171 w = w((1+max([0,findstr(w,10)])):end);
172 % Debug
173 %disp([cmd,' -> ','*',w,'*']);