Mercurial > hg > camir-aes2014
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/mp3readwrite/mp3write.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,173 @@ +function mp3write(D,SR,NBITS,FILE,OPTIONS) +% MP3WRITE Write MP3 file by use of external binary +% MP3WRITE(Y,FS,NBITS,FILE) writes waveform data Y to mp3-encoded +% file FILE at sampling rate FS using bitdepth NBITS. +% The syntax exactly mirrors WAVWRITE. NBITS must be 16. +% MP3WRITE(Y,FS,FILE) assumes NBITS is 16 +% MP3WRITE(Y,FILE) further assumes FS = 8000. +% +% MP3WRITE(..., OPTIONS) specifies additional compression control +% options as a string passed directly to the lame encoder +% program; default is '--quiet -h' for high-quality model. +% +% Example: +% To convert a wav file to mp3 (assuming the sample rate is +% supported): +% [Y,FS] = wavread('piano.wav'); +% mp3write(Y,FS,'piano.mp3'); +% To force lame to use 160 kbps (instead of default 128 kbps) +% with the default filename extension (mp3): +% mp3write(Y,FS,'piano','--quiet -h -b 160'); +% +% Note: The actual mp3 encoding is done by an external binary, +% lame, which is available for multiple platforms. Usable +% binaries are available from: +% http://labrosa.ee.columbia.edu/matlab/mp3read.html +% +% Note: MP3WRITE will use the mex file popenw, if available, to +% open a pipe to the lame encoder. Otherwise, it will have to +% write a large temporary file, then execute lame on that file. +% popenw is available at: +% http://labrosa.ee.columbia.edu/matlab/popenrw.html +% This is a nice way to save large audio files as the +% incremental output of your code, but you'll have to adapt the +% central loop of this function (rather than using it directly). +% +% See also: mp3read, wavwrite, popenw. + +% 2005-11-10 Original version +% 2007-02-04 Modified to exactly match wavwrite syntax, and to +% automatically find architecture-dependent binaries. +% 2007-07-26 Writing of stereo files via tmp file fixed (thx Yu-ching Lin) +% +% $Header: /Users/dpwe/matlab/columbiafns/RCS/mp3write.m,v 1.2 2007/07/26 15:09:16 dpwe Exp $ + +% find our baseline directory +[path] = fileparts(which('mp3write')); + +% %%%%% Directory for temporary file (if needed) +% % Try to read from environment, or use /tmp if it exists, or use CWD +tmpdir = getenv('TMPDIR'); +if isempty(tmpdir) || exist(tmpdir,'file')==0 + tmpdir = '/tmp'; +end +if exist(tmpdir,'file')==0 + tmpdir = ''; +end +% ensure it exists +%if length(tmpdir) > 0 && exist(tmpdir,'file')==0 +% mkdir(tmpdir); +%end + +%%%%%% Command to delete temporary file (if needed) +rmcmd = 'rm'; + +%%%%%% Location of the binary - attempt to choose automatically +%%%%%% (or edit to be hard-coded for your installation) +ext = lower(computer); +if ispc + ext = 'exe'; + rmcmd = 'del'; +end +lame = fullfile(path,['lame.',ext]); + +%%%% Process input arguments +% Do we have NBITS? +mynargin = nargin; +if ischar(NBITS) + % NBITS is a string i.e. it's actually the filename + if mynargin > 3 + OPTIONS = FILE; + end + FILE = NBITS; + NBITS = 16; + % it's as if NBITS had been specified... + mynargin = mynargin + 1; +end + +if mynargin < 5 + OPTIONS = '--quiet -h'; % -h means high-quality psych model +end + +[nr, nc] = size(D); +if nc < nr + D = D'; + [nr, nc] = size(D); +end +% Now rows are channels, cols are time frames (so interleaving is right) + +%%%%% add extension if none (like wavread) +[path,file,ext] = fileparts(FILE); +if isempty(ext) + FILE = [FILE, '.mp3']; +end + +nchan = nr; +nfrm = nc; + +if nchan == 1 + monostring = ' -m m'; +else + monostring = ''; +end + +lameopts = [' ', OPTIONS, monostring, ' ']; + +%if exist('popenw') == 3 +if length(which('popenw')) > 0 + + % We have the writable stream process extensions + cmd = ['"',lame,'"', lameopts, '-r -s ',num2str(SR),' - "',FILE,'"']; + + p = popenw(cmd); + if p < 0 + error(['Error running popen(',cmd,')']); + end + + % We feed the audio to the encoder in blocks of <blksize> frames. + % By adapting this loop, you can create your own code to + % write a single, large, MP3 file one part at a time. + + blksiz = 10000; + + nrem = nfrm; + base = 0; + + while nrem > 0 + thistime = min(nrem, blksiz); + done = popenw(p,32767*D(:,base+(1:thistime)),'int16be'); + nrem = nrem - thistime; + base = base + thistime; + %disp(['done=',num2str(done)]); + end + + % Close pipe + popenw(p,[]); + +else + disp('Warning: popenw not available, writing temporary file'); + + tmpfile = fullfile(tmpdir,['tmp',num2str(round(1000*rand(1))),'.wav']); + + wavwrite(D',SR,tmpfile); + + cmd = ['"',lame,'"', lameopts, '"',tmpfile, '" "', FILE, '"']; + + mysystem(cmd); + + % Delete tmp file + mysystem([rmcmd, ' "', tmpfile,'"']); + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function w = mysystem(cmd) +% Run system command; report error; strip all but last line +[s,w] = system(cmd); +if s ~= 0 + error(['unable to execute ',cmd,' (',w,')']); +end +% Keep just final line +w = w((1+max([0,findstr(w,10)])):end); +% Debug +%disp([cmd,' -> ','*',w,'*']);