Add basic application

This commit is contained in:
coderkun 2020-12-25 20:12:40 +01:00
commit badeb5e843
3 changed files with 314 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/build/
/.gradle/

16
build.gradle Normal file
View file

@ -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")
}

View file

@ -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<TGTrack> getDrumTracks(TGSong song) {
List<TGTrack> drumTracks = new ArrayList<>();
Iterator<TGTrack> 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<TGNote> consumer) {
// Traverse all measures
Iterator<TGMeasure> 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<beat.countVoices(); v++) {
TGVoice voice = beat.getVoice(v);
// Traverse all notes
for(TGNote note : voice.getNotes()) {
consumer.accept(note);
}
}
}
}
}
/**
* Run the application.
*
* @param args Commandline arguments.
*/
public static void main(String[] args) {
// Parse arguments
File sourceFile;
File targetFile;
if(args.length < 1) {
System.err.println("Please specify an input file");
System.exit(1);
}
sourceFile = new File(args[0]);
if(args.length > 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);
}
}
}