streaming MIDI

Started by dario, August 08, 2016, 11:52:33 AM

Previous topic - Next topic

Administrator

Hello and sorry for the late answer, we were closed for summer holidays.
The problem appears to be quite simple: by enumerating notes on each of the tracks in use, it seems that the Midi file "Bada bambina" has notes distributed on different channels while the second Midi file "Camminando" has notes on channel 0 only while all of the other channels are simply empty.
I don't think that the MIDI standard requires that different instruments are redistributed on specific channels so the behaviour will obviously change depending upon the composer of the Midi file.
You can know if a specific channels is empty, and eventually hide it from the user interface, by calling the MIDI.StreamEventsEnum method on each track: if after return from the call its nCount parameter reports 0 or -1, this means that the track is empty.

Hope this helps.

Kind Regards

Severino Delaurenti
MultiMedia Soft


dario

Hello,

sorry, but your reply does not help, since the matter is absolutely not so easy.
As a matter of fact, both songs have more than one channel (or track) and the control recognises it.
Particularly, for the song Camminando the traks are 8, and the control sees them all.
Using the MidiStreamEventNotification procedure I liste the first 100 notes detected by the control in each song (see attachment): it is clear that in both cases the right note is coupled to the corresponding track (instrument). It is not true that in one song all notes are directed to channel 0. Moreover, listening to the output, one clearly recognizes that more than one instrument is involded,  and no MIDI composer  would address each note to the same channel, changing for every note the instrument patch.
Thus, my question is absolutely unsolved: I must understadn why, (playing Camminando) setting to 0 the volume of channels 2-8, I hear nothing from channel 1 (which has notes) ; then I must understand why (playing Bada bambina) the changes in output volume of channel 0 can be ontained addressing the proper instruction to channel 2 (so 1 to 3, 2 t o 4, and so on).
As far as I can understand from these 2 examples, I must express my wonder and doubt that the SetTrackVolume commands are not working properly.
In conclusion: the control perfectly recognizes the MIDI structure and events, but I am afraid to say that it is not possible to control MIDI output or, at least, the volume control is not trustworthy.

Best wishes

Dario Barbieri

Administrator

Hello,

my test was based upon adding the following code at the end of the SoundLoaded event handler


    Dim nEvents As Long
    Dim i As Integer
    For i = 0 To 15
        Amp3dj1.MIDI.StreamEventsEnum 0, i, MIDI_EVENT_ALL, nEvents
        Debug.Print "Track: " & i & " --> " & nEvents
    Next


If you try this code you will see that in the second case all of the events appear to be on the first track only. I'm not an expert about MIDI composition but the two files appear to be composed very differently.

Kind Regards

Severino Delaurenti
MultiMedia Soft

dario

Hello,

I used this code

Private Sub Amp3dj1_MidiStreamEventNotification(ByVal nPlayer As Integer, ByVal nMidiEvent As AMP3DJLib.enumMidiStreamEvents, ByVal nMidiParam1 As Integer, ByVal nMidiParam2 As Integer, ByVal nMidiChannel As Integer, ByVal fPositionInMs As Double, ByVal fPositionInTicks As Double, ByVal fPositionInPercentage As Double)
Dim w As integer
Dim z As integer
Dim I, J

If nMidiEvent = MIDI_EVENT_NOTE Then
I = nMidiChannel 'volume
w = nMidiParam2 ' channel
z = nMidiParam1 'note number
End If

End Sub

If you try it you'll see than in any MIDI file for each midi event the note, the channel and the volume are correctly recognized. In my appication I pair each channel to a VUmeter which shows the volume and, during song playback, ALL vumeter are active and show the involvement of each individual intrument (and this happens with ALL midi files), i.e. the MIDI event is perfecly decoded. These are matter of fact. If you check MIDIs with any freeware midi editor (Anvil studio, for example) you will find a full confirmation of what I am stating. Moreover, the structure of the midi messages is independent fron the composer or the midi type: noteon, noteoff, channel, patch are main information required.
What apparently you are not prone to accept is that the control works perfectly with midi files and perfectly recognises midi events, no one may deny such a thing, BUT, very simply, SOMETHING WRONG happens when you try to interact with the event itself, at least as far as volume handling is concerned.
I don't know why, but it's a pity.

Best regards

Administrator

Hello,

we will go forward with our analysis in order to understand if something is missing in our code and will let you know our findings at the soonest.

Kind Regards

Severino Delaurenti
MultiMedia Soft

Administrator

Hello,

after a further analysis I've found the real difference between the 2 midi files:
- the first one comes with 16 channels and 16 tracks, apparently each channel is mapped over a different track
- the second one comes with 16 channels and 1 single track on which all of the channels are mapped

In MIDI standard tracks and channels are different entities which are controlled separately (quite confusing in my opinion but this wan't our choice) so this explains why the MIDI.TrackVolumeSet method will apply the same volume all over the channels of the second midi file (it works like a sort of master volume).
If you need to apply a different volume to each channel, you should replace the call to MIDI.TrackVolumeSet with a call to the MIDI.StreamEventApply method having the nMidiEvent parameter set to MIDI_EVENT_VOLUME, so your current code:



Private Sub Option1_Click(Index As Integer)
    Dim i
    For i = 0 To 15
        Amp3dj1.MIDI.TrackVolumeSet 0, i, 0
    Next i
    Amp3dj1.MIDI.TrackVolumeSet 0, Index, 100
    If Index = 16 Then
        For i = 0 To 15
            Amp3dj1.MIDI.TrackVolumeSet 0, i, 100
        Next i
    End If
End Sub


should be replaced by this:



Private Sub Option1_Click(Index As Integer)
    Dim i
    For i = 0 To 15
        Amp3dj1.MIDI.StreamEventApply 0, MIDI_EVENT_VOLUME, 0, 0, i, BOOL_FALSE
    Next i
    Amp3dj1.MIDI.StreamEventApply 0, MIDI_EVENT_VOLUME, 127, 0, Index, BOOL_FALSE
    If Index = 16 Then
        For i = 0 To 15
            Amp3dj1.MIDI.StreamEventApply 0, MIDI_EVENT_VOLUME, 127, 0, i, BOOL_FALSE
        Next i
    End If
End Sub



Just tried on your sample and it seems to work as expected :-)

Let me know if this works for you as well.

Kind Regards

Severino Delaurenti
MultiMedia Soft

dario

Hello.

It works perfectly.
Many thanks and congratulations.

Dario

Administrator

You are welcome and thanks for your feedback.

Kind Regards

Severino Delaurenti
MultiMedia Soft