tomwalters@0: % tool tomwalters@0: % tomwalters@0: % INPUT VALUES: tomwalters@0: % tomwalters@0: % RETURN VALUE: tomwalters@0: % tomwalters@0: % bleeck@3: % (c) 2011, University of Southampton bleeck@3: % Maintained by Stefan Bleeck (bleeck@gmail.com) bleeck@3: % download of current version is on the soundsoftware site: bleeck@3: % http://code.soundsoftware.ac.uk/projects/aimmat bleeck@3: % documentation and everything is on http://www.acousticscale.org bleeck@3: tomwalters@0: tomwalters@0: function makeaimmovie(varargin) tomwalters@0: %usage: function makemovie(arguments) tomwalters@0: % tomwalters@0: % produces a quicktime-video from an AMS/AIM spf file and a sound file tomwalters@0: % inputs: tomwalters@0: % if no or only one parameter is given, than a make file is read instead tomwalters@0: % that should contain all parameters and their values tomwalters@0: % this file is generated automatically as "lastrun.genmovie" tomwalters@0: % tomwalters@0: % otherwise parameter must come in pairs: 'param','value' tomwalters@0: % tomwalters@0: % parameters for generating the SAI: tomwalters@0: % modelfile - the spf file that specifies the version of AMS/AIM (required) tomwalters@0: % output_normalization - the norm_mode parameter in out_file very useful for automatic scaling tomwalters@0: % soundfile - a wave or raw file with the sound in (required) tomwalters@0: % sound_sample_rate - the sample rate of the sound file tomwalters@0: % sound_endian - endian of the sound file (l or b)(PC's are little endian Suns are big endian) tomwalters@0: % framespersecond (default: 12) tomwalters@0: % moviefile - the name of the output file (default: "name of model plus name of sound") tomwalters@0: % echo - if off, than no output is created on screen tomwalters@0: % aifffile - optional instead of model. When aifffile is given, the aif file is read in directly from it tomwalters@0: % tomwalters@0: % Parameter for generating the graphic tomwalters@0: % AuditoryImageFormat: "AI", "AIpitch", "AIsum", "AIsum2", "sumai", or "AIsurface" (default: AIsum) or any user-defined-function tomwalters@0: % the user-defined-function is called with the current frame and must produce a picture tomwalters@0: % currently supported: show_pitch_spiral tomwalters@0: % AIFrePtiPStress (Auditory Image with Frequency profile and time interval profile with the colors in the image where the information was derived from tomwalters@0: % tomwalters@0: % TimeIntervalUnits "log" or "linear" (default: log) tomwalters@0: % colormap (default: black) tomwalters@0: % input_scale - scaling factor, that is directly applied to the input values - to prevent too loud sounds (default 1 can be set to auto) tomwalters@0: % minimum_time_interval - the minimal time that should be displayed in logarithmic form (in ms) tomwalters@0: % maximum_time_interval - the maximal time that should be displayed in logarithmic form tomwalters@0: % linewidth - Width of all plotted lines (default 1) tomwalters@0: % showtime - plot the time and the number of each frame (default on) tomwalters@0: % text - show a text in each frame in the upper right corner. The text must be given in a struct with .time and .label tomwalters@0: % plot_scale - scales the whole frame up or down tomwalters@0: % profile_scale - increases the amplitude of the profiles tomwalters@0: tomwalters@0: % the length of the final movie is the length of the soundfile plus the length of one picture in the beginning tomwalters@0: tomwalters@0: % valid calls: tomwalters@0: % the shortest valid call: tomwalters@0: % makemovie('modelfile''aim.spf','soundfile','cegc_br.raw') tomwalters@0: % produces the video "aim.mov" from the soundfile "cegc_br.wav" and the model file aim.spf tomwalters@0: % example tomwalters@0: %makemovie( 'modelfile','AIMghs.spf',... tomwalters@0: % 'soundfile','f128h8j0-2.wav',... tomwalters@0: % 'framespersecond','12',... tomwalters@0: % 'moviefile', 'impressing_movie',... %(".mov" is added) tomwalters@0: % 'TimeIntervalUnits','log',... % (or linear) tomwalters@0: % 'input_scale','default',... % ( or any number >0) tomwalters@0: % 'output_normalization','1000',... % (this number overwrites the NORM_MODE.DataFile_Out) tomwalters@0: % 'AuditoryImageFormat','sum',... % ( or AI,AIsurface,AIsum) tomwalters@0: % 'sound_sample_rate','20000',... % ( if the soundfile is not a wavfile - this must be togehter with the next one) tomwalters@0: % 'minimum_time_interval','2',... % ( in ms the smalles time, that is displayed) tomwalters@0: % 'sound_endian','l') % ( if the soundfile is not a wavfile - this must be togehter with the previous one) tomwalters@0: tomwalters@0: tomwalters@0: % you can choose between several types without changing the spf-file! If you want all channels with the waterfal than tomwalters@0: % the according reduce_channels are commented out automatically tomwalters@0: tomwalters@0: % the full movie will consist of so many pictures as the length of the soundfile divided by the frames per seconds. tomwalters@0: % To avoid clicks (due to quicktime) at the onset of the sound one frame and tomwalters@0: % an pause of one frame is inserted at the beginning of the movie. tomwalters@0: % To avoid a black picture at the end, one more frame is inserted at the end of the movie, so that the final movie tomwalters@0: % is slighly longer than the sound and the last picture is shown twice tomwalters@0: tomwalters@0: % the principle of the generation is to load the spf file and crucial variables are overwwitten: tomwalters@0: % the file_in is overwritten by the calling "soundfile" and the sound-out is overwritten by some temp-aiff file tomwalters@0: % the modified spf-file is stored under makemovie_temp.spf and this file is called via ams tomwalters@0: tomwalters@0: temp_sound_file_name='temp_sound.wav'; % must be the same as in getaiffs!!! tomwalters@0: tomwalters@0: if nargin<2 % only one parameter -> read file tomwalters@0: if size(varargin)==1 tomwalters@0: makefilename=varargin{1}; tomwalters@0: else tomwalters@0: makefilename='lastrun.genmovie'; tomwalters@0: end tomwalters@0: % fprintf('movie is produced from file %s from aifffile "makemovie_temp.aif"\n!',makefilename); tomwalters@0: % fprintf('movie is produced from file ''%s''\n',makefilename); tomwalters@0: else tomwalters@0: makefilename='lastrun.genmovie'; tomwalters@0: generateparameterfile(makefilename,varargin); tomwalters@0: end tomwalters@0: arguments=readparameterfile(makefilename); tomwalters@0: tomwalters@0: tomwalters@0: str_moviefile=getargument(arguments,'moviefile'); tomwalters@0: str_aifffile=getargument(arguments,'aifffile'); tomwalters@0: str_movie_duration=getargument(arguments,'movie_duration'); tomwalters@0: str_movie_start_time=getargument(arguments,'movie_start_time'); tomwalters@0: str_AuditoryImageFormat=getargument(arguments,'AuditoryImageFormat'); tomwalters@0: str_TimeIntervalUnits=getargument(arguments,'TimeIntervalUnits'); tomwalters@0: str_colormap=getargument(arguments,'colormap'); tomwalters@0: str_minimum_time_interval=getargument(arguments,'minimum_time_interval'); tomwalters@0: str_maximum_time_interval=getargument(arguments,'maximum_time_interval'); tomwalters@0: str_sound_sample_rate=getargument(arguments,'sound_sample_rate'); tomwalters@0: str_sound_endian=getargument(arguments,'sound_endian'); tomwalters@0: str_linewidth=getargument(arguments,'linewidth'); tomwalters@0: str_echo=getargument(arguments,'echo'); tomwalters@0: str_showtime=getargument(arguments,'showtime'); tomwalters@0: str_showtextname=getargument(arguments,'showtextname'); tomwalters@0: str_showtexttime=getargument(arguments,'showtexttime'); tomwalters@0: str_plotscale=getargument(arguments,'plotscale'); tomwalters@0: str_profile_scale=getargument(arguments,'profile_scale'); tomwalters@0: tomwalters@0: % data originally used in readaiff, but needed here also: tomwalters@0: str_framespersecond=getargument(arguments,'framespersecond'); tomwalters@0: str_model=getargument(arguments,'modelfile'); tomwalters@0: str_soundcommand=getargument(arguments,'soundfile'); tomwalters@0: tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % set some default values, if the values are not explecitly given: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % scale the amplitude of the whole picture up tomwalters@0: if isempty(str_plotscale) % default frames per second tomwalters@0: plot_scale=1; tomwalters@0: else tomwalters@0: eval(sprintf('plot_scale=%s;',str_plotscale)); tomwalters@0: end tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % scale the amplitude of the profiles (only when profiles are plotted of course) tomwalters@0: if isempty(str_profile_scale) % default frames per second tomwalters@0: profile_scale=1; tomwalters@0: else tomwalters@0: eval(sprintf('profile_scale=%s;',str_profile_scale)); tomwalters@0: end tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % show time and number of frame tomwalters@0: if isempty(str_showtime) % default frames per second tomwalters@0: showtime=1; tomwalters@0: else tomwalters@0: if strcmp(str_showtime,'off') tomwalters@0: showtime=0; tomwalters@0: else tomwalters@0: showtime=1; tomwalters@0: end tomwalters@0: end tomwalters@0: tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % frames per second tomwalters@0: if isempty(str_framespersecond) % default frames per second tomwalters@0: framespersecond=12; tomwalters@0: else tomwalters@0: eval(sprintf('framespersecond=%s;',str_framespersecond)); tomwalters@0: end tomwalters@0: tomwalters@0: tomwalters@0: if isempty(str_linewidth) % how much the spf file should be normalized by setting the norm_mode parameter in out_file tomwalters@0: line_width=1; tomwalters@0: else tomwalters@0: eval(sprintf('line_width=%s;',str_linewidth)); tomwalters@0: end tomwalters@0: tomwalters@0: if isempty(str_TimeIntervalUnits) % output is linear or logarithmic tomwalters@0: TimeIntervalUnits='log'; tomwalters@0: else tomwalters@0: TimeIntervalUnits=str_TimeIntervalUnits; tomwalters@0: end tomwalters@0: tomwalters@0: if isempty(str_moviefile) % default name of the movie tomwalters@0: [dumy_path,tempmodelname,ext,versn] = fileparts(str_model); tomwalters@0: [dumy_path,tempsoundname,ext,versn] = fileparts(str_soundcommand); tomwalters@0: moviefile=sprintf('soundfile_%s_model_%s.mov',tempsoundname,tempmodelname); tomwalters@0: else tomwalters@0: [dumy_path,tempmodelname,ext,versn] = fileparts(str_moviefile); tomwalters@0: if strcmp(ext,'') tomwalters@0: moviefile=sprintf('%s.mov',str_moviefile); tomwalters@0: else tomwalters@0: moviefile=str_moviefile; tomwalters@0: end tomwalters@0: end tomwalters@0: tomwalters@0: if isempty(str_AuditoryImageFormat) % which AuditoryImageFormat should be used tomwalters@0: AuditoryImageFormat='AIsum'; tomwalters@0: else tomwalters@0: AuditoryImageFormat=str_AuditoryImageFormat; tomwalters@0: end tomwalters@0: tomwalters@0: if isempty(str_colormap) % an aifffile that is read instead tomwalters@0: if strcmp(AuditoryImageFormat,'AI') | strcmp(AuditoryImageFormat,'AIsum') | strcmp(AuditoryImageFormat,'sum')| strcmp(AuditoryImageFormat,'singlegraphic') tomwalters@0: clrmap=zeros(64,3); % all black tomwalters@0: end tomwalters@0: if strcmp(AuditoryImageFormat,'AIsurface') tomwalters@0: clrmap=1-gray; % invertes grayscale: 0 is white and 1 is black tomwalters@0: end tomwalters@0: else % colormap was given tomwalters@0: eval(sprintf('clrmap=%s;',str_colormap)); tomwalters@0: end tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % sound-file. can be a command or a file tomwalters@0: if isempty(str_soundcommand) % tomwalters@0: error('soundcommand must be given'); tomwalters@0: else tomwalters@0: soundcommand=str_soundcommand; tomwalters@0: end tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % echo on screen tomwalters@0: if isempty(str_echo) % default frames per second tomwalters@0: echo=1; tomwalters@0: else tomwalters@0: if strcmp(str_echo,'off') tomwalters@0: echo=0; tomwalters@0: else tomwalters@0: echo=1; tomwalters@0: end tomwalters@0: end tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % construct the aiff-file with a call to the dsam-routine: tomwalters@0: tomwalters@0: % if aifffile is given from a previous run, than simply load it: tomwalters@0: if ~isempty(str_aifffile) tomwalters@0: allframes=SBReadAiff(str_aifffile,echo); % returns all info in a struct tomwalters@0: else tomwalters@0: allframes=getaiffs(makefilename); tomwalters@0: end tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tomwalters@0: % read the sound command and transfere the data to the buffer tomwalters@0: if ~isempty(str_movie_duration) % default frames per second tomwalters@0: eval(sprintf('movie_duration=%s;',str_movie_duration)); tomwalters@0: eval(sprintf('movie_start_time=%s;',str_movie_start_time)); tomwalters@0: [sounddata,samplerate,bits,endian]=producesounddata(soundcommand,temp_sound_file_name,str_sound_sample_rate,str_sound_endian,movie_start_time,movie_duration); tomwalters@0: else tomwalters@0: movie_start_time=0; tomwalters@0: [sounddata,samplerate,bits,endian]=producesounddata(soundcommand,temp_sound_file_name,str_sound_sample_rate,str_sound_endian); tomwalters@0: movie_duration=length(sounddata)/samplerate; tomwalters@0: end tomwalters@0: tomwalters@0: tomwalters@0: % the duration of the whole video tomwalters@0: videolength=size(sounddata,1)/samplerate; tomwalters@0: % so long is one picture: tomwalters@0: duration=1/framespersecond; tomwalters@0: tomwalters@0: % so many frames is the video size in the end: tomwalters@0: nr_frames=videolength*framespersecond; tomwalters@0: tomwalters@0: % find out about the general structure of all frames by taking the first as a sample (they are all identical) tomwalters@0: sample_frame=allframes(1); tomwalters@0: nr_channels=getnrchannels(sample_frame); tomwalters@0: nr_points=getnrpoints(sample_frame); tomwalters@0: nr_frames=size(allframes,2); tomwalters@0: t_plus=getmaximumtime(sample_frame); % usually 5 ms tomwalters@0: t_minus=getminimumtime(sample_frame); % usually -35 ms tomwalters@0: tomwalters@0: % set a variable for the current starting time of each frame for plotting tomwalters@0: for i=1:nr_frames tomwalters@0: allframes(i)=setcurrentframestarttime(allframes(i),(i-1)*duration); tomwalters@0: end tomwalters@0: tomwalters@0: % start producing the movie! tomwalters@0: MakeQTMovie('start',moviefile); tomwalters@0: MakeQTMovie('size', [640 400]); tomwalters@0: MakeQTMovie('quality', 0.8); % reduces the size tomwalters@0: tomwalters@0: if echo fprintf('start produce pictures:\n'); end tomwalters@0: tomwalters@0: % We start the time at zero: tomwalters@0: current_time=0; tomwalters@0: tomwalters@0: for i=0:nr_frames tomwalters@0: if echo tomwalters@0: % plot a start for each frame, so that we see, how long it takes tomwalters@0: fprintf('*'); tomwalters@0: if(mod(i+1,30)==0) tomwalters@0: fprintf('\n'); tomwalters@0: end tomwalters@0: end tomwalters@0: tomwalters@0: if i==0 % trick: the first picture is the same as the second to prevent quick time from producing a click sound, that it otherwise does tomwalters@0: c_frame=allframes(1); tomwalters@0: current_time=0; tomwalters@0: else tomwalters@0: c_frame=allframes(i); tomwalters@0: end tomwalters@0: tomwalters@0: % set some default values that depend on the frames tomwalters@0: if strcmp(TimeIntervalUnits,'log')>0 tomwalters@0: framestruct.is_log=1; tomwalters@0: else tomwalters@0: framestruct.is_log=0; tomwalters@0: end tomwalters@0: tomwalters@0: if showtime tomwalters@0: framestruct.show_time=1; tomwalters@0: else tomwalters@0: framestruct.show_time=0; tomwalters@0: end tomwalters@0: tomwalters@0: if ~isempty(str_showtextname) tomwalters@0: texts=str2cell(str_showtextname); tomwalters@0: times=str2cell(str_showtexttime); tomwalters@0: nr_times=size(times,1); tomwalters@0: if nr_times<=1 % every picture tomwalters@0: c_frame=settext(c_frame,texts(1)); tomwalters@0: else tomwalters@0: for i=1:nr_times tomwalters@0: tt=str2num(times{i}); tomwalters@0: if tt>current_time tomwalters@0: c_frame=settext(c_frame,texts(i)); tomwalters@0: break; tomwalters@0: end tomwalters@0: end tomwalters@0: end tomwalters@0: end tomwalters@0: tomwalters@0: if isempty(str_minimum_time_interval) % how much the spf file should be normalized by setting the norm_mode parameter in out_file tomwalters@0: if framestruct.is_log tomwalters@0: minimum_time_interval=2; % ms = default value for the minimum time tomwalters@0: else tomwalters@0: minimum_time_interval=-t_plus*1000; % ms = default value for the minimum time tomwalters@0: end tomwalters@0: else tomwalters@0: eval(sprintf('minimum_time_interval=%s;',str_minimum_time_interval)); tomwalters@0: if framestruct.is_log tomwalters@0: if minimum_time_interval < 0 tomwalters@0: disp('minimum time interval must be >0 for log plots'); tomwalters@0: minimum_time_interval=2; tomwalters@0: end tomwalters@0: end tomwalters@0: end tomwalters@0: tomwalters@0: if isempty(str_maximum_time_interval) % default value for maximum time tomwalters@0: maximum_time_interval=-t_minus*1000; % in ms! % to the end of the stimulus tomwalters@0: else tomwalters@0: eval(sprintf('maximum_time_interval=%s;',str_maximum_time_interval)); tomwalters@0: end tomwalters@0: tomwalters@0: % construct the framestructure for calling the plotting-routine tomwalters@0: framestruct.current_frame = c_frame; tomwalters@0: framestruct.maximum_time_interval=maximum_time_interval; tomwalters@0: framestruct.minimum_time_interval=minimum_time_interval; tomwalters@0: framestruct.plot_scale=plot_scale; tomwalters@0: framestruct.profile_scale=profile_scale; tomwalters@0: tomwalters@0: tomwalters@0: % call the plotting routine tomwalters@0: eval(sprintf('%s(framestruct);',AuditoryImageFormat)); tomwalters@0: tomwalters@0: % bring the figure to front tomwalters@0: figure(gcf); tomwalters@0: tomwalters@0: % and add it to the movie tomwalters@0: MakeQTMovie('addframe'); tomwalters@0: tomwalters@0: current_time=current_time+duration; tomwalters@0: tomwalters@0: end % End of current_frame - loop tomwalters@0: tomwalters@0: % add one, to fill the last picture (the sound is longer than n*nr_frames) tomwalters@0: MakeQTMovie('addframe'); tomwalters@0: MakeQTMovie('framerate', framespersecond); tomwalters@0: tomwalters@0: % soundgap=zeros(floor(samplerate/framespersecond),1); tomwalters@0: % stemp=[soundgap' sounddata']; tomwalters@0: % sounddata=stemp'; tomwalters@0: MakeQTMovie('addsound',sounddata,samplerate); tomwalters@0: tomwalters@0: MakeQTMovie('finish'); tomwalters@0: MakeQTMovie('cleanup'); tomwalters@0: tomwalters@0: % fprintf('\n\nFinished successfully! :-)\n'); tomwalters@0: if echo tomwalters@0: disp(sprintf('\n\nWrote QuickTime movie %s\\%s',pwd,moviefile)); tomwalters@0: end tomwalters@0: tomwalters@0: return tomwalters@0: tomwalters@0: tomwalters@0: % clean up tomwalters@0: ans=input('start with QuickTime? y/[n]','s') tomwalters@0: if ans=='y' tomwalters@0: !C:\Program Files\QuickTime\QuickTimePlayer tomwalters@0: end tomwalters@0: tomwalters@0: tomwalters@0: % not cleaning up: (for test purpose) tomwalters@0: return tomwalters@0: % clean up temporary files tomwalters@0: try tomwalters@0: delete('makemovie_temp.spf'); tomwalters@0: end tomwalters@0: try tomwalters@0: delete('makemovie_temp.aif'); tomwalters@0: end tomwalters@0: if rememberdeletesoundfile tomwalters@0: try tomwalters@0: delete(soundfile); tomwalters@0: end tomwalters@0: end