views:

296

answers:

5

I want to use jFuge to play some MIDI music in an applet. There's a class for the MIDI pattern - Pattern - and the only method to load the pattern is from a File. Now, I don't know how applets load files and what not, but I am using a framework (PulpCore) that makes loading assets a simple task. If I need to grab an asset from a ZIP catalogue, I can use the Assets class which provides get() and getAsStream() methods. get() returns the given asset as a ByteArray, the other as an InputStream.

I need jFuge to load the pattern from either ByteArray or InputStream. In pseudo-code, I would like to do this:

Pattern.load(new File(Assets.get("mymidifile.midi")));

however there is no File constructor that would take a ByteArray. Suggestions, please?

A: 

You could read the byte array and turn it into a String.

The problem will be the InputStream. There's a StringBufferInputStream, but it's deprecated in favor of StringReader.

byte [] b = Assets.get();
InputStream is = new StringBufferInputStream(new String(b));
Pattern.load(is);
duffymo
What could this possibly do other than corrupting the data?
Michael Borgwardt
Wow - why the down vote?
duffymo
Now I know......
duffymo
Look at that - not so far off after all.
duffymo
After a third look, it's wrong again :)
Michael Borgwardt
A: 

You don't want to use File, you want to use java.io.ByteArrayInputStream

Rob Di Marco
This is not useful, we've been told that the Pattern.load only takes a file as an argument.
Geoff
+1  A: 

If I am not wrong, the Pattern files contain plain text. Load the file using getAsStream(), then convert it into a string using

BufferedReader br = new BufferedReader(new InputStreamReader(yourStream));
//...
String pattern = convertToString(br); // you should implement convertToString yourself. It's easy. Read the java.io APIs.

Where yourStream is the InputStream returned by getAsStream(). Then use the add(String... patterns) method to load the pattern:

add(pattern);
Bytecode Ninja
This seems like the best choice to me. You can see on the examples page (http://www.jfugue.org/examples.html) that pattern can be constructed with a Stirng if you'd prefer. Pattern pattern = new Pattern( convertToString( getInputStream() ) );
Geoff
looks good, i tried, but i got error messages. the file contains some non-music data, title, author, or whatever and it would parse. I went for one of the more complete examples posted below.
Peter Perháč
+1  A: 

You can use this code (taken from the implementation of the Pattern.loadPattern() method):

    InputStream is = ...; // Get a stream from the Asset object

    // Prepare a pattern object
    Pattern pattern = new Pattern();

    // Now start reaing from the stream
    StringBuffer buffy = new StringBuffer();
    BufferedReader bread = new BufferedReader(new InputStreamReader(is));
    while (bread.ready()) {
        String s = bread.readLine();
        if ((s != null) && (s.length() > 1)) {
            if (s.charAt(0) != '#') {
                buffy.append(" ");
                buffy.append(s);
            } else {
                String key = s.substring(1, s.indexOf(':')).trim();
                String value = s.substring(s.indexOf(':')+1, s.length()).trim();
                if (key.equalsIgnoreCase(TITLE)) {
                    pattern.setTitle(value);
                } else {
                    pattern.setProperty(key, value);
                }
            }
        }
    }
    bread.close();
    pattern.setMusicString(buffy.toString());

    // Your pattern is now ready
Itay
+2  A: 

It's true that jFugue doesn't allow to load anything but a file, which is a shame because nothing prevents from using any other kind of stream:

public static final String TITLE = "Title";

public static Pattern loadPattern(File file) throws IOException {
    InputStream in = new FileInputStream(file);
    try {
        return loadPattern(in);
    } finally {
        in.close();
    }
}

public static Pattern loadPattern(URL url) throws IOException {
    InputStream in = url.openStream();
    try {
        return loadPattern(in);
    } finally {
        in.close();
    }
}

public static Pattern loadPattern(InputStream in) throws IOException {
    return loadPattern(new InputStreamReader(in, "UTF-8")); // or ISO-8859-1 ?
}

public static Pattern loadPattern(Reader reader) throws IOException {
    if (reader instanceof BufferedReader) {
        return loadPattern(reader);
    } else {
        return loadPattern(new BufferedReader(reader));
    }
}

public static Pattern loadPattern(BufferedReader bread) throws IOException {
    StringBuffer buffy = new StringBuffer();

    Pattern pattern = new Pattern();
    while (bread.ready()) {
        String s = bread.readLine();
        if ((s != null) && (s.length() > 1)) {
            if (s.charAt(0) != '#') {
                buffy.append(" ");
                buffy.append(s);
            } else {
                String key = s.substring(1, s.indexOf(':')).trim();
                String value = s.substring(s.indexOf(':')+1, s.length()).trim();
                if (key.equalsIgnoreCase(TITLE)) {
                    pattern.setTitle(value);
                } else {
                    pattern.setProperty(key, value);
                }
            }
        }
    }
    return pattern;
}

UPDATE (for loadMidi)

public static Pattern loadMidi(InputStream in) throws IOException, InvalidMidiDataException
{
    MidiParser parser = new MidiParser();
    MusicStringRenderer renderer = new MusicStringRenderer();
    parser.addParserListener(renderer);
    parser.parse(MidiSystem.getSequence(in));
    Pattern pattern = new Pattern(renderer.getPattern().getMusicString());
    return pattern;
}

public static Pattern loadMidi(URL url) throws IOException, InvalidMidiDataException
{
    MidiParser parser = new MidiParser();
    MusicStringRenderer renderer = new MusicStringRenderer();
    parser.addParserListener(renderer);
    parser.parse(MidiSystem.getSequence(url));
    Pattern pattern = new Pattern(renderer.getPattern().getMusicString());
    return pattern;
}
Maurice Perry
using this code the file is loaded without errors but won't play. I am completely losing my mind now. all i wanted was to load a midi and play it.
Peter Perháč
I guess you should use loadMidi to load a midi file
Maurice Perry