Tux Guitar

Open Discussion

Subject Java to C++ translation problems



Author Message
Hanz
Post: Jun 3rd 2010 at 8:36 PM

I'm trying to translate parts of the tuxguitar code to c++. But I have no idea how to translate this method correctly:

private String newString(byte[] bytes, int length, String charset) {
try
{
String s = new String(new String(bytes, 0, length, charset).getBytes(DEFAULT_TG_CHARSET), DEFAULT_TG_CHARSET);
System.out.println(s);
return s;
} catch (Throwable e) {
e.printStackTrace();
}
return new String(bytes, 0, length);
}

Since I am only using DEFAULT_TG_CHARSET (=UTF8) I don't need the 3rd parameter. But how do I convert a char* to an UTF8 string? This is the code I am currently using:

string readString(int size, int len)
{
int length = (size > 0 ? size : len);
char* bytes = new char[length];

stream.read(bytes, length);

std::string str;
str += bytes;

return str;
}

I hope anyone here has has an idea!


Back to Top
 
julian
Post: Jun 3rd 2010 at 9:17 PM

Im not sure how to convert it in C++, but don't you have to know the source encoding before ? i didn't find a way to autodetect it with java, even with GP application it seems to be impossible.. just seems that if you make a GP file with jappanese version, and then you open it in the spanish version, the strings characters are all wrong. this was the reason because i added the Charset setup..


Back to Top
 
Hanz
Post: Jun 3rd 2010 at 10:35 PM

I only had a look at the classes GTPFileFormat and GP5InputStream (since I am focussing on GP5 files) and found the variable DEFAULT_TG_CHARSET, so I assumed utf8 should work for the majority of gp5-files. My solution doesn't have to be perfect, so if I can't read japanese characters it's ok.


Back to Top
 
Julian
Post: Jun 3rd 2010 at 11:53 PM

Note that the default GTP charset is "ISO-8859-15"
the DEFAULT_TG_CHARSET, is the used by tuxguitar.

However, the most important thing here, is to read all bytes.
then they can display a good or a bad string, but only if you read the exactly byte cound you can continue reading next chars..
and as i saw, i think your code have to work without problems for that.


Back to Top
 
Hanz
Post: Jun 4th 2010 at 11:27 PM

ok, most of the characters seem be ok even without converting them. So I won't spend more time on that.

I'm not yet done with reading the files, but later I'd like to play the song and display the notes/tabs that are currently played. Where exactly do I find the code that reads data from the class TGSong and transforms it to MIDI?


Back to Top
 
Julian
Post: Jun 4th 2010 at 11:38 PM

the TG Player is at:
org.herac.tuxguitar.player.base.MidiPlayer

And this is the class that make all midi events:
org.herac.tuxguitar.player.base.MidiSequenceParser


Back to Top
 
Hanz
Post: Jun 5th 2010 at 10:10 PM

I don't know.. for some reason I wasn't able to parse GP5 files, but at least it worked for GP4 files :) .

Before translating the MIDI package I'd first like to get a working java-code that plays the file, but I can't figure out how to do this.

This is my current code:


