From badeb5e84338d33a0ad1b9f59f67a94782d7898d Mon Sep 17 00:00:00 2001 From: coderkun Date: Fri, 25 Dec 2020 20:12:40 +0100 Subject: [PATCH] Add basic application --- .gitignore | 2 + build.gradle | 16 + .../tuxguitar/drumsheets/Drumsheets.java | 296 ++++++++++++++++++ 3 files changed, 314 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle create mode 100644 src/main/java/xyz/suruatoel/tuxguitar/drumsheets/Drumsheets.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c9cf9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build/ +/.gradle/ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..d71704c --- /dev/null +++ b/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'java' + id 'application' +} + +description = """TuxGuitar Drumsheets""" +group = 'xyz.suruatoel.tuxguitar.drumsheets' +version = '0.1.0' + +dependencies { + implementation files('/usr/share/tuxguitar/lib/tuxguitar-lib.jar') +} + +application { + mainClass.set("xyz.suruatoel.tuxguitar.drumsheets.Drumsheets") +} diff --git a/src/main/java/xyz/suruatoel/tuxguitar/drumsheets/Drumsheets.java b/src/main/java/xyz/suruatoel/tuxguitar/drumsheets/Drumsheets.java new file mode 100644 index 0000000..f0f294a --- /dev/null +++ b/src/main/java/xyz/suruatoel/tuxguitar/drumsheets/Drumsheets.java @@ -0,0 +1,296 @@ +package xyz.suruatoel.tuxguitar.drumsheets; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; + +import org.herac.tuxguitar.graphics.control.TGFactoryImpl; +import org.herac.tuxguitar.io.base.TGSongReader; +import org.herac.tuxguitar.io.base.TGSongReaderHandle; +import org.herac.tuxguitar.io.base.TGSongWriter; +import org.herac.tuxguitar.io.base.TGSongWriterHandle; +import org.herac.tuxguitar.io.tg.TGSongReaderImpl; +import org.herac.tuxguitar.io.tg.TGSongWriterImpl; +import org.herac.tuxguitar.song.factory.TGFactory; +import org.herac.tuxguitar.song.models.TGBeat; +import org.herac.tuxguitar.song.models.TGMeasure; +import org.herac.tuxguitar.song.models.TGNote; +import org.herac.tuxguitar.song.models.TGSong; +import org.herac.tuxguitar.song.models.TGTrack; +import org.herac.tuxguitar.song.models.TGVoice; + + + +/** + * Application to clean drumset tracks in TuxGuitar files. + */ +public class Drumsheets { + /** + * TuxGuitar factory + */ + private TGFactory factory; + /** + * TuxGuitar song reader + */ + private TGSongReader songReader; + /** + * TuxGuitar song writer + */ + private TGSongWriter songWriter; + + + + + /** + * Create a new drumsheet instance. + */ + public Drumsheets() { + this.factory = new TGFactoryImpl(); + this.songReader = new TGSongReaderImpl(); + this.songWriter = new TGSongWriterImpl(); + } + + + /** + * Read a tg file as TuxGuitar song. + * + * @param file TG file to read + * @return TuxGuitar song + * @throws IOException Failed to read file + */ + public TGSong readSong(File file) throws IOException { + System.out.println(String.format("Reading song file: %s", file.getAbsolutePath())); + try(InputStream is = new FileInputStream(file)) { + TGSongReaderHandle songHandle = new TGSongReaderHandle(); + songHandle.setFactory(this.factory); + songHandle.setInputStream(is); + + this.songReader.read(songHandle); + + return songHandle.getSong(); + } + } + + + /** + * Write a TuxGuitar song as tg file. + * + * @param song TuxGuitar song to write + * @param file File to write song to + * @throws IOException Failed to write file + */ + public void writeSong(TGSong song, File file) throws IOException { + System.out.println(String.format("Writing song file: %s", file.getAbsolutePath())); + try(OutputStream os = new FileOutputStream(file)) { + TGSongWriterHandle songHandle = new TGSongWriterHandle(); + songHandle.setSong(song); + songHandle.setOutputStream(os); + + this.songWriter.write(songHandle); + } + } + + + /** + * Get all drum tracks of a TuxGuitar song. + * + * @param song TuxGuitar song to get drum tracks of + * @return List of TuxGuitar tracks + */ + public List getDrumTracks(TGSong song) { + List drumTracks = new ArrayList<>(); + Iterator it = song.getTracks(); + while(it.hasNext()) { + TGTrack track = it.next(); + // TODO Use a more reliable way to detect drum track + if(track.getName().equals("Drumkit")) { + drumTracks.add(track); + } + } + + return drumTracks; + } + + + /** + * Apply all (currently hard coded) fixes for all drum tracks of a song. + * + * @param song TuxGuitar song to fix drum tracks of + */ + public void fixDrums(TGSong song) { + System.out.println("Fix drums"); + for(TGTrack drumTrack : getDrumTracks(song)) { + fixDrum(drumTrack); + } + } + + + /** + * Apply all (currently hard coded) fixes for a drum track. + * + * @param drumTrack TuxGuitar drum track to fix + */ + public void fixDrum(TGTrack drumTrack) { + System.out.println(String.format("Fix drum track: %s", drumTrack.getName())); + + // Crash cymbals + changeNoteString(drumTrack, 57, 1); + changeNoteString(drumTrack, 49, 1); + // China cymbal + changeNoteString(drumTrack, 52, 1); + // Hi-Hat + changeNoteString(drumTrack, 46, 2); + changeNoteString(drumTrack, 42, 2); + // Ride cymbal + changeNoteString(drumTrack, 51, 2); + changeNoteString(drumTrack, 53, 2); + // Snare drum + fixDrumNote(drumTrack, 38, 40); + changeNoteString(drumTrack, 40, 3); + // Toms + fixDrumNote(drumTrack, 50, 48); + changeNoteString(drumTrack, 48, 4); + fixDrumNote(drumTrack, 47, 45); + changeNoteString(drumTrack, 45, 4); + changeNoteString(drumTrack, 43, 5); + changeNoteString(drumTrack, 41, 5); + // Bass drum + changeNoteString(drumTrack, 36, 6); + } + + + /** + * Move a note of a track to a string. + * + * @param track TuxGuitar track to change note of + * @param note Value of note to change + * @param string String to move note to + */ + public void changeNoteString(TGTrack track, int note, int string) { + // Check if target string exists + if(string > track.stringCount()) { + System.err.println( + String.format( + "Cannot move note %d to string %d, string doas not exist", + note, + string + ) + ); + } + + eachNote( + track, + tgNote -> { + if(tgNote.getValue() == note && tgNote.getString() != string) { + System.out.println( + String.format( + "Move note %d from string %d to %d", + tgNote.getValue(), + tgNote.getString(), + string + ) + ); + tgNote.setString(string); + } + } + ); + } + + + /** + * Change a note to another note. + * + * @param track TuxGuitar track to change note of + * @param sourceNote Value of note to change + * @param targetNote Value to change note to + */ + public void fixDrumNote(TGTrack track, int sourceNote, int targetNote) { + eachNote( + track, + note -> { + if(note.getValue() == sourceNote) { + System.out.println(String.format("Change note %d to %d", sourceNote, targetNote)); + note.setValue(targetNote); + } + } + ); + } + + + /** + * Call a consumer for each note of a track. + * + * @param track TuxGuitar track to traverse notes of + * @param consumer Consumer to call for each note + */ + private void eachNote(TGTrack track, Consumer consumer) { + // Traverse all measures + Iterator measureIt = track.getMeasures(); + while(measureIt.hasNext()) { + TGMeasure measure = measureIt.next(); + + // Traverse all beats + for(TGBeat beat : measure.getBeats()) { + // Traverse all voices + for(int v=0; v 1) { + targetFile = new File(args[1]); + } + else { + targetFile = sourceFile; + } + + // Create application instance + Drumsheets sheet = new Drumsheets(); + try { + // Read file + TGSong song = sheet.readSong(sourceFile); + + // Fix drumset + sheet.fixDrums(song); + + // Write file + sheet.writeSong(song, targetFile); + } + catch(IOException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + } + +}