├── LyrePlayer
├── .gitignore
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── top
│ │ │ └── weixiansen574
│ │ │ └── LyrePlayer
│ │ │ └── ExampleInstrumentedTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ │ └── ResolutionCoordinateMapping.json
│ │ ├── java
│ │ │ ├── com
│ │ │ │ └── sun
│ │ │ │ │ └── media
│ │ │ │ │ └── sound
│ │ │ │ │ ├── FastShortMessage.java
│ │ │ │ │ ├── MidiUtils.java
│ │ │ │ │ ├── StandardMidiFileReader.java
│ │ │ │ │ └── StandardMidiFileWriter.java
│ │ │ ├── javax
│ │ │ │ └── sound
│ │ │ │ │ └── midi
│ │ │ │ │ ├── ControllerEventListener.java
│ │ │ │ │ ├── InvalidMidiDataException.java
│ │ │ │ │ ├── MetaEventListener.java
│ │ │ │ │ ├── MetaMessage.java
│ │ │ │ │ ├── MidiChannel.java
│ │ │ │ │ ├── MidiDevice.java
│ │ │ │ │ ├── MidiDeviceReceiver.java
│ │ │ │ │ ├── MidiDeviceTransmitter.java
│ │ │ │ │ ├── MidiEvent.java
│ │ │ │ │ ├── MidiFileFormat.java
│ │ │ │ │ ├── MidiMessage.java
│ │ │ │ │ ├── MidiSystem.java
│ │ │ │ │ ├── MidiUnavailableException.java
│ │ │ │ │ ├── Patch.java
│ │ │ │ │ ├── Receiver.java
│ │ │ │ │ ├── Sequence.java
│ │ │ │ │ ├── Sequencer.java
│ │ │ │ │ ├── ShortMessage.java
│ │ │ │ │ ├── SysexMessage.java
│ │ │ │ │ ├── Track.java
│ │ │ │ │ ├── Transmitter.java
│ │ │ │ │ ├── VoiceStatus.java
│ │ │ │ │ ├── package-info.java
│ │ │ │ │ └── spi
│ │ │ │ │ ├── MidiDeviceProvider.java
│ │ │ │ │ ├── MidiFileReader.java
│ │ │ │ │ ├── MidiFileWriter.java
│ │ │ │ │ └── package-info.java
│ │ │ └── top
│ │ │ │ └── weixiansen574
│ │ │ │ └── LyrePlayer
│ │ │ │ ├── AboutActivity.java
│ │ │ │ ├── AdjustAndStartActivity.java
│ │ │ │ ├── ClickService.java
│ │ │ │ ├── FileHelp.java
│ │ │ │ ├── FloatListActivity.java
│ │ │ │ ├── FloatListManager.java
│ │ │ │ ├── FloatingButtonService.java
│ │ │ │ ├── MD5.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MusicListAdapter.java
│ │ │ │ ├── NetworkHelpActivity.java
│ │ │ │ ├── SelecFromServerActivity.java
│ │ │ │ ├── adapter
│ │ │ │ ├── FLoatMusicListAdapter.java
│ │ │ │ └── MusicListAdapterForOnline.java
│ │ │ │ ├── enums
│ │ │ │ ├── InvalidKeySetting.java
│ │ │ │ └── MusicInstrumentType.java
│ │ │ │ ├── midi
│ │ │ │ ├── FloatMusicBean.java
│ │ │ │ ├── MidiProcessor.java
│ │ │ │ ├── Note.java
│ │ │ │ └── SequenceOfNotes.java
│ │ │ │ └── util
│ │ │ │ ├── AccessibilityUtil.java
│ │ │ │ ├── HttpUtil.java
│ │ │ │ ├── NoteListStorage.java
│ │ │ │ ├── RootUtils.java
│ │ │ │ └── ShellUtils.java
│ │ └── res
│ │ │ ├── drawable-v24
│ │ │ └── test_ipv6.jpg
│ │ │ ├── drawable
│ │ │ ├── file_help_1.jpg
│ │ │ ├── file_help_2.jpg
│ │ │ ├── file_help_3.jpg
│ │ │ ├── ic_delete.xml
│ │ │ ├── ic_floder.xml
│ │ │ ├── ic_list.xml
│ │ │ ├── ic_menu.xml
│ │ │ ├── ic_music.xml
│ │ │ ├── ic_search.xml
│ │ │ ├── ic_server.xml
│ │ │ ├── ic_user.xml
│ │ │ ├── key_map.jpg
│ │ │ ├── logo.png
│ │ │ ├── lrye_round_icon.png
│ │ │ ├── lyre.png
│ │ │ ├── old_lyre.png
│ │ │ ├── old_lyre_round_icon.png
│ │ │ └── upload.png
│ │ │ ├── layout
│ │ │ ├── activity_about.xml
│ │ │ ├── activity_adjust_and_start.xml
│ │ │ ├── activity_adjust_and_start_new.xml
│ │ │ ├── activity_file_help.xml
│ │ │ ├── activity_float_list.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_network_help.xml
│ │ │ ├── activity_selec_from_server.xml
│ │ │ ├── edit_text.xml
│ │ │ ├── float_layout.xml
│ │ │ ├── float_music_list.xml
│ │ │ ├── foot_view.xml
│ │ │ ├── foot_view_page.xml
│ │ │ ├── item_float_window_music.xml
│ │ │ ├── list_item.xml
│ │ │ ├── list_item_online_music.xml
│ │ │ ├── online_music_info_dialog.xml
│ │ │ └── upload_dialog.xml
│ │ │ ├── menu
│ │ │ ├── menu.xml
│ │ │ └── menu_search.xml
│ │ │ ├── values-land
│ │ │ └── dimens.xml
│ │ │ ├── values-w1240dp
│ │ │ └── dimens.xml
│ │ │ ├── values-w600dp
│ │ │ └── dimens.xml
│ │ │ ├── values-zh-rTW
│ │ │ └── strings.xml
│ │ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ ├── styles.xml
│ │ │ └── themes.xml
│ │ │ └── xml
│ │ │ ├── accessibility_service_config.xml
│ │ │ └── network_security_config.xml
│ │ └── test
│ │ └── java
│ │ └── top
│ │ └── weixiansen574
│ │ └── LyrePlayer
│ │ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── README.md
├── output.json
└── screenshot.jpg
/LyrePlayer/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/LyrePlayer/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/LyrePlayer/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 30
5 | buildToolsVersion '32.0.0'
6 | defaultConfig {
7 | applicationId "top.weixiansen574.LyrePlayer"
8 | minSdkVersion 24
9 | targetSdkVersion 30
10 | versionCode 500
11 | versionName "5.0.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility JavaVersion.VERSION_1_8
22 | targetCompatibility JavaVersion.VERSION_1_8
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 | implementation 'androidx.appcompat:appcompat:1.0.2'
29 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
30 | implementation 'androidx.navigation:navigation-fragment:2.3.5'
31 | implementation 'androidx.navigation:navigation-ui:2.3.5'
32 | implementation 'androidx.cardview:cardview:1.0.0'
33 | implementation 'com.squareup.okhttp3:okhttp:3.10.0'
34 | implementation 'com.alibaba:fastjson:1.2.79'
35 | implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
36 |
37 | }
38 | repositories {
39 | mavenCentral()
40 | }
41 |
--------------------------------------------------------------------------------
/LyrePlayer/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/androidTest/java/top/weixiansen574/LyrePlayer/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.LyrePlayer;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 |
25 | assertEquals("top.weixiansen574.LyrePlayer", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
40 | * When data is being transported using MIDI wire protocol, a
41 | * {@link ShortMessage} with the status value {@code 0xFF} represents a system
42 | * reset message. In MIDI files, this same status value denotes a
43 | * {@code MetaMessage}. The types of meta-message are distinguished from each
44 | * other by the first byte that follows the status byte {@code 0xFF}. The
45 | * subsequent bytes are data bytes. As with system exclusive messages, there are
46 | * an arbitrary number of data bytes, depending on the type of
47 | * {@code MetaMessage}.
48 | *
49 | * @author David Rivas
50 | * @author Kara Kytle
51 | * @see MetaEventListener
52 | */
53 | public class MetaMessage extends MidiMessage {
54 |
55 | /**
56 | * Status byte for {@code MetaMessage} (0xFF, or 255), which is used in MIDI
57 | * files. It has the same value as {@link ShortMessage#SYSTEM_RESET}, which
58 | * is used in the real-time "MIDI wire" protocol.
59 | *
60 | * @see MidiMessage#getStatus
61 | */
62 | public static final int META = 0xFF; // 255
63 |
64 | /**
65 | * The length of the actual message in the data array. This is used to
66 | * determine how many bytes of the data array is the message, and how many
67 | * are the status byte, the type byte, and the variable-length-int
68 | * describing the length of the message.
69 | */
70 | private int dataLength = 0;
71 |
72 | /**
73 | * Constructs a new {@code MetaMessage}. The contents of the message are not
74 | * set here; use {@link #setMessage(int, byte[], int) setMessage} to set
75 | * them subsequently.
76 | */
77 | public MetaMessage() {
78 | // Default meta message data: just the META status byte value
79 | this(new byte[]{(byte) META, 0});
80 | }
81 |
82 | /**
83 | * Constructs a new {@code MetaMessage} and sets the message parameters. The
84 | * contents of the message can be changed by using the {@code setMessage}
85 | * method.
86 | *
87 | * @param type meta-message type (must be less than 128)
88 | * @param data the data bytes in the MIDI message
89 | * @param length an amount of bytes in the {@code data} byte array; it
90 | * should be non-negative and less than or equal to
91 | * {@code data.length}
92 | * @throws InvalidMidiDataException if the parameter values do not specify a
93 | * valid MIDI meta message
94 | * @see #setMessage(int, byte[], int)
95 | * @see #getType()
96 | * @see #getData()
97 | * @since 1.7
98 | */
99 | public MetaMessage(int type, byte[] data, int length)
100 | throws InvalidMidiDataException {
101 | super(null);
102 | setMessage(type, data, length); // can throw InvalidMidiDataException
103 | }
104 |
105 | /**
106 | * Constructs a new {@code MetaMessage}.
107 | *
108 | * @param data an array of bytes containing the complete message. The
109 | * message data may be changed using the {@code setMessage} method.
110 | * @see #setMessage
111 | */
112 | protected MetaMessage(byte[] data) {
113 | super(data);
114 | //$$fb 2001-10-06: need to calculate dataLength. Fix for bug #4511796
115 | if (data.length>=3) {
116 | dataLength=data.length-3;
117 | int pos=2;
118 | while (pos
34 | * In Java Sound, {@code MidiEvent} objects are typically contained in a
35 | * {@link Track}, and {@code Tracks} are likewise contained in a
36 | * {@code Sequence}.
37 | *
38 | * @author David Rivas
39 | * @author Kara Kytle
40 | */
41 | public class MidiEvent {
42 |
43 | /**
44 | * The MIDI message for this event.
45 | */
46 | private final MidiMessage message;
47 |
48 | /**
49 | * The tick value for this event.
50 | */
51 | private long tick;
52 |
53 | /**
54 | * Constructs a new {@code MidiEvent}.
55 | *
56 | * @param message the MIDI message contained in the event
57 | * @param tick the time-stamp for the event, in MIDI ticks
58 | */
59 | public MidiEvent(MidiMessage message, long tick) {
60 |
61 | this.message = message;
62 | this.tick = tick;
63 | }
64 |
65 | /**
66 | * Obtains the MIDI message contained in the event.
67 | *
68 | * @return the MIDI message
69 | */
70 | public MidiMessage getMessage() {
71 | return message;
72 | }
73 |
74 | /**
75 | * Sets the time-stamp for the event, in MIDI ticks.
76 | *
77 | * @param tick the new time-stamp, in MIDI ticks
78 | */
79 | public void setTick(long tick) {
80 | this.tick = tick;
81 | }
82 |
83 | /**
84 | * Obtains the time-stamp for the event, in MIDI ticks.
85 | *
86 | * @return the time-stamp for the event, in MIDI ticks
87 | */
88 | public long getTick() {
89 | return tick;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/MidiFileFormat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | import java.util.Collections;
29 | import java.util.HashMap;
30 | import java.util.Map;
31 |
32 | /**
33 | * A {@code MidiFileFormat} object encapsulates a MIDI file's type, as well as
34 | * its length and timing information.
35 | *
36 | * A {@code MidiFileFormat} object can include a set of properties. A property
37 | * is a pair of key and value: the key is of type {@code String}, the associated
38 | * property value is an arbitrary object. Properties specify additional
39 | * informational meta data (like a author, or copyright). Properties are
40 | * optional information, and file reader and file writer implementations are not
41 | * required to provide or recognize properties.
42 | *
43 | * The following table lists some common properties that should be used in
44 | * implementations:
45 | *
46 | *
270 | * If the specified property is not defined for a particular file format,
271 | * this method returns {@code null}.
272 | *
273 | * @param key the key of the desired property
274 | * @return the value of the property with the specified key, or {@code null}
275 | * if the property does not exist
276 | * @see #properties()
277 | * @since 1.5
278 | */
279 | public Object getProperty(String key) {
280 | if (properties == null) {
281 | return null;
282 | }
283 | return properties.get(key);
284 | }
285 | }
286 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/MidiMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | /**
29 | * {@code MidiMessage} is the base class for MIDI messages. They include not
30 | * only the standard MIDI messages that a synthesizer can respond to, but also
31 | * "meta-events" that can be used by sequencer programs. There are meta-events
32 | * for such information as lyrics, copyrights, tempo indications, time and key
33 | * signatures, markers, etc. For more information, see the Standard MIDI Files
34 | * 1.0 specification, which is part of the Complete MIDI 1.0 Detailed
35 | * Specification published by the MIDI Manufacturer's Association
36 | * (http://www.midi.org).
37 | *
38 | * The base {@code MidiMessage} class provides access to three types of
39 | * information about a MIDI message:
40 | *
50 | * The MIDI standard expresses MIDI data in bytes.
51 | * However, because Java uses signed bytes, the Java Sound API uses
52 | * integers instead of bytes when expressing MIDI data. For example, the
53 | * {@link #getStatus()} method of {@code MidiMessage} returns MIDI status bytes
54 | * as integers. If you are processing MIDI data that originated outside Java
55 | * Sound and now is encoded as signed bytes, the bytes can be converted to
56 | * integers using this conversion:
57 | *
58 | * {@code int i = (int)(byte & 0xFF)}
59 | *
60 | * If you simply need to pass a known MIDI byte value as a method parameter, it
61 | * can be expressed directly as an integer, using (for example) decimal or
62 | * hexadecimal notation. For instance, to pass the "active sensing" status byte
63 | * as the first argument to {@code ShortMessage}'s
64 | * {@link ShortMessage#setMessage(int) setMessage(int)} method, you can express
65 | * it as 254 or 0xFE.
66 | *
67 | * @author David Rivas
68 | * @author Kara Kytle
69 | * @see Track
70 | * @see Sequence
71 | * @see Receiver
72 | */
73 | public abstract class MidiMessage implements Cloneable {
74 |
75 | /**
76 | * The MIDI message data. The first byte is the status byte for the message;
77 | * subsequent bytes up to the length of the message are data bytes for this
78 | * message.
79 | *
80 | * @see #getLength
81 | */
82 | protected byte[] data;
83 |
84 | /**
85 | * The number of bytes in the MIDI message, including the status byte and
86 | * any data bytes.
87 | *
88 | * @see #getLength
89 | */
90 | protected int length = 0;
91 |
92 | /**
93 | * Constructs a new {@code MidiMessage}. This protected constructor is
94 | * called by concrete subclasses, which should ensure that the data array
95 | * specifies a complete, valid MIDI message.
96 | *
97 | * @param data an array of bytes containing the complete message. The
98 | * message data may be changed using the {@code setMessage} method.
99 | * @see #setMessage
100 | */
101 | protected MidiMessage(byte[] data) {
102 | this.data = data;
103 | if (data != null) {
104 | this.length = data.length;
105 | }
106 | }
107 |
108 | /**
109 | * Sets the data for the MIDI message. This protected method is called by
110 | * concrete subclasses, which should ensure that the data array specifies a
111 | * complete, valid MIDI message.
112 | *
113 | * @param data the data bytes in the MIDI message
114 | * @param length the number of bytes in the data byte array
115 | * @throws InvalidMidiDataException if the parameter values do not specify a
116 | * valid MIDI meta message
117 | */
118 | protected void setMessage(byte[] data, int length)
119 | throws InvalidMidiDataException {
120 | if (length < 0 || (length > 0 && length > data.length)) {
121 | throw new IndexOutOfBoundsException(
122 | "length out of bounds: " + length);
123 | }
124 | this.length = length;
125 |
126 | if (this.data == null || this.data.length < this.length) {
127 | this.data = new byte[this.length];
128 | }
129 | System.arraycopy(data, 0, this.data, 0, length);
130 | }
131 |
132 | /**
133 | * Obtains the MIDI message data. The first byte of the returned byte array
134 | * is the status byte of the message. Any subsequent bytes up to the length
135 | * of the message are data bytes. The byte array may have a length which is
136 | * greater than that of the actual message; the total length of the message
137 | * in bytes is reported by the {@link #getLength} method.
138 | *
139 | * @return the byte array containing the complete {@code MidiMessage} data
140 | */
141 | public byte[] getMessage() {
142 | byte[] returnedArray = new byte[length];
143 | System.arraycopy(data, 0, returnedArray, 0, length);
144 | return returnedArray;
145 | }
146 |
147 | /**
148 | * Obtains the status byte for the MIDI message. The status "byte" is
149 | * represented as an integer; see the
150 | * discussion in the {@code MidiMessage}
151 | * class description.
152 | *
153 | * @return the integer representation of this event's status byte
154 | */
155 | public int getStatus() {
156 | if (length > 0) {
157 | return (data[0] & 0xFF);
158 | }
159 | return 0;
160 | }
161 |
162 | /**
163 | * Obtains the total length of the MIDI message in bytes. A MIDI message
164 | * consists of one status byte and zero or more data bytes. The return value
165 | * ranges from 1 for system real-time messages, to 2 or 3 for channel
166 | * messages, to any value for meta and system exclusive messages.
167 | *
168 | * @return the length of the message in bytes
169 | */
170 | public int getLength() {
171 | return length;
172 | }
173 |
174 | /**
175 | * Creates a new object of the same class and with the same contents as this
176 | * object.
177 | *
178 | * @return a clone of this instance
179 | */
180 | @Override
181 | public abstract Object clone();
182 | }
183 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/MidiUnavailableException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | /**
29 | * A {@code MidiUnavailableException} is thrown when a requested MIDI component
30 | * cannot be opened or created because it is unavailable. This often occurs when
31 | * a device is in use by another application. More generally, it can occur when
32 | * there is a finite number of a certain kind of resource that can be used for
33 | * some purpose, and all of them are already in use (perhaps all by this
34 | * application). For an example of the latter case, see the
35 | * {@link Transmitter#setReceiver(Receiver) setReceiver} method of
36 | * {@code Transmitter}.
37 | *
38 | * @author Kara Kytle
39 | */
40 | public class MidiUnavailableException extends Exception {
41 |
42 | /**
43 | * Use serialVersionUID from JDK 1.3 for interoperability.
44 | */
45 | private static final long serialVersionUID = 6093809578628944323L;
46 |
47 | /**
48 | * Constructs a {@code MidiUnavailableException} that has {@code null} as
49 | * its error detail message.
50 | */
51 | public MidiUnavailableException() {
52 | super();
53 | }
54 |
55 | /**
56 | * Constructs a {@code MidiUnavailableException} with the specified detail
57 | * message.
58 | *
59 | * @param message the string to display as an error detail message
60 | */
61 | public MidiUnavailableException(final String message) {
62 | super(message);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/Patch.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | /**
29 | * A {@code Patch} object represents a location, on a MIDI synthesizer, into
30 | * which a single instrument is stored (loaded). Every {@code Instrument} object
31 | * has its own {@code Patch} object that specifies the memory location into
32 | * which that instrument should be loaded. The location is specified abstractly
33 | * by a bank index and a program number (not by any scheme that directly refers
34 | * to a specific address or offset in RAM). This is a hierarchical indexing
35 | * scheme: MIDI provides for up to 16384 banks, each of which contains up to 128
36 | * program locations. For example, a minimal sort of synthesizer might have only
37 | * one bank of instruments, and only 32 instruments (programs) in that bank.
38 | *
39 | * To select what instrument should play the notes on a particular MIDI channel,
40 | * two kinds of MIDI message are used that specify a patch location: a
41 | * bank-select command, and a program-change channel command. The Java Sound
42 | * equivalent is the
43 | * {@link MidiChannel#programChange(int, int) programChange(int, int)} method of
44 | * {@code MidiChannel}.
45 | *
46 | * @author Kara Kytle
47 | * @see Instrument
48 | * @see Instrument#getPatch()
49 | * @see MidiChannel#programChange(int, int)
50 | * @see Synthesizer#loadInstruments(Soundbank, Patch[])
51 | * @see Soundbank
52 | * @see Sequence#getPatchList()
53 | */
54 | public class Patch {
55 |
56 | /**
57 | * Bank index.
58 | */
59 | private final int bank;
60 |
61 | /**
62 | * Program change number.
63 | */
64 | private final int program;
65 |
66 | /**
67 | * Constructs a new patch object from the specified bank and program
68 | * numbers.
69 | *
70 | * @param bank the bank index (in the range from 0 to 16383)
71 | * @param program the program index (in the range from 0 to 127)
72 | */
73 | public Patch(int bank, int program) {
74 | this.bank = bank;
75 | this.program = program;
76 | }
77 |
78 | /**
79 | * Returns the number of the bank that contains the instrument whose
80 | * location this {@code Patch} specifies.
81 | *
82 | * @return the bank number, whose range is from 0 to 16383
83 | * @see MidiChannel#programChange(int, int)
84 | */
85 | public int getBank() {
86 | return bank;
87 | }
88 |
89 | /**
90 | * Returns the index, within a bank, of the instrument whose location this
91 | * {@code Patch} specifies.
92 | *
93 | * @return the instrument's program number, whose range is from 0 to 127
94 | * @see MidiChannel#getProgram
95 | * @see MidiChannel#programChange(int)
96 | * @see MidiChannel#programChange(int, int)
97 | */
98 | public int getProgram() {
99 | return program;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/Receiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | /**
29 | * A {@code Receiver} receives {@link MidiEvent} objects and typically does
30 | * something useful in response, such as interpreting them to generate sound or
31 | * raw MIDI output. Common MIDI receivers include synthesizers and MIDI Out
32 | * ports.
33 | *
34 | * @author Kara Kytle
35 | * @see MidiDevice
36 | * @see Synthesizer
37 | * @see Transmitter
38 | */
39 | public interface Receiver extends AutoCloseable {
40 |
41 | //$$fb 2002-04-12: fix for 4662090: Contradiction in Receiver specification
42 |
43 | /**
44 | * Sends a MIDI message and time-stamp to this receiver. If time-stamping is
45 | * not supported by this receiver, the time-stamp value should be -1.
46 | *
47 | * @param message the MIDI message to send
48 | * @param timeStamp the time-stamp for the message, in microseconds
49 | * @throws IllegalStateException if the receiver is closed
50 | */
51 | void send(MidiMessage message, long timeStamp);
52 |
53 | /**
54 | * Indicates that the application has finished using the receiver, and that
55 | * limited resources it requires may be released or made available.
56 | *
57 | * If the creation of this {@code Receiver} resulted in implicitly opening
58 | * the underlying device, the device is implicitly closed by this method.
59 | * This is true unless the device is kept open by other {@code Receiver} or
60 | * {@code Transmitter} instances that opened the device implicitly, and
61 | * unless the device has been opened explicitly. If the device this
62 | * {@code Receiver} is retrieved from is closed explicitly by calling
63 | * {@link MidiDevice#close MidiDevice.close}, the {@code Receiver} is
64 | * closed, too. For a detailed description of open/close behaviour see the
65 | * class description of {@link MidiDevice MidiDevice}.
66 | *
67 | * @see MidiSystem#getReceiver
68 | */
69 | @Override
70 | void close();
71 | }
72 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/SysexMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | import com.sun.media.sound.MidiUtils;
29 |
30 | /**
31 | * A {@code SysexMessage} object represents a MIDI system exclusive message.
32 | *
33 | * When a system exclusive message is read from a MIDI file, it always has a
34 | * defined length. Data from a system exclusive message from a MIDI file should
35 | * be stored in the data array of a {@code SysexMessage} as follows: the system
36 | * exclusive message status byte (0xF0 or 0xF7), all message data bytes, and
37 | * finally the end-of-exclusive flag (0xF7). The length reported by the
38 | * {@code SysexMessage} object is therefore the length of the system exclusive
39 | * data plus two: one byte for the status byte and one for the end-of-exclusive
40 | * flag.
41 | *
42 | * As dictated by the Standard MIDI Files specification, two status byte values
43 | * are legal for a {@code SysexMessage} read from a MIDI file:
44 | *
66 | * If system exclusive data from {@code SysexMessages} objects is being
67 | * transmitted using MIDI wire protocol, only the initial 0xF0 status byte, the
68 | * system exclusive data itself, and the final 0xF7 (EOX) byte should be
69 | * propagated; any 0xF7 status bytes used to indicate that a
70 | * {@code SysexMessage} contains continuing system exclusive data should not be
71 | * propagated via MIDI wire protocol.
72 | *
73 | * @author David Rivas
74 | * @author Kara Kytle
75 | * @author Florian Bomers
76 | */
77 | public class SysexMessage extends MidiMessage {
78 |
79 | // Status byte defines
80 |
81 | /**
82 | * Status byte for System Exclusive message (0xF0, or 240).
83 | *
84 | * @see MidiMessage#getStatus
85 | */
86 | public static final int SYSTEM_EXCLUSIVE = 0xF0; // 240
87 |
88 | /**
89 | * Status byte for Special System Exclusive message (0xF7, or 247), which is
90 | * used in MIDI files. It has the same value as END_OF_EXCLUSIVE, which is
91 | * used in the real-time "MIDI wire" protocol.
92 | *
93 | * @see MidiMessage#getStatus
94 | */
95 | public static final int SPECIAL_SYSTEM_EXCLUSIVE = 0xF7; // 247
96 |
97 | /**
98 | * The data bytes for this system exclusive message. These are initialized
99 | * to {@code null} and are set explicitly by
100 | * {@link #setMessage(int, byte[], int, long) setMessage}.
101 | */
102 | //protected byte[] data = null;
103 |
104 | /**
105 | * Constructs a new {@code SysexMessage}. The contents of the new message
106 | * are guaranteed to specify a valid MIDI message. Subsequently, you may set
107 | * the contents of the message using one of the {@code setMessage} methods.
108 | *
109 | * @see #setMessage
110 | */
111 | public SysexMessage() {
112 | this(new byte[2]);
113 | // Default sysex message data: SOX followed by EOX
114 | data[0] = (byte) (SYSTEM_EXCLUSIVE & 0xFF);
115 | data[1] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);
116 | }
117 |
118 | /**
119 | * Constructs a new {@code SysexMessage} and sets the data for the message.
120 | * The first byte of the data array must be a valid system exclusive status
121 | * byte (0xF0 or 0xF7). The contents of the message can be changed by using
122 | * one of the {@code setMessage} methods.
123 | *
124 | * @param data the system exclusive message data including the status byte
125 | * @param length the length of the valid message data in the array,
126 | * including the status byte; it should be non-negative and less
127 | * than or equal to {@code data.length}
128 | * @throws InvalidMidiDataException if the parameter values do not specify a
129 | * valid MIDI meta message
130 | * @see #setMessage(byte[], int)
131 | * @see #setMessage(int, byte[], int)
132 | * @see #getData()
133 | * @since 1.7
134 | */
135 | public SysexMessage(byte[] data, int length)
136 | throws InvalidMidiDataException {
137 | super(null);
138 | setMessage(data, length);
139 | }
140 |
141 | /**
142 | * Constructs a new {@code SysexMessage} and sets the data for the message.
143 | * The contents of the message can be changed by using one of the
144 | * {@code setMessage} methods.
145 | *
146 | * @param status the status byte for the message; it must be a valid system
147 | * exclusive status byte (0xF0 or 0xF7)
148 | * @param data the system exclusive message data (without the status byte)
149 | * @param length the length of the valid message data in the array; it
150 | * should be non-negative and less than or equal to
151 | * {@code data.length}
152 | * @throws InvalidMidiDataException if the parameter values do not specify a
153 | * valid MIDI system exclusive message
154 | * @see #setMessage(byte[], int)
155 | * @see #setMessage(int, byte[], int)
156 | * @see #getData()
157 | * @since 1.7
158 | */
159 | public SysexMessage(int status, byte[] data, int length)
160 | throws InvalidMidiDataException {
161 | super(null);
162 | setMessage(status, data, length);
163 | }
164 |
165 | /**
166 | * Constructs a new {@code SysexMessage}.
167 | *
168 | * @param data an array of bytes containing the complete message. The
169 | * message data may be changed using the {@code setMessage} method.
170 | * @see #setMessage
171 | */
172 | protected SysexMessage(byte[] data) {
173 | super(data);
174 | }
175 |
176 | /**
177 | * Sets the data for the system exclusive message. The first byte of the
178 | * data array must be a valid system exclusive status byte (0xF0 or 0xF7).
179 | *
180 | * @param data the system exclusive message data
181 | * @param length the length of the valid message data in the array,
182 | * including the status byte
183 | * @throws InvalidMidiDataException if the parameter values do not specify a
184 | * valid MIDI system exclusive message
185 | */
186 | @Override
187 | public void setMessage(byte[] data, int length) throws InvalidMidiDataException {
188 | MidiUtils.checkSysexStatus(data, length);
189 | super.setMessage(data, length);
190 | }
191 |
192 | /**
193 | * Sets the data for the system exclusive message.
194 | *
195 | * @param status the status byte for the message (0xF0 or 0xF7)
196 | * @param data the system exclusive message data
197 | * @param length the length of the valid message data in the array
198 | * @throws InvalidMidiDataException if the status byte is invalid for a
199 | * system exclusive message
200 | */
201 | public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException {
202 | MidiUtils.checkSysexStatus(status);
203 | if (length < 0 || length > data.length) {
204 | throw new IndexOutOfBoundsException("length out of bounds: "+length);
205 | }
206 | this.length = length + 1;
207 |
208 | if (this.data==null || this.data.length < this.length) {
209 | this.data = new byte[this.length];
210 | }
211 |
212 | this.data[0] = (byte) (status & 0xFF);
213 | if (length > 0) {
214 | System.arraycopy(data, 0, this.data, 1, length);
215 | }
216 | }
217 |
218 | /**
219 | * Obtains a copy of the data for the system exclusive message. The returned
220 | * array of bytes does not include the status byte.
221 | *
222 | * @return array containing the system exclusive message data
223 | */
224 | public byte[] getData() {
225 | byte[] returnedArray = new byte[length - 1];
226 | System.arraycopy(data, 1, returnedArray, 0, (length - 1));
227 | return returnedArray;
228 | }
229 |
230 | /**
231 | * Creates a new object of the same class and with the same contents as this
232 | * object.
233 | *
234 | * @return a clone of this instance
235 | */
236 | @Override
237 | public Object clone() {
238 | byte[] newData = new byte[length];
239 | System.arraycopy(data, 0, newData, 0, newData.length);
240 | return new SysexMessage(newData);
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/Transmitter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | /**
29 | * A {@code Transmitter} sends {@link MidiEvent} objects to one or more
30 | * {@link Receiver Receivers}. Common MIDI transmitters include sequencers and
31 | * MIDI input ports.
32 | *
33 | * @author Kara Kytle
34 | * @see Receiver
35 | */
36 | public interface Transmitter extends AutoCloseable {
37 |
38 | /**
39 | * Sets the receiver to which this transmitter will deliver MIDI messages.
40 | * If a receiver is currently set, it is replaced with this one.
41 | *
42 | * @param receiver the desired receiver
43 | */
44 | void setReceiver(Receiver receiver);
45 |
46 | /**
47 | * Obtains the current receiver to which this transmitter will deliver MIDI
48 | * messages.
49 | *
50 | * @return the current receiver. If no receiver is currently set, returns
51 | * {@code null}.
52 | */
53 | Receiver getReceiver();
54 |
55 | /**
56 | * Indicates that the application has finished using the transmitter, and
57 | * that limited resources it requires may be released or made available.
58 | *
59 | * If the creation of this {@code Transmitter} resulted in implicitly
60 | * opening the underlying device, the device is implicitly closed by this
61 | * method. This is true unless the device is kept open by other
62 | * {@code Receiver} or {@code Transmitter} instances that opened the device
63 | * implicitly, and unless the device has been opened explicitly. If the
64 | * device this {@code Transmitter} is retrieved from is closed explicitly by
65 | * calling {@link MidiDevice#close MidiDevice.close}, the
66 | * {@code Transmitter} is closed, too. For a detailed description of
67 | * open/close behaviour see the class description of
68 | * {@link MidiDevice MidiDevice}.
69 | *
70 | * @see MidiSystem#getTransmitter
71 | */
72 | @Override
73 | void close();
74 | }
75 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/VoiceStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi;
27 |
28 | /**
29 | * A {@code VoiceStatus} object contains information about the current status of
30 | * one of the voices produced by a {@link Synthesizer}.
31 | *
32 | * MIDI synthesizers are generally capable of producing some maximum number of
33 | * simultaneous notes, also referred to as voices. A voice is a stream of
34 | * successive single notes, and the process of assigning incoming MIDI notes to
35 | * specific voices is known as voice allocation. However, the voice-allocation
36 | * algorithm and the contents of each voice are normally internal to a MIDI
37 | * synthesizer and hidden from outside view. One can, of course, learn from MIDI
38 | * messages which notes the synthesizer is playing, and one might be able deduce
39 | * something about the assignment of notes to voices. But MIDI itself does not
40 | * provide a means to report which notes a synthesizer has assigned to which
41 | * voice, nor even to report how many voices the synthesizer is capable of
42 | * synthesizing.
43 | *
44 | * In Java Sound, however, a {@code Synthesizer} class can expose the contents
45 | * of its voices through its
46 | * {@link Synthesizer#getVoiceStatus() getVoiceStatus()} method. This behavior
47 | * is recommended but optional; synthesizers that don't expose their voice
48 | * allocation simply return a zero-length array. A {@code Synthesizer} that does
49 | * report its voice status should maintain this information at all times for all
50 | * of its voices, whether they are currently sounding or not. In other words, a
51 | * given type of {@code Synthesizer} always has a fixed number of voices, equal
52 | * to the maximum number of simultaneous notes it is capable of sounding.
53 | *
54 | * If the voice is not currently processing a
55 | * MIDI note, it is considered inactive. A voice is inactive when it has been
56 | * given no note-on commands, or when every note-on command received has been
57 | * terminated by a corresponding note-off (or by an "all notes off" message).
58 | * For example, this happens when a synthesizer capable of playing 16
59 | * simultaneous notes is told to play a four-note chord; only four voices are
60 | * active in this case (assuming no earlier notes are still playing). Usually, a
61 | * voice whose status is reported as active is producing audible sound, but this
62 | * is not always true; it depends on the details of the instrument (that is, the
63 | * synthesis algorithm) and how long the note has been going on. For example, a
64 | * voice may be synthesizing the sound of a single hand-clap. Because this sound
65 | * dies away so quickly, it may become inaudible before a note-off message is
66 | * received. In such a situation, the voice is still considered active even
67 | * though no sound is currently being produced.
68 | *
69 | * Besides its active or inactive status, the {@code VoiceStatus} class provides
70 | * fields that reveal the voice's current MIDI channel, bank and program number,
71 | * MIDI note number, and MIDI volume. All of these can change during the course
72 | * of a voice. While the voice is inactive, each of these fields has an
73 | * unspecified value, so you should check the active field first.
74 | *
75 | * @author David Rivas
76 | * @author Kara Kytle
77 | * @see Synthesizer#getMaxPolyphony
78 | * @see Synthesizer#getVoiceStatus
79 | */
80 | public class VoiceStatus {
81 |
82 | /**
83 | * Indicates whether the voice is currently processing a MIDI note. See the
84 | * explanation of
85 | * active and inactive voices.
86 | */
87 | public boolean active = false;
88 |
89 | /**
90 | * The MIDI channel on which this voice is playing. The value is a
91 | * zero-based channel number if the voice is active, or unspecified if the
92 | * voice is inactive.
93 | *
94 | * @see MidiChannel
95 | * @see #active
96 | */
97 | public int channel = 0;
98 |
99 | /**
100 | * The bank number of the instrument that this voice is currently using.
101 | * This is a number dictated by the MIDI bank-select message; it does not
102 | * refer to a {@code SoundBank} object. The value ranges from 0 to 16383 if
103 | * the voice is active, and is unspecified if the voice is inactive.
104 | *
105 | * @see Patch
106 | * @see Soundbank
107 | * @see #active
108 | * @see MidiChannel#programChange(int, int)
109 | */
110 | public int bank = 0;
111 |
112 | /**
113 | * The program number of the instrument that this voice is currently using.
114 | * The value ranges from 0 to 127 if the voice is active, and is unspecified
115 | * if the voice is inactive.
116 | *
117 | * @see MidiChannel#getProgram
118 | * @see Patch
119 | * @see #active
120 | */
121 | public int program = 0;
122 |
123 | /**
124 | * The MIDI note that this voice is playing. The range for an active voice
125 | * is from 0 to 127 in semitones, with 60 referring to Middle C. The value
126 | * is unspecified if the voice is inactive.
127 | *
128 | * @see MidiChannel#noteOn
129 | * @see #active
130 | */
131 | public int note = 0;
132 |
133 | /**
134 | * The current MIDI volume level for the voice. The value ranges from 0 to
135 | * 127 if the voice is active, and is unspecified if the voice is inactive.
136 | *
137 | * Note that this value does not necessarily reflect the instantaneous level
138 | * of the sound produced by this voice; that level is the result of many
139 | * contributing factors, including the current instrument and the shape of
140 | * the amplitude envelope it produces.
141 | *
142 | * @see #active
143 | */
144 | public int volume = 0;
145 |
146 | /**
147 | * Constructs a {@code VoiceStatus}.
148 | */
149 | public VoiceStatus() {}
150 | }
151 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | /**
27 | * Provides interfaces and classes for I/O, sequencing, and synthesis of MIDI
28 | * (Musical Instrument Digital Interface) data.
29 | *
30 | *
47 | *
77 | *
78 | * @author Kara Kytle
79 | * @author Florian Bomers
80 | * @see MidiSystem#getMidiFileFormat(java.io.File)
81 | * @see Sequencer#setSequence(java.io.InputStream stream)
82 | */
83 | public class MidiFileFormat {
84 |
85 | /**
86 | * Represents unknown length.
87 | *
88 | * @see #getByteLength
89 | * @see #getMicrosecondLength
90 | */
91 | public static final int UNKNOWN_LENGTH = -1;
92 |
93 | /**
94 | * The type of MIDI file.
95 | */
96 | protected int type;
97 |
98 | /**
99 | * The division type of the MIDI file.
100 | *
101 | * @see Sequence#PPQ
102 | * @see Sequence#SMPTE_24
103 | * @see Sequence#SMPTE_25
104 | * @see Sequence#SMPTE_30DROP
105 | * @see Sequence#SMPTE_30
106 | */
107 | protected float divisionType;
108 |
109 | /**
110 | * The timing resolution of the MIDI file.
111 | */
112 | protected int resolution;
113 |
114 | /**
115 | * The length of the MIDI file in bytes.
116 | */
117 | protected int byteLength;
118 |
119 | /**
120 | * The duration of the MIDI file in microseconds.
121 | */
122 | protected long microsecondLength;
123 |
124 | /**
125 | * The set of properties.
126 | */
127 | private HashMap
50 | *
54 | *
55 | * Property key
51 | * Value type
52 | * Description
53 | *
56 | * "author"
57 | * {@link String String}
58 | * name of the author of this file
59 | *
60 | * "title"
61 | * {@link String String}
62 | * title of this file
63 | *
64 | * "copyright"
65 | * {@link String String}
66 | * copyright message
67 | *
68 | * "date"
69 | * {@link java.util.Date Date}
70 | * date of the recording or release
71 | *
72 | *
76 | * "comment"
73 | * {@link String String}
74 | * an arbitrary text
75 | *
41 | *
46 | *
47 | * {@code MidiMessage} includes methods to get, but not set, these values.
48 | * Setting them is a subclass responsibility.
49 | *
45 | *
48 | * When Java Sound is used to handle system exclusive data that is being
49 | * received using MIDI wire protocol, it should place the data in one or more
50 | * {@code SysexMessages}. In this case, the length of the system exclusive data
51 | * is not known in advance; the end of the system exclusive data is marked by an
52 | * end-of-exclusive flag (0xF7) in the MIDI wire byte stream.
53 | *
54 | *
57 | * The first {@code SysexMessage} object containing data for a particular system
58 | * exclusive message should have the status value 0xF0. If this message contains
59 | * all the system exclusive data for the message, it should end with the status
60 | * byte 0xF7 (EOX). Otherwise, additional system exclusive data should be sent
61 | * in one or more {@code SysexMessages} with a status value of 0xF7. The
62 | * {@code SysexMessage} containing the last of the data for the system exclusive
63 | * message should end with the value 0xF7 (EOX) to mark the end of the system
64 | * exclusive message.
65 | * Related Documentation
31 | * For more information on using Java Sound see:
32 | *
33 | *
36 | * Please note: In the {@code javax.sound.midi} APIs, a {@code null} reference
37 | * parameter to methods is incorrect unless explicitly documented on the method
38 | * as having a meaningful interpretation. Usage to the contrary is incorrect
39 | * coding and may result in a run time exception either immediately or at some
40 | * later time. {@code NullPointerException} is an example of typical and
41 | * acceptable run time exception for such cases.
42 | *
43 | * @since 1.3
44 | */
45 | package javax.sound.midi;
46 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/spi/MidiDeviceProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi.spi;
27 |
28 | import java.util.Arrays;
29 |
30 | import javax.sound.midi.MidiDevice;
31 |
32 | /**
33 | * A {@code MidiDeviceProvider} is a factory or provider for a particular type
34 | * of MIDI device. This mechanism allows the implementation to determine how
35 | * resources are managed in the creation and management of a device.
36 | *
37 | * @author Kara Kytle
38 | */
39 | public abstract class MidiDeviceProvider {
40 |
41 | /**
42 | * Constructor for subclasses to call.
43 | */
44 | protected MidiDeviceProvider() {}
45 |
46 | /**
47 | * Indicates whether the device provider supports the device represented by
48 | * the specified device info object.
49 | *
50 | * @param info an info object that describes the device for which support
51 | * is queried
52 | * @return {@code true} if the specified device is supported, otherwise
53 | * {@code false}
54 | * @throws NullPointerException if {@code info} is {@code null}
55 | */
56 | public boolean isDeviceSupported(final MidiDevice.Info info) {
57 | return Arrays.stream(getDeviceInfo()).anyMatch(info::equals);
58 | }
59 |
60 | /**
61 | * Obtains the set of info objects representing the device or devices
62 | * provided by this {@code MidiDeviceProvider}.
63 | *
64 | * @return set of device info objects
65 | */
66 | public abstract MidiDevice.Info[] getDeviceInfo();
67 |
68 | /**
69 | * Obtains an instance of the device represented by the info object.
70 | *
71 | * @param info an info object that describes the desired device
72 | * @return device instance
73 | * @throws IllegalArgumentException if the info object specified does not
74 | * match the info object for a device supported by this
75 | * {@code MidiDeviceProvider}
76 | * @throws NullPointerException if {@code info} is {@code null}
77 | */
78 | public abstract MidiDevice getDevice(MidiDevice.Info info);
79 | }
80 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/spi/MidiFileReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi.spi;
27 |
28 | import java.io.File;
29 | import java.io.IOException;
30 | import java.io.InputStream;
31 | import java.net.URL;
32 |
33 | import javax.sound.midi.InvalidMidiDataException;
34 | import javax.sound.midi.MidiFileFormat;
35 | import javax.sound.midi.Sequence;
36 |
37 | /**
38 | * A {@code MidiFileReader} supplies MIDI file-reading services. Classes
39 | * implementing this interface can parse the format information from one or more
40 | * types of MIDI file, and can produce a {@link Sequence} object from files of
41 | * these types.
42 | *
43 | * @author Kara Kytle
44 | * @since 1.3
45 | */
46 | public abstract class MidiFileReader {
47 |
48 | /**
49 | * Constructor for subclasses to call.
50 | */
51 | protected MidiFileReader() {}
52 |
53 | /**
54 | * Obtains the MIDI file format of the input stream provided. The stream
55 | * must point to valid MIDI file data. In general, MIDI file readers may
56 | * need to read some data from the stream before determining whether they
57 | * support it. These parsers must be able to mark the stream, read enough
58 | * data to determine whether they support the stream, and, if not, reset the
59 | * stream's read pointer to its original position. If the input stream does
60 | * not support this, this method may fail with an {@code IOException}.
61 | *
62 | * @param stream the input stream from which file format information should
63 | * be extracted
64 | * @return a {@code MidiFileFormat} object describing the MIDI file format
65 | * @throws InvalidMidiDataException if the stream does not point to valid
66 | * MIDI file data recognized by the system
67 | * @throws IOException if an I/O exception occurs
68 | * @throws NullPointerException if {@code stream} is {@code null}
69 | * @see InputStream#markSupported
70 | * @see InputStream#mark
71 | */
72 | public abstract MidiFileFormat getMidiFileFormat(InputStream stream)
73 | throws InvalidMidiDataException, IOException;
74 |
75 | /**
76 | * Obtains the MIDI file format of the {@code URL} provided. The {@code URL}
77 | * must point to valid MIDI file data.
78 | *
79 | * @param url the {@code URL} from which file format information should be
80 | * extracted
81 | * @return a {@code MidiFileFormat} object describing the MIDI file format
82 | * @throws InvalidMidiDataException if the {@code URL} does not point to
83 | * valid MIDI file data recognized by the system
84 | * @throws IOException if an I/O exception occurs
85 | * @throws NullPointerException if {@code url} is {@code null}
86 | */
87 | public abstract MidiFileFormat getMidiFileFormat(URL url)
88 | throws InvalidMidiDataException, IOException;
89 |
90 | /**
91 | * Obtains the MIDI file format of the {@code File} provided. The
92 | * {@code File} must point to valid MIDI file data.
93 | *
94 | * @param file the {@code File} from which file format information should
95 | * be extracted
96 | * @return a {@code MidiFileFormat} object describing the MIDI file format
97 | * @throws InvalidMidiDataException if the {@code File} does not point to
98 | * valid MIDI file data recognized by the system
99 | * @throws IOException if an I/O exception occurs
100 | * @throws NullPointerException if {@code file} is {@code null}
101 | */
102 | public abstract MidiFileFormat getMidiFileFormat(File file)
103 | throws InvalidMidiDataException, IOException;
104 |
105 | /**
106 | * Obtains a MIDI sequence from the input stream provided. The stream must
107 | * point to valid MIDI file data. In general, MIDI file readers may need to
108 | * read some data from the stream before determining whether they support
109 | * it. These parsers must be able to mark the stream, read enough data to
110 | * determine whether they support the stream, and, if not, reset the
111 | * stream's read pointer to its original position. If the input stream does
112 | * not support this, this method may fail with an {@code IOException}.
113 | *
114 | * @param stream the input stream from which the {@code Sequence} should be
115 | * constructed
116 | * @return a {@code Sequence} object based on the MIDI file data contained
117 | * in the input stream
118 | * @throws InvalidMidiDataException if the stream does not point to valid
119 | * MIDI file data recognized by the system
120 | * @throws IOException if an I/O exception occurs
121 | * @throws NullPointerException if {@code stream} is {@code null}
122 | * @see InputStream#markSupported
123 | * @see InputStream#mark
124 | */
125 | public abstract Sequence getSequence(InputStream stream)
126 | throws InvalidMidiDataException, IOException;
127 |
128 | /**
129 | * Obtains a MIDI sequence from the {@code URL} provided. The {@code URL}
130 | * must point to valid MIDI file data.
131 | *
132 | * @param url the {@code URL} for which the {@code Sequence} should be
133 | * constructed
134 | * @return a {@code Sequence} object based on the MIDI file data pointed to
135 | * by the {@code URL}
136 | * @throws InvalidMidiDataException if the {@code URL} does not point to
137 | * valid MIDI file data recognized by the system
138 | * @throws IOException if an I/O exception occurs
139 | * @throws NullPointerException if {@code url} is {@code null}
140 | */
141 | public abstract Sequence getSequence(URL url)
142 | throws InvalidMidiDataException, IOException;
143 |
144 | /**
145 | * Obtains a MIDI sequence from the {@code File} provided. The {@code File}
146 | * must point to valid MIDI file data.
147 | *
148 | * @param file the {@code File} from which the {@code Sequence} should be
149 | * constructed
150 | * @return a {@code Sequence} object based on the MIDI file data pointed to
151 | * by the {@code File}
152 | * @throws InvalidMidiDataException if the {@code File} does not point to
153 | * valid MIDI file data recognized by the system
154 | * @throws IOException if an I/O exception occurs
155 | * @throws NullPointerException if {@code file} is {@code null}
156 | */
157 | public abstract Sequence getSequence(File file)
158 | throws InvalidMidiDataException, IOException;
159 | }
160 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/spi/MidiFileWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | package javax.sound.midi.spi;
27 |
28 | import java.io.File;
29 | import java.io.IOException;
30 | import java.io.OutputStream;
31 | import java.util.Arrays;
32 |
33 | import javax.sound.midi.Sequence;
34 |
35 | /**
36 | * A {@code MidiFileWriter} supplies MIDI file-writing services. Classes that
37 | * implement this interface can write one or more types of MIDI file from a
38 | * {@link Sequence} object.
39 | *
40 | * @author Kara Kytle
41 | * @since 1.3
42 | */
43 | public abstract class MidiFileWriter {
44 |
45 | /**
46 | * Constructor for subclasses to call.
47 | */
48 | protected MidiFileWriter() {}
49 |
50 | /**
51 | * Obtains the set of MIDI file types for which file writing support is
52 | * provided by this file writer.
53 | *
54 | * @return array of file types. If no file types are supported, an array of
55 | * length 0 is returned.
56 | */
57 | public abstract int[] getMidiFileTypes();
58 |
59 | /**
60 | * Obtains the file types that this file writer can write from the sequence
61 | * specified.
62 | *
63 | * @param sequence the sequence for which MIDI file type support is queried
64 | * @return array of file types. If no file types are supported, returns an
65 | * array of length 0.
66 | * @throws NullPointerException if {@code sequence} is {@code null}
67 | */
68 | public abstract int[] getMidiFileTypes(Sequence sequence);
69 |
70 | /**
71 | * Indicates whether file writing support for the specified MIDI file type
72 | * is provided by this file writer.
73 | *
74 | * @param fileType the file type for which write capabilities are queried
75 | * @return {@code true} if the file type is supported, otherwise
76 | * {@code false}
77 | */
78 | public boolean isFileTypeSupported(final int fileType) {
79 | return Arrays.stream(getMidiFileTypes())
80 | .anyMatch(type -> fileType == type);
81 | }
82 |
83 | /**
84 | * Indicates whether a MIDI file of the file type specified can be written
85 | * from the sequence indicated.
86 | *
87 | * @param fileType the file type for which write capabilities are queried
88 | * @param sequence the sequence for which file writing support is queried
89 | * @return {@code true} if the file type is supported for this sequence,
90 | * otherwise {@code false}
91 | * @throws NullPointerException if {@code sequence} is {@code null}
92 | */
93 | public boolean isFileTypeSupported(final int fileType,
94 | final Sequence sequence) {
95 | return Arrays.stream(getMidiFileTypes(sequence))
96 | .anyMatch(type -> fileType == type);
97 | }
98 |
99 | /**
100 | * Writes a stream of bytes representing a MIDI file of the file type
101 | * indicated to the output stream provided.
102 | *
103 | * @param in sequence containing MIDI data to be written to the file
104 | * @param fileType type of the file to be written to the output stream
105 | * @param out stream to which the file data should be written
106 | * @return the number of bytes written to the output stream
107 | * @throws IOException if an I/O exception occurs
108 | * @throws IllegalArgumentException if the file type is not supported by
109 | * this file writer
110 | * @throws NullPointerException if {@code in} or {@code out} are
111 | * {@code null}
112 | * @see #isFileTypeSupported(int, Sequence)
113 | * @see #getMidiFileTypes(Sequence)
114 | */
115 | public abstract int write(Sequence in, int fileType, OutputStream out)
116 | throws IOException;
117 |
118 | /**
119 | * Writes a stream of bytes representing a MIDI file of the file type
120 | * indicated to the external file provided.
121 | *
122 | * @param in sequence containing MIDI data to be written to the external
123 | * file
124 | * @param fileType type of the file to be written to the external file
125 | * @param out external file to which the file data should be written
126 | * @return the number of bytes written to the file
127 | * @throws IOException if an I/O exception occurs
128 | * @throws IllegalArgumentException if the file type is not supported by
129 | * this file writer
130 | * @throws NullPointerException if {@code in} or {@code out} are
131 | * {@code null}
132 | * @see #isFileTypeSupported(int, Sequence)
133 | * @see #getMidiFileTypes(Sequence)
134 | */
135 | public abstract int write(Sequence in, int fileType, File out)
136 | throws IOException;
137 | }
138 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/javax/sound/midi/spi/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 | *
5 | *
6 | *
7 | *
8 | *
9 | *
10 | *
11 | *
12 | *
13 | *
14 | *
15 | *
16 | *
17 | *
18 | *
19 | *
20 | *
21 | *
22 | *
23 | *
24 | */
25 |
26 | /**
27 | * Supplies interfaces for service providers to implement when offering new MIDI
28 | * devices, MIDI file readers and writers, or sound bank readers.
29 | *
30 | * Related Documentation
31 | * For more information on using Java Sound see:
32 | *
33 | *
36 | * Please note: In the {@code javax.sound.midi.spi} APIs, a {@code null}
37 | * reference parameter to methods is incorrect unless explicitly documented on
38 | * the method as having a meaningful interpretation. Usage to the contrary is
39 | * incorrect coding and may result in a run time exception either immediately or
40 | * at some later time. {@code NullPointerException} is an example of typical and
41 | * acceptable run time exception for such cases.
42 | *
43 | * @since 1.3
44 | */
45 | package javax.sound.midi.spi;
46 |
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/top/weixiansen574/LyrePlayer/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.LyrePlayer;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.content.Intent;
6 | import android.content.pm.PackageInfo;
7 | import android.content.pm.PackageManager;
8 | import android.net.Uri;
9 | import android.os.Bundle;
10 | import android.text.SpannableString;
11 | import android.text.Spanned;
12 | import android.text.method.LinkMovementMethod;
13 | import android.text.style.ClickableSpan;
14 | import android.view.MenuItem;
15 | import android.view.View;
16 | import android.widget.TextView;
17 |
18 | public class AboutActivity extends AppCompatActivity {
19 | TextView versionName,github,bilibili,youtube;
20 | @Override
21 | public boolean onOptionsItemSelected(MenuItem item) {
22 | //工具栏返回上一级按钮
23 | if (item.getItemId() == 16908332){
24 | finish();
25 | }
26 | return true;
27 | }
28 | @Override
29 | protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_about);
32 |
33 | versionName = findViewById(R.id.version_name);
34 | PackageManager packageManager = getPackageManager();
35 | try {
36 | PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(),0);
37 | versionName.setText(packageInfo.versionName);
38 | } catch (PackageManager.NameNotFoundException e) {
39 | e.printStackTrace();
40 | }
41 | github = findViewById(R.id.github);
42 | bilibili = findViewById(R.id.bilibili);
43 | youtube = findViewById(R.id.youtube);
44 |
45 | SpannableString spannableString1 = new SpannableString("github");
46 | spannableString1.setSpan(new ClickableSpan() {
47 |
48 | @Override
49 | public void onClick(View widget) {
50 | Intent intent = new Intent();
51 | intent.setData(Uri.parse("https://github.com/weixiansen574/Genshin-Lyre-midi-player"));
52 | startActivity(intent);
53 | }
54 | }, 0, github.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
55 | github.setText(spannableString1);
56 | github.setMovementMethod(LinkMovementMethod.getInstance());
57 |
58 | SpannableString spannableString2 = new SpannableString("bilibili");
59 | spannableString2.setSpan(new ClickableSpan() {
60 |
61 | @Override
62 | public void onClick(View widget) {
63 | Intent intent = new Intent();
64 | intent.setData(Uri.parse("https://space.bilibili.com/503113802"));
65 | startActivity(intent);
66 | }
67 | }, 0, bilibili.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
68 | bilibili.setText(spannableString2);
69 | bilibili.setMovementMethod(LinkMovementMethod.getInstance());
70 |
71 | SpannableString spannableString3 = new SpannableString("YouTube");
72 | spannableString3.setSpan(new ClickableSpan() {
73 |
74 | @Override
75 | public void onClick(View widget) {
76 | Intent intent = new Intent();
77 | intent.setData(Uri.parse("https://www.youtube.com/channel/UCbCv9JlpYxGMj-fv5xiX4vA"));
78 | startActivity(intent);
79 | }
80 | }, 0, youtube.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
81 | youtube.setText(spannableString3);
82 | youtube.setMovementMethod(LinkMovementMethod.getInstance());
83 |
84 |
85 | }
86 |
87 | }
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/top/weixiansen574/LyrePlayer/ClickService.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.LyrePlayer;
2 |
3 | import android.accessibilityservice.AccessibilityService;
4 | import android.os.Build;
5 | import android.view.accessibility.AccessibilityEvent;
6 |
7 | import androidx.annotation.RequiresApi;
8 |
9 | public class ClickService extends AccessibilityService {
10 | public static ClickService mService;
11 |
12 | @RequiresApi(api = Build.VERSION_CODES.O)
13 |
14 | @Override
15 | protected void onServiceConnected() {
16 | super.onServiceConnected();
17 | mService = this;
18 | }
19 | public static boolean isStart() {
20 | return mService != null;
21 | }
22 |
23 | @Override
24 | public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
25 |
26 | }
27 |
28 | @Override
29 | public void onInterrupt() {
30 |
31 | }
32 | }
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/top/weixiansen574/LyrePlayer/FileHelp.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.LyrePlayer;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.view.MenuItem;
7 |
8 | public class FileHelp extends AppCompatActivity {
9 | @Override
10 | public boolean onOptionsItemSelected(MenuItem item) {
11 | //工具栏返回上一级按钮
12 | if (item.getItemId() == 16908332){
13 | finish();
14 | }
15 | return true;
16 | }
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_file_help);
21 | }
22 | }
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/java/top/weixiansen574/LyrePlayer/FloatListActivity.java:
--------------------------------------------------------------------------------
1 | package top.weixiansen574.LyrePlayer;
2 |
3 | import android.os.Bundle;
4 | import android.view.MenuItem;
5 |
6 | import androidx.appcompat.app.AppCompatActivity;
7 | import androidx.recyclerview.widget.LinearLayoutManager;
8 | import androidx.recyclerview.widget.RecyclerView;
9 |
10 | import java.util.ArrayList;
11 |
12 | public class FloatListActivity extends AppCompatActivity {
13 | RecyclerView music_list;
14 | FloatListManager floatListManager;
15 | @Override
16 | public boolean onOptionsItemSelected(MenuItem item) {
17 | //工具栏返回上一级按钮
18 | if (item.getItemId() == 16908332){
19 | finish();
20 | }
21 | return true;
22 | }
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | floatListManager = new FloatListManager(FloatListActivity.this);
28 | setContentView(R.layout.activity_float_list);
29 | music_list = findViewById(R.id.music_list_main);
30 | ArrayList
121 | *
126 | */
127 | public static CommandResult execCommand(String[] commands, boolean isRoot,
128 | boolean isNeedResultMsg) {
129 | int result = -1;
130 | if (commands == null || commands.length == 0) {
131 | return new CommandResult(result, null, null);
132 | }
133 |
134 | Process process = null;
135 | BufferedReader successResult = null;
136 | BufferedReader errorResult = null;
137 | StringBuilder successMsg = null;
138 | StringBuilder errorMsg = null;
139 |
140 | DataOutputStream os = null;
141 | try {
142 | process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
143 | os = new DataOutputStream(process.getOutputStream());
144 | for (String command : commands) {
145 | if (command == null) {
146 | continue;
147 | }
148 | // donnot use os.writeBytes(commmand), avoid chinese charset
149 | // error
150 | os.write(command.getBytes());
151 | os.writeBytes(COMMAND_LINE_END);
152 | os.flush();
153 | }
154 | os.writeBytes(COMMAND_EXIT);
155 | os.flush();
156 | result = process.waitFor();
157 | // get command result
158 | if (isNeedResultMsg) {
159 | successMsg = new StringBuilder();
160 | errorMsg = new StringBuilder();
161 | successResult = new BufferedReader(new InputStreamReader(
162 | process.getInputStream()));
163 | errorResult = new BufferedReader(new InputStreamReader(
164 | process.getErrorStream()));
165 | String s;
166 | while ((s = successResult.readLine()) != null) {
167 | successMsg.append(s);
168 | }
169 | while ((s = errorResult.readLine()) != null) {
170 | errorMsg.append(s);
171 | }
172 | }
173 | } catch (IOException e) {
174 | e.printStackTrace();
175 | } catch (Exception e) {
176 | e.printStackTrace();
177 | } finally {
178 | try {
179 | if (os != null) {
180 | os.close();
181 | }
182 | if (successResult != null) {
183 | successResult.close();
184 | }
185 | if (errorResult != null) {
186 | errorResult.close();
187 | }
188 | } catch (IOException e) {
189 | e.printStackTrace();
190 | }
191 | if (process != null) {
192 | process.destroy();
193 | }
194 | }
195 | return new CommandResult(result, successMsg == null ? null
196 | : successMsg.toString(), errorMsg == null ? null
197 | : errorMsg.toString());
198 | }
199 |
200 | /**
201 | * 运行结果
202 | *
203 | *
209 | *
210 | * @author Trinea
211 | * 2013-5-16
212 | */
213 | public static class CommandResult {
214 | /** 运行结果 **/
215 | public int result;
216 | /** 运行成功结果 **/
217 | public String successMsg;
218 | /** 运行失败结果 **/
219 | public String errorMsg;
220 |
221 | public CommandResult(int result) {
222 | this.result = result;
223 | }
224 |
225 | public CommandResult(int result, String successMsg, String errorMsg) {
226 | this.result = result;
227 | this.successMsg = successMsg;
228 | this.errorMsg = errorMsg;
229 | }
230 | }
231 | }
232 | //Copy自:https://blog.csdn.net/Sunxiaolin2016/article/details/100974661
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/res/drawable-v24/test_ipv6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/Genshin-Lyre-midi-player/d738b552652f1e4d8d5f4e83b9f675b9593d0e30/LyrePlayer/app/src/main/res/drawable-v24/test_ipv6.jpg
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/res/drawable/file_help_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/Genshin-Lyre-midi-player/d738b552652f1e4d8d5f4e83b9f675b9593d0e30/LyrePlayer/app/src/main/res/drawable/file_help_1.jpg
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/res/drawable/file_help_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/Genshin-Lyre-midi-player/d738b552652f1e4d8d5f4e83b9f675b9593d0e30/LyrePlayer/app/src/main/res/drawable/file_help_2.jpg
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/res/drawable/file_help_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/weixiansen574/Genshin-Lyre-midi-player/d738b552652f1e4d8d5f4e83b9f675b9593d0e30/LyrePlayer/app/src/main/res/drawable/file_help_3.jpg
--------------------------------------------------------------------------------
/LyrePlayer/app/src/main/res/drawable/ic_delete.xml:
--------------------------------------------------------------------------------
1 |