~ubuntu-branches/ubuntu/oneiric/tuxguitar/oneiric

« back to all changes in this revision

Viewing changes to TuxGuitar-tef/src/org/herac/tuxguitar/io/tef/TESongImporter.java

  • Committer: Bazaar Package Importer
  • Author(s): Philippe Coval
  • Date: 2008-06-19 00:30:30 UTC
  • mto: (5.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20080619003030-h719szrhsngou7c6
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.herac.tuxguitar.io.tef;
 
2
 
 
3
import java.io.InputStream;
 
4
import java.util.Collections;
 
5
import java.util.Comparator;
 
6
import java.util.Iterator;
 
7
 
 
8
import org.herac.tuxguitar.io.base.TGFileFormat;
 
9
import org.herac.tuxguitar.io.base.TGFileFormatException;
 
10
import org.herac.tuxguitar.io.base.TGSongImporter;
 
11
import org.herac.tuxguitar.io.tef.base.TEChord;
 
12
import org.herac.tuxguitar.io.tef.base.TEComponent;
 
13
import org.herac.tuxguitar.io.tef.base.TEComponentChord;
 
14
import org.herac.tuxguitar.io.tef.base.TEComponentNote;
 
15
import org.herac.tuxguitar.io.tef.base.TESong;
 
16
import org.herac.tuxguitar.io.tef.base.TETimeSignature;
 
17
import org.herac.tuxguitar.io.tef.base.TETrack;
 
18
import org.herac.tuxguitar.song.factory.TGFactory;
 
19
import org.herac.tuxguitar.song.managers.TGSongManager;
 
20
import org.herac.tuxguitar.song.models.TGBeat;
 
21
import org.herac.tuxguitar.song.models.TGChannel;
 
22
import org.herac.tuxguitar.song.models.TGChord;
 
23
import org.herac.tuxguitar.song.models.TGDuration;
 
24
import org.herac.tuxguitar.song.models.TGMeasure;
 
25
import org.herac.tuxguitar.song.models.TGMeasureHeader;
 
26
import org.herac.tuxguitar.song.models.TGNote;
 
27
import org.herac.tuxguitar.song.models.TGSong;
 
28
import org.herac.tuxguitar.song.models.TGString;
 
29
import org.herac.tuxguitar.song.models.TGTimeSignature;
 
30
import org.herac.tuxguitar.song.models.TGTrack;
 
31
import org.herac.tuxguitar.song.models.TGTupleto;
 
32
 
 
33
public class TESongImporter implements TGSongImporter{
 
34
        
 
35
        private static final int[][] PERCUSSION_TUNINGS = new int[][]{
 
36
                new int[]{ 49, 41, 32 },
 
37
                new int[]{ 49, 51, 42, 50 },
 
38
                new int[]{ 49, 42, 50, 37, 32 },
 
39
                new int[]{ 49, 51, 42, 50, 45, 37 },
 
40
                new int[]{ 49, 51, 42, 50, 45, 37, 41 },
 
41
        };
 
42
        
 
43
        protected TGSongManager manager;
 
44
        
 
45
        public TESongImporter(){
 
46
                super();
 
47
        }
 
48
        
 
49
        public TGFileFormat getFileFormat() {
 
50
                return new TGFileFormat("Tef","*.tef");
 
51
        }
 
52
        
 
53
        public String getImportName() {
 
54
                return "Tef";
 
55
        }
 
56
        
 
57
        public boolean configure(boolean setDefaults){
 
58
                return true;
 
59
        }
 
60
        
 
61
        public TGSong importSong(TGFactory factory,InputStream stream) throws TGFileFormatException {
 
62
                try {
 
63
                        this.manager = new TGSongManager(factory);
 
64
                        return this.parseSong(new TEInputStream(stream).readSong());
 
65
                } catch (Exception e) {
 
66
                        e.printStackTrace();
 
67
                }
 
68
                throw new TGFileFormatException();
 
69
        }
 
70
        
 
71
        private TGSong parseSong(TESong song){
 
72
                this.sortComponents(song);
 
73
                this.newTGSong(song.getTracks().length,song.getMeasures(),song.getTempo().getValue());
 
74
                this.addMeasureValues(song);
 
75
                this.addTrackValues(song.getTracks());
 
76
                this.addComponents(song);
 
77
                
 
78
                return new TGSongAdjuster(this.manager).process();
 
79
        }
 
80
        
 
81
        private void newTGSong(int tracks,int measures,int tempo){
 
82
                this.manager.setSong(this.manager.newSong());
 
83
                this.manager.getFirstMeasureHeader().getTempo().setValue(tempo);
 
84
                
 
85
                while(this.manager.getSong().countTracks() < tracks){
 
86
                        this.manager.createTrack();
 
87
                }
 
88
                while(this.manager.getSong().countMeasureHeaders() < measures){
 
89
                        this.manager.addNewMeasureBeforeEnd();
 
90
                }
 
91
        }
 
92
        
 
93
        private void addMeasureValues(TESong song){
 
94
                TGTimeSignature timeSignature = this.manager.getFactory().newTimeSignature();
 
95
                for(int i = 0; i < this.manager.getSong().countMeasureHeaders(); i ++){
 
96
                        TGMeasureHeader header = this.manager.getSong().getMeasureHeader(i);
 
97
                        TETimeSignature ts = song.getTimeSignature(i);
 
98
                        timeSignature.setNumerator( ts.getNumerator() );
 
99
                        timeSignature.getDenominator().setValue( ts.getDenominator() );
 
100
                        this.manager.changeTimeSignature(header, timeSignature,false);
 
101
                }
 
102
        }
 
103
        
 
104
        private void addTrackValues(TETrack[] tracks){
 
105
                for(int i = 0; i < tracks.length; i ++){
 
106
                        TGTrack track = this.manager.getSong().getTrack(i);
 
107
                        track.getChannel().setVolume((short)((  (15 - tracks[i].getVolume()) * 127) / 15));
 
108
                        track.getChannel().setBalance((short)(( tracks[i].getPan() * 127) / 15));
 
109
                        track.getChannel().setInstrument((short)tracks[i].getInstrument());
 
110
                        if(tracks[i].isPercussion()){
 
111
                                TGChannel.setPercusionChannel(track.getChannel());
 
112
                        }
 
113
                        track.getStrings().clear();
 
114
                        int strings[] = tracks[i].getStrings();
 
115
                        
 
116
                        for(int j = 0; j < strings.length;j ++){
 
117
                                if(j >= 7){
 
118
                                        break;
 
119
                                }
 
120
                                TGString string = this.manager.getFactory().newString();
 
121
                                string.setNumber( (j + 1) );
 
122
                                string.setValue( (tracks[i].isPercussion() ?0:(96 - strings[j])) );
 
123
                                track.getStrings().add(string);
 
124
                        }
 
125
                }
 
126
        }
 
127
        
 
128
        private void addComponents(TESong song){
 
129
                Iterator it = song.getComponents().iterator();
 
130
                while(it.hasNext()){
 
131
                        TEComponent component = (TEComponent)it.next();
 
132
                        
 
133
                        if(component.getMeasure() >= 0 && component.getMeasure() < this.manager.getSong().countMeasureHeaders()){
 
134
                                int offset = 0;
 
135
                                TETrack[] tracks = song.getTracks();
 
136
                                for(int i = 0; i < tracks.length; i ++){
 
137
                                        int strings = tracks[i].getStrings().length;
 
138
                                        int string = (component.getString() - offset);
 
139
                                        if( string >= 0 && string <  strings && string < 7){
 
140
                                                TGTrack tgTrack = this.manager.getSong().getTrack(i);
 
141
                                                TGMeasure tgMeasure = tgTrack.getMeasure(component.getMeasure());
 
142
                                                if(component instanceof TEComponentNote){
 
143
                                                        addNote(tracks[i], (TEComponentNote)component,string,strings,tgMeasure);
 
144
                                                }
 
145
                                                else if(component instanceof TEComponentChord){
 
146
                                                        addChord(song.getChords(),(TEComponentChord)component,tgTrack,tgMeasure);
 
147
                                                }
 
148
                                        }
 
149
                                        offset += strings;
 
150
                                }
 
151
                        }
 
152
                }
 
153
        }
 
154
        
 
155
        private TGBeat getBeat(TGMeasure measure, long start){
 
156
                TGBeat beat = this.manager.getMeasureManager().getBeat(measure, start);
 
157
                if(beat == null){
 
158
                        beat = this.manager.getFactory().newBeat();
 
159
                        beat.setStart(start);
 
160
                        measure.addBeat(beat);
 
161
                }
 
162
                return beat;
 
163
        }
 
164
        
 
165
        private long getStart(TGDuration duration, TGMeasure measure,int position){
 
166
                float fixedPosition = position;
 
167
                if(duration != null && !duration.getTupleto().isEqual(TGTupleto.NORMAL)){
 
168
                        fixedPosition = (( fixedPosition - (fixedPosition % 64)) + ((((fixedPosition % 64) * 2) * 2) / 3) );
 
169
                }
 
170
                long start = ((long) (measure.getStart() + ( (fixedPosition * TGDuration.QUARTER_TIME)  / 64)) );
 
171
                
 
172
                return start;
 
173
        }
 
174
        
 
175
        private TGDuration getDuration(int duration){
 
176
                TGDuration tgDuration = this.manager.getFactory().newDuration();
 
177
                
 
178
                int value = TGDuration.WHOLE;
 
179
                for(int i = 0; i <  ( duration / 3); i ++){
 
180
                        value = (value * 2);
 
181
                }
 
182
                if( (duration % 3) == 1){
 
183
                        value = (value * 2);
 
184
                        tgDuration.setDotted(true);
 
185
                }
 
186
                else if( (duration % 3) == 2){
 
187
                        tgDuration.getTupleto().setEnters(3);
 
188
                        tgDuration.getTupleto().setTimes(2);
 
189
                }
 
190
                tgDuration.setValue(value);
 
191
                
 
192
                return tgDuration;
 
193
        }
 
194
        
 
195
        private void addNote(TETrack track,TEComponentNote note,int string,int strings,TGMeasure tgMeasure){
 
196
                int value = note.getFret();
 
197
                if(track.isPercussion() ){
 
198
                        int tuning = (Math.min( (strings - 2) ,(PERCUSSION_TUNINGS.length )) - 1);
 
199
                        if(string >= 0 && string < PERCUSSION_TUNINGS[tuning].length){
 
200
                                value += PERCUSSION_TUNINGS[tuning][string];
 
201
                        }
 
202
                }
 
203
                
 
204
                TGNote tgNote = this.manager.getFactory().newNote();
 
205
                tgNote.setString( string + 1 );
 
206
                tgNote.setValue( value );
 
207
                
 
208
                TGDuration tgDuration = getDuration( note.getDuration() );
 
209
                TGBeat tgBeat = getBeat(tgMeasure, getStart(tgDuration, tgMeasure, note.getPosition()));
 
210
                tgDuration.copy(tgBeat.getDuration());
 
211
                tgBeat.addNote(tgNote);
 
212
        }
 
213
        
 
214
        private void addChord(TEChord[] chords,TEComponentChord component,TGTrack tgTrack,TGMeasure tgMeasure){
 
215
                if(component.getChord() >= 0 && component.getChord() < chords.length){
 
216
                        TEChord chord = chords[component.getChord()];
 
217
                        byte[] strings = chord.getStrings();
 
218
                        
 
219
                        TGChord tgChord = this.manager.getFactory().newChord(tgTrack.stringCount());
 
220
                        tgChord.setName(chord.getName());
 
221
                        for(int i = 0; i < tgChord.countStrings(); i ++){
 
222
                                int value = ( ( i < strings.length )?strings[i]:-1 );
 
223
                                tgChord.addFretValue(i,value);
 
224
                        }
 
225
                        if(tgChord.countNotes() > 0){
 
226
                                TGBeat tgBeat = getBeat(tgMeasure, getStart(null, tgMeasure, component.getPosition()));
 
227
                                tgBeat.setChord(tgChord);
 
228
                        }
 
229
                }
 
230
        }
 
231
        
 
232
        public void sortComponents(TESong song){
 
233
                Collections.sort(song.getComponents(),new Comparator() {
 
234
                        public int compare(Object o1, Object o2) {
 
235
                                if(o1 instanceof TEComponent && o2 instanceof TEComponent){
 
236
                                        TEComponent c1 = (TEComponent)o1;
 
237
                                        TEComponent c2 = (TEComponent)o2;
 
238
                                        
 
239
                                        if ( c1.getMeasure() < c2.getMeasure() ){
 
240
                                                return -1;
 
241
                                        }
 
242
                                        if ( c1.getMeasure() > c2.getMeasure() ){
 
243
                                                return 1;
 
244
                                        }
 
245
                                        if ( c1.getPosition() < c2.getPosition() ){
 
246
                                                return -1;
 
247
                                        }
 
248
                                        if ( c1.getPosition() > c2.getPosition() ){
 
249
                                                return 1;
 
250
                                        }
 
251
                                        if(  ( c1 instanceof TEComponentNote ) && !( c2 instanceof TEComponentNote ) ){
 
252
                                                return -1;
 
253
                                        }
 
254
                                        if(  ( c2 instanceof TEComponentNote ) && !( c1 instanceof TEComponentNote ) ){
 
255
                                                return 1;
 
256
                                        }
 
257
                                }
 
258
                                return 0;
 
259
                        }
 
260
                });
 
261
        }
 
262
}
 
263
 
 
264
class TGSongAdjuster{
 
265
        
 
266
        protected TGSongManager manager;
 
267
        
 
268
        public TGSongAdjuster(TGSongManager manager){
 
269
                this.manager = manager;
 
270
        }
 
271
        
 
272
        public TGSong process(){
 
273
                Iterator tracks = this.manager.getSong().getTracks();
 
274
                while(tracks.hasNext()){
 
275
                        TGTrack track = (TGTrack)tracks.next();
 
276
                        Iterator measures = track.getMeasures();
 
277
                        while(measures.hasNext()){
 
278
                                TGMeasure measure = (TGMeasure)measures.next();
 
279
                                this.process(measure);
 
280
                        }
 
281
                }
 
282
                return this.manager.getSong();
 
283
        }
 
284
        
 
285
        public void process(TGMeasure measure){
 
286
                this.manager.getMeasureManager().orderBeats(measure);
 
287
                this.adjustBeats(measure);
 
288
        }
 
289
        
 
290
        public void adjustBeats(TGMeasure measure){
 
291
                TGBeat previous = null;
 
292
                boolean finish = true;
 
293
                
 
294
                long measureStart = measure.getStart();
 
295
                long measureEnd = (measureStart + measure.getLength());
 
296
                for(int i = 0;i < measure.countBeats();i++){
 
297
                        TGBeat beat = measure.getBeat( i );
 
298
                        long beatStart = beat.getStart();
 
299
                        long beatLength = beat.getDuration().getTime();
 
300
                        if(previous != null){
 
301
                                long previousStart = previous.getStart();
 
302
                                long previousLength = previous.getDuration().getTime();
 
303
                                
 
304
                                // check for a chord in a rest beat
 
305
                                if( beat.isRestBeat() && beat.isChordBeat() ){
 
306
                                        TGBeat candidate = null;
 
307
                                        TGBeat next = this.manager.getMeasureManager().getFirstBeat( measure.getBeats() );
 
308
                                        while( next != null ){
 
309
                                                if( candidate != null && next.getStart() > beat.getStart() ){
 
310
                                                        break;
 
311
                                                }
 
312
                                                if(! next.isRestBeat() && !next.isChordBeat() ){
 
313
                                                        candidate = next;
 
314
                                                }
 
315
                                                next = this.manager.getMeasureManager().getNextBeat(measure.getBeats(), next);
 
316
                                        }
 
317
                                        if(candidate != null){
 
318
                                                candidate.setChord( beat.getChord() );
 
319
                                        }
 
320
                                        measure.removeBeat(beat);
 
321
                                        finish = false;
 
322
                                        break;
 
323
                                }
 
324
                                
 
325
                                // check the duration
 
326
                                if(previousStart < beatStart && (previousStart + previousLength) > beatStart){
 
327
                                        if(beat.isRestBeat()){
 
328
                                                measure.removeBeat(beat);
 
329
                                                finish = false;
 
330
                                                break;
 
331
                                        }
 
332
                                        TGDuration duration = TGDuration.fromTime(this.manager.getFactory(), (beatStart - previousStart) );
 
333
                                        duration.copy( previous.getDuration() );
 
334
                                }
 
335
                        }
 
336
                        if( (beatStart + beatLength) > measureEnd ){
 
337
                                if(beat.isRestBeat()){
 
338
                                        measure.removeBeat(beat);
 
339
                                        finish = false;
 
340
                                        break;
 
341
                                }
 
342
                                TGDuration duration = TGDuration.fromTime(this.manager.getFactory(), (measureEnd - beatStart) );
 
343
                                duration.copy( beat.getDuration() );
 
344
                        }
 
345
                        previous = beat;
 
346
                }
 
347
                if(!finish){
 
348
                        adjustBeats(measure);
 
349
                }
 
350
        }
 
351
}