To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / _dbn / dbn_ISMIR2010.m @ 8:b5b38998ef3b

History | View | Annotate | Download (7.83 KB)

1
function bnet = dbn_thesis_mbk24bx(param)
2

    
3
node_sizes = [param.dbn.nMetpos param.dbn.nKey param.dbn.nChord 13 13 12];
4
discrete = 1:4;
5
observed = 5:6;
6
%% topology: metric position
7

    
8
nodenames = {'metpos', 'key', 'chord', 'bass' , 'basschroma','treblechroma'};
9

    
10
%% topology: dependencies
11
% I first create full dependency matrices, and then eliminate the
12
% inapproapriate rows and columns
13

    
14
intra = zeros(6);
15
inter = zeros(6);
16

    
17
intra(1,3) = 1; % metpos to chord
18
intra(2,3) = 1; % key to chord
19
intra(3,4) = 1; % chord to bass
20
intra(3,6) = 1; % chord to treble chroma
21
intra(4,5) = 1; % bass to bass chroma
22

    
23
inter(1,1) = 1; % metpos to metpos
24
inter(2,2) = 1; % key to key
25
inter(3,3) = 1; % chord to chord
26
inter(3,4) = 1; % chord to bass
27

    
28
bnet = mk_dbn(intra, inter, ...
29
    node_sizes, 'discrete', discrete, 'observed', observed, ...
30
    'names', nodenames);
31

    
32
%-------------------------------------------------------
33
% Flat initialisation for hidden nodes in first slice
34
%-------------------------------------------------------
35
fprintf(1,'   - First Slice\n');
36
iNode = 1;
37
for nodename = nodenames(discrete)
38
    fprintf(1,'    %s \n', nodename{1});
39
    bnet.CPD{iNode} = tabular_CPD(bnet, iNode, 'CPT', 'unif');
40
    iNode = iNode + 1;
41
end
42

    
43
%-------------------------------------------------------
44
% Observed nodes
45
%-------------------------------------------------------
46
bnet.CPD{bnet.names('basschroma')} = ...
47
    gaussian_CPD(bnet,bnet.names('basschroma'), ...
48
    'mean', eye(13), 'cov', repmat(eye(13) * sqrt(param.dbn.basschromavar),[1,1,13]));
49
chordpcs = param.dbn.chordpcs;
50
chordpcs(:,end) = chordpcs(:,end) - 0.5;
51
cova = param.dbn.cova;
52
cova(:,:,end) = cova(:,:,end);
53
bnet.CPD{bnet.names('treblechroma')} = ...
54
    gaussian_CPD(bnet,bnet.names('treblechroma'), ...
55
    'mean', chordpcs, 'cov', cova);
56

    
57
%-------------------------------------------------------
58
% second slice -- more elaborate stuff ...
59
%-------------------------------------------------------
60

    
61
fprintf(1,'   - Second Slice\n');
62
nodename = 'metpos';
63
nodenumber = bnet.names(nodename) + bnet.nnodes_per_slice;
64
fprintf(1,'    (%d) %s (slice 2) \n', nodenumber, nodename);
65
% columns are:
66
% (1) old metpos,
67
% (2) this metpos,
68
% (3) conditional probability.
69

    
70
helper_table = get_field(tabular_CPD(bnet,nodenumber,'CPT','unif'),'cpt');
71
helper_table = helper_table * 0;
72
for oldmetpos = 1:param.dbn.nMetpos
73
    for thismetpos = 1:param.dbn.nMetpos
74
        if oldmetpos <= 4
75
            if mod(oldmetpos + 1,4)  == ...
76
                    mod(thismetpos,4)
77
                helper_table(oldmetpos,thismetpos) = param.dbn.beattrans;
78
            else
79
                helper_table(oldmetpos,thismetpos) = (1-param.dbn.beattrans)/3;
80
            end
81
        else
82
            helper_table(oldmetpos,thismetpos) = 1/param.dbn.nMetpos;
83
        end
84
    end
85
end
86

    
87
bnet.CPD{nodenumber} = tabular_CPD(bnet,nodenumber,helper_table);
88

    
89
%-------------------------------------------------------
90

    
91
nodename = 'key';
92
nodenumber = bnet.names(nodename) + bnet.nnodes_per_slice;
93
fprintf(1,'    (%d) %s (slice 2) \n', nodenumber, nodename);
94
% columns are
95
% (1) old key
96
% (2) this key
97
% (3) probability.
98

    
99
helper_table = get_field(tabular_CPD(bnet,nodenumber,'CPT','unif'),'cpt');
100

    
101
for iOld = 1:param.dbn.nKey
102
    for iThis = 1:param.dbn.nKey
103
        if iOld == iThis
104
            helper_table(iOld,iThis) = 1-param.dbn.keychange;
105
        else
106
            helper_table(iOld,iThis) = param.dbn.keychange/(param.dbn.nKey-1);
107
        end
108
    end
109
end
110

    
111
bnet.CPD{nodenumber} = tabular_CPD(bnet,nodenumber,helper_table);
112

    
113
%-------------------------------------------------------
114
nodename = 'chord';
115
nodenumber = bnet.names(nodename) + bnet.nnodes_per_slice;
116
fprintf(1,'    (%d) %s (slice 2) \n', nodenumber, nodename);
117
% columns are:
118
% (1) old chord,
119
% (2) new metpos,
120
% (3) new harmonic meter,
121
% () new key,
122
% (5) this chord,
123
% (6) probability.
124

    
125
helper_table = get_field(tabular_CPD(bnet,nodenumber,'CPT','unif'),'cpt');
126
[cgivenk, param] = chordgivenkey(param);
127

    
128
for iKey = 1:param.dbn.nKey
129
    for iThis = 1:param.dbn.nChord
