1
package org.herac.tuxguitar.io.tef;
3
import java.io.InputStream;
4
import java.util.Collections;
5
import java.util.Comparator;
6
import java.util.Iterator;
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;
33
public class TESongImporter implements TGSongImporter{
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 },
43
protected TGSongManager manager;
45
public TESongImporter(){
49
public TGFileFormat getFileFormat() {
50
return new TGFileFormat("Tef","*.tef");
53
public String getImportName() {
57
public boolean configure(boolean setDefaults){
61
public TGSong importSong(TGFactory factory,InputStream stream) throws TGFileFormatException {
63
this.manager = new TGSongManager(factory);
64
return this.parseSong(new TEInputStream(stream).readSong());
65
} catch (Exception e) {
68
throw new TGFileFormatException();
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);
78
return new TGSongAdjuster(this.manager).process();
81
private void newTGSong(int tracks,int measures,int tempo){
82
this.manager.setSong(this.manager.newSong());
83
this.manager.getFirstMeasureHeader().getTempo().setValue(tempo);
85
while(this.manager.getSong().countTracks() < tracks){
86
this.manager.createTrack();
88
while(this.manager.getSong().countMeasureHeaders() < measures){
89
this.manager.addNewMeasureBeforeEnd();
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);
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());
113
track.getStrings().clear();
114
int strings[] = tracks[i].getStrings();
116
for(int j = 0; j < strings.length;j ++){
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);
128
private void addComponents(TESong song){
129
Iterator it = song.getComponents().iterator();
131
TEComponent component = (TEComponent)it.next();
133
if(component.getMeasure() >= 0 && component.getMeasure() < this.manager.getSong().countMeasureHeaders()){
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);
145
else if(component instanceof TEComponentChord){
146
addChord(song.getChords(),(TEComponentChord)component,tgTrack,tgMeasure);
155
private TGBeat getBeat(TGMeasure measure, long start){
156
TGBeat beat = this.manager.getMeasureManager().getBeat(measure, start);
158
beat = this.manager.getFactory().newBeat();
159
beat.setStart(start);
160
measure.addBeat(beat);
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) );
170
long start = ((long) (measure.getStart() + ( (fixedPosition * TGDuration.QUARTER_TIME) / 64)) );
175
private TGDuration getDuration(int duration){
176
TGDuration tgDuration = this.manager.getFactory().newDuration();
178
int value = TGDuration.WHOLE;
179
for(int i = 0; i < ( duration / 3); i ++){
182
if( (duration % 3) == 1){
184
tgDuration.setDotted(true);
186
else if( (duration % 3) == 2){
187
tgDuration.getTupleto().setEnters(3);
188
tgDuration.getTupleto().setTimes(2);
190
tgDuration.setValue(value);
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];
204
TGNote tgNote = this.manager.getFactory().newNote();
205
tgNote.setString( string + 1 );
206
tgNote.setValue( value );
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);
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();
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);
225
if(tgChord.countNotes() > 0){
226
TGBeat tgBeat = getBeat(tgMeasure, getStart(null, tgMeasure, component.getPosition()));
227
tgBeat.setChord(tgChord);
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;
239
if ( c1.getMeasure() < c2.getMeasure() ){
242
if ( c1.getMeasure() > c2.getMeasure() ){
245
if ( c1.getPosition() < c2.getPosition() ){
248
if ( c1.getPosition() > c2.getPosition() ){
251
if( ( c1 instanceof TEComponentNote ) && !( c2 instanceof TEComponentNote ) ){
254
if( ( c2 instanceof TEComponentNote ) && !( c1 instanceof TEComponentNote ) ){
264
class TGSongAdjuster{
266
protected TGSongManager manager;
268
public TGSongAdjuster(TGSongManager manager){
269
this.manager = manager;
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);
282
return this.manager.getSong();
285
public void process(TGMeasure measure){
286
this.manager.getMeasureManager().orderBeats(measure);
287
this.adjustBeats(measure);
290
public void adjustBeats(TGMeasure measure){
291
TGBeat previous = null;
292
boolean finish = true;
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();
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() ){
312
if(! next.isRestBeat() && !next.isChordBeat() ){
315
next = this.manager.getMeasureManager().getNextBeat(measure.getBeats(), next);
317
if(candidate != null){
318
candidate.setChord( beat.getChord() );
320
measure.removeBeat(beat);
325
// check the duration
326
if(previousStart < beatStart && (previousStart + previousLength) > beatStart){
327
if(beat.isRestBeat()){
328
measure.removeBeat(beat);
332
TGDuration duration = TGDuration.fromTime(this.manager.getFactory(), (beatStart - previousStart) );
333
duration.copy( previous.getDuration() );
336
if( (beatStart + beatLength) > measureEnd ){
337
if(beat.isRestBeat()){
338
measure.removeBeat(beat);
342
TGDuration duration = TGDuration.fromTime(this.manager.getFactory(), (measureEnd - beatStart) );
343
duration.copy( beat.getDuration() );
348
adjustBeats(measure);