%% Formant frequency movement % Make arrow plots showing the pattern of movement in time % of first formant versus second formant frequency (F1 x F2) % for each vowel. % % Steps: % % (1) Load the Hillenbrand database file % clear all; close all; more off; clc; [filenames,dur,F0s,F1s,F2s,F3s,F4s,F120,F220,F320,F150,F250,F350,F180,F280,F380] = ... textread('D:\hillen\vowdata_no_header.txt',... '%s%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f%4.1f'); % (2) Get rid of zero entries ind20=union(find(F120==0),find(F220==0)); % eliminate all "0" entries ind80=union(find(F180==0),find(F280==0)); ind=union(ind20,ind80); filenames(ind,:)=[]; F120(ind)=[]; F220(ind)=[]; F180(ind)=[]; F280(ind)=[]; % (3) As in assignments 1 & 2, add vowel, talker group, and talker number codes: % character 1: m=man, w=woman, b=boy, g=girl % characters 2-3: talker number % characters 4-5: vowel (ae="had", ah="hod", aw="hawed", eh="head", er="heard", % ei="haid", ih="hid", iy="heed", oa=/o/ as in "boat", % oo="hood", uh="hud", uw="who'd") vowel = str2mat('ae','ah','aw','eh','er','ei','ih','iy','oa','oo','uh','uw'); talker_group = str2mat('m','w','b','g'); filenames=char(filenames); % convert cell array to character matrix [nfiles,nchar]=size(filenames); for ifile=1:nfiles, vowel_code(ifile) = strmatch(filenames(ifile,4:5),vowel); talker_group_code(ifile) = strmatch(filenames(ifile,1),talker_group); talker_number(ifile) = str2num(filenames(ifile,2:3)); end; % (4) Use a for-loop to average formant frequencies across talker groups (ig=1:4) % and vowels (iv=1:12). Calculate 4x12 separate averages for two time points in % the vowel, 20% (F120,F220) and 80% (F180,F280). % Draw arrows linking the 20% and 80% sample points in F1xF2 space: for ig=1:4 for iv=1:12 indg=find(talker_group_code==ig); % find indices for all members of this group indv=find(vowel_code==iv); % find indices for all tokens of this vowel indgv=intersect(indg,indv); % intersection (all tokens of this vowel for this talker group) meanF120=mean(log(F120(indgv))); meanF220=mean(log(F220(indgv))); meanF180=mean(log(F180(indgv))); meanF280=mean(log(F280(indgv))); % Use different colored arrows for each group: if ig==1, % males figure(1); hm=arrow([meanF120,meanF220],[meanF180,meanF280]); set(hm,'Color','b'); hold on; elseif ig==2, % females figure(1); hf=arrow([meanF120,meanF220],[meanF180,meanF280]); set(hf,'Color','r'); hold on; elseif ig==3, % boys figure(2); hb=arrow([meanF120,meanF220],[meanF180,meanF280]); set(hb,'Color','b'); hold on; elseif ig==4, % girls figure(2); hg=arrow([meanF120,meanF220],[meanF180,meanF280]); set(hg,'Color','r'); hold on; end; end; end; % (5) Phonetic symbols: must have the SIL phonetic fonts installed % for this to work :-) % heed ii [i] (char(105),'FontName','SILManuscriptIPA') % hid il [I] (char(73),'FontName','SILManuscriptIPA') % hayed ee [e] (char(101),'FontName','SILManuscriptIPA') % head el [E] (char(69),'FontName','SILManuscriptIPA') % had al [ae] (char(81),'FontName','SILManuscriptIPA') % hud uh [^] (char(195),'FontName','SILManuscriptIPA') % herd er [3] (char(212),'FontName','SILManuscriptIPA') + % hod aa [a] (char(65),'FontName','SILManuscriptIPA') % hawed aw [c] (char(141),'FontName','SILManuscriptIPA') % hoed oo [o] (char(111),'FontName','SILManuscriptIPA') % hood ul [U] (char(85),'FontName','SILManuscriptIPA') % who'd uu [u] (char(117),'FontName','SILManuscriptIPA') vsym=str2mat(char(81),char(65),char(141),char(69),char(212),char(101),char(73),char(105),... char(111),char(85),char(195),char(117)); hvd=str2mat('had','hod','hawed','head','herd','hayed','hid','heed','hoed','hood','hud','whod'); for ig=1:4 for iv=1:12 indg=find(talker_group_code==ig); % find indices for all members of this group indv=find(vowel_code==iv); % find indices for all tokens of this vowel indgv=intersect(indg,indv); % intersection (all tokens of this vowel for this talker group) meanF120=mean(log(F120(indgv))); meanF220=mean(log(F220(indgv))); % Use different colored phonetic symbols for each group: if ig==1, % males figure(1); % hm=text(meanF120,meanF220,vsym(iv,:),'FontSize',14,'FontName','SILManuscriptIPA'); hm=text(meanF120,meanF220,hvd(iv,:),'FontSize',10); set(hm,'Color','b'); hold on; elseif ig==2, % females figure(1); % hf=text(meanF120,meanF220,vsym(iv,:),'FontSize',14,'FontName','SILManuscriptIPA'); hf=text(meanF120,meanF220,hvd(iv,:),'FontSize',10); set(hf,'Color','r'); hold on; elseif ig==3, % boys figure(2); % hb=text(meanF120,meanF220,vsym(iv,:),'FontSize',14,'FontName','SILManuscriptIPA'); hb=text(meanF120,meanF220,hvd(iv,:),'FontSize',10); set(hb,'Color','b'); hold on; elseif ig==4, % girls figure(2); % hg=text(meanF120,meanF220,vsym(iv,:),'FontSize',14,'FontName','SILManuscriptIPA'); hg=text(meanF120,meanF220,hvd(iv,:),'FontSize',10); set(hg,'Color','r'); hold on; end; end; end; % (5) set axis limits: 250-1300 Hz for F1; 500-3500 Hz for F2 % Plot annotation and axis labeling. % Although the data are plotted in log units, it's useful to % see the axis tick labels in linear Hz. Here's how you can choose the % axis tick labels, convert them to log, but display them in linear Hz: figure(1); axis(log([250 1300 500 4000])) set(gca,'Box','On','XTick',log([300:100:1300]),... 'XTickLabel','300|400||600||800||1000||1200|'); set(gca,'YTick',log([500:500:4000]),... 'YTickLabel','500|1000|1500|2000|2500|3000|3500|4000'); xlabel('F1 frequency (Hz)'); ylabel('F2 frequency (Hz)'); title('Hillenbrand vowels - W. Michigan (adults)'); hm=findobj(1,'type','line','Color',[0 0 1]); hf=findobj(1,'type','line','Color',[1 0 0]); legend([max(hm),max(hf)],'Men','Women'); figure(2); axis(log([250 1300 500 4000])) set(gca,'Box','On','XTick',log([300:100:1300]),... 'XTickLabel','300|400||600||800||1000||1200|'); set(gca,'YTick',log([500:500:4000]),... 'YTickLabel','500|1000|1500|2000|2500|3000|3500|4000'); xlabel('F1 frequency (Hz)'); ylabel('F2 frequency (Hz)'); title('Hillenbrand vowels - W. Michigan (children)'); hm=findobj(2,'type','line','Color',[0 0 1]); hf=findobj(2,'type','line','Color',[1 0 0]); legend([max(hm),max(hf)],'Boys','Girls');