Search in sources :

Example 1 with MidiMessage

use of javax.sound.midi.MidiMessage in project jdk8u_jdk by JetBrains.

the class SoftMidiAudioFileReader method getAudioInputStream.

public AudioInputStream getAudioInputStream(Sequence seq) throws UnsupportedAudioFileException, IOException {
    AudioSynthesizer synth = (AudioSynthesizer) new SoftSynthesizer();
    AudioInputStream stream;
    Receiver recv;
    try {
        stream = synth.openStream(format, null);
        recv = synth.getReceiver();
    } catch (MidiUnavailableException e) {
        throw new IOException(e.toString());
    }
    float divtype = seq.getDivisionType();
    Track[] tracks = seq.getTracks();
    int[] trackspos = new int[tracks.length];
    int mpq = 500000;
    int seqres = seq.getResolution();
    long lasttick = 0;
    long curtime = 0;
    while (true) {
        MidiEvent selevent = null;
        int seltrack = -1;
        for (int i = 0; i < tracks.length; i++) {
            int trackpos = trackspos[i];
            Track track = tracks[i];
            if (trackpos < track.size()) {
                MidiEvent event = track.get(trackpos);
                if (selevent == null || event.getTick() < selevent.getTick()) {
                    selevent = event;
                    seltrack = i;
                }
            }
        }
        if (seltrack == -1)
            break;
        trackspos[seltrack]++;
        long tick = selevent.getTick();
        if (divtype == Sequence.PPQ)
            curtime += ((tick - lasttick) * mpq) / seqres;
        else
            curtime = (long) ((tick * 1000000.0 * divtype) / seqres);
        lasttick = tick;
        MidiMessage msg = selevent.getMessage();
        if (msg instanceof MetaMessage) {
            if (divtype == Sequence.PPQ) {
                if (((MetaMessage) msg).getType() == 0x51) {
                    byte[] data = ((MetaMessage) msg).getData();
                    if (data.length < 3) {
                        throw new UnsupportedAudioFileException();
                    }
                    mpq = ((data[0] & 0xff) << 16) | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
                }
            }
        } else {
            recv.send(msg, curtime);
        }
    }
    long totallen = curtime / 1000000;
    long len = (long) (stream.getFormat().getFrameRate() * (totallen + 4));
    stream = new AudioInputStream(stream, stream.getFormat(), len);
    return stream;
}
Also used : MidiUnavailableException(javax.sound.midi.MidiUnavailableException) MidiMessage(javax.sound.midi.MidiMessage) Receiver(javax.sound.midi.Receiver) MidiEvent(javax.sound.midi.MidiEvent) IOException(java.io.IOException) AudioInputStream(javax.sound.sampled.AudioInputStream) UnsupportedAudioFileException(javax.sound.sampled.UnsupportedAudioFileException) MetaMessage(javax.sound.midi.MetaMessage) Track(javax.sound.midi.Track)

Example 2 with MidiMessage

use of javax.sound.midi.MidiMessage in project tika by apache.

the class MidiParser method parse.

public void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException {
    metadata.set(Metadata.CONTENT_TYPE, "audio/midi");
    XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
    xhtml.startDocument();
    // MidiSystem expects the stream to support the mark feature
    if (!stream.markSupported()) {
        stream = new BufferedInputStream(stream);
    }
    try {
        Sequence sequence = MidiSystem.getSequence(stream);
        Track[] tracks = sequence.getTracks();
        metadata.set("tracks", String.valueOf(tracks.length));
        // TODO: Use XMPDM.TRACKS?
        Patch[] patches = sequence.getPatchList();
        metadata.set("patches", String.valueOf(patches.length));
        float type = sequence.getDivisionType();
        if (type == Sequence.PPQ) {
            metadata.set("divisionType", "PPQ");
        } else if (type == Sequence.SMPTE_24) {
            metadata.set("divisionType", "SMPTE_24");
        } else if (type == Sequence.SMPTE_25) {
            metadata.set("divisionType", "SMPTE_25");
        } else if (type == Sequence.SMPTE_30) {
            metadata.set("divisionType", "SMPTE_30");
        } else if (type == Sequence.SMPTE_30DROP) {
            metadata.set("divisionType", "SMPTE_30DROP");
        } else if (type == Sequence.SMPTE_24) {
            metadata.set("divisionType", String.valueOf(type));
        }
        for (Track track : tracks) {
            xhtml.startElement("p");
            for (int i = 0; i < track.size(); i++) {
                MidiMessage message = track.get(i).getMessage();
                if (message instanceof MetaMessage) {
                    MetaMessage meta = (MetaMessage) message;
                    // Types 1-15 are reserved for text events
                    if (meta.getType() >= 1 && meta.getType() <= 15) {
                        // FIXME: What's the encoding?
                        xhtml.characters(new String(meta.getData(), ISO_8859_1));
                    }
                }
            }
            xhtml.endElement("p");
        }
    } catch (InvalidMidiDataException ignore) {
    // There is no way to know whether this exception was
    // caused by the document being corrupted or by the format
    // just being unsupported. So we do nothing.
    }
    xhtml.endDocument();
}
Also used : InvalidMidiDataException(javax.sound.midi.InvalidMidiDataException) MidiMessage(javax.sound.midi.MidiMessage) Sequence(javax.sound.midi.Sequence) XHTMLContentHandler(org.apache.tika.sax.XHTMLContentHandler) BufferedInputStream(java.io.BufferedInputStream) MetaMessage(javax.sound.midi.MetaMessage) Patch(javax.sound.midi.Patch) Track(javax.sound.midi.Track)

