B4A Library MidiSystem

Discussion in 'Additional libraries, classes and official updates' started by stevel05, Feb 1, 2015.

  1. stevel05

    stevel05 Expert Licensed User

    OK, here is the culmination of many months of work, it is a port of a large part of the javax MidiSystem, written entirely in Basic4Android.

    This Library gives access to a Midi file at the event/message level, you can create, load, play and save midi files and much more. It incorporates a USB manager module so you can attach external midi devices via USB and receive and send midi messages to the attached hardware. You can also create your own transmitter module and send midi data to the Sequencer as if it were a hardware device.

    I have simplified some of the workings as Android devices do not provide as many in/out configurations as working on a PC.

    The biggest problem remains audio latency especially when playing from a User module to the internal Midi module, using USB hardware provides better performance.

    I will post some complete examples so you can see how the System works in the Example forum as there are a few of them. Most of the documentation for the Javax Midi System is relevant.

    The library depends on these libraries which should be in your additional libs folder:

    threading, javaobject, slbytearraybuffer, mididriver, usb, slstreams, nanotime, android-support-v4

    if you don't already have it, android-support-v4 has to be downloaded using the Android SDK Manager. Add the extras/Android Support package, then copy the jar file from <SDK root folder>\extras\android\support\v4 to your addl libs folder.

    This is a large library, although I have tested it as thoroughly as possible, I am sure there will be some bugs in there somewhere, please treat it as Beta software and test any app using it thoroughly yourself prior to release.

    I have a reasonably fast (2013 Asus Nexus 7) which handles the workload very well, I can't guarantee that all devices will do the same. Please have a target in mind and test developed software on that. I would be surprised if anything over 3 years old would give acceptable performance. There could be as many a 5 threads (including the Gui thread) running at once if you are recording, so it could be a drain on resources for older / slower devices.

    Updated to v1.01 as post#2
    Update to V2 to allow newer android versions to access the midi driver. (You also need the mididriver2 Lib)

    Enjoy

    178
     

    Attached Files:

    Last edited: May 29, 2018
  2. stevel05

    stevel05 Expert Licensed User

    Right, I win the prize for finding the first bug :( Repeatedly unplugging and plugging a USB cable would crash the library. Why would you do that you may well ask, I was thinking like a user :).

    Fixed in V1.01 updated in the first post.
     
  3. GCOINC

    GCOINC Guest

    Line 129 unknown member = max

    Code:
    SliTempo.Max = MaxTempo * 100 / Seqr.BPM
    SliTempo.Value = Seqr.TempoFactor * 
    100
     
  4. stevel05

    stevel05 Expert Licensed User

  5. GCOINC

    GCOINC Guest

    Clearly I want to really play with this ;)

    Code:
    Error compiling program.
    Error description: Unknown member: setlayoutanimated
    Occurred on line: 
    241
    P.SetLayoutAnimated(
    50,0,LineSpace + (LineSpace + LineHeight) * i,svBG.Panel.Width,LineHeight)
    Word: setlayoutanimated
     
  6. stevel05

    stevel05 Expert Licensed User

    If you don't have B4a 4.3, you'll need to change that line to P.SetLayout(50,0,LineSpace + (LineSpace + LineHeight) * i,svBG.Panel.Width,LineHeight).

    There may be more changes required.
     
  7. GCOINC

    GCOINC Guest

    Thx stevel05. I will make the change to see if it compiles and give it a go - Then make the update my B4A to the latest and greatest to avoid this in the future...
     
  8. wonder

    wonder Expert Licensed User

    Hello @stevel05!

    I'm a little bit confused, can I use this library as a simple media player for .mid files? In games, for example.
     
  9. stevel05

    stevel05 Expert Licensed User

    Hi Wonder,

    Although it would do that job, you would be loading an additional large library and not getting any benefit from it.

    You can use MediaPlayer for that. It would also use more resources than Media player.

    This is useful for creating and manipulating Midi files in code.

    Steve
     
    wonder likes this.
  10. wonder

    wonder Expert Licensed User

    Thanks!! I didn't know that the MediaPlayer could play .mid files. I'll give it a try!! :)
     
  11. robertyoungs

    robertyoungs Member Licensed User

    Hi @stevel05 - been having lots of Fun playing with your most excellent midisystem

    But, is there are way I can get to the MidiEvents from a loaded midi file (I can successfully load and play it in the sequencer) - I'm just trying to get to the NoteOn/Off and midi note data from this file. It compiles with error: java.lang.RuntimeException: Method: _geteventlist not found in: [Lcom.stevel05.midilib.miditrack; when I try and get it from MidiTrack instance

    Code:
    Dim track As MidiTrack
    Dim midEvts As MidiEvent
    Dim midlist As List
    midlist.Initialize
    track.Initialize

    Main.Seq = MidiSystem_Static.GetSequence(Main.SettingsDataMap.Get(
    "midi_file_path"),TEEventDataMap.Get("file_name"),False)
    Main.Seqr.SetSequence(Main.Seq)
    track = Main.Seq.GetTracks
    midlist = track.EventList
     
  12. stevel05

    stevel05 Expert Licensed User

    Hi Robert, I'm glad you are getting some use out of the library. I will try to have a look at the issue tomorrow and let you know.

    Steve
     
  13. robertyoungs

    robertyoungs Member Licensed User

    Hi Steve - thanks for quick response - I actually managed to get to the information I need in real-time by going through and mangling your midi monitor class. This allows me to then use the sequencer to play tunes using my samples in a soundPool player class

    Sorry to have bothered you

    But still would be very handy to know how to get to the midi note, noteOn/Off events and time deltas from a file if at all possible?

    Best
    Rob
     
  14. stevel05

    stevel05 Expert Licensed User

    Hi Rob,

    Now I've had a proper look at your code (and reminded myself how the library works), Seq.Gettracks returns an array of tracks. i.e. all of the tracks in the sequence. So to get the events you need to first assign them to a Track array, then pick the track you want and get the events from that.

    Code:
    Dim Tracks() As MidiTrack =  Seq.GetTracks
        
    For Each MT As MidiTrack In Tracks
            
    Log (MT.EventList.Size)
        
    Next
    What is the preformance like playing the midi through sound pool? It's a nice idea.
     
  15. robertyoungs

    robertyoungs Member Licensed User

    Hi Steve, Doh... many thanks for that and the snippet

    Performance is very good on an older type nexus 7, and the samples are about 1Mb each, so very pleasantly surprised. Also triggering the soundpool with messages from your Piano class, and appears to have less latency than the midi engine. Very rudimentary at the moment and only a few samples, but promising

    So a big thanks for how your contribution is helping me move forward!
    Rob
     
  16. stevel05

    stevel05 Expert Licensed User

    That's good.

    The screen touch also introduces latency. I would hazard a guess that triggering from an external USB device would be better again.
     
  17. Michael Wenning

    Michael Wenning Member Licensed User

    Hello steve,
    i like your MidiSystem1-01 libary.
    I want change the instrument for the internal piano like in your driver sample:
    Sub SendProgramChange(Value As Int)
    Dim Msg() As Byte = Array As Byte(0xC0 + mPno.Channel,Value)
    mPno.Midi.SendMidi(Msg)
    End Sub
    I have seen that the Modul MidiGeneralMidi_Static is included your libary.
    I have tried
    MMsg.setShortMessageWithChannel1(0xC0 + Starter.Channel,Starter.Channel,Value)
    But the piano reference is missing.
    Can you give me an answer?
    Thank's and regards,
    Michael
     
  18. stevel05

    stevel05 Expert Licensed User

    There are several pianos in the list they are listed under their standard midi names, so the first piano is "Acoustic Grand Piano". The names 'should' match the list found here. https://www.midi.org/specifications/item/gm-level-1-sound-set

    To double check, you can iterate over the ProgNameMap Values and list them all.
     
  19. Michael Wenning

    Michael Wenning Member Licensed User

    With your MidiDriver.lib it works great:

    intNumber= MIDI Program Change or "PC#

    sample: intNumber = 33 ' ==> 33 is Bass from your MidiGeneralMidi_Static or https://www.midi.org/specifications/item/gm-level-1-sound-set

    Msg is ( -64, 33)

    mPno.Midi.SendMidi(Msg)

    after this piano plays like a Bass!

    How can i do this with your MidiSystem1-01 libary?

    Thank's and regards,
    Michael Wenning
     
  20. stevel05

    stevel05 Expert Licensed User

    Sorry Michael,

    I won't have access to my Pc until Tuesday. I'll take a look then.

    Steve
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice