1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.tika.parser.audio;
18
19 import java.io.BufferedInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.Set;
26
27 import javax.sound.midi.InvalidMidiDataException;
28 import javax.sound.midi.MetaMessage;
29 import javax.sound.midi.MidiMessage;
30 import javax.sound.midi.MidiSystem;
31 import javax.sound.midi.Patch;
32 import javax.sound.midi.Sequence;
33 import javax.sound.midi.Track;
34
35 import org.apache.tika.exception.TikaException;
36 import org.apache.tika.metadata.Metadata;
37 import org.apache.tika.mime.MediaType;
38 import org.apache.tika.parser.ParseContext;
39 import org.apache.tika.parser.Parser;
40 import org.apache.tika.sax.XHTMLContentHandler;
41 import org.xml.sax.ContentHandler;
42 import org.xml.sax.SAXException;
43
44 public class MidiParser implements Parser {
45
46 private static final Set<MediaType> SUPPORTED_TYPES =
47 Collections.unmodifiableSet(new HashSet<MediaType>(Arrays.asList(
48 MediaType.application("x-midi"),
49 MediaType.audio("midi"))));
50
51 public Set<MediaType> getSupportedTypes(ParseContext context) {
52 return SUPPORTED_TYPES;
53 }
54
55 public void parse(
56 InputStream stream, ContentHandler handler,
57 Metadata metadata, ParseContext context)
58 throws IOException, SAXException, TikaException {
59 metadata.set(Metadata.CONTENT_TYPE, "audio/midi");
60
61 XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
62 xhtml.startDocument();
63
64
65 InputStream buffered = new BufferedInputStream(stream);
66 try {
67 Sequence sequence = MidiSystem.getSequence(buffered);
68
69 Track[] tracks = sequence.getTracks();
70 metadata.set("tracks", String.valueOf(tracks.length));
71
72
73 Patch[] patches = sequence.getPatchList();
74 metadata.set("patches", String.valueOf(patches.length));
75
76 float type = sequence.getDivisionType();
77 if (type == Sequence.PPQ) {
78 metadata.set("divisionType", "PPQ");
79 } else if (type == Sequence.SMPTE_24) {
80 metadata.set("divisionType", "SMPTE_24");
81 } else if (type == Sequence.SMPTE_25) {
82 metadata.set("divisionType", "SMPTE_25");
83 } else if (type == Sequence.SMPTE_30) {
84 metadata.set("divisionType", "SMPTE_30");
85 } else if (type == Sequence.SMPTE_30DROP) {
86 metadata.set("divisionType", "SMPTE_30DROP");
87 } else if (type == Sequence.SMPTE_24) {
88 metadata.set("divisionType", String.valueOf(type));
89 }
90
91 for (Track track : tracks) {
92 xhtml.startElement("p");
93 for (int i = 0; i < track.size(); i++) {
94 MidiMessage message = track.get(i).getMessage();
95 if (message instanceof MetaMessage) {
96 MetaMessage meta = (MetaMessage) message;
97
98 if (meta.getType() >= 1 && meta.getType() <= 15) {
99
100 xhtml.characters(
101 new String(meta.getData(), "ISO-8859-1"));
102 }
103 }
104 }
105 xhtml.endElement("p");
106 }
107 } catch (InvalidMidiDataException ignore) {
108
109
110
111 }
112
113 xhtml.endDocument();
114 }
115
116
117
118
119 public void parse(
120 InputStream stream, ContentHandler handler, Metadata metadata)
121 throws IOException, SAXException, TikaException {
122 parse(stream, handler, metadata, new ParseContext());
123 }
124
125 }