/*
* Created on 09-ene-2006
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org.herac.tuxguitar.io.gtp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.herac.tuxguitar.gm.GMChannelRoute;
import org.herac.tuxguitar.io.base.TGFileFormat;
import org.herac.tuxguitar.io.base.TGFileFormatException;
import org.herac.tuxguitar.song.models.TGBeat;
import org.herac.tuxguitar.song.models.TGChannel;
import org.herac.tuxguitar.song.models.TGChord;
import org.herac.tuxguitar.song.models.TGColor;
import org.herac.tuxguitar.song.models.TGDivisionType;
import org.herac.tuxguitar.song.models.TGDuration;
import org.herac.tuxguitar.song.models.TGMarker;
import org.herac.tuxguitar.song.models.TGMeasure;
import org.herac.tuxguitar.song.models.TGMeasureHeader;
import org.herac.tuxguitar.song.models.TGNote;
import org.herac.tuxguitar.song.models.TGNoteEffect;
import org.herac.tuxguitar.song.models.TGSong;
import org.herac.tuxguitar.song.models.TGString;
import org.herac.tuxguitar.song.models.TGStroke;
import org.herac.tuxguitar.song.models.TGTempo;
import org.herac.tuxguitar.song.models.TGText;
import org.herac.tuxguitar.song.models.TGTimeSignature;
import org.herac.tuxguitar.song.models.TGTrack;
import org.herac.tuxguitar.song.models.TGVelocities;
import org.herac.tuxguitar.song.models.TGVoice;
import org.herac.tuxguitar.song.models.effects.TGEffectBend;
import org.herac.tuxguitar.song.models.effects.TGEffectGrace;
import org.herac.tuxguitar.song.models.effects.TGEffectTremoloBar;
import org.herac.tuxguitar.song.models.effects.TGEffectTremoloPicking;
import org.herac.tuxguitar.song.models.effects.TGEffectTrill;
/**
* @author julian
*
* TODO To change the template for this generated type comment go to Window - Preferences - Java - Code Style - Code Templates
*/
public class GP5OutputStream extends GTPOutputStream {
private static final String GP5_FORMAT_EXTENSION = ".gp5";
private static final String GP5_VERSION = "FICHIER GUITAR PRO v5.00";
private static final int GP_BEND_SEMITONE = 25;
private static final int GP_BEND_POSITION = 60;
private static final String[] PAGE_SETUP_LINES = {
"%TITLE%",
"%SUBTITLE%",
"%ARTIST%",
"%ALBUM%",
"Words by %WORDS%",
"Music by %MUSIC%",
"Words & Music by %WORDSMUSIC%",
"Copyright %COPYRIGHT%",
"All Rights Reserved - International Copyright Secured",
"Page %N%/%P%",
"Moderate",
};
public GP5OutputStream(GTPSettings settings) {
super(settings);
}
@Override
public TGFileFormat getFileFormat(){
return new TGFileFormat("Guitar Pro 5","*.gp5");
}
@Override
public boolean isSupportedExtension(String extension) {
return (extension.toLowerCase().equals(GP5_FORMAT_EXTENSION)) ;
}
@Override
public void writeSong(TGSong song){
try {
if(song.isEmpty()){
throw new TGFileFormatException("Empty Song!!!");
}
configureChannelRouter(song);
TGMeasureHeader header = song.getMeasureHeader(0);
writeStringByte(GP5_VERSION, 30, DEFAULT_VERSION_CHARSET);
writeInfo(song);
writeLyrics(song);
writePageSetup();
writeInt(header.getTempo().getValue());
writeInt(0);
writeByte((byte)0);
writeChannels(song);
for(int i = 0; i < 42; i ++){
writeByte((byte)0xff);
}
writeInt(song.countMeasureHeaders());
writeInt(song.countTracks());
writeMeasureHeaders(song);
writeTracks(song);
skipBytes(2);
writeMeasures(song, header.getTempo().clone(getFactory()));
close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void writeInfo(TGSong song) throws IOException{
List comments = toCommentLines(song.getComments());
writeStringByteSizeOfInteger(song.getName());
writeStringByteSizeOfInteger("");
writeStringByteSizeOfInteger(song.getArtist());
writeStringByteSizeOfInteger(song.getAlbum());
writeStringByteSizeOfInteger(song.getAuthor());
writeStringByteSizeOfInteger("");
writeStringByteSizeOfInteger(song.getCopyright());
writeStringByteSizeOfInteger(song.getWriter());
writeStringByteSizeOfInteger("");
writeInt( comments.size() );
for (int i = 0; i < comments.size(); i++) {
writeStringByteSizeOfInteger( (String)comments.get(i) );
}
}
private void writeLyrics(TGSong song) throws IOException{
TGTrack lyricTrack = null;
Iterator it = song.getTracks();
while(it.hasNext()){
TGTrack track = (TGTrack)it.next();
if(!track.getLyrics().isEmpty()){
lyricTrack = track;
break;
}
}
writeInt( (lyricTrack == null)?0:lyricTrack.getNumber() );
writeInt((lyricTrack == null)?0:lyricTrack.getLyrics().getFrom());
writeStringInteger((lyricTrack == null)?"":lyricTrack.getLyrics().getLyrics());
for (int i = 0; i < 4; i++) {
writeInt((lyricTrack == null)?0:1);
writeStringInteger("");
}
}
private void writePageSetup() throws IOException{
writeInt( 210 ); // Page width
writeInt( 297 ); // Page height
writeInt( 10 ); // Margin left
writeInt( 10 ); // Margin right
writeInt( 15 ); // Margin top
writeInt( 10 ); // Margin bottom
writeInt( 100 ); // Score size percent
writeByte( ( byte )0xff ); // View flags
writeByte( ( byte )0x01 ); // View flags
for (int i = 0; i < PAGE_SETUP_LINES.length; i++) {
writeInt( (PAGE_SETUP_LINES[i].length() + 1) );
writeStringByte(PAGE_SETUP_LINES[i],0);
}
}
private void writeChannels(TGSong song) throws IOException{
TGChannel[] channels = makeChannels(song);
for (int i = 0; i < channels.length; i++) {
writeInt(channels[i].getProgram());
writeByte(toChannelByte(channels[i].getVolume()));
writeByte(toChannelByte(channels[i].getBalance()));
writeByte(toChannelByte(channels[i].getChorus()));
writeByte(toChannelByte(channels[i].getReverb()));
writeByte(toChannelByte(channels[i].getPhaser()));
writeByte(toChannelByte(channels[i].getTremolo()));
writeBytes(new byte[]{0,0});
}
}
private void writeMeasureHeaders(TGSong song) throws IOException {
TGTimeSignature timeSignature = getFactory().newTimeSignature();
if (song.countMeasureHeaders() > 0) {
for (int i = 0; i < song.countMeasureHeaders(); i++) {
if(i > 0 ){
skipBytes(1);
}
TGMeasureHeader measure = song.getMeasureHeader(i);
writeMeasureHeader(measure, timeSignature);
timeSignature.setNumerator(measure.getTimeSignature().getNumerator());
timeSignature.getDenominator().setValue(measure.getTimeSignature().getDenominator().getValue());
}
}
}
private void writeMeasureHeader(TGMeasureHeader measure, TGTimeSignature timeSignature) throws IOException {
int flags = 0;
if(measure.getNumber() == 1){
flags |= 0x40;
}
if (measure.getNumber() == 1 || !measure.getTimeSignature().isEqual(timeSignature)) {
flags |= 0x01;
flags |= 0x02;
}
if (measure.isRepeatOpen()) {
flags |= 0x04;
}
if (measure.getRepeatClose() > 0) {
flags |= 0x08;
}
if (measure.getRepeatAlternative() > 0) {
flags |= 0x10;
}
if (measure.hasMarker()) {
flags |= 0x20;
}
writeUnsignedByte(flags);
if ((flags & 0x01) != 0) {
writeByte((byte) measure.getTimeSignature().getNumerator());
}
if ((flags & 0x02) != 0) {
writeByte((byte) measure.getTimeSignature().getDenominator().getValue());
}
if ((flags & 0x08) != 0) {
writeByte((byte) (measure.getRepeatClose() + 1));
}
if ((flags & 0x20) != 0) {
writeMarker(measure.getMarker());
}
if ((flags & 0x10) != 0) {
writeByte((byte)measure.getRepeatAlternative());
}
if ((flags & 0x40) != 0) {
skipBytes(2);
}
if ((flags & 0x01) != 0) {
writeBytes( makeBeamEighthNoteBytes( measure.getTimeSignature() ));
}
if((flags & 0x10) == 0){
writeByte((byte)0);
}
if(measure.getTripletFeel() == TGMeasureHeader.TRIPLET_FEEL_NONE){
writeByte((byte)0);
}
else if(measure.getTripletFeel() == TGMeasureHeader.TRIPLET_FEEL_EIGHTH){
writeByte((byte)1);
}
else if(measure.getTripletFeel() == TGMeasureHeader.TRIPLET_FEEL_SIXTEENTH){
writeByte((byte)2);
}
}
private void writeTracks(TGSong song) throws IOException {
for (int i = 0; i < song.countTracks(); i++) {
TGTrack track = song.getTrack(i);
writeTrack(track);
}
}
private void writeTrack(TGTrack track) throws IOException {
GMChannelRoute channel = getChannelRoute(track.getChannelId());
int flags = 0;
if (isPercussionChannel(track.getSong(),track.getChannelId())) {
flags |= 0x01;
}
writeUnsignedByte(flags);
writeUnsignedByte((8 | flags));
writeStringByte(track.getName(), 40);
writeInt(track.getStrings().size());
for (int i = 0; i < 7; i++) {
int value = 0;
if (track.getStrings().size() > i) {
TGString string = (TGString) track.getStrings().get(i);
value = string.getValue();
}
writeInt(value);
}
writeInt(1);
writeInt(channel.getChannel1() + 1);
writeInt(channel.getChannel2() + 1);
writeInt(24);
writeInt(track.getOffset());
writeColor(track.getColor());
writeBytes(new byte[]{ 67, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1});
}
private void writeMeasures(TGSong song, TGTempo tempo) throws IOException{
for (int i = 0; i < song.countMeasureHeaders(); i++) {
TGMeasureHeader header = song.getMeasureHeader(i);
for (int j = 0; j < song.countTracks(); j++) {
TGTrack track = song.getTrack(j);
TGMeasure measure = track.getMeasure(i);
writeMeasure(measure, (header.getTempo().getValue() != tempo.getValue()) );
skipBytes(1);
}
header.getTempo().copy( tempo );
}
}
private void writeMeasure(TGMeasure measure, boolean changeTempo) throws IOException {
for(int v = 0; v < 2 ; v ++){
List voices = new ArrayList();
for (int m = 0; m < measure.countBeats(); m ++) {
TGBeat beat = measure.getBeat( m );
if( v < beat.countVoices() ){
TGVoice voice = beat.getVoice( v );
if(!voice.isEmpty()){
voices.add( voice );
}
}
}
if( voices.size() > 0 ){
writeInt( voices.size() );
for( int i = 0; i < voices.size() ; i ++ ){
TGVoice voice = (TGVoice) voices.get( i );
writeBeat(voice, voice.getBeat(), measure, ( changeTempo && i == 0 ) );
}
}else{
// Fill empty voices.
int count = measure.getTimeSignature().getNumerator();
TGBeat beat = getFactory().newBeat();
if( v < beat.countVoices() ){
TGVoice voice = beat.getVoice( v );
voice.getDuration().setValue( measure.getTimeSignature().getDenominator().getValue() );
voice.setEmpty(true);
writeInt( count );
for( int i = 0; i < count ; i ++ ){
writeBeat(voice, voice.getBeat(), measure, ( changeTempo && i == 0 ));
}
}
}
}
}
private void writeBeat(TGVoice voice, TGBeat beat, TGMeasure measure, boolean changeTempo) throws IOException {
TGDuration duration = voice.getDuration();
TGNoteEffect effect = getFactory().newEffect();
for (int i = 0; i < voice.countNotes(); i++) {
TGNote playedNote = voice.getNote(i);
if(playedNote.getEffect().isFadeIn()){
effect.setFadeIn(true);
}
if(playedNote.getEffect().isTremoloBar()){
effect.setTremoloBar(playedNote.getEffect().getTremoloBar().clone(getFactory()));
}
if(playedNote.getEffect().isTapping()){
effect.setTapping(true);
}
if(playedNote.getEffect().isSlapping()){
effect.setSlapping(true);
}
if(playedNote.getEffect().isPopping()){
effect.setPopping(true);
}
}
int flags = 0;
if (duration.isDotted() || duration.isDoubleDotted()) {
flags |= 0x01;
}
if (voice.getIndex() == 0 && beat.isChordBeat()) {
flags |= 0x02;
}
if (voice.getIndex() == 0 && beat.isTextBeat()) {
flags |= 0x04;
}
if ( beat.getStroke().getDirection() != TGStroke.STROKE_NONE ){
flags |= 0x08;
}
else if (effect.isTremoloBar() || effect.isTapping() || effect.isSlapping() || effect.isPopping() || effect.isFadeIn()) {
flags |= 0x08;
}
if (changeTempo) {
flags |= 0x10;
}
if (!duration.getDivision().isEqual(TGDivisionType.NORMAL)) {
flags |= 0x20;
}
if (voice.isEmpty() || voice.isRestVoice()) {
flags |= 0x40;
}
writeUnsignedByte(flags);
if ((flags & 0x40) != 0) {
writeUnsignedByte( (voice.isEmpty() ? 0x00 : 0x02) );
}
writeByte(parseDuration(duration));
if ((flags & 0x20) != 0) {
writeInt(duration.getDivision().getEnters());
}
if ((flags & 0x02) != 0) {
writeChord(beat.getChord());
}
if ((flags & 0x04) != 0) {
writeText(beat.getText());
}
if ((flags & 0x08) != 0) {
writeBeatEffects(beat, effect);
}
if ((flags & 0x10) != 0) {
writeMixChange(measure.getTempo());
}
int stringFlags = 0;
if (!voice.isRestVoice()) {
for (int i = 0; i < voice.countNotes(); i++) {
TGNote playedNote = voice.getNote(i);
int string = (7 - playedNote.getString());
stringFlags |= (1 << string);
}
}
writeUnsignedByte(stringFlags);
for (int i = 6; i >= 0; i--) {
if ((stringFlags & (1 << i)) != 0 ) {
for( int n = 0; n < voice.countNotes(); n ++){
TGNote playedNote = voice.getNote( n );
if( playedNote.getString() == (6 - i + 1) ){
writeNote(playedNote);
break;
}
}
}
}
skipBytes(2);
}
private void writeNote(TGNote note) throws IOException {
//int flags = 0x20;
int flags = ( 0x20 | 0x10 );
if (note.getEffect().isVibrato() ||
note.getEffect().isBend() ||
note.getEffect().isSlide() ||
note.getEffect().isHammer() ||
note.getEffect().isLetRing() ||
note.getEffect().isPalmMute() ||
note.getEffect().isStaccato() ||
note.getEffect().isTrill() ||
note.getEffect().isGrace() ||
note.getEffect().isHarmonic() ||
note.getEffect().isTremoloPicking()) {
flags |= 0x08;
}
if( note.getEffect().isGhostNote() ){
flags |= 0x04;
}
if( note.getEffect().isHeavyAccentuatedNote() ){
flags |= 0x02;
}
if( note.getEffect().isAccentuatedNote() ){
flags |= 0x40;
}
writeUnsignedByte(flags);
if ((flags & 0x20) != 0) {
int typeHeader = 0x01;
if (note.isTiedNote()) {
typeHeader = 0x02;
}else if(note.getEffect().isDeadNote()){
typeHeader = 0x03;
}
writeUnsignedByte(typeHeader);
}
if ((flags & 0x10) != 0) {
writeByte((byte)(((note.getVelocity() - TGVelocities.MIN_VELOCITY) / TGVelocities.VELOCITY_INCREMENT) + 1));
}
if ((flags & 0x20) != 0) {
writeByte((byte) note.getValue());
}
skipBytes(1);
if ((flags & 0x08) != 0) {
writeNoteEffects(note.getEffect());
}
}
private byte parseDuration(TGDuration duration) {
byte value = 0;
switch (duration.getValue()) {
case TGDuration.WHOLE:
value = -2;
break;
case TGDuration.HALF:
value = -1;
break;
case TGDuration.QUARTER:
value = 0;
break;
case TGDuration.EIGHTH:
value = 1;
break;
case TGDuration.SIXTEENTH:
value = 2;
break;
case TGDuration.THIRTY_SECOND:
value = 3;
break;
case TGDuration.SIXTY_FOURTH:
value = 4;
break;
}
return value;
}
private void writeChord(TGChord chord) throws IOException{
this.writeBytes( new byte[] {1,1,0,0,0,12,0,0,-1,-1,-1,-1,0,0,0,0,0} );
writeStringByte( chord.getName(), 21);
skipBytes(4);
writeInt( chord.getFirstFret() );
for (int i = 0; i < 7; i++) {
writeInt( (i < chord.countStrings() ? chord.getFretValue(i) : -1 ) ) ;
}
this.skipBytes(32);
}
private void writeBeatEffects(TGBeat beat,TGNoteEffect effect) throws IOException{
int flags1 = 0;
int flags2 = 0;
if(effect.isFadeIn()){
flags1 |= 0x10;
}
if(effect.isTapping() || effect.isSlapping() || effect.isPopping()){
flags1 |= 0x20;
}
if(effect.isTremoloBar()){
flags2 |= 0x04;
}
if(beat.getStroke().getDirection() != TGStroke.STROKE_NONE){
flags1 |= 0x40;
}
writeUnsignedByte(flags1);
writeUnsignedByte(flags2);
if ((flags1 & 0x20) != 0) {
if(effect.isTapping()){
writeUnsignedByte(1);
}else if(effect.isSlapping()){
writeUnsignedByte(2);
}else if(effect.isPopping()){
writeUnsignedByte(3);
}
}
if ((flags2 & 0x04) != 0) {
writeTremoloBar(effect.getTremoloBar());
}
if ((flags1 & 0x40) != 0) {
writeUnsignedByte( (beat.getStroke().getDirection() == TGStroke.STROKE_UP ? toStrokeValue(beat.getStroke()) : 0 ) );
writeUnsignedByte( (beat.getStroke().getDirection() == TGStroke.STROKE_DOWN ? toStrokeValue(beat.getStroke()) : 0 ) );
}
}
private void writeNoteEffects(TGNoteEffect effect) throws IOException {
int flags1 = 0;
int flags2 = 0;
if (effect.isBend()) {
flags1 |= 0x01;
}
if (effect.isHammer()) {
flags1 |= 0x02;
}
if (effect.isLetRing()) {
flags1 |= 0x08;
}
if (effect.isGrace()) {
flags1 |= 0x10;
}
if (effect.isStaccato()) {
flags2 |= 0x01;
}
if (effect.isPalmMute()) {
flags2 |= 0x02;
}
if (effect.isTremoloPicking()) {
flags2 |= 0x04;
}
if (effect.isSlide()) {
flags2 |= 0x08;
}
if (effect.isHarmonic()) {
flags2 |= 0x10;
}
if (effect.isTrill()) {
flags2 |= 0x20;
}
if (effect.isVibrato()) {
flags2 |= 0x40;
}
writeUnsignedByte(flags1);
writeUnsignedByte(flags2);
if ((flags1 & 0x01) != 0) {
writeBend(effect.getBend());
}
if ((flags1 & 0x10) != 0) {
writeGrace(effect.getGrace());
}
if ((flags2 & 0x04) != 0) {
writeTremoloPicking(effect.getTremoloPicking());
}
if ((flags2 & 0x08) != 0) {
writeByte((byte)1);
}
if ((flags2 & 0x10) != 0) {
writeByte((byte)1);
}
if ((flags2 & 0x20) != 0) {
writeTrill(effect.getTrill());
}
}
private void writeBend(TGEffectBend bend) throws IOException {
int points = bend.getPoints().size();
writeByte((byte) 1);
writeInt(0);
writeInt(points);
for (int i = 0; i < points; i++) {
TGEffectBend.BendPoint point = (TGEffectBend.BendPoint) bend.getPoints().get(i);
writeInt( (point.getPosition() * GP_BEND_POSITION / TGEffectBend.MAX_POSITION_LENGTH) );
writeInt( (point.getValue() * GP_BEND_SEMITONE / TGEffectBend.SEMITONE_LENGTH) );
writeByte((byte) 0);
}
}
private void writeTremoloBar(TGEffectTremoloBar tremoloBar) throws IOException {
int points = tremoloBar.getPoints().size();
writeByte((byte) 1);
writeInt(0);
writeInt(points);
for (int i = 0; i < points; i++) {
TGEffectTremoloBar.TremoloBarPoint point = (TGEffectTremoloBar.TremoloBarPoint) tremoloBar.getPoints().get(i);
writeInt( (point.getPosition() * GP_BEND_POSITION / TGEffectBend.MAX_POSITION_LENGTH) );
writeInt( (point.getValue() * (GP_BEND_SEMITONE * 2)) );
writeByte((byte) 0);
}
}
private void writeGrace(TGEffectGrace grace) throws IOException {
writeUnsignedByte(grace.getFret());
writeUnsignedByte(((grace.getDynamic() - TGVelocities.MIN_VELOCITY) / TGVelocities.VELOCITY_INCREMENT) + 1);
if(grace.getTransition() == TGEffectGrace.TRANSITION_NONE){
writeUnsignedByte(0);
}
else if(grace.getTransition() == TGEffectGrace.TRANSITION_SLIDE){
writeUnsignedByte(1);
}
else if(grace.getTransition() == TGEffectGrace.TRANSITION_BEND){
writeUnsignedByte(2);
}
else if(grace.getTransition() == TGEffectGrace.TRANSITION_HAMMER){
writeUnsignedByte(3);
}
writeUnsignedByte(grace.getDuration());
writeUnsignedByte( (grace.isDead() ? 0x01 : 0) | (grace.isOnBeat() ? 0x02 : 0) );
}
private void writeTrill(TGEffectTrill trill) throws IOException {
writeByte((byte)trill.getFret());
if(trill.getDuration().getValue() == TGDuration.SIXTEENTH){
writeByte((byte)1);
}else if(trill.getDuration().getValue() == TGDuration.THIRTY_SECOND){
writeByte((byte)2);
}else if(trill.getDuration().getValue() == TGDuration.SIXTY_FOURTH){
writeByte((byte)3);
}
}
private void writeTremoloPicking(TGEffectTremoloPicking tremoloPicking) throws IOException{
if(tremoloPicking.getDuration().getValue() == TGDuration.EIGHTH){
writeByte((byte)1);
}else if(tremoloPicking.getDuration().getValue() == TGDuration.SIXTEENTH){
writeByte((byte)2);
}else if(tremoloPicking.getDuration().getValue() == TGDuration.THIRTY_SECOND){
writeByte((byte)3);
}
}
private void writeText(TGText text) throws IOException {
writeStringByteSizeOfInteger(text.getValue());
}
private void writeMixChange(TGTempo tempo) throws IOException {
writeByte((byte) 0xff);
for(int i = 0; i < 16; i++){
writeByte((byte) 0xff);
}
writeByte((byte) 0xff); //volume
writeByte((byte) 0xff); //int pan
writeByte((byte) 0xff); //int chorus
writeByte((byte) 0xff); //int reverb
writeByte((byte) 0xff); //int phaser
writeByte((byte) 0xff); //int tremolo
writeStringByteSizeOfInteger(""); //tempo name
writeInt((tempo != null)?tempo.getValue():-1); //tempo value
if((tempo != null)){
skipBytes(1);
}
writeByte((byte)1);
writeByte((byte)0xff);
}
private void writeMarker(TGMarker marker) throws IOException {
writeStringByteSizeOfInteger(marker.getTitle());
writeColor(marker.getColor());
}
private void writeColor(TGColor color) throws IOException {
writeUnsignedByte(color.getR());
writeUnsignedByte(color.getG());
writeUnsignedByte(color.getB());
writeByte((byte)0);
}
private TGChannel[] makeChannels(TGSong song) {
TGChannel[] channels = new TGChannel[64];
for (int i = 0; i < channels.length; i++) {
channels[i] = getFactory().newChannel();
channels[i].setProgram((short)24);
channels[i].setVolume((short)13);
channels[i].setBalance((short)8);
channels[i].setChorus((short)0);
channels[i].setReverb((short)0);
channels[i].setPhaser((short)0);
channels[i].setTremolo((short)0);
}
Iterator it = song.getChannels();
while (it.hasNext()) {
TGChannel tgChannel = (TGChannel) it.next();
GMChannelRoute gmChannelRoute = getChannelRoute(tgChannel.getChannelId());
channels[gmChannelRoute.getChannel1()].setProgram(tgChannel.getProgram());
channels[gmChannelRoute.getChannel1()].setVolume(tgChannel.getVolume());
channels[gmChannelRoute.getChannel1()].setBalance(tgChannel.getBalance());
channels[gmChannelRoute.getChannel2()].setProgram(tgChannel.getProgram());
channels[gmChannelRoute.getChannel2()].setVolume(tgChannel.getVolume());
channels[gmChannelRoute.getChannel1()].setBalance(tgChannel.getBalance());
}
return channels;
}
private byte[] makeBeamEighthNoteBytes(TGTimeSignature ts){
byte[] bytes = new byte[]{0,0,0,0};
if( ts.getDenominator().getValue() <= TGDuration.EIGHTH ){
int eighthsInDenominator = (TGDuration.EIGHTH / ts.getDenominator().getValue());
int total = (eighthsInDenominator * ts.getNumerator());
int byteValue = ( total / 4 );
int missingValue = ( total - (4 * byteValue) );
for( int i = 0 ; i < bytes.length; i ++ ){
bytes[i] = (byte)byteValue;
}
if( missingValue > 0 ){
bytes[0] += missingValue;
}
}
return bytes;
}
private int toStrokeValue( TGStroke stroke ){
if( stroke.getValue() == TGDuration.SIXTY_FOURTH ){
return 2;
}
if( stroke.getValue() == TGDuration.THIRTY_SECOND ){
return 3;
}
if( stroke.getValue() == TGDuration.SIXTEENTH ){
return 4;
}
if( stroke.getValue() == TGDuration.EIGHTH ){
return 5;
}
if( stroke.getValue() == TGDuration.QUARTER ){
return 6;
}
return 2;
}
private byte toChannelByte(short s){
return (byte) ((s + 1) / 8);
}
private List toCommentLines( String comments ){
List lines = new ArrayList();
String line = comments;
while( line.length() > Byte.MAX_VALUE ) {
String subline = line.substring(0, Byte.MAX_VALUE);
lines.add( subline );
line = line.substring( Byte.MAX_VALUE );
}
lines.add( line );
return lines;
}
}