130
        for iBeat = 1:param.dbn.nMetpos
131
            for iOld = 1:param.dbn.nChord
132
                if iOld == iThis
133
                    helper_table(iOld,iBeat,iKey,iThis) = ...
134
                        param.dbn.chordchange(iBeat) * cgivenk(iKey, iThis);
135
                else
136
                    helper_table(iOld,iBeat,iKey,iThis) = ...
137
                        (1-param.dbn.chordchange(iBeat)) / (param.dbn.nChord - 1) * cgivenk(iKey, iThis);
138
                end
139
            end
140
        end
141
    end
142
end
143
bnet.CPD{nodenumber} = tabular_CPD(bnet,nodenumber,helper_table);
144

    
145
%-------------------------------------------------------
146
nodename = 'bass';
147
% (1) old chord
148
% (2) new chord
149
% (3) this bass
150
nodenumber = bnet.names(nodename) + bnet.nnodes_per_slice;
151
fprintf(1,'    (%d) %s (slice 2) \n', nodenumber, nodename);
152
helper_table = get_field(tabular_CPD(bnet,nodenumber,'CPT','unif'),'cpt');
153
for iOldchord = 1:param.dbn.nChord
154
    for iNewchord = 1:param.dbn.nChord
155
        if iOldchord ~= iNewchord % first beat of new chord
156
            for iThisbass = 1:param.dbn.nBass
157
                if iThisbass == param.dbn.chordbassnotes(iNewchord) % correct bass note
158
                    helper_table(iOldchord, iNewchord, iThisbass) = param.dbn.nominalbass;
159
                else
160
                    helper_table(iOldchord, iNewchord, iThisbass) = (1 - param.dbn.nominalbass) / (param.dbn.nBass-1);
161
                end
162
            end
163
        else
164
            for iThisbass = 1:param.dbn.nBass
165
                if ~param.dbn.basshaschordnotes
166
                    if iThisbass == param.dbn.chordbassnotes(iNewchord) % correct bass note
167
                        helper_table(iOldchord, iNewchord, iThisbass) = param.dbn.nominalbass_inner;
168
                    else
169
                        helper_table(iOldchord, iNewchord, iThisbass) = (1 - param.dbn.nominalbass_inner) / (param.dbn.nBass-1);
170
                    end
171
                else
172
                    chordnbass = [param.dbn.chordpcs(:,iNewchord); 0];
173
                    chordnbass(param.dbn.chordbassnotes(iNewchord)) = chordnbass(param.dbn.chordbassnotes(iNewchord))+1;
174
                    if ismember(iThisbass, find(chordnbass)) % chord bass note
175
                        helper_table(iOldchord, iNewchord, iThisbass) = param.dbn.nominalbass_inner * chordnbass(iThisbass) / sum(chordnbass);
176
                    else
177
                        helper_table(iOldchord, iNewchord, iThisbass) = (1 - param.dbn.nominalbass_inner) / (param.dbn.nBass-sum(chordnbass)-1);
178
                    end
179
                end
180
            end
181
        end
182
    end
183
end
184

    
185
bnet.CPD{nodenumber} = tabular_CPD(bnet,nodenumber,helper_table);
186

    
187

    
188

    
189
function [cgivenk, param] = chordgivenkey(param)
190
switch param.dbn.keyset
191
    case 'major'
192
        profile = [1 0 1 0 1 1 0 1 0 1 0 1];
193
    case 'majorminor'
194
        profile = [1 0 1 0 1 1 0 1 0 1 0 1;
195
                   1 0 1 1 0 1 0 1 1 1 1 1];
196
end
197

    
198
nMode = size(profile,1);
199

    
200
profiles = zeros(12 * nMode, 12);
201
param.dbn.nKey = nMode * 12;
202

    
203
for iMode = 1:nMode
204
    for iSemitone = 1:12
205
        profiles(12 * (iMode-1) + iSemitone,:) = ...
206
            circshift(profile(iMode,:),[0,iSemitone-1]);
207
    end
208
end
209

    
210
cgivenk = zeros([param.dbn.nKey,param.dbn.nChord]);
211

    
212
% for iKey = 1:param.dbn.nKey
213
%     for iChord = 1:param.dbn.nChord
214
%         chord_prefit = ...
215
%             (1-profiles(iKey,:)) * param.dbn.chordpcs(:,iChord);
216
%         cgivenk(iKey,iChord) = 1 / (chord_prefit + param.dbn.key_c);
217
%     end
218
% end
219

    
220

    
221
for iKey = 1:param.dbn.nKey
222
    for iChord = 1:param.dbn.nChord
223
        chord_prefit = ...
224
            (1-profiles(iKey,:)) * param.dbn.chordpcs(:,iChord);
225
        if chord_prefit == 0 && mod(iKey-iChord,12) == 0 % is in key and key and chord share root
226
            chord_chord_prefit = 2;
227
        else
228
            chord_chord_prefit = 1;
229
        end
230
        cgivenk(iKey,iChord) = (chord_chord_prefit / exp(chord_prefit + 0.0997)) * 0.0363 + 0.0667;
231
    end
232
end
233

    
234
cgivenk = qnormalise(cgivenk,1,2);
235

    
236