Example 3 with MidiMessage

use of javax.sound.midi.MidiMessage in project jdk8u_jdk by JetBrains.

the class SMFParser method readTrack.

void readTrack(Track track) throws IOException, InvalidMidiDataException {
    try {
        // reset current tick to 0
        long tick = 0;
        // reset current status byte to 0 (invalid value).
        // this should cause us to throw an InvalidMidiDataException if we don't
        // get a valid status byte from the beginning of the track.
        int status = 0;
        boolean endOfTrackFound = false;
        while (!trackFinished() && !endOfTrackFound) {
            MidiMessage message;
            // initialize to invalid value
            int data1 = -1;
            int data2 = 0;
            // each event has a tick delay and then the event data.
            // first read the delay (a variable-length int) and update our tick value
            tick += readVarInt();
            // check for new status
            int byteValue = readUnsigned();
            if (byteValue >= 0x80) {
                status = byteValue;
            } else {
                data1 = byteValue;
            }
            switch(status & 0xF0) {
                case 0x80:
                case 0x90:
                case 0xA0:
                case 0xB0:
                case 0xE0:
                    // two data bytes
                    if (data1 == -1) {
                        data1 = readUnsigned();
                    }
                    data2 = readUnsigned();
                    message = new FastShortMessage(status | (data1 << 8) | (data2 << 16));
                    break;
                case 0xC0:
                case 0xD0:
                    // one data byte
                    if (data1 == -1) {
                        data1 = readUnsigned();
                    }
                    message = new FastShortMessage(status | (data1 << 8));
                    break;
                case 0xF0:
                    // sys-ex or meta
                    switch(status) {
                        case 0xF0:
                        case 0xF7:
                            // sys ex
                            int sysexLength = (int) readVarInt();
                            byte[] sysexData = new byte[sysexLength];
                            read(sysexData);
                            SysexMessage sysexMessage = new SysexMessage();
                            sysexMessage.setMessage(status, sysexData, sysexLength);
                            message = sysexMessage;
                            break;
                        case 0xFF:
                            // meta
                            int metaType = readUnsigned();
                            int metaLength = (int) readVarInt();
                            final byte[] metaData;
                            try {
                                metaData = new byte[metaLength];
                            } catch (final OutOfMemoryError oom) {
                                throw new IOException("Meta length too big", oom);
                            }
                            read(metaData);
                            MetaMessage metaMessage = new MetaMessage();
                            metaMessage.setMessage(metaType, metaData, metaLength);
                            message = metaMessage;
                            if (metaType == 0x2F) {
                                // end of track means it!
                                endOfTrackFound = true;
                            }
                            break;
                        default:
                            throw new InvalidMidiDataException("Invalid status byte: " + status);
                    }
                    // switch sys-ex or meta
                    break;
                default:
                    throw new InvalidMidiDataException("Invalid status byte: " + status);
            }
            // switch
            track.add(new MidiEvent(message, tick));
        }
    // while
    } catch (ArrayIndexOutOfBoundsException e) {
        if (DEBUG)
            e.printStackTrace();
        // fix for 4834374
        throw new EOFException("invalid MIDI file");
    }
}
Also used : InvalidMidiDataException(javax.sound.midi.InvalidMidiDataException) MidiMessage(javax.sound.midi.MidiMessage) MidiEvent(javax.sound.midi.MidiEvent) IOException(java.io.IOException) SysexMessage(javax.sound.midi.SysexMessage) EOFException(java.io.EOFException) MetaMessage(javax.sound.midi.MetaMessage)

Aggregations

MetaMessage (javax.sound.midi.MetaMessage)3 MidiMessage (javax.sound.midi.MidiMessage)3 IOException (java.io.IOException)2 InvalidMidiDataException (javax.sound.midi.InvalidMidiDataException)2 MidiEvent (javax.sound.midi.MidiEvent)2 Track (javax.sound.midi.Track)2 BufferedInputStream (java.io.BufferedInputStream)1 EOFException (java.io.EOFException)1 MidiUnavailableException (javax.sound.midi.MidiUnavailableException)1 Patch (javax.sound.midi.Patch)1 Receiver (javax.sound.midi.Receiver)1 Sequence (javax.sound.midi.Sequence)1 SysexMessage (javax.sound.midi.SysexMessage)1 AudioInputStream (javax.sound.sampled.AudioInputStream)1 UnsupportedAudioFileException (javax.sound.sampled.UnsupportedAudioFileException)1 XHTMLContentHandler (org.apache.tika.sax.XHTMLContentHandler)1