public static void main(String[] args) {
GP4InputStream gp4 = new GP4InputStream(new GTPSettings());

try {
String path = "C: est.gp4";
InputStream in = new FileInputStream(new File(path));
gp4.init(new TGFactory(), in);
TGSong song = gp4.readSong();

TGSongManager mgr = new TGSongManager();
mgr.setSong(song);

MidiPlayer player = new MidiPlayer();
player.init(mgr);
player.play();

} catch (GTPFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (MidiPlayerException e) {
e.printStackTrace();
}

}

I hope you can help me again.


Back to Top
 
Julian
Post: Jun 6th 2010 at 2:31 PM

> or some reason I wasn't able to parse GP5 files,
Are they really GP5 files ? or just the extension ?

The code you made is fine. but you are missing MIDI devices.
The MidiPlayer is like a manager, but it don't make the sounds.
So you need the Sequencer, and the OutputPort.

try add this code, beetween player.init(mgr) and player.play();

// ===============

player.addSequencerProvider(new org.herac.tuxguitar.player.impl.sequencer.MidiSequencerProviderImpl());
player.addOutputPortProvider(new org.herac.tuxguitar.player.impl.jsa.midiport.MidiPortProviderImpl());

player.openSequencer("tuxguitar.sequencer");
player.openOutputPort("Java Sound Synthesizer");

// ===============


This is assuming you have tuxguitar-jsa classes ( that provides Java Sound Synthesizer ) that is the "easier" example to test.

Then i suggest you take a look to TuxGuitar-winmm, that uses JNI (java native interface) to work with the winmm API. so there you have the C code to play the MIDI Sounds.

If you need to see what MIDI Ports you have available, you can do:

Iterator it = player.listOutputPorts().iterator();
while( it.hasNext() ){
MidiOutputPort port = (MidiOutputPort) it.next();
System.out.println( port.getKey() + " " + port.getName() );
}


Back to Top
 
Hanz
Post: Jun 7th 2010 at 2:03 PM

now it's working, thanks!

I guess translating this may take longer than expected, there were lots of classes I had to import ;) .


Back to Top
 
Julian
Post: Jun 7th 2010 at 2:24 PM

Well you don't have to translate all of these... if you want to make the Midi Sequence, you only need the MidiSequenceParser class, and reimplement the way it makes the MidiEvents. then the winmm API should have it's own MIDI sequencer,
I used this way, to have a plugin support, so as you see it don't depends on the Java sound API, it's a plugin but it can work with other APIs ( having native plugins such as winmm for windows, alsa/oss for linux, and some others like fluidsynth/jack ) and also because there were some java alternatives that didn't had java sound API support.


Back to Top
 
Hanz
Post: Jun 13th 2010 at 4:20 PM

ok, so far I've tried to understand your code and managed to implemented the MidiSequencerParser. All MidiEvents are stored in a MidiEventPlayer, of which the MidiSequencerImpl holds a reference.

Now I'd like to play the song. Therefore you're using several classes like MidiEventDispatcher, MidiTransmitter, MidiReceiver and so on.. but I think that's too complicated for my needs.

Since all events are stored in the MidiEventPlayer couldn't I just process them sequentially (I assume they are sorted by the time of their occurance, right?) like this:

- process current event
- sleep for the amount of time until the next event
- process next event
- and so on..


Back to Top
 
Julian
Post: Jun 13th 2010 at 5:22 PM

Let's define these items before:

* Midi Sequence: imagine a MIDI File.. it's just a list of midi events, with a tick position for each one.

* Midi Sequencer: this is the sequence player, it checks when is time to fire a midi event, and send the midi message to a synthesizer.

* Midi Synthesizer: and this one is who receibe the midi messages to play/stop sounds.

So, you basically needs MidiSequenceParser to know how to create the Midi Sequence from a TGSong..
Then this of MidiEventPlayer is part of the TuxGuitar Sequencer, a MidiSequencer implementation, while you don't should need it.. just look for any existing midi sequencer for C++, doesn't the winmm API provide one ?

Take a look to the MidiSequenceParser, it don't creates a MidiSequence object, but uses a MidiSequenceHandler interface, and here is where you could end with tuxguitar. just rewrite that sequence handler methods..

something like
addNoteOn(long tick,int track,int channel,int note,int velocity)
{
// 1_ you create a NOTE_ON Midi Message.
// 2_ then you create a Midi Event for this message at the "tick" position
// 3_ then you can add the Midi Event, to the MidiSequence/MidiFile
}


Back to Top
 
Hanz
Post: Aug 25th 2010 at 10:31 PM

after some time off I'm now working on the project again. In the meantime I was able to play the midi events (although some instruments are not correct yet).

Anyway, the next step is to display the tablature. I'd like to develop something like a simplified 2D version of guitar hero's GUI, where instead of buttons the tablature is displayed.

I only need to access the tablature information of one track. But I'm not sure how to do this.

Could you please tell me where I find the corresponding code in tuxguitar?


Back to Top