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 / _writetools / write_song2.m

History | View | Annotate | Download (8.78 KB)

1
function write_song2(song, bnet, param, outfilename, filetype, verbose)
2

    
3
prelabels = {'C','Db','D','Eb','E','F','Gb','G','Ab','A','Bb','B','N'};
4
chordindex = bnet.names('chord');
5
metposindex = bnet.names('metpos');
6
if param.dbn.nKey > 0
7
    keyindex = bnet.names('key');
8
end
9

    
10
switch filetype
11
    case 'chordlab'
12
        chordsequence = [song.mpe{chordindex,:}];
13
        oldchord = 0;
14
        oldlabel ='N';
15
        outfile = fopen(outfilename,'w');
16
        if verbose
17
            fprintf(1, '0.0 ');
18
        end
19
        fprintf(outfile, '0.0 ');
20
        for iChord= 1:length(chordsequence)
21
            newchord = song.mpe{chordindex, iChord};
22
            if newchord ~= oldchord
23
                if param.dbn.nKey > 0
24
                    keylabel = param.dbn.keynames{song.mpe{keyindex,iChord}};
25
                else
26
                    keylabel = 'C';
27
                end
28
                if ischar(param.dbn.chordnames{newchord})
29
                    prelabel = ['C',param.dbn.chordnames{newchord}];
30
                    [c.rootnote, c.shorthand, c.degreelist, c.bassdegree, success, error] =...
31
                        getchordinfo(prelabel);
32
                    c.string = addshort2list(c.shorthand, c.degreelist);
33
                    label = [chordroot_spelling(keylabel, param.dbn.chordrootnotes(newchord)-1 ,strsplit(',',c.string)),param.dbn.chordnames{newchord}];
34
                else
35
                    label = 'N';
36
                end
37
                if verbose
38
                    fprintf(1,'%0.3f %s\n%0.3f ', song.beattimes(iChord,1), oldlabel,song.beattimes(iChord,1));
39
                end
40
                fprintf(outfile,'%0.3f %s\n%0.3f ', song.beattimes(iChord,1), oldlabel,song.beattimes(iChord,1));
41
                oldlabel = label;
42
            end
43
            oldchord = newchord;
44
        end
45
        if verbose
46
            fprintf(1,'%0.3f %s', song.beattimes(iChord,2), oldlabel);
47
        end
48
        fprintf(outfile,'%0.3f %s', song.beattimes(iChord,2), oldlabel);
49
        fclose(outfile);
50
    case 'keylab'
51
        keysequence = [song.mpe{keyindex,:}];
52
        oldkey = 0;
53
        oldlabel ='N';
54
        outfile = fopen(outfilename,'w');
55
        if verbose
56
            fprintf(1, '0.0 ');
57
        end
58
        fprintf(outfile, '0.0 ');
59
        for iKey = 1:length(keysequence)
60
            newkey = song.mpe{keyindex, iKey};
61
            if newkey ~= oldkey
62
                keylabel = param.dbn.keynames{song.mpe{keyindex,iKey}};
63
                if verbose
64
                    fprintf(1,'%0.3f %s\n%0.3f ', song.beattimes(iKey,1), oldlabel,song.beattimes(iKey,1));
65
                end
66
                fprintf(outfile,'%0.3f %s\n%0.3f ', song.beattimes(iKey,1), oldlabel,song.beattimes(iKey,1));
67
                oldlabel = keylabel;
68
            end
69
            oldkey = newkey;
70
        end
71
        if verbose
72
            fprintf(1,'%0.3f %s', song.beattimes(iKey,2), oldlabel);
73
        end
74
        fprintf(outfile,'%0.3f %s', song.beattimes(iKey,2), oldlabel);
75
        fclose(outfile);
76
    case 'lilypond'
77
        bassindex = bnet.names('bass');
78
        lilychordnames = repmat(param.dbn.lilytypechordnames,[1,12]);
79
        lilychordnames{numel(lilychordnames)+1} = '';
80

    
81
        chordsequence = [song.mpe{chordindex,:}];
82

    
83
        nBeat = length(chordsequence);
84

    
85
        keysequence = [song.mpe{keyindex,:}];
86

    
87
%         label = cell(nBeat,1);
88
%         keylabel = cell(nBeat,1);
89

    
90
        metpossequence = [song.mpe{metposindex,:}];
91
        oldchord = 0;
92
        oldkey = 0;
93
        oldbass = 0;
94

    
95

    
96

    
97
        chordcount = 0;
98
        basscount = 0;
99
        chordduration = 1;
100
        bassduration = 1;
101
        
102
        % time signature stuff
103
        partial = find(metpossequence == 1,1)-1;
104
        if partial > 0
105
            partial = ['\partial ' lilylength(partial)];
106
        else 
107
            partial = '';
108
        end
109
        barlines = find(metpossequence == 1);
110
        timesig = diff(barlines); % for barlines, not beats
111
        ind = min(length(timesig),union(find(timesig~=4),find(timesig~=4)+1));
112
        non4timesig = barlines(ind);  % in beats
113
        timesig = timesig(ind);
114
        
115
        % chord and bass loop
116

    
117
        for iBeat= 1:length(chordsequence)
118
            newchord = song.mpe{chordindex, iBeat};
119
            newkey = song.mpe{keyindex, iBeat};
