Pregunta

Quiero utilizar JFugue para jugar un poco de música MIDI en un applet. Hay una clase para el patrón de MIDI - Pattern - y el único método para cargar el patrón es de un archivo. Ahora, yo no sé cómo applets de archivos de carga y lo que no, pero yo estoy usando un marco (PulpCore) que hace que los activos de carga una tarea sencilla. Si tengo que agarrar un activo de un catálogo postal, puedo utilizar la clase Assets que proporciona métodos y get() getAsStream(). get() devuelve el activo dado como ByteArray, el otro como un InputStream.

Necesito JFugue para cargar el patrón de cualquiera ByteArray o InputStream. En pseudo-código, me gustaría hacer esto:

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

Sin embargo, no hay ningún constructor del archivo que tomaría un ByteArray. Sugerencias, por favor?

¿Fue útil?

Solución

Es cierto que JFugue no permite a cualquier cosa, pero la carga de un archivo, lo cual es una lástima, porque impide nada de usar cualquier otro tipo de corriente:

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 (para 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;
}

Otros consejos

Si no estoy equivocado, los archivos de patrones contienen texto sin formato. Cargar el archivo con getAsStream (), luego convertirlo en una cadena utilizando

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

Donde yourStream es el InputStream devuelto por getAsStream (). A continuación, utilice el método add (String ... patrones) para cargar el patrón:

add(pattern);

Se puede utilizar este código (tomado de la aplicación del método Pattern.loadPattern()):

    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

Se podía leer la matriz de bytes y convertirlo en una cadena.

El problema será el InputStream. Hay una StringBufferInputStream, pero es utilizar para sustituirla por StringReader.

byte [] b = Assets.get();
InputStream is = new StringBufferInputStream(new String(b));
Pattern.load(is);

Usted no desea utilizar File, que desea utilizar java.io.ByteArrayInputStream

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top