Add basic application
This commit is contained in:
commit
badeb5e843
3 changed files with 314 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/build/
|
||||||
|
/.gradle/
|
16
build.gradle
Normal file
16
build.gradle
Normal 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")
|
||||||
|
}
|
296
src/main/java/xyz/suruatoel/tuxguitar/drumsheets/Drumsheets.java
Normal file
296
src/main/java/xyz/suruatoel/tuxguitar/drumsheets/Drumsheets.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue