Skip to content

Commit

Permalink
Merge pull request #23 from kshoji/feature/fix-smf-sequencer-issues-2…
Browse files Browse the repository at this point in the history
…0230520

Fix SMF read/write and sequencer playback issues
  • Loading branch information
kshoji authored May 5, 2024
2 parents 8d82cce + 0ae9686 commit ca9d465
Show file tree
Hide file tree
Showing 13 changed files with 364 additions and 126 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: set up JDK 11
uses: actions/setup-java@v3
- uses: actions/checkout@v4
- name: set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '11'
java-version: '21'
distribution: 'temurin'
cache: gradle
cache: 'gradle'

- name: Grant execute permission for gradlew
run: chmod +x gradlew
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.4'
classpath 'com.android.tools.build:gradle:8.3.2'
}
}

Expand Down
16 changes: 16 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Fri May 14 16:38:35 JST 2021
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m
android.useAndroidX=true
org.gradle.unsafe.configuration-cache=true
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Nov 17 05:31:03 JST 2020
#Sat May 20 22:29:59 GMT+09:00 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
5 changes: 1 addition & 4 deletions javax.sound.midi/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.kshoji.javax_sound_midi" >

</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
67 changes: 55 additions & 12 deletions javax.sound.midi/build.gradle
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
apply plugin: 'com.android.library'
plugins {
id 'com.android.library'
id 'maven-publish'
}

repositories {
mavenCentral()
}

dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
api 'com.android.support:support-annotations:28.0.0'
}

