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