B4J Question JavaxMidi-B4xLib for B4j

Luca1967

Active Member
Hi,

I am trying to use this nice library but I am having problems
1) I can't read the instruments in the tracks
2) I can't mute a channel
3) Are there any explanations or examples online? If so, where can I get them?
Thank you
 

Luca1967

Active Member
Replace the MidiData_Event sub in the MidiTransmitter Class with:

B4X:
Private Sub MidiData_Event (MethodName As String, Args() As Object)
    Dim Msg As MidiMessage
    Msg.Initialize
    Msg.SetObject(Args(0))
    For Each LT As MidiListenerClass In ListenerMap.Keys
        CallSub3(LT.Callback,LT.EventName & "_Received",Msg,Args(1))
    Next
End Sub

Create a listener on the Sequencer Transmitter after the sequencer is opened:

B4X:
Seqr.GetTransmitter.AddListener(Me,"Trans")

Add this sub in the module that the listener is created in:

B4X:
Private Sub Trans_Received(Msg As MidiMessage, TimeStamp As Long)
    If Msg.IsShortMessage Then
        Dim SM As MidiShortMessage = Msg.AsShortMessage
        If SM.GetCommand = MidiStatus.NOTE_ON Or SM.GetCommand = MidiStatus.NOTE_OFF Then
            Log(SM.GetCommand & " : " & SM.GetChannel & " : " & SM.GetData1 & " : " & SM.GetData2)
        End If
    End If
End Sub

I have updated the library.
Thanks.
Data transmission is much slower than the notes being played.
Do you have any ideas about it?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Data transmission is much slower than the notes being played.
Do you have any ideas about it?
How are you measuring the speed? Make sure you are not testing it in Debug mode. Logging the data will be behind the actual received data.
 
Last edited:
Upvote 0

Luca1967

Active Member
I made a simple program that displays notes on a piano. I put only the listening channel 3, and it shows that the notes are delayed. With certain bases they start correct, but after that they are late.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I made a simple program that displays notes on a piano. I put only the listening channel 3, and it shows that the notes are delayed. With certain bases they start correct, but after that they are late.
Can you post or send me the project.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I don't have your version of midi1 lib, but as it's a type 1 midi file I just commented out the convert method and used the standard javaxmidilib.

I tried your app with your midi file. In release mode it appears to work fine. It doesn't work in debug mode which is to be expected.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Looking at your code, you are calling the sub zitto for every event, you should only need to do that once in the Button1_Click sub after the sequence is set. That may reduce any lag you are seeing.
 
Last edited:
Upvote 0

stevel05

Expert
Licensed User
Longtime User
If there is still an issue, it would be faster to draw the piano on a canvas, rather than using views and css.
 
Upvote 0

Luca1967

Active Member
If I capture keyboard events from MAINFORM, it works correctly, if I try to capture them from FORMPIANO it doesn't work.
Am I wrong something?

Dim CJO As JavaObject = FormPiano.RootPane
Dim O As Object = CJO.CreateEventFromUI("javafx.event.EventHandler","CvsKeyPressed",Null)
CJO.RunMethod("setOnKeyPressed",Array(O))
CJO.RunMethod("setFocusTraversable",Array(True))
Dim O As Object = CJO.CreateEventFromUI("javafx.event.EventHandler","CvsKeyReleased",Null)
CJO.RunMethod("setOnKeyReleased",Array(O))
CJO.RunMethod("setFocusTraversable",Array(True))
 
Upvote 0

Luca1967

Active Member
If I capture keyboard events from MAINFORM, it works correctly, if I try to capture them from FORMPIANO it doesn't work.
Am I wrong something?

Dim CJO As JavaObject = FormPiano.RootPane
Dim O As Object = CJO.CreateEventFromUI("javafx.event.EventHandler","CvsKeyPressed",Null)
CJO.RunMethod("setOnKeyPressed",Array(O))
CJO.RunMethod("setFocusTraversable",Array(True))
Dim O As Object = CJO.CreateEventFromUI("javafx.event.EventHandler","CvsKeyReleased",Null)
CJO.RunMethod("setOnKeyReleased",Array(O))
CJO.RunMethod("setFocusTraversable",Array(True))