android {
compileSdkVersion 29

defaultConfig {
compileSdk 34
minSdkVersion 12
targetSdkVersion 29
targetSdkVersion 34
}

sourceSets {
Expand All @@ -36,15 +42,52 @@ android {
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}

defaultConfig {
consumerProguardFiles 'proguard-rules.pro'
}

buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

publishing {
singleVariant('release') {
withSourcesJar()
}
}

namespace 'jp.kshoji.javax.sound.midi'

buildFeatures {
renderScript true
aidl true
}
}

apply plugin: 'maven'
group = 'jp.kshoji'
uploadArchives {
repositories.mavenDeployer {
repository url: 'file://' + file('repository').absolutePath
pom.version = '0.0.4'
pom.artifactId = 'javax-sound-midi'
publishing {
publications {
release(MavenPublication) {
group = 'jp.kshoji'
artifactId = 'javax-sound-midi'
version = '0.0.5'

afterEvaluate {
from components.release
}
}
}

repositories {
maven {
url = "${project.projectDir}/repository"
}
}
}
task install(dependsOn: uploadArchives)
21 changes: 21 additions & 0 deletions javax.sound.midi/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-keep public class jp.kshoji.javax.sound.midi.** { public protected *; }

-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Signature,Exceptions,*Annotation*,
InnerClasses,PermittedSubclasses,EnclosingMethod,
Deprecated,SourceFile,LineNumberTable

-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
42 changes: 22 additions & 20 deletions javax.sound.midi/src/jp/kshoji/javax/sound/midi/MidiSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ public static List<Receiver> getReceivers() throws MidiUnavailableException {
final List<Receiver> result = new ArrayList<Receiver>();
final Info[] midiDeviceInfos = MidiSystem.getMidiDeviceInfo();
for (final Info midiDeviceInfo : midiDeviceInfos) {
result.addAll(MidiSystem.getMidiDevice(midiDeviceInfo).getReceivers());
MidiDevice midiDevice = MidiSystem.getMidiDevice(midiDeviceInfo);
if (midiDevice != null) {
result.addAll(midiDevice.getReceivers());
}
}

return result;
Expand All @@ -106,7 +109,10 @@ public static List<Transmitter> getTransmitters() throws MidiUnavailableExceptio
final List<Transmitter> result = new ArrayList<Transmitter>();
final Info[] midiDeviceInfos = MidiSystem.getMidiDeviceInfo();
for (final Info midiDeviceInfo : midiDeviceInfos) {
result.addAll(MidiSystem.getMidiDevice(midiDeviceInfo).getTransmitters());
MidiDevice midiDevice = MidiSystem.getMidiDevice(midiDeviceInfo);
if (midiDevice != null) {
result.addAll(midiDevice.getTransmitters());
}
}

return result;
Expand All @@ -129,12 +135,12 @@ public static MidiDevice.Info[] getMidiDeviceInfo() {
final List<MidiDevice.Info> result = new ArrayList<MidiDevice.Info>();
synchronized (midiDevices) {
for (final MidiDevice device : midiDevices) {
final Info deviceInfo = device.getDeviceInfo();
if (deviceInfo != null) {
result.add(deviceInfo);
}
if (device != null) {
result.add(device.getDeviceInfo());
}
}
}

return result.toArray(new MidiDevice.Info[result.size()]);
}

Expand All @@ -148,19 +154,17 @@ public static MidiDevice.Info[] getMidiDeviceInfo() {
*/
@NonNull
public static MidiDevice getMidiDevice(@NonNull final MidiDevice.Info info) throws MidiUnavailableException, IllegalArgumentException {
if (midiDevices.isEmpty()) {
throw new MidiUnavailableException("MidiDevice not found");
}

synchronized (midiDevices) {
for (final MidiDevice midiDevice : midiDevices) {
if (info.equals(midiDevice.getDeviceInfo())) {
return midiDevice;
}
if (midiDevice != null) {
if (info.equals(midiDevice.getDeviceInfo())) {
return midiDevice;
}
}
}
}

throw new IllegalArgumentException("Requested device not installed: " + info);
throw new MidiUnavailableException("MidiDevice not found");
}

/**
Expand All @@ -173,9 +177,8 @@ public static MidiDevice getMidiDevice(@NonNull final MidiDevice.Info info) thro
public static Receiver getReceiver() throws MidiUnavailableException {
synchronized (midiDevices) {
for (final MidiDevice midiDevice : midiDevices) {
final Receiver receiver = midiDevice.getReceiver();
if (receiver != null) {
return receiver;
if (midiDevice != null) {
return midiDevice.getReceiver();
}
}
}
Expand All @@ -192,9 +195,8 @@ public static Receiver getReceiver() throws MidiUnavailableException {
public static Transmitter getTransmitter() throws MidiUnavailableException {
synchronized (midiDevices) {
for (final MidiDevice midiDevice : midiDevices) {
final Transmitter transmitter = midiDevice.getTransmitter();
if (transmitter != null) {
return transmitter;
if (midiDevice != null) {
return midiDevice.getTransmitter();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ public void setMessage(final int status, @NonNull final byte[] data, final int l
*/
@NonNull
public byte[] getData() {
final byte[] result = new byte[data.length];
System.arraycopy(data, 0, result, 0, result.length);
if (data.length == 0) {
return new byte[] {};
}

final byte[] result = new byte[data.length - 1];
System.arraycopy(data, 1, result, 0, result.length);
return result;
}

Expand Down
16 changes: 2 additions & 14 deletions javax.sound.midi/src/jp/kshoji/javax/sound/midi/Track.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,10 @@ public int compare(MidiEvent lhs, MidiEvent rhs) {

// same timing
// sort by the MIDI data priority order, as:
// system message > control messages > note on > note off
// swap the priority of note on, and note off
// system message > control messages > note off > note on
int lhsInt = lhsMessage[0] & 0xf0;
int rhsInt = rhsMessage[0] & 0xf0;

if ((lhsInt & 0x90) == 0x80) {
lhsInt |= 0x10;
} else {
lhsInt &= ~0x10;
}
if ((rhsInt & 0x90) == 0x80) {
rhsInt |= 0x10;
} else {
rhsInt &= ~0x10;
}

return -(lhsInt - rhsInt);
}
};
Expand Down Expand Up @@ -134,7 +122,7 @@ public static void sortEvents(@NonNull final Track track) {
// remove all of END_OF_TRACK
final Collection<MidiEvent> filtered = new ArrayList<MidiEvent>();
for (final MidiEvent event : track.events) {
if (!Arrays.equals(END_OF_TRACK, event.getMessage().getMessage())) {
if (event != null && !Arrays.equals(END_OF_TRACK, event.getMessage().getMessage())) {
filtered.add(event);
}
}
Expand Down
Loading

0 comments on commit ca9d465

Please sign in to comment.