0001 function annot = bml_coding2annot(cfg)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 if nargin ~= 1
0023 error('Use as bml_coding2annot(cfg)');
0024 end
0025
0026 CodingMatPath = bml_getopt_single(cfg,'CodingMatPath');
0027 assert(~isempty(CodingMatPath),'cfg.CodingMatPath required in single argument call');
0028 load(CodingMatPath,'CodingMatrix');
0029 load(CodingMatPath,'EventTimes');
0030 load(CodingMatPath,'SkipEvents');
0031 load(CodingMatPath,'WordList');
0032 load(CodingMatPath,'Afs');
0033
0034 roi = bml_getopt(cfg,'roi');
0035 CodingAppVersion = bml_getopt(cfg,'CodingAppVersion','U01_v1');
0036 AudioCoord = bml_getopt(cfg,'warpcoords');
0037 praat = bml_getopt(cfg,'praat');
0038 audio_channel = bml_getopt(cfg,'audio_channel');
0039
0040 if isempty(AudioCoord) || praat
0041
0042 roi = bml_sync_consolidate(roi);
0043 sync_audio = bml_load_continuous(roi);
0044
0045 if ~isempty(audio_channel)
0046 cfg1=[];
0047 cfg1.channel = audio_channel;
0048 sync_audio = ft_selectdata(cfg1,sync_audio);
0049 end
0050
0051
0052 loadedAudioCoord = bml_raw2coord(sync_audio);
0053 sync_audio_time = sync_audio.time;
0054 sync_audio.time{1} = (1:length(sync_audio.time{1}))./sync_audio.fsample;
0055
0056
0057 cfg1=[]; cfg1.CodingMatPath = CodingMatPath;
0058 coding_audio = bml_coding2raw(cfg1);
0059
0060 if isempty(AudioCoord)
0061 AudioCoord = loadedAudioCoord;
0062
0063 fprintf('Calculating alignment between coding and roi audios');
0064 cfg1=[]; cfg1.method='lpf';
0065 assert(sync_audio.fsample == Afs, 'roi''s Fs should be equivalent to Coding Audio Afs');
0066 [coding_audio_dt, max_corr] = bml_timealign(cfg1, sync_audio, coding_audio);
0067
0068 AudioCoord.s1 = AudioCoord.s1 - round(coding_audio_dt*Afs);
0069 AudioCoord.s2 = AudioCoord.s2 - round(coding_audio_dt*Afs);
0070
0071 if max_corr < 0.95
0072 warning('max_cor = %f should be near 1', max_corr)
0073 end
0074 end
0075 if praat
0076 sync_audio.time = sync_audio_time;
0077 coding_audio.time{1} = bml_idx2time(AudioCoord, 1:length(coding_audio.time{1}));
0078 bml_praat(sync_audio, bml_conform_to(sync_audio,coding_audio));
0079 end
0080 end
0081
0082 annot=table();
0083 if ismember(CodingAppVersion,{'U01_v1'})
0084 EventsPerTrial = bml_getopt(cfg,'EventsPerTrial',3);
0085 N_trials = size(CodingMatrix,2);
0086 if SkipEvents + N_trials * EventsPerTrial > length(EventTimes)
0087 warning("Less EventTimes than expected based on CodingMatrix.");
0088 N_trials = floor((length(EventTimes) - SkipEvents)/EventsPerTrial);
0089 end
0090 for i=1:N_trials
0091 id=i;
0092
0093
0094 ti = EventTimes(SkipEvents + i * EventsPerTrial);
0095
0096
0097 phoneticCode=CodingMatrix(1,i);
0098
0099
0100 err_syl1=CodingMatrix{2,i}(1);
0101 err_syl2=CodingMatrix{2,i}(2);
0102 err_syl3=CodingMatrix{2,i}(3);
0103
0104
0105 onset_syl=bml_strnumcell2ordvec(CodingMatrix{3,i});
0106 if size(onset_syl,2) < 3
0107 onset_syl = [onset_syl, nan(1,3-size(onset_syl,2))];
0108 end
0109 onset_syl1=bml_idx2time(AudioCoord,(onset_syl(1)+ti)*Afs);
0110 onset_syl2=bml_idx2time(AudioCoord,(onset_syl(2)+ti)*Afs);
0111 onset_syl3=bml_idx2time(AudioCoord,(onset_syl(3)+ti)*Afs);
0112
0113
0114 offset_syl = bml_strnumcell2ordvec(CodingMatrix{4,i});
0115 if isempty(offset_syl)
0116 offset_syl = nan;
0117 end
0118
0119 if length(offset_syl)==length(onset_syl)
0120 offset_syl_complete = offset_syl;
0121 offset_syl_coded = ones(1,length(offset_syl_complete));
0122 else
0123 offset_syl_complete = zeros(1,length(onset_syl));
0124 offset_syl_coded = zeros(1,length(onset_syl));
0125 onset_syl_inf = [onset_syl inf];
0126 j=1;
0127 for k=1:(length(onset_syl))
0128 if j <= length(offset_syl)
0129 if offset_syl(j) <= onset_syl_inf(k+1)
0130 offset_syl_complete(k) = offset_syl(j);
0131 offset_syl_coded(k) = 1;
0132 j = j + 1;
0133 else
0134 offset_syl_complete(k) = onset_syl_inf(k+1);
0135 offset_syl_coded(k) = 0;
0136 end
0137 else
0138 offset_syl_complete(k) = NaN;
0139 offset_syl_coded(k) = 0;
0140 warning('Inconsistent syl offset times in trial %i',i)
0141 end
0142 end
0143 end
0144 offset_syl1=bml_idx2time(AudioCoord,(offset_syl_complete(1)+ti) * Afs);
0145 offset_syl2=bml_idx2time(AudioCoord,(offset_syl_complete(2)+ti) * Afs);
0146 offset_syl3=bml_idx2time(AudioCoord,(offset_syl_complete(3)+ti) * Afs);
0147 offset_coded_syl1=offset_syl_coded(1);
0148 offset_coded_syl2=offset_syl_coded(2);
0149 offset_coded_syl3=offset_syl_coded(3);
0150
0151
0152 onset_vowel=bml_strnumcell2ordvec(CodingMatrix{5,i});
0153 if size(onset_vowel,2) < 3
0154 onset_vowel = [onset_vowel, nan(1,3-size(onset_vowel,2))];
0155 end
0156 onset_vowel1=bml_idx2time(AudioCoord,(onset_vowel(1)+ti) * Afs);
0157 onset_vowel2=bml_idx2time(AudioCoord,(onset_vowel(2)+ti) * Afs);
0158 onset_vowel3=bml_idx2time(AudioCoord,(onset_vowel(3)+ti) * Afs);
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 comment=CodingMatrix(13,i);
0170
0171
0172
0173 word_triplet = WordList(i);
0174
0175 starts = bml_idx2time(AudioCoord,(min(onset_syl)+ti) * Afs);
0176 ends = bml_idx2time(AudioCoord,(max(offset_syl)+ti) * Afs);
0177
0178 annot = [annot; table(id, starts, ends, phoneticCode, err_syl1, err_syl2, err_syl3,...
0179 onset_syl1, offset_syl1, onset_syl2, offset_syl2, onset_syl3, offset_syl3,...
0180 onset_vowel1, onset_vowel2, onset_vowel3,...
0181 offset_coded_syl1, offset_coded_syl2, offset_coded_syl3, word_triplet, comment)];
0182
0183 end
0184
0185 elseif ismember(CodingAppVersion,{'pilot'})
0186 EventsPerTrial = bml_getopt(cfg,'EventsPerTrial',4);
0187 N_trials = size(CodingMatrix,2);
0188 if SkipEvents + N_trials * EventsPerTrial > length(EventTimes)
0189 warning("Less EventTimes than expected based on CodingMatrix.");
0190 N_trials = floor((length(EventTimes) - SkipEvents)/EventsPerTrial);
0191 end
0192 for i=1:N_trials
0193 id=i;
0194 ti = EventTimes(SkipEvents + i * EventsPerTrial);
0195
0196
0197 phoneticCode = default_str(CodingMatrix(1,i));
0198
0199
0200 err_cons1 = CodingMatrix(2,i);
0201
0202
0203 err_vowel = CodingMatrix(3,i);
0204
0205
0206 err_cons2 = CodingMatrix(4,i);
0207
0208
0209 onset_word=bml_idx2time(AudioCoord,(default_nan(CodingMatrix{5,i}) + ti) * Afs);
0210
0211
0212 offset_word=bml_idx2time(AudioCoord,(default_nan(CodingMatrix{6,i}) + ti) * Afs);
0213
0214
0215 unveil=default_int(CodingMatrix{7,i});
0216
0217
0218 comment=CodingMatrix(8,i);
0219
0220
0221 onset_vowel=bml_idx2time(AudioCoord,(default_nan(CodingMatrix{9,i}) + ti) * Afs);
0222
0223
0224 offset_vowel=bml_idx2time(AudioCoord,(default_nan(CodingMatrix{10,i}) + ti) * Afs);
0225
0226 word = WordList(i);
0227
0228 starts = onset_word;
0229 ends = offset_word;
0230
0231 annot = [annot; table(id, starts, ends, phoneticCode,...
0232 err_cons1, err_vowel, err_cons2, onset_word, offset_word, ...
0233 unveil, comment, onset_vowel, offset_vowel, word)];
0234
0235 end
0236 else
0237 error('unknown CodingAppVersion')
0238 end
0239
0240 annot = bml_annot_table(annot);
0241 annot.trial_id = annot.id;
0242 end
0243
0244
0245
0246
0247
0248
0249
0250 function default = default_str(input)
0251 if isempty(input)
0252 default = {''};
0253 else
0254 default = input;
0255 end
0256 end
0257
0258 function default = default_int(input)
0259 if isempty(input)
0260 default = 0;
0261 else
0262 default = input;
0263 end
0264 end
0265
0266 function default = default_nan(input)
0267 if isempty(input)
0268 default = nan;
0269 else
0270 default = input;
0271 end
0272 end