I Solved.
Add this instruction next show.
FormPiano.RootPane.RequestFocus
 
Upvote 0

Luca1967

Active Member
Hi Stevel,
I also wanted to put in my karaoke program the capture of the webcam while singing (without recording the video)
Do you know how to please?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
What do you want to use it for?

If you just want to know the current position you can use Sequencer.GetMicrosecondPosition.
 
Upvote 0

Luca1967

Active Member
What do you want to use it for?

If you just want to know the current position you can use Sequencer.GetMicrosecondPosition.

I need it to make the slash that slides backwards to show how long the next verse to sing is missing

For example.

I have the tick for each verse

0:All rights reserved
176:(c) 05-2005 By M-Live S.r.l.
446:"COME SE NON FOSSE STATO MAI AMORE"
536:(Laura Pausini)
596:Endadp
686:WWW.OKYWEB.COM
7730:WWW.OKYWEB.COM
17280:IERI HO CAPITO CHE
20880:E' DA OGGI CHE COMINCIO SENZA TE
24720:E TU L'ARIA ASSENTE
28560:QUASI COME SE IO FOSSI TRASPARENTE
32400:E VORREI FUGGIRE VIA E NASCONDERMI
34800:DA TUTTO QUESTO MA RESTO IMMOBILE QUI
39360:SENZA PARLARE
41280:NON CI RIESCO A STACCARMI DA TE
45127:E CANCELLARE
47040:TUTTE LE PAGINE CON LA TUA IMMAGINE
51120:E VIVERE
55680:COME SE NON FOSSE STATO MAI AMORE
59520:IO SOPRAVVIVERO'
63240:ADESSO ANCORA COME NON LO SO
67080:IL TEMPO QUALCHE VOLTA PUO' AIUTARE
70800:A SENTIRSI MENO MALE
74640:A POTER DIMENTICARE
76680:MA ADESSO E' TROPPO PRESTO E
78480:RESTO IMMOBILE QUI
81600:SENZA PARLARE
83520:NON CI RIESCO A STANCARMI DI TE
87367:E CANCELLARE
89280:TUTTE LE PAGINE CON LA TUA IMMAGINE
93360:E VIVERE
97920:COME SE NON FOSSE STATO MAI AMORE
101578:(Instrumental)
109440:COME SE NON FOSSE STATO AMORE
113280:COME SE NON FOSSE STATO MAI
116880:E VORREI FUGGIRE VIA VORREI NASCONDERMI
120480:MA RESTO ANCORA COSI' SENZA PARLARE
125592:SENZA DIRTI NON TE NE ANDARE
129360:NON MI LASCIARE TRA QUESTE PAGINE
142320:E POI E POI E POI VIVERE
147840:COME SE NON FOSSE STATO MAI AMORE
151385:(Instrumental)
159360:COME SE NON FOSSE STATO AMORE
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Calculating the time between ticks is quite complex as you need to know the current bpm at the two positions and any changes between them, then use the sequences resolution (ticks per quarternote) taking into acccount the sequences time signature, to calculate as many values that are needed.

If the bpm will not change during playback, you can get the information from the sequence on the initial parse by setting the tickposition and reading the Microsecond tick position for the positions you are interested in.

If the bpm is likely to change, you could always calculate for the initial bpm, then modify the output by the ratio of the initial bpm to the new bpm. This is probably the simplest way.
 
Last edited:
Upvote 0

Luca1967

Active Member
Calculating the time between ticks is quite complex as you need to know the current bpm at the two positions and any changes between them, then use the sequences resolution (ticks per quarternote) to calculate as many values that are needed.

If the bpm will not change during playback, you can get the information from the sequence on the initial parse by setting the tickposition and reading the Microsecond tick position for the positions you are interested in.

If the bpm is likely to change, you could always calculate for the initial bpm, then modify the output by the ratio of the initial bpm to the new bpm. This is probably the simplest way.

Can i use this formula?

currentMillis = tick * 60000 / ppqn / tempo

Where do I get the data from?

seqr.gettempoinbpm
seq.getdivisiontype
seq.getresolution

?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I've not tried it, but it is likely to be: currentMillis = tick * 60000 / Seq.GetResolution / Seqr.GetTempoInBpm

Try it.
 
Upvote 0
Top