kshoji / javax.sound.midi-for-android Goto Github PK
View Code? Open in Web Editor NEWPackage javax.sound.midi porting for Android
License: Apache License 2.0
Package javax.sound.midi porting for Android
License: Apache License 2.0
Hi,
I have a small project that uses this library, and I'd like to publish it on the F-Droid app store. I was able to include the project like this:
maven {
url 'https://github.com/kshoji/javax.sound.midi-for-Android/raw/master/javax.sound.midi/repository'
}
But unfortunately F-Droid won't accept that as a maven repo. They do, however, accept JitPack. Unfortunately it looks like the latest working build on JitPack is v0.0.3:
https://jitpack.io/#kshoji/javax.sound.midi-for-Android
It seems that the v0.0.4 build is broken because JitPack looks for the library in the local repository in ~/.m2
and it can't find it. I ran the builds locally, and from what I could tell, there were some changes in the way the maven plugin works so that in v0.0.3 the library is also deployed locally:
$ git checkout v0.0.3
$ ANDROID_HOME=$HOME/Android/Sdk ./gradlew clean -Pgroup=com.github.kshoji -Pversion=v0.0.3 -xtest -xlint install
...
$ find ~/.m2/repository/jp/kshoji/javax-sound-midi/
~/.m2/repository/jp/kshoji/javax-sound-midi/
~/.m2/repository/jp/kshoji/javax-sound-midi/0.0.3
~/.m2/repository/jp/kshoji/javax-sound-midi/0.0.3/javax-sound-midi-0.0.3.aar
~/.m2/repository/jp/kshoji/javax-sound-midi/0.0.3/javax-sound-midi-0.0.3.pom
~/.m2/repository/jp/kshoji/javax-sound-midi/maven-metadata-remote.xml.sha1
~/.m2/repository/jp/kshoji/javax-sound-midi/maven-metadata-remote.xml
But this no longer happens when building v0.0.4:
$ git checkout v0.0.4
$ ANDROID_HOME=$HOME/Android/Sdk ./gradlew clean -Pgroup=com.github.kshoji -Pversion=v0.0.4 -xtest -xlint install
...
$ find ~/.m2/repository/jp/kshoji/javax-sound-midi/
~/.m2/repository/jp/kshoji/javax-sound-midi/
~/.m2/repository/jp/kshoji/javax-sound-midi/maven-metadata-remote.xml.sha1
~/.m2/repository/jp/kshoji/javax-sound-midi/maven-metadata-remote.xml
~/.m2/repository/jp/kshoji/javax-sound-midi/resolver-status.properties
Thanks!
Some methods on MidiSystem like getReceiver
, or getTransmitter
returns null
when the object is not found.
The other JDK's method throws MidiUnavailableException
on the same situation.
Hi,
I'm trying to retrieve the "transmitter" in order to assign it my own "receiver" (to handle every MidiMessage
).
Sequence sequence = MidiSystem.getSequence(getResources().openRawResource(R.raw.my_midi));
midiSequencer = MidiSystem.getSequencer();
midiSequencer.open();
midiSequencer.setSequence(sequence);
midiSequencer.start();
From here midiSequencer.getTransmitter()
returns null. Please note the same piece of code using the javax.sound.midi
API works well.
PS: I don't use USB/BLE features. I also tried with and without calling MidiSystem.initialize()
/MidiSystem.terminate()
, and the result is the same.
Thanks,
Victor
SequencerImpl
throws NullPointerException
when the thread is not initialized.Receiver
and Transmitter
will be closed when the sequencer closed. They should not be closed.I can see that this is licensed under the Apache License, Version 2.0, but what should be entered for the copyright notice? Kshoji? If so, what year?
My Code in Android Studio is:
try {
Synthesizer synthesizer = MidiSystem.getSynthesizer();
synthesizer.open();
synthesizer.unloadAllInstruments(synthesizer.getDefaultSoundbank());
synthesizer.loadAllInstruments(MidiSystem.getSoundbank(getAssets().open("SmallTimGM6mb.sf2")));
Sequencer sequencer = MidiSystem.getSequencer(false);
sequencer.open();
sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
InputStream inputStream = new BufferedInputStream(getAssets().open("lagu.mid"));
sequencer.setSequence(inputStream);
sequencer.start();
Toast.makeText(this, "play", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "error "+e.toString(), Toast.LENGTH_SHORT).show();
}
A call to MetaMessage() results in a NegativeArraySizeException.
The reason is that the defaultMessage Array in MetaMessage has got only a length of 2. So it always throws a java.lang.NegativeArraySizeException (Invalid meta event. data: [-1, 0] );
A solution is to change the default message initialisation to
private static final byte[] defaultMessage = { (byte) META, (byte)0, (byte)1, (byte)0 };
as it is done in the reference implementation of javax.sound.midi.MetaMessage( http://developer.classpath.org/doc/javax/sound/midi/MetaMessage-source.html )
`
private static File sound;
private static Sequence seq;
private static Sequencer midi;
sound = new File(pathname);
seq = MidiSystem.getSequence(sound);
midi= MidiSystem.getSequencer();
midi.open();
midi.setSequence(seq);
if(!midi.isRunning()) {
midi.start();
Log.v("start", "start");
}
`
When I run the above code, there is no sound.
But there's sound on the window.
The non-standard listener API described in this old wiki entry seems to have been removed, and so it is no longer possible to detect device (dis)connections at runtime. Any chance of bringing back those listeners?
I might be doing something wrong here but when I include the library in my android app when I generate the sequence and register a receiver I am not getting the TIMING_CLOCK ShortMessages. Reading through the source code I can see when read through StandardMidiFileReader the TIMING_CLOCK status is never read. The same midi file on ios gives me back timing events. Is this the designated behaviour?
ERROR: Failed to resolve: jp.kshoji:javax-sound-midi:0.0.2
Show in Project Structure dialog
Affected Modules: app
ERROR: Failed to resolve: jp.kshoji:midi-driver:0.1.3
Show in Project Structure dialog
Affected Modules: app
Add these methods to MidiSystem
.
Report from twitter: isacben
Sequencer resumes to the beginning automatically.
After 2 seconds from stopping, the getTicks method reports 0.
new MetaMessage()
を呼ぶと必ずNegativeArraySizeException
を投げられます。
new MetaMessage()
の中でthis(defaultMessage)
を呼んでいますが、
その引数のサイズが2なので、その中のif(data.length<3)
の文に
引っかかっていました。
MIDIファイルを読み込ませるときにも発生し、Sequence
が作られない事態になっています。
修正をお願いします。
The repository at https://github.com/kshoji/USB-MIDI-Driver/raw/master/library/repository does not exit, as described here: https://github.com/kshoji/javax.sound.midi-for-Android/wiki/Use-library-with-Android-Studio
Also, in Android Studio, the project root build.gradle need two separate entries for maven url like this:
allprojects {
repositories {
google()
jcenter()
maven {
url 'https://github.com/kshoji/BLE-MIDI-for-Android/raw/master/library/repository'
}
maven {
url 'https://github.com/kshoji/USB-MIDI-Driver/raw/master/library/repository'
}
mavenCentral()
}
}
and
compile 'jp.kshoji:midi-driver:0.1.4:@aar'
should be replaced by
implementation 'jp.kshoji:midi-driver:0.1.4:@aar'
Looking through the code I see this comment which is basically asking how do you handle this in a running status case.
The answer is you don't because none of the messages in the F1-F6 and F8-FE range are actually allowed in a midi file and make no sense to have in a file.
See the spec here. You will see that only channel events (80-EF), sysex events (F0, F7) and meta events (FF) are allowed in a file and running status only applies to channel events.
This document even makes it more explicit:
Note that the status bytes associated with System Common messages (0xF1 to 0xF6 inclusive) and System Real Time messages (0xF8 to 0xFE inclusive) are not valid within a MIDI file. Generally none of these messages are relevant within a MIDI file, though for the rare occasion when you do need to include one, it should be embedded within a SysEx escape sequence.
StandardMidiFileWriter
outputs unplayable MIDI file.
The code it uses to iterate over the loops is here:
for (int loop = 0; loop < getLoopCount() + 1; loop = (getLoopCount() == LOOP_CONTINUOUSLY ? loop : loop + 1)) {
where LOOP_CONTINUOUSLY
is equal to -1
. In the case where getLoopCount() == LOOP_CONTINUOUSLY
, this is saying:
for (int loop = 0; loop < -1 + 1; loop = loop) {
clearly, this means that the code in the for
loop never executes, since loop
is always 0
and 0 < 0
is false.
I think this line should be:
for (
int loop = 0; // initialize at 0
loop < getLoopCount + 1 || getLoopCount() == LOOP_CONTINUOUSLY; // keep going if set to loop continuously
loop++ // iterate up in increments of 1, as standard
)
I'm trying to write code which plays MIDI notes from file.
I want to be able to intercept packets sent by the sequencer, and then process them, before sending them on to the synthesizer.
Sequencer -> Custom processing -> Synthesizer
I don't want the sequencer to send events directly to the Synthesizer!
Based on reading the JavaX docs, I think I should be able to do the following:
// get sequencer
Sequencer seq = MidiSystem.getSequencer(false);
seq.open();
seq.setSequence((new StandardMidiFileReader()).getSequence(getActivity().getAssets().open("test.mid")));
// get synth
Synthesizer synth = new SoftSynthesizer();
synth.open();
synth.loadAllInstruments(SF2Soundbank(getActivity().getAssets().open("test.sf2")));
// get middleware - this implements Transmitter and Receiver
PacketInterceptor intercept = new PacketInterceptor();
// connect everything together
sequencer.getTransmitter().setReceiver(packetInterceptor);
packetInterceptor.setReceiver(synth.getReceiver());
However, I'm seeing jp.kshoji.javax.sound.midi.MidiUnavailableException: Transmitter not found
.
From looking at the code, it seems like the Sequencer isn't created with any Transmitters. Bizarrely, it seems to get its transmitters from other devices, using MidiSystemUtils.getTransmitters()
. This doesn't seem right. It is contrary to the documentation at https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MidiSystem.html#getSequencer(boolean), which indicates that the Sequencer should have no open transmitters, but that there should still be transmitters that I can get so that I can set their receivers.
This issue seems related to #2, but the resolution of that doesn't seem applicable to me, because I want to control which device is connected to which other device, using transmitters/receivers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.