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