120
            newbass = song.mpe{bassindex, iBeat};
121
            newmetpos = song.mpe{metposindex, iBeat};
122
            if param.dbn.nKey > 0
123
                prekeylabel = param.dbn.keynames{song.mpe{keyindex,iBeat}};
124
            else
125
                prekeylabel = 'C';
126
            end
127
            if newchord ~= oldchord  || newmetpos == 1 || chordduration == 4
128
                % get the chord name
129
                chordcount = chordcount + 1;
130
                if iBeat > 1
131
                    chordlabelduration(chordcount-1) = chordduration;
132
                end
133
                if ischar(param.dbn.chordnames{newchord})
134
                    preroot = spellnote(newkey, param.dbn.chordrootnotes(newchord),'lily');
135
                    root{chordcount} = preroot;
136
                    if isempty(strfind(param.dbn.chordnames{newchord},'/'))
137
                        label{chordcount} = lilychordnames{newchord};
138
                    else
139
                        bass = spellnote(newkey, param.dbn.chordbassnotes(newchord),'lily');
140
                        label{chordcount} = [strrep(lilychordnames{newchord},' ',''),'/',bass];
141
                    end
142
                else
143
                    root{chordcount} = 'r';
144
                    label{chordcount} = '';
145
                end
146
                chordbeat(chordcount) = iBeat;
147

    
148
%                 oldlabel = label{iBeat};
149
                chordduration = 1;
150
            else
151
                chordduration = chordduration + 1;
152
            end
153
            if oldkey ~= newkey
154
                keylabel{iBeat} = param.dbn.lilykeynames{song.mpe{keyindex,iBeat}};
155
%                 keylabel{iBeat} = strrep(keylabel{iBeat},'#','is');
156
%                 keylabel{iBeat} = strrep(keylabel{iBeat},'b','es');
157
%                 keylabel{iBeat} = lower(keylabel{iBeat});
158
%                 oldkeylabel = keylabel{iBeat};
159
            end
160
            if oldbass ~= newbass || newmetpos == 1 || bassduration == 4
161
                basscount = basscount + 1;
162
                if iBeat > 1
163
                    basslabelduration(basscount-1) = bassduration;
164
                end
165
                basslabel{basscount} = spellnote(newkey, param.dbn.chordbassnotes(newbass),'lily');
166
                bassbeat(basscount) = iBeat;
167
                bassduration = 1;
168
            else                
169
                bassduration = bassduration + 1;
170
            end
171

    
172
            oldbass = newbass;
173
            oldkey = newkey;
174
            oldchord = newchord;
175
        end
176
        
177

    
178
        % finish off the durations etc
179
        basslabelduration(basscount) = bassduration;
180
        chordlabelduration(chordcount) = chordduration;
181

    
182
        
183
        chord_string = 'chordsymb = { \chordmode { ';
184
        bass_string = 'bassnotes = { \override TextScript #''box-padding = #.7 \override TextScript #''font-size = #-3 \override TextScript #''thickness = #.03 \clef bass';
185
        for iBeat = 1:nBeat
186
            chordind = find(chordbeat == iBeat);
187
            bassind = find(bassbeat == iBeat);
188
            timesigind = find(non4timesig == iBeat);
189
            if ~(iBeat > numel(keylabel) || isempty(keylabel{iBeat}))
190
                chord_string = [chord_string sprintf('  } \\key %s \\chordmode { ', keylabel{iBeat})];
191
                bass_string = [bass_string sprintf(' \\key %s', keylabel{iBeat})];
192
            end
193
            if ~isempty(chordind)
194
                if ~isempty(timesigind)
195
                    chord_string = [chord_string sprintf(' \\time %0.0f/4',timesig(timesigind))];
196
                end
197
                chord_string = [chord_string sprintf(' %s%s%s',root{chordind}, lilylength(chordlabelduration(chordind)), label{chordind})];
198
            end
199
            if ~isempty(bassind)
200
                bass_string = [bass_string sprintf(' %s%s',basslabel{bassind},lilylength(basslabelduration(bassind)))];
201

    
202
            end
203
                
204

    
205
        end
206
        fid = fopen(outfilename);
207
        fprintf(fid,'\\header{title = "%s"}\n%s}}\n%s\n}\n<<\n\\new ChordNames {\n\\set chordChanges = ##t\n%s\n\\chordsymb\n\n}\n\\new Voice {\n\\chordsymb\n}\n\\new Voice {\n\\bassnotes\n}\n>>\n\\version "2.10.33"\n',...
208
            song.filenametrunk, chord_string, bass_string, partial);
209
        fclose(fid);
210
        if verbose
211
            fprintf(1,'\\header{title = "%s"}\n%s}}\n%s\n}\n<<\n\\new ChordNames {\n\\set chordChanges = ##t\n%s\n\\chordsymb\n\n}\n\\new Voice {\n\\chordsymb\n}\n\\new Voice {\n\\bassnotes\n}\n>>\n\\version "2.10.33"\n',...
212
                song.filenametrunk, chord_string, bass_string, partial);
213
        end
214
end
215

    
216
function L = lilylength(beats)
217
switch beats
218
    case 1
219
        L = '4';
220
    case 2
221
        L = '2';
222
    case 3
223
        L = '2.';
224
    case 4
225
        L = '1';
226
end