1 package org.herac.tuxguitar.song.managers; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.Iterator; 7 import java.util.List; 8 9 import org.herac.tuxguitar.song.factory.TGFactory; 10 import org.herac.tuxguitar.song.models.TGBeat; 11 import org.herac.tuxguitar.song.models.TGChord; 12 import org.herac.tuxguitar.song.models.TGDuration; 13 import org.herac.tuxguitar.song.models.TGMeasure; 14 import org.herac.tuxguitar.song.models.TGNote; 15 import org.herac.tuxguitar.song.models.TGString; 16 import org.herac.tuxguitar.song.models.TGStroke; 17 import org.herac.tuxguitar.song.models.TGText; 18 import org.herac.tuxguitar.song.models.TGTrack; 19 import org.herac.tuxguitar.song.models.TGVoice; 20 import org.herac.tuxguitar.song.models.effects.TGEffectBend; 21 import org.herac.tuxguitar.song.models.effects.TGEffectGrace; 22 import org.herac.tuxguitar.song.models.effects.TGEffectHarmonic; 23 import org.herac.tuxguitar.song.models.effects.TGEffectTremoloBar; 24 import org.herac.tuxguitar.song.models.effects.TGEffectTremoloPicking; 25 import org.herac.tuxguitar.song.models.effects.TGEffectTrill; 26 27 public class TGMeasureManager { 28 private TGSongManager songManager; 29 TGMeasureManager(TGSongManager songManager)30 public TGMeasureManager(TGSongManager songManager){ 31 this.songManager = songManager; 32 } 33 getSongManager()34 public TGSongManager getSongManager(){ 35 return this.songManager; 36 } 37 orderBeats(TGMeasure measure)38 public void orderBeats(TGMeasure measure){ 39 for(int i = 0;i < measure.countBeats();i++){ 40 TGBeat minBeat = null; 41 for(int j = i;j < measure.countBeats();j++){ 42 TGBeat beat = measure.getBeat(j); 43 if(minBeat == null || beat.getStart() < minBeat.getStart()){ 44 minBeat = beat; 45 } 46 } 47 measure.moveBeat(i, minBeat); 48 } 49 } 50 51 /** 52 * Agrega un beat al compas 53 */ addBeat(TGMeasure measure,TGBeat beat)54 public void addBeat(TGMeasure measure,TGBeat beat){ 55 //Verifico si entra en el compas 56 //if(validateDuration(measure,beat,false,false)){ 57 58 //Agrego el beat 59 measure.addBeat(beat); 60 //} 61 } 62 removeBeat(TGBeat beat)63 public void removeBeat(TGBeat beat){ 64 beat.getMeasure().removeBeat(beat); 65 } 66 removeBeat(TGMeasure measure,long start,boolean moveNextComponents)67 public void removeBeat(TGMeasure measure,long start,boolean moveNextComponents){ 68 TGBeat beat = getBeat(measure, start); 69 if(beat != null){ 70 removeBeat(beat, moveNextComponents); 71 } 72 } 73 74 /** 75 * Elimina un silencio del compas. 76 * si se asigna moveNextComponents = true. los componentes que le siguen 77 * se moveran para completar el espacio vacio que dejo el silencio 78 */ removeBeat(TGBeat beat,boolean moveNextBeats)79 public void removeBeat(TGBeat beat,boolean moveNextBeats){ 80 TGMeasure measure = beat.getMeasure(); 81 82 removeBeat(beat); 83 if(moveNextBeats){ 84 TGDuration minimumDuration = getMinimumDuration(beat); 85 long start = beat.getStart(); 86 long length = (minimumDuration != null ? minimumDuration.getTime() : 0); 87 88 TGBeat next = getNextBeat(measure.getBeats(),beat); 89 if(next != null){ 90 length = next.getStart() - start; 91 } 92 moveBeatsInMeasure(beat.getMeasure(),start + length,-length, minimumDuration); 93 } 94 } 95 removeEmptyBeats(TGMeasure measure)96 public void removeEmptyBeats(TGMeasure measure){ 97 List beats = new ArrayList(); 98 Iterator it = measure.getBeats().iterator(); 99 while(it.hasNext()){ 100 TGBeat beat = (TGBeat)it.next(); 101 boolean emptyBeat = true; 102 for( int v = 0; v < beat.countVoices() ; v ++){ 103 TGVoice voice = beat.getVoice( v ); 104 if(!voice.isEmpty()){ 105 emptyBeat = false; 106 } 107 } 108 if( emptyBeat ){ 109 beats.add( beat ); 110 } 111 } 112 113 it = beats.iterator(); 114 while(it.hasNext()){ 115 TGBeat beat = (TGBeat)it.next(); 116 this.removeBeat( beat ); 117 } 118 } 119 removeBeatsBeforeEnd(TGMeasure measure,long fromStart)120 public void removeBeatsBeforeEnd(TGMeasure measure,long fromStart){ 121 List beats = getBeatsBeforeEnd( measure.getBeats() , fromStart); 122 Iterator it = beats.iterator(); 123 while(it.hasNext()){ 124 TGBeat beat = (TGBeat) it.next(); 125 removeBeat(beat); 126 } 127 } 128 removeBeatsBeetween(TGMeasure measure,long p1, long p2)129 public void removeBeatsBeetween(TGMeasure measure,long p1, long p2){ 130 List beats = getBeatsBeetween( measure.getBeats() , p1, p2 ); 131 Iterator it = beats.iterator(); 132 while(it.hasNext()){ 133 TGBeat beat = (TGBeat) it.next(); 134 removeBeat(beat); 135 } 136 } 137 addNote(TGMeasure measure,long start, TGNote note, TGDuration duration, int voice)138 public void addNote(TGMeasure measure,long start, TGNote note, TGDuration duration, int voice){ 139 TGBeat beat = getBeat(measure, start); 140 if(beat != null){ 141 addNote(beat, note, duration, voice); 142 } 143 } 144 addNote(TGBeat beat, TGNote note, TGDuration duration, int voice)145 public void addNote(TGBeat beat, TGNote note, TGDuration duration, int voice){ 146 addNote(beat, note, duration, beat.getStart(),voice); 147 } 148 addNote(TGBeat beat, TGNote note, TGDuration duration, long start, int voice)149 public void addNote(TGBeat beat, TGNote note, TGDuration duration, long start, int voice){ 150 boolean emptyVoice = beat.getVoice( voice ).isEmpty(); 151 if( emptyVoice ){ 152 beat.getVoice( voice ).setEmpty( false ); 153 } 154 155 //Verifico si entra en el compas 156 if(validateDuration(beat.getMeasure(),beat, voice, duration,true,true)){ 157 //Borro lo que haya en la misma posicion 158 for( int v = 0 ; v < beat.countVoices() ; v ++ ){ 159 removeNote(beat.getMeasure(),beat.getStart(), v, note.getString(), false); 160 } 161 162 duration.copy(beat.getVoice(voice).getDuration()); 163 164 //trato de agregar un silencio similar al lado 165 tryChangeSilenceAfter(beat.getMeasure(),beat.getVoice(voice)); 166 167 // Despues de cambiar la duracion, verifico si hay un beat mejor para agregar la nota. 168 TGVoice realVoice = beat.getVoice(voice); 169 if(realVoice.getBeat().getStart() != start){ 170 TGVoice beatIn = getVoiceIn(realVoice.getBeat().getMeasure(), start, voice); 171 if( beatIn != null ) { 172 realVoice = beatIn; 173 } 174 } 175 realVoice.addNote(note); 176 }else{ 177 beat.getVoice( voice ).setEmpty( emptyVoice ); 178 } 179 } 180 removeNote(TGNote note, boolean checkRestBeat)181 public void removeNote(TGNote note, boolean checkRestBeat){ 182 //note.getVoice().removeNote(note); 183 TGVoice voice = note.getVoice(); 184 if( voice != null ){ 185 // Remove the note 186 voice.removeNote(note); 187 188 TGBeat beat = voice.getBeat(); 189 if(checkRestBeat && beat.isRestBeat()){ 190 //Anulo un posible stroke 191 beat.getStroke().setDirection( TGStroke.STROKE_NONE ); 192 193 //Borro un posible acorde 194 if( beat.getMeasure() != null ){ 195 removeChord(beat.getMeasure(), beat.getStart()); 196 } 197 } 198 } 199 } 200 removeNote(TGNote note)201 public void removeNote(TGNote note){ 202 this.removeNote(note, true); 203 } 204 removeNote(TGMeasure measure,long start, int voiceIndex,int string)205 public void removeNote(TGMeasure measure,long start, int voiceIndex,int string){ 206 this.removeNote(measure, start, voiceIndex, string, true); 207 } 208 209 /** 210 * Elimina los Componentes que empiecen en Start y esten en la misma cuerda 211 * Si hay un Silencio lo borra sin importar la cuerda 212 */ removeNote(TGMeasure measure,long start, int voiceIndex,int string, boolean checkRestBeat)213 public void removeNote(TGMeasure measure,long start, int voiceIndex,int string, boolean checkRestBeat){ 214 TGBeat beat = getBeat(measure, start); 215 if(beat != null){ 216 TGVoice voice = beat.getVoice(voiceIndex); 217 for( int i = 0; i < voice.countNotes(); i ++){ 218 TGNote note = voice.getNote(i); 219 if(note.getString() == string){ 220 removeNote(note , checkRestBeat); 221 return; 222 } 223 } 224 } 225 } 226 removeNotesAfterString(TGMeasure measure,int string)227 public void removeNotesAfterString(TGMeasure measure,int string){ 228 List notesToRemove = new ArrayList(); 229 230 Iterator beats = measure.getBeats().iterator(); 231 while(beats.hasNext()){ 232 TGBeat beat = (TGBeat)beats.next(); 233 for(int v = 0; v < beat.countVoices(); v ++){ 234 TGVoice voice = beat.getVoice( v ); 235 Iterator notes = voice.getNotes().iterator(); 236 while(notes.hasNext()){ 237 TGNote note = (TGNote)notes.next(); 238 if(note.getString() > string){ 239 notesToRemove.add(note); 240 } 241 } 242 } 243 } 244 Iterator it = notesToRemove.iterator(); 245 while(it.hasNext()){ 246 TGNote note = (TGNote)it.next(); 247 removeNote(note); 248 } 249 } 250 251 /** 252 * Retorna Todas las Notas en la posicion Start 253 */ getNotes(TGMeasure measure,long start)254 public List getNotes(TGMeasure measure,long start){ 255 List notes = new ArrayList(); 256 257 TGBeat beat = getBeat(measure, start); 258 if(beat != null){ 259 for(int v = 0 ; v < beat.countVoices(); v ++){ 260 TGVoice voice = beat.getVoice( v ); 261 Iterator it = voice.getNotes().iterator(); 262 while(it.hasNext()){ 263 TGNote note = (TGNote)it.next(); 264 notes.add(note); 265 } 266 } 267 } 268 return notes; 269 } 270 271 /** 272 * Retorna Todas las Notas en el pulso 273 */ getNotes(TGBeat beat)274 public List getNotes(TGBeat beat){ 275 List notes = new ArrayList(); 276 277 if(beat != null){ 278 for(int v = 0 ; v < beat.countVoices(); v ++){ 279 TGVoice voice = beat.getVoice( v ); 280 if( !voice.isEmpty() && !voice.isRestVoice() ){ 281 Iterator it = voice.getNotes().iterator(); 282 while(it.hasNext()){ 283 TGNote note = (TGNote)it.next(); 284 notes.add(note); 285 } 286 } 287 } 288 } 289 return notes; 290 } 291 292 /** 293 * Retorna la Nota en la posicion y cuerda 294 */ getNote(TGMeasure measure,long start,int string)295 public TGNote getNote(TGMeasure measure,long start,int string) { 296 TGBeat beat = getBeat(measure, start); 297 if(beat != null){ 298 return getNote(beat, string); 299 } 300 return null; 301 } 302 303 /** 304 * Retorna la Nota en la cuerda 305 */ getNote(TGBeat beat,int string)306 public TGNote getNote(TGBeat beat,int string) { 307 for( int v = 0; v < beat.countVoices(); v ++){ 308 TGVoice voice = beat.getVoice(v); 309 if(!voice.isEmpty()){ 310 TGNote note = getNote(voice, string); 311 if(note != null){ 312 return note; 313 } 314 } 315 } 316 return null; 317 } 318 getNote(TGVoice voice,int string)319 public TGNote getNote(TGVoice voice,int string) { 320 Iterator it = voice.getNotes().iterator(); 321 while(it.hasNext()){ 322 TGNote note = (TGNote)it.next(); 323 if (note.getString() == string) { 324 return note; 325 } 326 } 327 return null; 328 } 329 getPreviousNote(TGMeasure measure,long start, int voiceIndex, int string)330 public TGNote getPreviousNote(TGMeasure measure,long start, int voiceIndex, int string) { 331 TGBeat beat = getBeat(measure, start); 332 if( beat != null ){ 333 TGBeat previous = getPreviousBeat(measure.getBeats(),beat); 334 while(previous != null){ 335 TGVoice voice = previous.getVoice(voiceIndex); 336 if(!voice.isEmpty()){ 337 for (int i = 0; i < voice.countNotes(); i++) { 338 TGNote current = voice.getNote(i); 339 if (current.getString() == string) { 340 return current; 341 } 342 } 343 } 344 previous = getPreviousBeat(measure.getBeats(),previous); 345 } 346 } 347 return null; 348 } 349 getNextNote(TGMeasure measure,long start, int voiceIndex, int string)350 public TGNote getNextNote(TGMeasure measure,long start, int voiceIndex, int string) { 351 TGBeat beat = getBeat(measure, start); 352 if( beat != null ){ 353 TGBeat next = getNextBeat(measure.getBeats(),beat); 354 while(next != null){ 355 TGVoice voice = next.getVoice(voiceIndex); 356 if(!voice.isEmpty()){ 357 for (int i = 0; i < voice.countNotes(); i++) { 358 TGNote current = voice.getNote(i); 359 if (current.getString() == string) { 360 return current; 361 } 362 } 363 } 364 next = getNextBeat(measure.getBeats(),next); 365 } 366 } 367 return null; 368 } 369 getMinimumDuration(TGBeat beat)370 public TGDuration getMinimumDuration(TGBeat beat){ 371 TGDuration minimumDuration = null; 372 for(int v = 0; v < beat.countVoices(); v ++){ 373 TGVoice voice = beat.getVoice( v ); 374 if( !voice.isEmpty() ){ 375 if(minimumDuration == null || voice.getDuration().getTime() < minimumDuration.getTime()){ 376 minimumDuration = voice.getDuration(); 377 } 378 } 379 } 380 return minimumDuration; 381 } 382 getBeat(TGTrack track,long start)383 public TGBeat getBeat(TGTrack track,long start) { 384 Iterator measures = track.getMeasures(); 385 while( measures.hasNext() ){ 386 TGMeasure measure = (TGMeasure)measures.next(); 387 Iterator beats = measure.getBeats().iterator(); 388 while(beats.hasNext()){ 389 TGBeat beat = (TGBeat)beats.next(); 390 if (beat.getStart() == start) { 391 return beat; 392 } 393 } 394 } 395 return null; 396 } 397 /** 398 * Retorna las Nota en la posicion y cuerda 399 */ getBeat(TGMeasure measure,long start)400 public TGBeat getBeat(TGMeasure measure,long start) { 401 Iterator it = measure.getBeats().iterator(); 402 while(it.hasNext()){ 403 TGBeat beat = (TGBeat)it.next(); 404 if (beat.getStart() == start) { 405 return beat; 406 } 407 } 408 return null; 409 } 410 411 /** 412 * Retorna las Nota en la posicion y cuerda 413 */ getBeatIn(TGMeasure measure,long start)414 public TGBeat getBeatIn(TGMeasure measure,long start) { 415 TGBeat beatIn = null; 416 Iterator it = measure.getBeats().iterator(); 417 while(it.hasNext()){ 418 TGBeat beat = (TGBeat)it.next(); 419 TGDuration duration = getMinimumDuration(beat); 420 if (beat.getStart() <= start && (beat.getStart() + duration.getTime() > start)) { 421 if(beatIn == null || beat.getStart() > beatIn.getStart()){ 422 beatIn = beat; 423 } 424 } 425 } 426 return beatIn; 427 } 428 429 /** 430 * Retorna las Nota en la posicion y cuerda 431 */ getVoiceIn(TGMeasure measure,long start, int voiceIndex)432 public TGVoice getVoiceIn(TGMeasure measure,long start, int voiceIndex) { 433 Iterator it = measure.getBeats().iterator(); 434 while(it.hasNext()){ 435 TGBeat beat = (TGBeat)it.next(); 436 TGVoice voice = beat.getVoice(voiceIndex); 437 if (!voice.isEmpty() && beat.getStart() <= start && (beat.getStart() + voice.getDuration().getTime() > start)) { 438 return voice; 439 } 440 } 441 return null; 442 } 443 444 /** 445 * Retorna el Siguiente Componente 446 */ getNextBeat(List beats,TGBeat beat)447 public TGBeat getNextBeat(List beats,TGBeat beat) { 448 TGBeat next = null; 449 for (int i = 0; i < beats.size(); i++) { 450 TGBeat current = (TGBeat) beats.get(i); 451 if (current.getStart() > beat.getStart()) { 452 if (next == null) { 453 next = current; 454 } else if (current.getStart() < next.getStart()) { 455 next = current; 456 } /*else if (current.getStart() == next.getStart() && current.getDuration().getTime() <= next.getDuration().getTime()) { 457 next = current; 458 }*/ 459 } 460 } 461 return next; 462 } 463 464 /** 465 * Retorna el Componente Anterior 466 */ getPreviousBeat(List beats,TGBeat beat)467 public TGBeat getPreviousBeat(List beats,TGBeat beat) { 468 TGBeat previous = null; 469 for (int i = 0; i < beats.size(); i++) { 470 TGBeat current = (TGBeat) beats.get(i); 471 if (current.getStart() < beat.getStart()) { 472 if (previous == null) { 473 previous = current; 474 } else if (current.getStart() > previous.getStart()) { 475 previous = current; 476 } /*else if (current.getStart() == previous.getStart() && current.getDuration().getTime() <= previous.getDuration().getTime()) { 477 previous = current; 478 }*/ 479 } 480 } 481 return previous; 482 } 483 484 /** 485 * Retorna el Primer Componente 486 */ getFirstBeat(List components)487 public TGBeat getFirstBeat(List components) { 488 TGBeat first = null; 489 for (int i = 0; i < components.size(); i++) { 490 TGBeat component = (TGBeat) components.get(i); 491 if (first == null || component.getStart() < first.getStart()) { 492 first = component; 493 } 494 } 495 return first; 496 } 497 498 /** 499 * Retorna el Ultimo Componente 500 */ getLastBeat(List components)501 public TGBeat getLastBeat(List components) { 502 TGBeat last = null; 503 for (int i = 0; i < components.size(); i++) { 504 TGBeat component = (TGBeat) components.get(i); 505 if (last == null || last.getStart() < component.getStart()) { 506 last = component; 507 } 508 } 509 return last; 510 } 511 512 /** 513 * Retorna el Siguiente Componente 514 */ 515 /* 516 public TGBeat getNextRestBeat(List beats,TGBeat component) { 517 TGBeat next = getNextBeat(beats, component); 518 while(next != null && !next.isRestBeat()){ 519 next = getNextBeat(beats, next); 520 } 521 return next; 522 } 523 */ 524 525 /** 526 * Retorna Todos los desde Start hasta el final del compas 527 */ getBeatsBeforeEnd(List beats,long fromStart)528 public List getBeatsBeforeEnd(List beats,long fromStart) { 529 List list = new ArrayList(); 530 Iterator it = beats.iterator(); 531 while(it.hasNext()){ 532 TGBeat current = (TGBeat)it.next(); 533 if (current.getStart() >= fromStart) { 534 list.add(current); 535 } 536 } 537 return list; 538 } 539 getBeatsBeetween(List beats,long p1, long p2)540 public List getBeatsBeetween(List beats,long p1, long p2) { 541 List list = new ArrayList(); 542 Iterator it = beats.iterator(); 543 while(it.hasNext()){ 544 TGBeat current = (TGBeat)it.next(); 545 if (current.getStart() >= p1 && current.getStart() < p2 ) { 546 list.add(current); 547 } 548 } 549 return list; 550 } 551 locateBeat( TGBeat beat, TGTrack track , boolean newMeasureAlsoForRestBeats)552 public void locateBeat( TGBeat beat, TGTrack track , boolean newMeasureAlsoForRestBeats) { 553 if( beat.getMeasure() != null ){ 554 beat.getMeasure().removeBeat(beat); 555 beat.setMeasure(null); 556 } 557 TGMeasure newMeasure = getSongManager().getTrackManager().getMeasureAt(track, beat.getStart() ); 558 if( newMeasure == null ){ 559 boolean createNewMeasure = newMeasureAlsoForRestBeats; 560 if( !createNewMeasure ){ 561 createNewMeasure = ( !beat.isRestBeat() || beat.isTextBeat() ); 562 } 563 if( createNewMeasure ){ 564 565 while( newMeasure == null && beat.getStart() >= TGDuration.QUARTER_TIME){ 566 getSongManager().addNewMeasureBeforeEnd(); 567 newMeasure = getSongManager().getTrackManager().getMeasureAt(track, beat.getStart() ); 568 } 569 } 570 } 571 if( newMeasure != null ){ 572 long mStart = newMeasure.getStart(); 573 long mLength = newMeasure.getLength(); 574 long bStart = beat.getStart(); 575 for( int v = 0 ; v < beat.countVoices() ; v ++ ){ 576 TGVoice voice = beat.getVoice( v ); 577 long vDuration = voice.getDuration().getTime(); 578 if(!voice.isEmpty() && (bStart + vDuration) > (mStart + mLength) ){ 579 long vTiedDuration = ( (bStart + vDuration) - (mStart + mLength) ); 580 vDuration -= vTiedDuration; 581 if( vDuration > 0 ){ 582 TGDuration duration = TGDuration.fromTime(getSongManager().getFactory(), vDuration); 583 if( duration != null ){ 584 duration.copy( voice.getDuration() ); 585 } 586 } 587 if( vTiedDuration > 0 ) { 588 TGDuration newVoiceDuration = TGDuration.fromTime(getSongManager().getFactory(), vTiedDuration); 589 if( newVoiceDuration != null ){ 590 long newBeatStart = (bStart + vDuration); 591 TGBeat newBeat = getBeat(track, newBeatStart); 592 if( newBeat == null ){ 593 newBeat = getSongManager().getFactory().newBeat(); 594 newBeat.setStart( (bStart + vDuration) ); 595 } 596 TGVoice newVoice = newBeat.getVoice( v ); 597 for( int n = 0 ; n < voice.countNotes() ; n ++ ){ 598 TGNote note = voice.getNote( n ); 599 TGNote newNote = getSongManager().getFactory().newNote(); 600 newNote.setTiedNote( true ); 601 newNote.setValue( note.getValue() ); 602 newNote.setString( note.getString() ); 603 newNote.setVelocity( note.getVelocity() ); 604 newVoice.addNote( newNote ); 605 } 606 newVoice.setEmpty( false ); 607 newVoiceDuration.copy( newVoice.getDuration() ); 608 609 locateBeat(newBeat, track, newMeasureAlsoForRestBeats); 610 } 611 } 612 } 613 } 614 615 newMeasure.addBeat(beat); 616 } 617 } 618 moveOutOfBoundsBeatsToNewMeasure(TGMeasure measure)619 public void moveOutOfBoundsBeatsToNewMeasure(TGMeasure measure){ 620 this.moveOutOfBoundsBeatsToNewMeasure(measure, true ); 621 } 622 moveOutOfBoundsBeatsToNewMeasure(TGMeasure measure, boolean newMeasureAlsoForRestBeats )623 public void moveOutOfBoundsBeatsToNewMeasure(TGMeasure measure, boolean newMeasureAlsoForRestBeats ){ 624 List beats = new ArrayList(); 625 long mStart = measure.getStart(); 626 long mLength = measure.getLength(); 627 for( int i = 0; i < measure.countBeats() ; i ++ ){ 628 TGBeat beat = measure.getBeat( i ); 629 if( beat.getStart() < mStart || beat.getStart() >= mStart + mLength ){ 630 beats.add( beat ); 631 } 632 else{ 633 long bStart = beat.getStart(); 634 for( int v = 0 ; v < beat.countVoices() ; v ++ ){ 635 TGVoice voice = beat.getVoice( v ); 636 long vDuration = voice.getDuration().getTime(); 637 if(!voice.isEmpty() && (bStart + vDuration) > (mStart + mLength) ){ 638 beats.add( beat ); 639 } 640 } 641 } 642 } 643 while( !beats.isEmpty() ){ 644 TGBeat beat = (TGBeat)beats.get( 0 ); 645 if( beat.getMeasure() != null ){ 646 beat.getMeasure().removeBeat(beat); 647 beat.setMeasure(null); 648 } 649 this.locateBeat(beat, measure.getTrack(), newMeasureAlsoForRestBeats); 650 651 beats.remove(0); 652 } 653 } 654 moveBeatsInMeasure(TGMeasure measure,long start,long theMove, TGDuration fillDuration)655 public boolean moveBeatsInMeasure(TGMeasure measure,long start,long theMove, TGDuration fillDuration){ 656 if( theMove == 0 ){ 657 return false; 658 } 659 boolean success = true; 660 long measureStart = measure.getStart(); 661 long measureEnd = (measureStart + measure.getLength()); 662 663 // Muevo los componentes 664 List beatsToMove = getBeatsBeforeEnd(measure.getBeats(),start); 665 moveBeats(beatsToMove,theMove); 666 667 if(success){ 668 List beatsToRemove = new ArrayList(); 669 List beats = new ArrayList(measure.getBeats()); 670 671 // Verifica los silencios a eliminar al principio del compas 672 TGBeat first = getFirstBeat( beats ); 673 while(first != null && first.isRestBeat() && !first.isTextBeat() && first.getStart() < measureStart){ 674 beats.remove(first); 675 beatsToRemove.add(first); 676 first = getNextBeat( beats,first); 677 } 678 679 // Verifica los silencios a eliminar al final del compas 680 TGBeat last = getLastBeat(beats); 681 TGDuration lastDuration = (last != null ? getMinimumDuration(last) : null); 682 while(last != null && lastDuration != null && last.isRestBeat() && !last.isTextBeat() && (last.getStart() + lastDuration.getTime() ) > measureEnd ){ 683 beats.remove(last); 684 beatsToRemove.add(last); 685 last = getPreviousBeat(beats,last); 686 lastDuration = (last != null ? getMinimumDuration(last) : null); 687 } 688 689 // Si el primer o ultimo componente, quedan fuera del compas, entonces el movimiento no es satisfactorio 690 if(first != null && last != null && lastDuration != null){ 691 if(first.getStart() < measureStart || (last.getStart() + lastDuration.getTime()) > measureEnd){ 692 success = false; 693 } 694 } 695 696 if(success){ 697 // Elimino los silencios que quedaron fuera del compas. 698 Iterator it = beatsToRemove.iterator(); 699 while( it.hasNext() ){ 700 TGBeat beat = (TGBeat)it.next(); 701 removeBeat(beat); 702 } 703 704 // Se crean silencios en los espacios vacios, si la duracion fue especificada. 705 if( fillDuration != null ){ 706 if( theMove < 0 ){ 707 last = getLastBeat(measure.getBeats()); 708 lastDuration = (last != null ? getMinimumDuration(last) : null); 709 TGBeat beat = getSongManager().getFactory().newBeat(); 710 beat.setStart( (last != null && lastDuration != null ? last.getStart() + lastDuration.getTime() : start ) ); 711 if( (beat.getStart() + fillDuration.getTime()) <= measureEnd ){ 712 for(int v = 0; v < beat.countVoices(); v ++){ 713 TGVoice voice = beat.getVoice(v); 714 voice.setEmpty(false); 715 fillDuration.copy( voice.getDuration() ); 716 } 717 addBeat(measure, beat ); 718 } 719 } 720 else{ 721 first = getFirstBeat(getBeatsBeforeEnd(measure.getBeats(),start)); 722 TGBeat beat = getSongManager().getFactory().newBeat(); 723 beat.setStart( start ); 724 if( (beat.getStart() + fillDuration.getTime()) <= (first != null ?first.getStart() : measureEnd ) ){ 725 for(int v = 0; v < beat.countVoices(); v ++){ 726 TGVoice voice = beat.getVoice(v); 727 voice.setEmpty(false); 728 fillDuration.copy( voice.getDuration() ); 729 } 730 addBeat(measure, beat ); 731 } 732 } 733 } 734 } 735 } 736 737 // Si el movimiento no es satisfactorio, regreso todo como estaba 738 if(! success ){ 739 moveBeats(beatsToMove,-theMove); 740 } 741 742 return success; 743 } 744 moveAllBeats(TGMeasure measure,long theMove)745 public void moveAllBeats(TGMeasure measure,long theMove){ 746 moveBeats(measure.getBeats(),theMove); 747 } 748 moveBeats(TGMeasure measure, long start, long theMove)749 public void moveBeats(TGMeasure measure, long start, long theMove){ 750 moveBeats(getBeatsBeforeEnd(measure.getBeats(), start),theMove); 751 } 752 753 /** 754 * Mueve los componentes 755 */ moveBeats(List beats,long theMove)756 private void moveBeats(List beats,long theMove){ 757 Iterator it = beats.iterator(); 758 while(it.hasNext()){ 759 TGBeat beat = (TGBeat)it.next(); 760 moveBeat(beat,theMove); 761 } 762 } 763 764 /** 765 * Mueve el componente 766 */ moveBeat(TGBeat beat,long theMove)767 private void moveBeat(TGBeat beat,long theMove){ 768 //obtengo el start viejo 769 long start = beat.getStart(); 770 771 //asigno el nuevo start 772 beat.setStart(start + theMove); 773 } 774 cleanBeat(TGBeat beat)775 public void cleanBeat(TGBeat beat){ 776 beat.getStroke().setDirection( TGStroke.STROKE_NONE ); 777 if( beat.getText() != null ){ 778 beat.removeText(); 779 } 780 if( beat.getChord() != null){ 781 beat.removeChord(); 782 } 783 784 this.cleanBeatNotes(beat); 785 } 786 cleanBeatNotes(TGBeat beat)787 public void cleanBeatNotes(TGBeat beat){ 788 for(int v = 0; v < beat.countVoices(); v ++){ 789 cleanVoiceNotes(beat.getVoice( v )); 790 } 791 } 792 cleanBeatNotes(TGMeasure measure, long start)793 public void cleanBeatNotes(TGMeasure measure, long start){ 794 TGBeat beat = getBeat(measure, start); 795 if(beat != null){ 796 cleanBeatNotes(beat); 797 } 798 } 799 cleanVoiceNotes(TGVoice voice)800 public void cleanVoiceNotes(TGVoice voice){ 801 if(!voice.isEmpty()){ 802 while(voice.countNotes() > 0 ){ 803 TGNote note = voice.getNote(0); 804 removeNote(note); 805 } 806 } 807 } 808 /** 809 * Agrega el acorde al compas 810 */ addChord(TGMeasure measure,long start, TGChord chord)811 public void addChord(TGMeasure measure,long start, TGChord chord){ 812 TGBeat beat = getBeat(measure, start); 813 if(beat != null){ 814 addChord(beat, chord); 815 } 816 } 817 818 /** 819 * Agrega el acorde al compas 820 */ addChord(TGBeat beat,TGChord chord)821 public void addChord(TGBeat beat,TGChord chord){ 822 beat.removeChord(); 823 beat.setChord(chord); 824 } 825 826 /** 827 * Retorna el acorde en la position 828 */ getChord(TGMeasure measure,long start)829 public TGChord getChord(TGMeasure measure,long start) { 830 TGBeat beat = getBeat(measure, start); 831 if(beat != null){ 832 return beat.getChord(); 833 } 834 return null; 835 } 836 837 /** 838 * Borra el acorde en la position 839 */ removeChord(TGMeasure measure,long start)840 public void removeChord(TGMeasure measure,long start) { 841 TGBeat beat = getBeat(measure, start); 842 if(beat != null){ 843 beat.removeChord(); 844 } 845 } 846 847 /** 848 * Agrega el texto al compas 849 */ addText(TGMeasure measure,long start, TGText text)850 public void addText(TGMeasure measure,long start, TGText text){ 851 TGBeat beat = getBeat(measure, start); 852 if(beat != null){ 853 addText(beat, text); 854 } 855 } 856 857 /** 858 * Agrega el texto al compas 859 */ addText(TGBeat beat,TGText text)860 public void addText(TGBeat beat,TGText text){ 861 beat.removeText(); 862 if(!text.isEmpty()){ 863 beat.setText(text); 864 } 865 } 866 867 /** 868 * Retorna el texto en la position 869 */ getText(TGMeasure measure,long start)870 public TGText getText(TGMeasure measure,long start) { 871 TGBeat beat = getBeat(measure, start); 872 if(beat != null){ 873 return beat.getText(); 874 } 875 return null; 876 } 877 878 /** 879 * Borra el texto en el pulso 880 */ removeText(TGBeat beat)881 public void removeText(TGBeat beat){ 882 beat.removeText(); 883 } 884 885 /** 886 * Borra el texto en la position 887 */ removeText(TGMeasure measure,long start)888 public boolean removeText(TGMeasure measure,long start) { 889 TGBeat beat = getBeat(measure, start); 890 if(beat != null){ 891 removeText(beat); 892 return true; 893 } 894 return false; 895 } 896 cleanMeasure(TGMeasure measure)897 public void cleanMeasure(TGMeasure measure){ 898 while( measure.countBeats() > 0){ 899 removeBeat( measure.getBeat(0)); 900 } 901 } 902 903 /** 904 * Mueve la nota a la cuerda de arriba 905 */ shiftNoteUp(TGMeasure measure,long start,int string)906 public int shiftNoteUp(TGMeasure measure,long start,int string){ 907 return shiftNote(measure, start, string,-1); 908 } 909 910 /** 911 * Mueve la nota a la cuerda de abajo 912 */ shiftNoteDown(TGMeasure measure,long start,int string)913 public int shiftNoteDown(TGMeasure measure,long start,int string){ 914 return shiftNote(measure, start, string,1); 915 } 916 917 /** 918 * Mueve la nota a la siguiente cuerda 919 */ shiftNote(TGMeasure measure,long start,int string,int move)920 private int shiftNote(TGMeasure measure,long start,int string,int move){ 921 TGNote note = getNote(measure,start,string); 922 if(note != null){ 923 int nextStringNumber = (note.getString() + move); 924 while(getNote(measure,start,nextStringNumber) != null){ 925 nextStringNumber += move; 926 } 927 if(nextStringNumber >= 1 && nextStringNumber <= measure.getTrack().stringCount()){ 928 TGString currentString = measure.getTrack().getString(note.getString()); 929 TGString nextString = measure.getTrack().getString(nextStringNumber); 930 int noteValue = (note.getValue() + currentString.getValue()); 931 if(noteValue >= nextString.getValue() && ((nextString.getValue() + 30 > noteValue) || measure.getTrack().isPercussionTrack()) ){ 932 note.setValue(noteValue - nextString.getValue()); 933 note.setString(nextString.getNumber()); 934 return note.getString(); 935 } 936 } 937 } 938 return 0; 939 } 940 941 /** 942 * Mueve la nota 1 semitono arriba 943 */ moveSemitoneUp(TGMeasure measure,long start,int string)944 public boolean moveSemitoneUp(TGMeasure measure,long start,int string){ 945 return moveSemitone(measure, start, string,1); 946 } 947 948 /** 949 * Mueve la nota 1 semitono abajo 950 */ moveSemitoneDown(TGMeasure measure,long start,int string)951 public boolean moveSemitoneDown(TGMeasure measure,long start,int string){ 952 return moveSemitone(measure, start, string,-1); 953 } 954 955 /** 956 * Mueve la nota los semitonos indicados 957 */ moveSemitone(TGMeasure measure,long start,int string,int semitones)958 private boolean moveSemitone(TGMeasure measure,long start,int string,int semitones){ 959 TGNote note = getNote(measure,start,string); 960 if(note != null){ 961 int newValue = (note.getValue() + semitones); 962 if(newValue >= 0 && (newValue < 30 || measure.getTrack().isPercussionTrack()) ){ 963 note.setValue(newValue); 964 return true; 965 } 966 } 967 return false; 968 } 969 970 /** 971 * Set the beat stroke 972 */ setStroke(TGMeasure measure,long start,int value, int direction)973 public boolean setStroke(TGMeasure measure,long start,int value, int direction){ 974 TGBeat beat = getBeat(measure, start); 975 if( beat != null ){ 976 beat.getStroke().setValue(value); 977 beat.getStroke().setDirection(direction); 978 return true; 979 } 980 return false; 981 } 982 983 /** 984 * Verifica si el componente se puede insertar en el compas. 985 * si no puede, con la opcion removeSilences, verifica si el motivo por el 986 * cual no entra es que lo siguen silencios. de ser asi los borra. 987 */ 988 /* 989 public boolean validateDuration(TGMeasure measure,TGBeat beat,boolean moveNextComponents, boolean setCurrentDuration){ 990 return validateDuration(measure, beat, beat.getDuration(),moveNextComponents, setCurrentDuration); 991 } 992 993 994 public boolean validateDuration(TGMeasure measure,TGBeat beat,TGDuration duration,boolean moveNextBeats, boolean setCurrentDuration){ 995 int errorMargin = 10; 996 this.orderBeats(measure); 997 long measureStart = measure.getStart(); 998 long measureEnd = (measureStart + measure.getLength()); 999 long beatStart = beat.getStart(); 1000 long beatLength = duration.getTime(); 1001 long beatEnd = (beatStart + beatLength); 1002 List beats = measure.getBeats(); 1003 1004 //Verifico si hay un beat en el mismo lugar, y comparo las duraciones. 1005 TGBeat currentBeat = getBeat(measure,beatStart); 1006 if(currentBeat != null && beatLength <= currentBeat.getDuration().getTime()){ 1007 return true; 1008 } 1009 1010 //Verifico si hay lugar para meter el beat 1011 TGBeat nextComponent = getNextBeat(beats,beat); 1012 if(currentBeat == null){ 1013 if(nextComponent == null && beatEnd < (measureEnd + errorMargin)){ 1014 return true; 1015 } 1016 if(nextComponent != null && beatEnd < (nextComponent.getStart() + errorMargin)){ 1017 return true; 1018 } 1019 } 1020 1021 // Busca si hay espacio disponible de silencios entre el componente y el el que le sigue.. si encuentra lo borra 1022 if(nextComponent != null && nextComponent.isRestBeat()){ 1023 //Verifico si lo que sigue es un silencio. y lo borro 1024 long nextBeatEnd = 0; 1025 List nextBeats = new ArrayList(); 1026 while(nextComponent != null && nextComponent.isRestBeat() && !nextComponent.isTextBeat()){ 1027 nextBeats.add(nextComponent); 1028 nextBeatEnd = nextComponent.getStart() + nextComponent.getDuration().getTime(); 1029 nextComponent = getNextBeat(beats,nextComponent); 1030 } 1031 if(nextComponent == null){ 1032 nextBeatEnd = measureEnd; 1033 }else if(!nextComponent.isRestBeat() || nextComponent.isTextBeat()){ 1034 nextBeatEnd = nextComponent.getStart(); 1035 } 1036 if(beatEnd <= (nextBeatEnd + errorMargin)){ 1037 while(!nextBeats.isEmpty()){ 1038 TGBeat currBeat = (TGBeat)nextBeats.get(0); 1039 nextBeats.remove(currBeat); 1040 removeBeat(currBeat, false); 1041 } 1042 return true; 1043 } 1044 } 1045 1046 // Busca si hay espacio disponible de silencios entre el componente y el final.. si encuentra mueve todo 1047 if(moveNextBeats){ 1048 nextComponent = getNextBeat(beats,beat); 1049 if(nextComponent != null){ 1050 long requiredLength = (beatLength - (nextComponent.getStart() - beatStart)); 1051 long nextSilenceLength = 0; 1052 TGBeat nextRestBeat = getNextRestBeat(beats, beat); 1053 while(nextRestBeat != null && !nextRestBeat.isTextBeat()){ 1054 nextSilenceLength += nextRestBeat.getDuration().getTime(); 1055 nextRestBeat = getNextRestBeat(beats, nextRestBeat); 1056 } 1057 1058 if(requiredLength <= (nextSilenceLength + errorMargin)){ 1059 beats = getBeatsBeforeEnd(measure.getBeats(),nextComponent.getStart()); 1060 while(!beats.isEmpty()){ 1061 TGBeat current = (TGBeat)beats.get(0); 1062 if(current.isRestBeat() && !current.isTextBeat()){ 1063 requiredLength -= current.getDuration().getTime(); 1064 removeBeat(current, false); 1065 }else if(requiredLength > 0){ 1066 moveBeat(current,requiredLength); 1067 } 1068 beats.remove(0); 1069 } 1070 return true; 1071 } 1072 } 1073 } 1074 1075 // como ultimo intento, asigno la duracion de cualquier componente existente en el lugar. 1076 if(setCurrentDuration && currentBeat != null){ 1077 currentBeat.getDuration().copy( duration ); 1078 return true; 1079 } 1080 return false; 1081 } 1082 */ 1083 /** 1084 * Cambia la Duracion del pulso. 1085 */ 1086 /* 1087 @Deprecated 1088 public void changeDuration(TGMeasure measure,TGBeat beat,TGDuration duration,boolean tryMove){ 1089 //obtengo la duracion vieja 1090 TGDuration oldDuration = beat.getDuration().clone(getSongManager().getFactory()); 1091 1092 //si no entra vuelvo a dejar la vieja 1093 if(validateDuration(measure,beat, duration,tryMove,false)){ 1094 //se lo agrego a todas las notas en la posicion 1095 beat.setDuration(duration.clone(getSongManager().getFactory())); 1096 1097 //trato de agregar un silencio similar al lado 1098 tryChangeSilenceAfter(measure,beat); 1099 }else{ 1100 oldDuration.copy( beat.getDuration() ); 1101 } 1102 } 1103 */ 1104 /* 1105 @Deprecated 1106 public void tryChangeSilenceAfter(TGMeasure measure,TGBeat beat){ 1107 autoCompleteSilences(measure); 1108 TGBeat nextBeat = getNextBeat(measure.getBeats(),beat); 1109 1110 long beatEnd = (beat.getStart() + beat.getDuration().getTime()); 1111 long measureEnd = (measure.getStart() + measure.getLength()); 1112 if(nextBeat != null && nextBeat.isRestBeat() && beatEnd <= measureEnd){ 1113 long theMove = (getRealStart(measure,beatEnd)) - getRealStart(measure,nextBeat.getStart()); 1114 if((nextBeat.getStart() + theMove) < measureEnd && (nextBeat.getStart() + nextBeat.getDuration().getTime() + theMove) <= measureEnd){ 1115 moveBeat(nextBeat,theMove); 1116 changeDuration(measure,nextBeat,beat.getDuration().clone(getSongManager().getFactory()),false); 1117 } 1118 } 1119 } 1120 */ 1121 /** 1122 * Calcula si hay espacios libres. y crea nuevos silencios 1123 */ 1124 /* 1125 public void autoCompleteSilences(TGMeasure measure){ 1126 List components = measure.getBeats(); 1127 1128 for( int i = 0; i < TGBeat.MAX_VOICES; i ++ ){ 1129 //TGBeat component = getFirstBeat(components); 1130 TGVoice component = getFirstVoice(components, i); 1131 1132 long start = measure.getStart(); 1133 long end = 0; 1134 long diff = 0; 1135 1136 while (component != null) { 1137 end = component.getBeat().getStart() + component.getDuration().getTime(); 1138 if(component.getBeat().getStart() > start){ 1139 diff = component.getBeat().getStart() - start; 1140 if(diff > 0){ 1141 createSilences(measure,start,diff, i); 1142 } 1143 } 1144 start = end; 1145 component = getNextVoice(components,component.getBeat(), i); 1146 } 1147 end = measure.getStart() + measure.getLength(); 1148 diff = end - start; 1149 if(diff > 0){ 1150 createSilences(measure,start,diff, i); 1151 } 1152 } 1153 } 1154 */ autoCompleteSilences(TGMeasure measure)1155 public void autoCompleteSilences(TGMeasure measure){ 1156 TGBeat beat = getFirstBeat( measure.getBeats() ); 1157 if( beat == null ){ 1158 createSilences(measure, measure.getStart(), measure.getLength(), 0); 1159 return; 1160 } 1161 for( int v = 0 ; v < TGBeat.MAX_VOICES ; v ++ ){ 1162 TGVoice voice = getFirstVoice( measure.getBeats() , v ); 1163 if( voice != null && voice.getBeat().getStart() > measure.getStart() ){ 1164 createSilences(measure, measure.getStart(), (voice.getBeat().getStart() - measure.getStart()), v); 1165 } 1166 } 1167 1168 long[] start = new long[beat.countVoices()]; 1169 long[] uncompletedLength = new long[beat.countVoices()]; 1170 for( int v = 0; v < uncompletedLength.length; v ++ ){ 1171 start[v] = 0; 1172 uncompletedLength[v] = 0; 1173 } 1174 1175 while (beat != null) { 1176 for( int v = 0; v < beat.countVoices(); v ++ ){ 1177 TGVoice voice = beat.getVoice( v ); 1178 if( !voice.isEmpty() ){ 1179 long voiceEnd = (beat.getStart() + voice.getDuration().getTime()); 1180 long nextPosition = (measure.getStart() + measure.getLength()); 1181 1182 TGVoice nextVoice = getNextVoice(measure.getBeats(), beat, voice.getIndex()); 1183 if(nextVoice != null){ 1184 nextPosition = nextVoice.getBeat().getStart(); 1185 } 1186 if( voiceEnd < nextPosition ){ 1187 start[v] = voiceEnd; 1188 uncompletedLength[v] = (nextPosition - voiceEnd); 1189 } 1190 } 1191 } 1192 1193 for( int v = 0; v < uncompletedLength.length; v ++ ){ 1194 if( uncompletedLength[v] > 0 ){ 1195 createSilences(measure,start[v],uncompletedLength[v], v); 1196 } 1197 start[v] = 0; 1198 uncompletedLength[v] = 0; 1199 } 1200 beat = getNextBeat(measure.getBeats(), beat ); 1201 } 1202 } 1203 1204 /** 1205 * Crea Silencios temporarios en base a length 1206 */ createSilences(TGMeasure measure,long start,long length, int voiceIndex)1207 private void createSilences(TGMeasure measure,long start,long length, int voiceIndex){ 1208 long nextStart = start; 1209 List durations = createDurations(getSongManager().getFactory(),length); 1210 Iterator it = durations.iterator(); 1211 while(it.hasNext()){ 1212 TGDuration duration = (TGDuration)it.next(); 1213 1214 boolean isNew = false; 1215 long beatStart = getRealStart(measure, nextStart); 1216 TGBeat beat = getBeat(measure, beatStart); 1217 if( beat == null ){ 1218 beat = getSongManager().getFactory().newBeat(); 1219 beat.setStart( getRealStart(measure, nextStart) ); 1220 isNew = true; 1221 } 1222 //TGBeat beat = getSongManager().getFactory().newBeat(); 1223 //beat.setStart( getRealStart(measure, nextStart) ); 1224 1225 TGVoice voice = beat.getVoice(voiceIndex); 1226 voice.setEmpty(false); 1227 duration.copy(voice.getDuration()); 1228 1229 if( isNew ){ 1230 addBeat(measure,beat); 1231 } 1232 // temporal 1233 //beat.getVoice(0).setEmpty(false); 1234 //beat.getVoice(1).setEmpty(false); 1235 // /temporal 1236 1237 nextStart += duration.getTime(); 1238 } 1239 } 1240 getRealStart(TGMeasure measure,long currStart)1241 public long getRealStart(TGMeasure measure,long currStart){ 1242 long beatLength = TGSongManager.getDivisionLength(measure.getHeader()); 1243 long start = currStart; 1244 boolean startBeat = (start % beatLength == 0); 1245 if(!startBeat){ 1246 TGDuration minDuration = getSongManager().getFactory().newDuration(); 1247 minDuration.setValue(TGDuration.SIXTY_FOURTH); 1248 minDuration.getDivision().setEnters(3); 1249 minDuration.getDivision().setTimes(2); 1250 for(int i = 0;i < minDuration.getTime();i++){ 1251 start ++; 1252 startBeat = (start % beatLength == 0); 1253 if(startBeat){ 1254 break; 1255 } 1256 } 1257 if(!startBeat){ 1258 start = currStart; 1259 } 1260 } 1261 return start; 1262 } 1263 1264 /** 1265 * Liga la nota 1266 */ changeTieNote(TGMeasure measure,long start,int string)1267 public void changeTieNote(TGMeasure measure,long start,int string){ 1268 TGNote note = getNote(measure,start,string); 1269 if(note != null){ 1270 changeTieNote(note); 1271 } 1272 } 1273 1274 /** 1275 * Liga la nota 1276 */ changeTieNote(TGNote note)1277 public void changeTieNote(TGNote note){ 1278 note.setTiedNote(!note.isTiedNote()); 1279 note.getEffect().setDeadNote(false); 1280 } 1281 1282 /** 1283 * Agrega un vibrato 1284 */ changeVibratoNote(TGMeasure measure,long start,int string)1285 public void changeVibratoNote(TGMeasure measure,long start,int string){ 1286 TGNote note = getNote(measure,start,string); 1287 if(note != null){ 1288 note.getEffect().setVibrato(!note.getEffect().isVibrato()); 1289 } 1290 } 1291 1292 /** 1293 * Agrega una nota muerta 1294 */ changeDeadNote(TGNote note)1295 public void changeDeadNote(TGNote note){ 1296 note.getEffect().setDeadNote(!note.getEffect().isDeadNote()); 1297 note.setTiedNote(false); 1298 } 1299 1300 /** 1301 * Agrega un slide 1302 */ changeSlideNote(TGMeasure measure,long start,int string)1303 public void changeSlideNote(TGMeasure measure,long start,int string){ 1304 TGNote note = getNote(measure,start,string); 1305 if(note != null){ 1306 note.getEffect().setSlide(!note.getEffect().isSlide()); 1307 } 1308 } 1309 1310 /** 1311 * Agrega un hammer 1312 */ changeHammerNote(TGMeasure measure,long start,int string)1313 public void changeHammerNote(TGMeasure measure,long start,int string){ 1314 TGNote note = getNote(measure,start,string); 1315 if(note != null){ 1316 note.getEffect().setHammer(!note.getEffect().isHammer()); 1317 } 1318 } 1319 1320 /** 1321 * Agrega un palm-mute 1322 */ changePalmMute(TGMeasure measure,long start,int string)1323 public void changePalmMute(TGMeasure measure,long start,int string){ 1324 TGNote note = getNote(measure,start,string); 1325 if(note != null){ 1326 note.getEffect().setPalmMute(!note.getEffect().isPalmMute()); 1327 } 1328 } 1329 1330 /** 1331 * Agrega un staccato 1332 */ changeStaccato(TGMeasure measure,long start,int string)1333 public void changeStaccato(TGMeasure measure,long start,int string){ 1334 TGNote note = getNote(measure,start,string); 1335 if(note != null){ 1336 note.getEffect().setStaccato(!note.getEffect().isStaccato()); 1337 } 1338 } 1339 1340 /** 1341 * Agrega un tapping 1342 */ changeTapping(TGMeasure measure,long start,int string)1343 public void changeTapping(TGMeasure measure,long start,int string){ 1344 TGNote note = getNote(measure,start,string); 1345 if(note != null){ 1346 note.getEffect().setTapping(!note.getEffect().isTapping()); 1347 } 1348 } 1349 1350 /** 1351 * Agrega un slapping 1352 */ changeSlapping(TGMeasure measure,long start,int string)1353 public void changeSlapping(TGMeasure measure,long start,int string){ 1354 TGNote note = getNote(measure,start,string); 1355 if(note != null){ 1356 note.getEffect().setSlapping(!note.getEffect().isSlapping()); 1357 } 1358 } 1359 1360 /** 1361 * Agrega un popping 1362 */ changePopping(TGMeasure measure,long start,int string)1363 public void changePopping(TGMeasure measure,long start,int string){ 1364 TGNote note = getNote(measure,start,string); 1365 if(note != null){ 1366 note.getEffect().setPopping(!note.getEffect().isPopping()); 1367 } 1368 } 1369 1370 /** 1371 * Agrega un bend 1372 */ changeBendNote(TGMeasure measure,long start,int string,TGEffectBend bend)1373 public void changeBendNote(TGMeasure measure,long start,int string,TGEffectBend bend){ 1374 TGNote note = getNote(measure,start,string); 1375 if(note != null){ 1376 note.getEffect().setBend(bend); 1377 } 1378 } 1379 1380 /** 1381 * Agrega un tremoloBar 1382 */ changeTremoloBar(TGMeasure measure,long start,int string,TGEffectTremoloBar tremoloBar)1383 public void changeTremoloBar(TGMeasure measure,long start,int string,TGEffectTremoloBar tremoloBar){ 1384 TGNote note = getNote(measure,start,string); 1385 if(note != null){ 1386 note.getEffect().setTremoloBar(tremoloBar); 1387 } 1388 } 1389 1390 /** 1391 * Agrega un GhostNote 1392 */ changeGhostNote(TGMeasure measure,long start,int string)1393 public void changeGhostNote(TGMeasure measure,long start,int string){ 1394 TGNote note = getNote(measure,start,string); 1395 if(note != null){ 1396 note.getEffect().setGhostNote(!note.getEffect().isGhostNote()); 1397 } 1398 } 1399 1400 /** 1401 * Agrega un AccentuatedNote 1402 */ changeAccentuatedNote(TGMeasure measure,long start,int string)1403 public void changeAccentuatedNote(TGMeasure measure,long start,int string){ 1404 TGNote note = getNote(measure,start,string); 1405 if(note != null){ 1406 note.getEffect().setAccentuatedNote(!note.getEffect().isAccentuatedNote()); 1407 } 1408 } 1409 1410 /** 1411 * Agrega un GhostNote 1412 */ changeHeavyAccentuatedNote(TGMeasure measure,long start,int string)1413 public void changeHeavyAccentuatedNote(TGMeasure measure,long start,int string){ 1414 TGNote note = getNote(measure,start,string); 1415 if(note != null){ 1416 note.getEffect().setHeavyAccentuatedNote(!note.getEffect().isHeavyAccentuatedNote()); 1417 } 1418 } 1419 1420 /** 1421 * Agrega un harmonic 1422 */ changeHarmonicNote(TGMeasure measure,long start,int string,TGEffectHarmonic harmonic)1423 public void changeHarmonicNote(TGMeasure measure,long start,int string,TGEffectHarmonic harmonic){ 1424 TGNote note = getNote(measure,start,string); 1425 if(note != null){ 1426 note.getEffect().setHarmonic(harmonic); 1427 } 1428 } 1429 1430 /** 1431 * Agrega un grace 1432 */ changeGraceNote(TGMeasure measure,long start,int string,TGEffectGrace grace)1433 public void changeGraceNote(TGMeasure measure,long start,int string,TGEffectGrace grace){ 1434 TGNote note = getNote(measure,start,string); 1435 if(note != null){ 1436 note.getEffect().setGrace(grace); 1437 } 1438 } 1439 1440 /** 1441 * Agrega un trill 1442 */ changeTrillNote(TGMeasure measure,long start,int string,TGEffectTrill trill)1443 public void changeTrillNote(TGMeasure measure,long start,int string,TGEffectTrill trill){ 1444 TGNote note = getNote(measure,start,string); 1445 if(note != null){ 1446 note.getEffect().setTrill(trill); 1447 } 1448 } 1449 1450 /** 1451 * Agrega un tremolo picking 1452 */ changeTremoloPicking(TGMeasure measure,long start,int string,TGEffectTremoloPicking tremoloPicking)1453 public void changeTremoloPicking(TGMeasure measure,long start,int string,TGEffectTremoloPicking tremoloPicking){ 1454 TGNote note = getNote(measure,start,string); 1455 if(note != null){ 1456 note.getEffect().setTremoloPicking(tremoloPicking); 1457 } 1458 } 1459 1460 /** 1461 * Agrega un fadeIn 1462 */ changeFadeIn(TGMeasure measure,long start,int string)1463 public void changeFadeIn(TGMeasure measure,long start,int string){ 1464 TGNote note = getNote(measure,start,string); 1465 if(note != null){ 1466 note.getEffect().setFadeIn(!note.getEffect().isFadeIn()); 1467 } 1468 } 1469 1470 /** 1471 * Cambia el Velocity 1472 */ changeVelocity(int velocity,TGMeasure measure,long start,int string)1473 public void changeVelocity(int velocity,TGMeasure measure,long start,int string){ 1474 TGNote note = getNote(measure,start,string); 1475 if(note != null){ 1476 note.setVelocity(velocity); 1477 } 1478 } 1479 /* 1480 public static List createDurations(TGFactory factory,long time){ 1481 List durations = new ArrayList(); 1482 TGDuration tempDuration = factory.newDuration(); 1483 tempDuration.setValue(TGDuration.WHOLE); 1484 tempDuration.setDotted(true); 1485 long tempTime = time; 1486 boolean finish = false; 1487 while(!finish){ 1488 long currentDurationTime = tempDuration.getTime(); 1489 if(currentDurationTime <= tempTime){ 1490 durations.add(tempDuration.clone(factory)); 1491 tempTime -= currentDurationTime; 1492 }else{ 1493 if(tempDuration.isDotted()){ 1494 tempDuration.setDotted(false); 1495 }else{ 1496 tempDuration.setValue(tempDuration.getValue() * 2); 1497 tempDuration.setDotted(true); 1498 } 1499 } 1500 if(tempDuration.getValue() > TGDuration.SIXTY_FOURTH){ 1501 finish = true; 1502 } 1503 } 1504 return durations; 1505 } 1506 */ 1507 createDurations(TGFactory factory,long time)1508 public static List createDurations(TGFactory factory,long time){ 1509 List durations = new ArrayList(); 1510 TGDuration minimum = factory.newDuration(); 1511 minimum.setValue(TGDuration.SIXTY_FOURTH); 1512 minimum.setDotted(false); 1513 minimum.setDoubleDotted(false); 1514 minimum.getDivision().setEnters(3); 1515 minimum.getDivision().setTimes(2); 1516 1517 long missingTime = time; 1518 while( missingTime > minimum.getTime() ){ 1519 TGDuration duration = TGDuration.fromTime(factory, missingTime, minimum , 10); 1520 durations.add( duration.clone(factory) ); 1521 missingTime -= duration.getTime(); 1522 } 1523 return durations; 1524 } 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 /** 1540 * Retorna el Siguiente Componente 1541 */ getNextVoice(List beats,TGBeat beat, int index)1542 public TGVoice getNextVoice(List beats,TGBeat beat, int index) { 1543 TGVoice next = null; 1544 for (int i = 0; i < beats.size(); i++) { 1545 TGBeat current = (TGBeat) beats.get(i); 1546 if (current.getStart() > beat.getStart() && !current.getVoice(index).isEmpty()) { 1547 if (next == null) { 1548 next = current.getVoice(index); 1549 } else if (current.getStart() < next.getBeat().getStart()) { 1550 next = current.getVoice(index); 1551 } /*else if (current.getStart() == next.getBeat().getStart() && current.getDuration().getTime() <= next.getDuration().getTime()) { 1552 next = current.getVoice(index); 1553 }*/ 1554 } 1555 } 1556 return next; 1557 } 1558 1559 /** 1560 * Retorna el Componente Anterior 1561 */ getPreviousVoice(List beats,TGBeat beat, int index)1562 public TGVoice getPreviousVoice(List beats,TGBeat beat, int index) { 1563 TGVoice previous = null; 1564 for (int i = 0; i < beats.size(); i++) { 1565 TGBeat current = (TGBeat) beats.get(i); 1566 if (current.getStart() < beat.getStart() && !current.getVoice(index).isEmpty()) { 1567 if (previous == null) { 1568 previous = current.getVoice(index); 1569 } else if (current.getStart() > previous.getBeat().getStart()) { 1570 previous = current.getVoice(index); 1571 } /*else if (current.getStart() == previous.getBeat().getStart() && current.getDuration().getTime() <= previous.getDuration().getTime()) { 1572 previous = current.getVoice(index); 1573 }*/ 1574 } 1575 } 1576 return previous; 1577 } 1578 1579 /** 1580 * Retorna el Primer Componente 1581 */ getFirstVoice(List beats, int index)1582 public TGVoice getFirstVoice(List beats, int index) { 1583 TGVoice first = null; 1584 for (int i = 0; i < beats.size(); i++) { 1585 TGBeat current = (TGBeat) beats.get(i); 1586 if ( (first == null || current.getStart() < first.getBeat().getStart() ) && !current.getVoice(index).isEmpty()) { 1587 first = current.getVoice(index); 1588 } 1589 } 1590 return first; 1591 } 1592 1593 /** 1594 * Retorna el Ultimo Componente 1595 */ getLastVoice(List beats, int index)1596 public TGVoice getLastVoice(List beats, int index) { 1597 TGVoice last = null; 1598 for (int i = 0; i < beats.size(); i++) { 1599 TGBeat current = (TGBeat) beats.get(i); 1600 if ( (last == null || last.getBeat().getStart() < current.getStart()) && !current.getVoice(index).isEmpty() ) { 1601 last = current.getVoice(index); 1602 } 1603 } 1604 return last; 1605 } 1606 1607 1608 /** 1609 * Retorna el Siguiente Componente 1610 */ getNextRestVoice(List beats,TGVoice voice)1611 public TGVoice getNextRestVoice(List beats,TGVoice voice) { 1612 TGVoice next = getNextVoice(beats, voice.getBeat(), voice.getIndex()); 1613 while(next != null && !next.isRestVoice()){ 1614 next = getNextVoice(beats, next.getBeat(), next.getIndex()); 1615 } 1616 return next; 1617 } 1618 getVoicesBeforeEnd(List beats,long fromStart, int index)1619 public List getVoicesBeforeEnd(List beats,long fromStart, int index) { 1620 List list = new ArrayList(); 1621 Iterator it = beats.iterator(); 1622 while(it.hasNext()){ 1623 TGBeat beat = (TGBeat)it.next(); 1624 if (beat.getStart() >= fromStart) { 1625 TGVoice voice = beat.getVoice(index); 1626 if(!voice.isEmpty()){ 1627 list.add(voice); 1628 } 1629 } 1630 } 1631 return list; 1632 } 1633 addSilence(TGMeasure measure,long start, TGDuration duration, int voice)1634 public void addSilence(TGMeasure measure,long start, TGDuration duration, int voice){ 1635 TGBeat beat = getBeat(measure, start); 1636 if(beat != null){ 1637 addSilence(beat, duration, voice); 1638 } 1639 } 1640 addSilence(TGBeat beat, TGDuration duration, int voice)1641 public void addSilence(TGBeat beat, TGDuration duration, int voice){ 1642 addSilence(beat, duration, beat.getStart(),voice); 1643 } 1644 addSilence(TGBeat beat, TGDuration duration, long start, int voice)1645 public void addSilence(TGBeat beat, TGDuration duration, long start, int voice){ 1646 boolean emptyVoice = beat.getVoice( voice ).isEmpty(); 1647 if( emptyVoice ){ 1648 beat.getVoice( voice ).setEmpty( false ); 1649 } 1650 1651 //Verifico si entra en el compas 1652 if(validateDuration(beat.getMeasure(),beat, voice, duration,true,true)){ 1653 //Borro lo que haya en la misma posicion 1654 //removeNote(beat.getMeasure(),beat.getStart(),voice, note.getString()); 1655 1656 duration.copy(beat.getVoice(voice).getDuration()); 1657 1658 //trato de agregar un silencio similar al lado 1659 tryChangeSilenceAfter(beat.getMeasure(),beat.getVoice(voice)); 1660 1661 // Despues de cambiar la duracion, verifico si hay un beat mejor para agregar el silencio. 1662 TGVoice realVoice = beat.getVoice(voice); 1663 if(realVoice.getBeat().getStart() != start){ 1664 TGVoice beatIn = getVoiceIn(realVoice.getBeat().getMeasure(), start, voice); 1665 if( beatIn != null ) { 1666 realVoice = beatIn; 1667 } 1668 } 1669 realVoice.setEmpty(false); 1670 }else{ 1671 beat.getVoice( voice ).setEmpty( emptyVoice ); 1672 } 1673 } 1674 removeVoice(TGVoice voice)1675 public void removeVoice(TGVoice voice){ 1676 voice.setEmpty(true); 1677 1678 // Remove the beat If all voices are empty 1679 TGBeat beat = voice.getBeat(); 1680 for(int i = 0; i < beat.countVoices(); i ++){ 1681 if( !beat.getVoice(i).isEmpty() ){ 1682 return; 1683 } 1684 } 1685 this.removeBeat(beat); 1686 } 1687 removeVoice(TGVoice voice,boolean moveNextVoices)1688 public void removeVoice(TGVoice voice,boolean moveNextVoices){ 1689 removeVoice(voice); 1690 if(moveNextVoices){ 1691 long start = voice.getBeat().getStart(); 1692 long length = voice.getDuration().getTime(); 1693 TGVoice next = getNextVoice(voice.getBeat().getMeasure().getBeats(),voice.getBeat(),voice.getIndex()); 1694 if(next != null){ 1695 length = next.getBeat().getStart() - start; 1696 } 1697 moveVoices(voice.getBeat().getMeasure(),start + length,-length, voice.getIndex(), voice.getDuration()); 1698 } 1699 } 1700 removeVoice(TGMeasure measure,long start,int index, boolean moveNextComponents)1701 public void removeVoice(TGMeasure measure,long start,int index, boolean moveNextComponents){ 1702 TGBeat beat = getBeat(measure, start); 1703 if(beat != null){ 1704 removeVoice(beat.getVoice(index), moveNextComponents); 1705 } 1706 } 1707 removeVoicesOutOfTime(TGMeasure measure)1708 public void removeVoicesOutOfTime(TGMeasure measure){ 1709 List voicesToRemove = new ArrayList(); 1710 1711 long mStart = measure.getStart(); 1712 long mEnd = mStart + measure.getLength(); 1713 1714 Iterator beats = measure.getBeats().iterator(); 1715 while(beats.hasNext()){ 1716 TGBeat beat = (TGBeat)beats.next(); 1717 for( int v = 0; v < beat.countVoices() ; v ++){ 1718 TGVoice voice = beat.getVoice( v ); 1719 if(!voice.isEmpty()){ 1720 if( beat.getStart() < mStart || (beat.getStart() + voice.getDuration().getTime()) > mEnd){ 1721 voicesToRemove.add( voice ); 1722 } 1723 } 1724 } 1725 } 1726 Iterator it = voicesToRemove.iterator(); 1727 while(it.hasNext()){ 1728 TGVoice voice = (TGVoice)it.next(); 1729 this.removeVoice( voice ); 1730 } 1731 } 1732 removeMeasureVoices(TGMeasure measure,int index)1733 public void removeMeasureVoices(TGMeasure measure,int index){ 1734 boolean hasNotes = false; 1735 1736 List voices = new ArrayList(); 1737 Iterator it = measure.getBeats().iterator(); 1738 while(it.hasNext()){ 1739 TGBeat beat = (TGBeat)it.next(); 1740 TGVoice voice = beat.getVoice(index); 1741 if(voice.isRestVoice()){ 1742 voices.add(voice); 1743 }else if(!voice.isEmpty()){ 1744 hasNotes = true; 1745 break; 1746 } 1747 } 1748 1749 if( !hasNotes ){ 1750 it = voices.iterator(); 1751 while(it.hasNext()){ 1752 TGVoice voice = (TGVoice)it.next(); 1753 this.removeVoice( voice ); 1754 } 1755 } 1756 } 1757 changeVoiceDirection( TGVoice voice , int direction)1758 public void changeVoiceDirection( TGVoice voice , int direction){ 1759 voice.setDirection( direction ); 1760 } 1761 changeDuration(TGMeasure measure,TGBeat beat,TGDuration duration,int voice, boolean tryMove)1762 public void changeDuration(TGMeasure measure,TGBeat beat,TGDuration duration,int voice, boolean tryMove){ 1763 //obtengo la duracion vieja 1764 TGDuration oldDuration = beat.getVoice(voice).getDuration().clone(getSongManager().getFactory()); 1765 1766 //si no entra vuelvo a dejar la vieja 1767 if(validateDuration(measure,beat, voice, duration,tryMove,false)){ 1768 //se lo agrego a todas las notas en la posicion 1769 beat.getVoice(voice).setDuration(duration.clone(getSongManager().getFactory())); 1770 1771 //trato de agregar un silencio similar al lado 1772 tryChangeSilenceAfter(measure,beat.getVoice(voice)); 1773 }else{ 1774 oldDuration.copy( beat.getVoice(voice).getDuration() ); 1775 } 1776 } 1777 tryChangeSilenceAfter(TGMeasure measure,TGVoice voice)1778 public void tryChangeSilenceAfter(TGMeasure measure,TGVoice voice){ 1779 autoCompleteSilences(measure); 1780 1781 TGVoice nextVoice = getNextVoice(measure.getBeats(),voice.getBeat(),voice.getIndex()); 1782 1783 long beatEnd = (voice.getBeat().getStart() + voice.getDuration().getTime()); 1784 long measureEnd = (measure.getStart() + measure.getLength()); 1785 if(nextVoice != null && !nextVoice.isEmpty() && nextVoice.isRestVoice() && beatEnd <= measureEnd){ 1786 long theMove = (getRealStart(measure,beatEnd)) - getRealStart(measure,nextVoice.getBeat().getStart()); 1787 if((nextVoice.getBeat().getStart() + theMove) < measureEnd && (nextVoice.getBeat().getStart() + nextVoice.getDuration().getTime() + theMove) <= measureEnd){ 1788 moveVoice(nextVoice,theMove); 1789 changeDuration(measure,nextVoice.getBeat(),voice.getDuration().clone(getSongManager().getFactory()),nextVoice.getIndex(),false); 1790 } 1791 } 1792 } 1793 moveVoices(List voices,long theMove)1794 private void moveVoices(List voices,long theMove){ 1795 /* 1796 Iterator it = voices.iterator(); 1797 while(it.hasNext()){ 1798 TGVoice voice = (TGVoice)it.next(); 1799 moveVoice(voice,theMove); 1800 } 1801 */ 1802 int count = voices.size(); 1803 for( int i = 0 ; i < count ; i ++ ){ 1804 TGVoice voice = (TGVoice)voices.get( (theMove < 0 ? i : ( (count - 1) - i ) ) ); 1805 moveVoice(voice,theMove); 1806 } 1807 } 1808 moveVoice(TGVoice voice, long theMove)1809 public void moveVoice(TGVoice voice, long theMove){ 1810 long newStart = (voice.getBeat().getStart() + theMove); 1811 1812 TGBeat newBeat = getBeat(voice.getBeat().getMeasure(),newStart); 1813 if( newBeat == null ){ 1814 newBeat = getSongManager().getFactory().newBeat(); 1815 newBeat.setStart( newStart ); 1816 addBeat(voice.getBeat().getMeasure(), newBeat); 1817 } 1818 1819 this.moveVoice(voice, newBeat); 1820 } 1821 moveVoice(TGVoice voice, TGBeat beat)1822 public void moveVoice(TGVoice voice, TGBeat beat){ 1823 TGBeat currentBeat = voice.getBeat(); 1824 if(!currentBeat.equals(beat)){ 1825 if(currentBeat.getVoice( voice.getIndex() ).equals( voice )){ 1826 if ( currentBeat.isTextBeat() && isUniqueVoice(voice, false) ){ 1827 beat.setText( currentBeat.getText() ); 1828 currentBeat.removeText(); 1829 } 1830 if( isUniqueVoice(voice, true) ){ 1831 if( currentBeat.isChordBeat() ){ 1832 beat.setChord( currentBeat.getChord() ); 1833 currentBeat.removeChord(); 1834 } 1835 if( currentBeat.getStroke().getDirection() != TGStroke.STROKE_NONE ){ 1836 currentBeat.getStroke().copy( beat.getStroke() ); 1837 currentBeat.getStroke().setDirection(TGStroke.STROKE_NONE); 1838 } 1839 } 1840 // Make sure to remove another voice instance from old beat. 1841 TGVoice newVoice = getSongManager().getFactory().newVoice(voice.getIndex()); 1842 currentBeat.setVoice( voice.getIndex(), newVoice); 1843 this.removeVoice(newVoice); 1844 } 1845 beat.setVoice( voice.getIndex() , voice); 1846 } 1847 } 1848 validateDuration(TGMeasure measure,TGBeat beat,int voice, TGDuration duration,boolean moveNextBeats, boolean setCurrentDuration)1849 public boolean validateDuration(TGMeasure measure,TGBeat beat,int voice, TGDuration duration,boolean moveNextBeats, boolean setCurrentDuration){ 1850 int errorMargin = 10; 1851 this.orderBeats(measure); 1852 long measureStart = measure.getStart(); 1853 long measureEnd = (measureStart + measure.getLength()); 1854 long beatStart = beat.getStart(); 1855 long beatLength = duration.getTime(); 1856 long beatEnd = (beatStart + beatLength); 1857 List beats = measure.getBeats(); 1858 1859 //Verifico si hay un beat en el mismo lugar, y comparo las duraciones. 1860 TGBeat currentBeat = getBeat(measure,beatStart); 1861 TGVoice currentVoice = null; 1862 if(currentBeat != null){ 1863 currentVoice = currentBeat.getVoice(voice); 1864 if(!currentVoice.isEmpty() && beatLength <= currentVoice.getDuration().getTime()){ 1865 return true; 1866 } 1867 } 1868 1869 //Verifico si hay lugar para meter el beat 1870 TGVoice nextVoice = getNextVoice(beats,beat, voice); 1871 if(currentVoice == null || currentVoice.isEmpty()){ 1872 if((nextVoice == null || nextVoice.isEmpty()) && beatEnd < (measureEnd + errorMargin)){ 1873 return true; 1874 } 1875 if((nextVoice != null && !nextVoice.isEmpty()) && beatEnd < (nextVoice.getBeat().getStart() + errorMargin)){ 1876 return true; 1877 } 1878 } 1879 1880 // Busca si hay espacio disponible de silencios entre el componente y el el que le sigue.. si encuentra lo borra 1881 if(nextVoice != null && !nextVoice.isEmpty() && nextVoice.isRestVoice()){ 1882 //Verifico si lo que sigue es un silencio. y lo borro 1883 long nextBeatEnd = 0; 1884 List nextBeats = new ArrayList(); 1885 while(nextVoice != null && !nextVoice.isEmpty() && nextVoice.isRestVoice() && !nextVoice.getBeat().isTextBeat()){ 1886 nextBeats.add(nextVoice); 1887 nextBeatEnd = nextVoice.getBeat().getStart() + nextVoice.getDuration().getTime(); 1888 nextVoice = getNextVoice(beats,nextVoice.getBeat(), voice); 1889 } 1890 if(nextVoice == null || nextVoice.isEmpty()){ 1891 nextBeatEnd = measureEnd; 1892 }else if(!nextVoice.isRestVoice() || nextVoice.getBeat().isTextBeat()){ 1893 nextBeatEnd = nextVoice.getBeat().getStart(); 1894 } 1895 if(beatEnd <= (nextBeatEnd + errorMargin)){ 1896 while(!nextBeats.isEmpty()){ 1897 TGVoice currVoice = (TGVoice)nextBeats.get(0); 1898 nextBeats.remove(currVoice); 1899 removeVoice(currVoice, false); 1900 } 1901 return true; 1902 } 1903 } 1904 1905 // Busca si hay espacio disponible de silencios entre el componente y el final.. si encuentra mueve todo 1906 1907 if(moveNextBeats){ 1908 nextVoice = getNextVoice(beats,beat, voice); 1909 if(nextVoice != null){ 1910 long requiredLength = (beatLength - (nextVoice.getBeat().getStart() - beatStart)); 1911 long nextSilenceLength = 0; 1912 TGVoice nextRestBeat = getNextRestVoice(beats, beat.getVoice(voice)); 1913 while(nextRestBeat != null){ 1914 nextSilenceLength += nextRestBeat.getDuration().getTime(); 1915 nextRestBeat = getNextRestVoice(beats, nextRestBeat); 1916 } 1917 1918 if(requiredLength <= (nextSilenceLength + errorMargin)){ 1919 List voices = getVoicesBeforeEnd(measure.getBeats(),nextVoice.getBeat().getStart(), voice); 1920 while(!voices.isEmpty()){ 1921 TGVoice currentVocie = (TGVoice)voices.get(0); 1922 if(currentVocie.isRestVoice()){ 1923 requiredLength -= currentVocie.getDuration().getTime(); 1924 removeVoice(currentVocie, false); 1925 }else if(requiredLength > 0){ 1926 moveVoice(currentVocie,requiredLength); 1927 } 1928 voices.remove(0); 1929 } 1930 return true; 1931 } 1932 } 1933 } 1934 1935 1936 // como ultimo intento, asigno la duracion de cualquier componente existente en el lugar. 1937 if(setCurrentDuration && currentVoice != null && !currentVoice.isEmpty()){ 1938 currentVoice.getDuration().copy( duration ); 1939 return true; 1940 } 1941 return false; 1942 } 1943 /* 1944 public boolean moveVoices(TGMeasure measure,long start,long theMove, int voiceIndex, TGDuration fillDuration){ 1945 if( theMove == 0 ){ 1946 return false; 1947 } 1948 boolean success = true; 1949 long measureStart = measure.getStart(); 1950 long measureEnd = (measureStart + measure.getLength()); 1951 1952 // Muevo los componentes 1953 List voicesToMove = getVoicesBeforeEnd(measure.getBeats(),start, voiceIndex); 1954 moveVoices(voicesToMove,theMove); 1955 1956 if(success){ 1957 List voicesToRemove = new ArrayList(); 1958 List beats = new ArrayList(measure.getBeats()); 1959 1960 // Verifica los silencios a eliminar al principio del compas 1961 TGVoice first = getFirstVoice( beats, voiceIndex ); 1962 while(first != null && first.isRestVoice() && first.getBeat().getStart() < measureStart){ 1963 beats.remove(first); 1964 voicesToRemove.add(first); 1965 first = getNextVoice( beats,first.getBeat(), voiceIndex); 1966 } 1967 1968 // Verifica los silencios a eliminar al final del compas 1969 TGVoice last = getLastVoice(beats, voiceIndex); 1970 TGDuration lastDuration = (last != null ? last.getDuration() : null); 1971 while(last != null && lastDuration != null && last.isRestVoice() && (last.getBeat().getStart() + lastDuration.getTime() ) > measureEnd ){ 1972 beats.remove(last); 1973 voicesToRemove.add(last); 1974 last = getPreviousVoice(beats,last.getBeat(), voiceIndex); 1975 lastDuration = (last != null ? last.getDuration() : null); 1976 } 1977 1978 // Si el primer o ultimo componente, quedan fuera del compas, entonces el movimiento no es satisfactorio 1979 if(first != null && last != null && lastDuration != null){ 1980 if(first.getBeat().getStart() < measureStart || (last.getBeat().getStart() + lastDuration.getTime()) > measureEnd){ 1981 success = false; 1982 } 1983 } 1984 1985 if(success){ 1986 // Elimino los silencios que quedaron fuera del compas. 1987 Iterator it = voicesToRemove.iterator(); 1988 while( it.hasNext() ){ 1989 TGVoice beat = (TGVoice)it.next(); 1990 removeVoice(beat); 1991 } 1992 1993 // Se crean silencios en los espacios vacios, si la duracion fue especificada. 1994 if( fillDuration != null ){ 1995 if( theMove < 0 ){ 1996 last = getLastVoice(measure.getBeats(), voiceIndex); 1997 lastDuration = (last != null ? last.getDuration() : null); 1998 long beatStart = ( (last != null && lastDuration != null ? last.getBeat().getStart() + lastDuration.getTime() : start ) ); 1999 if( (beatStart + fillDuration.getTime()) <= measureEnd ){ 2000 boolean beatNew = false; 2001 TGBeat beat = getBeat(measure, beatStart); 2002 if(beat == null){ 2003 beat = getSongManager().getFactory().newBeat(); 2004 beat.setStart( beatStart ); 2005 beatNew = true; 2006 } 2007 TGVoice voice = beat.getVoice(voiceIndex); 2008 voice.setEmpty(false); 2009 fillDuration.copy( voice.getDuration() ); 2010 if( beatNew ){ 2011 addBeat(measure, beat ); 2012 } 2013 } 2014 } 2015 else{ 2016 first = getFirstVoice(getBeatsBeforeEnd(measure.getBeats(),start), voiceIndex); 2017 if( (start + fillDuration.getTime()) <= (first != null ?first.getBeat().getStart() : measureEnd ) ){ 2018 boolean beatNew = false; 2019 TGBeat beat = getBeat(measure, start); 2020 if(beat == null){ 2021 beat = getSongManager().getFactory().newBeat(); 2022 beat.setStart( start ); 2023 beatNew = true; 2024 } 2025 TGVoice voice = beat.getVoice(voiceIndex); 2026 voice.setEmpty(false); 2027 fillDuration.copy( voice.getDuration() ); 2028 if( beatNew ){ 2029 addBeat(measure, beat ); 2030 } 2031 } 2032 } 2033 } 2034 } 2035 } 2036 2037 // Si el movimiento no es satisfactorio, regreso todo como estaba 2038 if(! success ){ 2039 moveVoices(voicesToMove,-theMove); 2040 } 2041 this.removeEmptyBeats(measure); 2042 2043 return success; 2044 } 2045 */ 2046 moveVoices(TGMeasure measure,long start,long theMove, int voiceIndex, TGDuration fillDuration)2047 public boolean moveVoices(TGMeasure measure,long start,long theMove, int voiceIndex, TGDuration fillDuration){ 2048 if( theMove == 0 ){ 2049 return false; 2050 } 2051 boolean success = true; 2052 long measureStart = measure.getStart(); 2053 long measureEnd = (measureStart + measure.getLength()); 2054 2055 List voicesToMove = getVoicesBeforeEnd(measure.getBeats(),start, voiceIndex); 2056 List voicesToRemove = new ArrayList(); 2057 List currentBeats = getBeatsBeforeEnd(measure.getBeats(), start); 2058 2059 // Verifica los silencios a eliminar al principio del compas 2060 TGVoice first = getFirstVoice( currentBeats, voiceIndex ); 2061 while(first != null && first.isRestVoice() && (!first.getBeat().isTextBeat() || !isUniqueVoice(first,false)) && (first.getBeat().getStart() + theMove) < measureStart){ 2062 currentBeats.remove(first.getBeat()); 2063 voicesToRemove.add(first); 2064 first = getNextVoice( currentBeats,first.getBeat(), voiceIndex); 2065 } 2066 2067 // Verifica los silencios a eliminar al final del compas 2068 TGVoice last = getLastVoice(currentBeats, voiceIndex); 2069 TGDuration lastDuration = (last != null ? last.getDuration() : null); 2070 while(last != null && lastDuration != null && last.isRestVoice() && (!last.getBeat().isTextBeat() || !isUniqueVoice(last,false)) && (last.getBeat().getStart() + lastDuration.getTime() + theMove) > measureEnd ){ 2071 currentBeats.remove(last.getBeat()); 2072 voicesToRemove.add(last); 2073 last = getPreviousVoice(currentBeats,last.getBeat(), voiceIndex); 2074 lastDuration = (last != null ? last.getDuration() : null); 2075 } 2076 2077 // Si el primer o ultimo componente, quedan fuera del compas, entonces el movimiento no es satisfactorio 2078 if(first != null && last != null && lastDuration != null){ 2079 if((first.getBeat().getStart() + theMove) < measureStart || (last.getBeat().getStart() + lastDuration.getTime() + theMove) > measureEnd){ 2080 success = false; 2081 } 2082 } 2083 2084 if(success){ 2085 this.moveVoices(voicesToMove,theMove); 2086 2087 // Elimino los silencios que quedaron fuera del compas. 2088 Iterator it = voicesToRemove.iterator(); 2089 while( it.hasNext() ){ 2090 TGVoice beat = (TGVoice)it.next(); 2091 removeVoice(beat); 2092 } 2093 2094 // Se crean silencios en los espacios vacios, si la duracion fue especificada. 2095 if( fillDuration != null ){ 2096 if( theMove < 0 ){ 2097 last = getLastVoice(measure.getBeats(), voiceIndex); 2098 lastDuration = (last != null ? last.getDuration() : null); 2099 long beatStart = ( (last != null && lastDuration != null ? last.getBeat().getStart() + lastDuration.getTime() : start ) ); 2100 if( (beatStart + fillDuration.getTime()) <= measureEnd ){ 2101 boolean beatNew = false; 2102 TGBeat beat = getBeat(measure, beatStart); 2103 if(beat == null){ 2104 beat = getSongManager().getFactory().newBeat(); 2105 beat.setStart( beatStart ); 2106 beatNew = true; 2107 } 2108 TGVoice voice = beat.getVoice(voiceIndex); 2109 voice.setEmpty(false); 2110 fillDuration.copy( voice.getDuration() ); 2111 if( beatNew ){ 2112 addBeat(measure, beat ); 2113 } 2114 } 2115 } 2116 else{ 2117 first = getFirstVoice(getBeatsBeforeEnd(measure.getBeats(),start), voiceIndex); 2118 if( (start + fillDuration.getTime()) <= (first != null ?first.getBeat().getStart() : measureEnd ) ){ 2119 boolean beatNew = false; 2120 TGBeat beat = getBeat(measure, start); 2121 if(beat == null){ 2122 beat = getSongManager().getFactory().newBeat(); 2123 beat.setStart( start ); 2124 beatNew = true; 2125 } 2126 TGVoice voice = beat.getVoice(voiceIndex); 2127 voice.setEmpty(false); 2128 fillDuration.copy( voice.getDuration() ); 2129 if( beatNew ){ 2130 addBeat(measure, beat ); 2131 } 2132 } 2133 } 2134 } 2135 2136 // Borro todos los beats que quedaron vacios. 2137 this.removeEmptyBeats(measure); 2138 } 2139 2140 return success; 2141 } 2142 isUniqueVoice(TGVoice voice, boolean ignoreRests)2143 public boolean isUniqueVoice(TGVoice voice, boolean ignoreRests){ 2144 TGBeat beat = voice.getBeat(); 2145 for( int v = 0 ; v < beat.countVoices() ; v ++ ){ 2146 if( v != voice.getIndex() ){ 2147 TGVoice currentVoice = beat.getVoice( v ); 2148 if( !currentVoice.isEmpty() && (!ignoreRests || !currentVoice.isRestVoice())){ 2149 return false; 2150 } 2151 } 2152 } 2153 return true; 2154 } 2155 transposeNotes( TGMeasure measure, int transposition , boolean tryKeepString, boolean applyToChords, int applyToString)2156 public void transposeNotes( TGMeasure measure, int transposition , boolean tryKeepString, boolean applyToChords, int applyToString){ 2157 if( transposition != 0 ){ 2158 if( measure != null ){ 2159 TGTrack track = measure.getTrack(); 2160 if( track != null ){ 2161 List strings = getSortedStringsByValue(track, ( transposition > 0 ? 1 : -1 ) ) ; 2162 for( int i = 0 ; i < measure.countBeats() ; i ++ ){ 2163 TGBeat beat = measure.getBeat( i ); 2164 transposeNotes( beat, strings, transposition , tryKeepString, applyToChords, applyToString ); 2165 } 2166 } 2167 } 2168 } 2169 } 2170 transposeNotes( TGMeasure measure, int[] transpositionStrings , boolean tryKeepString , boolean applyToChords)2171 public void transposeNotes( TGMeasure measure, int[] transpositionStrings , boolean tryKeepString , boolean applyToChords){ 2172 if( transpositionStrings != null && transpositionStrings.length > 0 ){ 2173 if( measure != null ){ 2174 TGTrack track = measure.getTrack(); 2175 if( track != null ){ 2176 TGNote[] notes = new TGNote[ transpositionStrings.length ]; 2177 2178 for( int b = 0 ; b < measure.countBeats() ; b ++ ){ 2179 TGBeat beat = measure.getBeat( b ); 2180 2181 for( int n = 0 ; n < notes.length ; n ++ ){ 2182 notes[ n ] = getNote( beat, (n + 1) ); 2183 } 2184 2185 for( int i = 0 ; i < notes.length ; i ++ ){ 2186 if( notes[ i ] != null ){ 2187 int transposition = transpositionStrings[ i ]; 2188 if( transposition != 0 ){ 2189 int applyToString = notes[i].getString(); 2190 List strings = getSortedStringsByValue(track, ( transposition > 0 ? 1 : -1 ) ) ; 2191 transposeNotes( beat, strings, transposition , tryKeepString, applyToChords, applyToString ); 2192 } 2193 } 2194 } 2195 } 2196 } 2197 } 2198 } 2199 } 2200 transposeNotes( TGBeat beat, List strings, int transposition , boolean tryKeepString, boolean applyToChord, int applyToString)2201 public void transposeNotes( TGBeat beat, List strings, int transposition , boolean tryKeepString, boolean applyToChord, int applyToString){ 2202 if( transposition != 0 ){ 2203 List notes = getNotes(beat); 2204 2205 int stringCount = strings.size(); 2206 for( int i = 0 ; i < stringCount ; i ++ ){ 2207 TGString string = (TGString)strings.get( (stringCount - i) - 1 ); 2208 if( applyToString == -1 || string.getNumber() == applyToString ){ 2209 TGNote note = null; 2210 for( int n = 0 ; n < notes.size() ; n ++ ){ 2211 TGNote current = (TGNote)notes.get( n ); 2212 if( current.getString() == string.getNumber() ){ 2213 note = current; 2214 } 2215 } 2216 if( note != null ){ 2217 transposeNote(note, notes, strings, transposition, tryKeepString, false ); 2218 } 2219 2220 if( applyToChord && beat.isChordBeat() ){ 2221 TGChord chord = beat.getChord(); 2222 int chordString = ( string.getNumber() - 1 ); 2223 if( chord.getFretValue( chordString ) >= 0 ){ 2224 transposeChordNote(chord, chordString, strings, transposition, tryKeepString, false); 2225 } 2226 chord.setFirstFret( -1 ); 2227 } 2228 } 2229 } 2230 } 2231 } 2232 transposeNote( TGNote note, List notes, List strings , int transposition , boolean tryKeepString, boolean forceChangeString )2233 private boolean transposeNote( TGNote note, List notes, List strings , int transposition , boolean tryKeepString, boolean forceChangeString ){ 2234 boolean canTransposeFret = false; 2235 2236 int maximumFret = 29; 2237 2238 int transposedFret = ( note.getValue() + transposition ); 2239 2240 // Check if transposition could be done without change the string 2241 if( transposedFret >= 0 && transposedFret <= maximumFret ){ 2242 // Do it now if keep string is the priority 2243 if( !forceChangeString && tryKeepString ){ 2244 note.setValue( transposedFret ); 2245 return true; 2246 } 2247 canTransposeFret = true; 2248 } 2249 2250 // Check the current string index for this note 2251 int stringIndex = -1; 2252 for( int i = 0 ; i < strings.size() ; i ++ ){ 2253 TGString string = ( TGString ) strings.get( i ); 2254 if( string.getNumber() == note.getString() ){ 2255 stringIndex = i; 2256 break; 2257 } 2258 } 2259 2260 // Try to change the string of the note 2261 TGString string = ( TGString ) strings.get( stringIndex ); 2262 int transposedValue = ( string.getValue() + note.getValue() + transposition ); 2263 int nextStringIndex = ( stringIndex + 1 ); 2264 while( nextStringIndex >= 0 && nextStringIndex < strings.size() ){ 2265 TGString nextString = ( TGString ) strings.get( nextStringIndex ); 2266 TGNote nextOwner = null; 2267 for( int i = 0 ; i < notes.size() ; i ++ ){ 2268 TGNote nextNote = (TGNote) notes.get( i ); 2269 if( nextNote.getString() == nextString.getNumber() ){ 2270 nextOwner = nextNote; 2271 } 2272 } 2273 2274 int transposedStringFret = ( transposedValue - nextString.getValue() ); 2275 if( transposedStringFret >= 0 && transposedStringFret <= maximumFret ){ 2276 if( nextOwner != null ){ 2277 if( ! transposeNote(nextOwner, notes, strings, 0 , tryKeepString , !canTransposeFret ) ){ 2278 // Note was removed. 2279 nextOwner = null ; 2280 } 2281 } 2282 if( nextOwner == null || nextOwner.getString() != nextString.getNumber() ){ 2283 note.setValue( transposedStringFret ); 2284 note.setString( nextString.getNumber() ); 2285 2286 return true; 2287 } 2288 } 2289 nextStringIndex ++; 2290 } 2291 2292 // Keep using same string if it's possible 2293 if( !forceChangeString && canTransposeFret ){ 2294 note.setValue( transposedFret ); 2295 return true; 2296 } 2297 2298 // If note can't be transposed, it must be removed. 2299 notes.remove( note ); 2300 removeNote(note); 2301 2302 return false; 2303 } 2304 transposeChordNote( TGChord chord, int chordString, List strings , int transposition , boolean tryKeepString, boolean forceChangeString )2305 private boolean transposeChordNote( TGChord chord, int chordString, List strings , int transposition , boolean tryKeepString, boolean forceChangeString ){ 2306 boolean canTransposeFret = false; 2307 2308 int maximumFret = 24; 2309 2310 int noteValue = chord.getFretValue( chordString ); 2311 int noteString = (chordString + 1 ); 2312 2313 int transposedFret = ( noteValue + transposition ); 2314 2315 // Check if transposition could be done without change the string 2316 if( transposedFret >= 0 && transposedFret <= maximumFret ){ 2317 // Do it now if keep string is the priority 2318 if( !forceChangeString && tryKeepString ){ 2319 chord.addFretValue(chordString, transposedFret); 2320 return true; 2321 } 2322 canTransposeFret = true; 2323 } 2324 2325 // Check the current string index for this note 2326 int stringIndex = -1; 2327 for( int i = 0 ; i < strings.size() ; i ++ ){ 2328 TGString string = ( TGString ) strings.get( i ); 2329 if( string.getNumber() == noteString ){ 2330 stringIndex = i; 2331 break; 2332 } 2333 } 2334 2335 // Try to change the string of the note 2336 TGString string = ( TGString ) strings.get( stringIndex ); 2337 int transposedValue = ( string.getValue() + noteValue + transposition ); 2338 int nextStringIndex = ( stringIndex + 1 ); 2339 while( nextStringIndex >= 0 && nextStringIndex < strings.size() ){ 2340 TGString nextString = ( TGString ) strings.get( nextStringIndex ); 2341 int nextChordString = -1; 2342 for( int i = 0 ; i < chord.countStrings() ; i ++ ){ 2343 if( (i + 1) == nextString.getNumber() ){ 2344 if( chord.getFretValue( i ) >= 0 ){ 2345 nextChordString = i; 2346 } 2347 } 2348 } 2349 2350 int transposedStringFret = ( transposedValue - nextString.getValue() ); 2351 if( transposedStringFret >= 0 && transposedStringFret <= maximumFret ){ 2352 if( nextChordString >= 0 ){ 2353 transposeChordNote(chord, nextChordString , strings, 0 , tryKeepString , !canTransposeFret ); 2354 } 2355 if( nextChordString < 0 || chord.getFretValue( nextChordString ) < 0 ){ 2356 chord.addFretValue( chordString , -1 ); 2357 chord.addFretValue( ( nextString.getNumber() - 1 ) , transposedStringFret ); 2358 2359 return true; 2360 } 2361 } 2362 nextStringIndex ++; 2363 } 2364 2365 // Keep using same string if it's possible 2366 if( !forceChangeString && canTransposeFret ){ 2367 chord.addFretValue( chordString , transposedFret ); 2368 return true; 2369 } 2370 2371 // If note can't be transposed, it must be removed. 2372 chord.addFretValue( chordString , -1 ); 2373 2374 return false; 2375 } 2376 getSortedStringsByValue( TGTrack track , final int direction )2377 public List getSortedStringsByValue( TGTrack track , final int direction ){ 2378 List strings = new ArrayList(); 2379 for( int number = 1 ; number <= track.stringCount() ; number ++ ){ 2380 strings.add( track.getString( number ) ); 2381 } 2382 2383 Collections.sort( strings , new Comparator() { 2384 public int compare(Object o1, Object o2) { 2385 if( o1 != null && o2 != null && o1 instanceof TGString && o2 instanceof TGString ){ 2386 TGString s1 = (TGString)o1; 2387 TGString s2 = (TGString)o2; 2388 int status = ( s1.getValue() - s2.getValue() ); 2389 if( status == 0 ){ 2390 return 0; 2391 } 2392 return ( (status * direction) > 0 ? 1 : -1 ); 2393 } 2394 return 0; 2395 } 2396 }); 2397 2398 return strings; 2399 } 2400 } 2401