Hello, I wonder if it is possible, playing streaming MIDI song, to change the volume and/or the panning of individual channel/tracks.
I use VB6.
Many thanks.
Dario Barbieri
Hello Dario,
the MIDI.TrackVolumeSet method, applied to a specific track, should be the way to go. Panning could be applied using a combination of values applied to single tracks using the mentioned method. Obviously, the total number of available MIDI tracks can be obtained through the MIDI:TrackCountGet method.
Hope this helps.
Kind regards
Severino Delaurenti
MultiMedia Soft
Many thanks for your reply.
I have another question (sorry, but my programming skill are still poor):
- which statement should I use how can I get (in a listbox) the list of the tracks (channels) and their corresponding instrument (trumpet, violin, ...) ?
This should allow me to select the track upon which apply the volume change.
Many thanks in advance.
Dario Barbieri
You are welcome.
as already mentioned before, the total number of available MIDI tracks can be obtained through the MIDI:TrackCountGet method but, unfortunately, there is no way to assign them a "friendly name", reporting the corresponding instrument, that could be used to list the track into a listbox.
Kind Regards
Severino Delaurenti
MultiMedia Soft
Salve, sono ancora qui a disturbare.
Mi piacerebbe inserire nel mio progetto un VUmeter per ogni canale, per visualizzare in tempo reale, durante la riproduzione del file MIDI, l'intensità (o volume) dei singoli strumenti, visualizzando così le loro "entrate" e "uscite".
Ho hatto qualche tentativo con i comandi Midi.stream.... ma temo di non aver compreso bene la sintassi.
Può aiutarmi ?
Grazie.
Dario
Hello,
please, note that the language for this forum is English only. If you need to ask support in Italian, please, fill the form on our "Contact us" web page:
http://www.multimediasoft.com/contact (http://www.multimediasoft.com/contact)
With regards to your question, if you need to receive notifications about each note in real-time, you may need to enable the MidiStreamEventNotification event by invoking the MIDI.StreamEventsEnableNotifications method for the MIDI_EVENT_NOTE option. An example of usage of this combination can be found inside the VB6 sample "MidiSynthesizer" installed with our setup package: inside this sample the note received through the MidiStreamEventNotification event contains the nMidiParam1 parameter which reports the played note and the nMidiParam2 which reports the related intensity: unfortunately at the moment I don't know if there is also a way to distinguish which instrument played the note.
Kind Regards
Severino Delaurenti
MultiMedia Soft
Hello, my project is proceeding well, but I have a new problem.
When I create a spectrum and i try to change the bar settings, the resulting spectrum remains "black", without any bars.
This is the code I use, can you show me, please, the errors?
Many thanks in advance
in declarations
Dim spettro As OLE_HANDLE
in Form_load
Amp3dj1.Spectrum.Create 0, 0
Amp3dj1.Spectrum.Show 0, BOOL_TRUE
spettro = Creaspettro(Picture3, GRAPHIC_BAR_ORIENT_HORIZONTAL)
' spettro = Creaspettro(Picture3, GRAPHIC_BAR_ORIENT_VERTICAL)
then
Private Function Creaspettro(ctrlPosition As PictureBox, ByVal nOrientation As enumGraphicBarOrientations) As OLE_HANDLE
Dim hWnd As OLE_HANDLE
hWnd = Amp3dj1.GraphicBarsManager.Create(Me.hWnd, ctrlPosition.Left, ctrlPosition.Top, _
ctrlPosition.Width, ctrlPosition.Height)
Amp3dj1.GraphicBarsManager.SetRange hWnd, 0, 100
Dim settings As GRAPHIC_BAR_SETTINGS
Amp3dj1.GraphicBarsManager.GetGraphicalSettings hWnd, VarPtr(settings)
settings.bAutomaticDrop = True
settings.nOrientation = nOrientation
Amp3dj1.GraphicBarsManager.SetGraphicalSettings hWnd, VarPtr(settings)
Creaspettro = hWnd
End Function
Hello,
when using a picture control as a positioning helper, please, be sure to set its Visible property to False or it could cover the graphic bars instanced directly on the container form.
Please, see the Feedbacks sample as a reference.
Hope this helps
Kind Regards
Severino Delaurenti
MultiMedia Soft
Hello,
I followed your instructions but nothing changes.
If I create a "standard" spectrum, referring directly to the Picture3.hWnd, it works perfectly.
When I shift to the "spettro" OLE_HANDLE I get a black picture with no bars.
I used strictly your samples, but seemingly there is some mistake in the code adjustements.
Hello,
please, send us a VB6 project reproducing the issue so we could check it directly and make needed modifications.
Kind Regards
Severino Delaurenti
MultiMedia Soft
Thank you for your reply.
Attached, please find the project (derived from your Test equalizer)
Hello,
there are 2 ways to create a spectrum:
1- using the embedded spectrum visual feedback, in which case you need to provide the hWnd of the picture control to the Spectrum.Create method
2- using a set of graphic bars (not a single one as it seems you are doing in your code) so you should add a number of graphic bars identical to the number of monitored frequencies, just as seen inside the Feedbacks sample, and drive their values inside the SpectrumValueChange event: values to apply for each bar can be obtained through the Spectrum.GetTable method. As mentioned, all of these steps can be found inside the Feedbacks sample.
Let me know if I can be of further help.
Kind Regards
Severino Delaurenti
MultiMedia Soft
Hello,
many thanks for your advice.
Now I've got a perfect "horizontal" spectrum.
Thank you once more.
Hello,
one more question.
During MIDI straming playback I can set the volume of each individual channel: this way I can perform a "mute" or "solo" handling of the song. However this does not happen for all MIDI files: sometimes the committed channels are correctly identified (i.e. Channel 5 plays note 64 at volume 124, .... ) when played "altogheter", but if I try to play each channel as "solo", (i.e. setting to 0 the outstreaming volume of the remaining channels) I get not sound. In addition, very often the effect of a command like "volume set" takes effect only if addressed to a channel number bigger than tha real one: for example, to "mute" channel 0 I must address the command to channel 3, and so on.
Do you have any advice?
Many thanks in advance.
Dario
Hello,
since I got no reply, I think that maybe my question was not clear.
Therefore I send you the code of your MidiPlayer example and two midi files to explain what I mean.
In the code I simply added some Option buttons to "silence" all channels except the checked one.
I invite you to to play the Midi file "Bada bambina":
- checking the option buttons the system works correctly and you can hear each instrument playing alone. However, for example, to hear the "Grand piano" (which plays on Channel 0) you must check che 0ption button indexed 2, and so on.
Play now the Midi file "Camminando":
- checking any Option buttons obtains the result of "silencing" the whole song.
My question is:
why the "MIDI.TrackVolumeSet" command does not work correctly or the results are unpredictable?
Many thanks for your reply.
Dario Barbieri
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
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
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
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
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
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
Hello.
It works perfectly.
Many thanks and congratulations.
Dario
You are welcome and thanks for your feedback.
Kind Regards
Severino Delaurenti
MultiMedia Soft