|
|
![Go to Parent](https://www.codeproject.com/App_Themes/CodeProject/Img/arrow-up24.png) Hi....i found this simple plugin called Jazz Plugin that seems to have a very simple code..although i am not figuring out why it is returning me these errors!
this is the thing:
<pre>Public Class Form1
Dim chan As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim list As String() = Jazz.MidiOutList()
For Each s In list
Out.Items.Add(s)
Next s
Out.SelectedIndex = 0
tone.SelectedIndex = 0
Channel.SelectedIndex = 0
End Sub
Private Sub Out_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Out.SelectedIndexChanged
Jazz.MidiOutOpen(Out.SelectedItem)
End Sub
Private Sub Channel_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Channel.SelectedIndexChanged
chan = Channel.SelectedIndex
End Sub
Private Function Note(ByVal obj As System.Object)
If ReferenceEquals(obj, Button1) Then
Return 53
ElseIf ReferenceEquals(obj, Button2) Then
Return 55
End If
Return 0
End Function
Private Sub ToneChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tone.SelectedIndexChanged
Jazz.MidiOut(&HC0 + chan, tone.SelectedIndex, 0)
End Sub
Private Sub Down(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown, Button2.MouseDown
Jazz.MidiOut(&H90 + chan, Note(sender), 100)
End Sub
Private Sub Up(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseUp, Button2.MouseUp
Jazz.MidiOut(&H80 + chan, Note(sender), 0)
End Sub
End Class
and its returnning the errors on these lines:
<pre> Private Sub ToneChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tone.SelectedIndexChanged
Jazz.MidiOut(&HC0 + chan, tone.SelectedIndex, 0)
End Sub
Private Sub Down(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown, Button2.MouseDown
Jazz.MidiOut(&H90 + chan, Note(sender), 100)
End Sub
Private Sub Up(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseUp, Button2.MouseUp
Jazz.MidiOut(&H80 + chan, Note(sender), 0)
End Sub
Any help...?!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Alienoiz wrote: and its returnning the errors on these lines:
Which errors?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
the code underlined is being treated as an error!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Yes.. but what's the description of the error
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
Severity Code Description Project File Line Suppression State
Error BC30311 Value of type 'Integer' cannot be converted to 'Object()'. WindowsApplication1 C:\Users\beata\Documents\Visual Studio 2015\Projects\WindowsApplication1\WindowsApplication1\Form1.vb 35 Active
Error BC30057 Too many arguments to 'Public Overridable Overloads Sub MidiOut([in] As Object())'. WindowsApplication1 C:\Users\beata\Documents\Visual Studio 2015\Projects\WindowsApplication1\WindowsApplication1\Form1.vb 35 Active
modified 7-Jan-19 21:02pm.
|
|
|
|
|
The method Jazz.MidiOut that's intended to being called there isn't part of the project you downloaded. I assume it's in that "Jazz-Plugin" which is advertised on the website and it doesn't look like the source code of that is being offered. You should ask for help on that website.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
OK..i will try..Thank You!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Well... i did not had an answer..even because my registration in their forums was a mess..and i could not even register there!
I searched for more help and i came accross with some examples..i kinda mixed 2 codes and i am now able to open my midi devices an play the sounds through my MIDI controller. I am only having 2 issues that i am not being able to solve!
1 - the sound is playing twice..one for "note on" another for "note off"...when i press my MIDI controller key it plays..and when i release it ..it plays again!!!!
2 - the notes seem to be infinite..i do not know where to put the
STOPAllMIDINotes() function!
I have all this code:
<pre> Public Declare Function midiInGetNumDevs Lib "winmm.dll" () As Integer
Public Declare Function midiInGetDevCaps Lib "winmm.dll" Alias "midiInGetDevCapsA" (ByVal uDeviceID As Integer, ByRef lpCaps As MIDIINCAPS, ByVal uSize As Integer) As Integer
Public Declare Function midiInOpen Lib "winmm.dll" (ByRef hMidiIn As Integer, ByVal uDeviceID As Integer, ByVal dwCallback As MidiInCallback, ByVal dwInstance As Integer, ByVal dwFlags As Integer) As Integer
Public Declare Function midiInStart Lib "winmm.dll" (ByVal hMidiIn As Integer) As Integer
Public Declare Function midiInStop Lib "winmm.dll" (ByVal hMidiIn As Integer) As Integer
Public Declare Function midiInReset Lib "winmm.dll" (ByVal hMidiIn As Integer) As Integer
Public Declare Function midiInClose Lib "winmm.dll" (ByVal hMidiIn As Integer) As Integer
Public Delegate Function MidiInCallback(ByVal hMidiIn As Integer, ByVal wMsg As UInteger, ByVal dwInstance As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
Public ptrCallback As New MidiInCallback(AddressOf MidiInProc)
Public Const CALLBACK_FUNCTION As Integer = &H30000
Public Const MIDI_IO_STATUS = &H20
Public Delegate Sub DisplayDataDelegate(dwParam1)
Public Structure MIDIINCAPS
Dim wMid As Int16
Dim wPid As Int16
Dim vDriverVersion As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim szPname As String
Dim dwSupport As Integer
End Structure
Dim hMidiIn As Integer
Dim DataByte1 As Byte
Dim m As New clsMIDI
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
FillInstrumentCombo()
If midiInGetNumDevs() = 0 Then
MsgBox("No MIDI devices connected")
Application.Exit()
End If
Dim InCaps As New MIDIINCAPS
Dim DevCnt As Integer
For DevCnt = 0 To (midiInGetNumDevs - 1)
midiInGetDevCaps(DevCnt, InCaps, Len(InCaps))
ComboBox1.Items.Add(InCaps.szPname)
Next DevCnt
midiInStart(hMidiIn)
End Sub
Function MidiInProc(ByVal hMidiIn As Integer, ByVal wMsg As UInteger, ByVal dwInstance As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
DataByte1 = (dwParam1 And &HFF00) >> 8
m.PlayMIDINote(DataByte1, 127)
m.STOPAllMIDINotes()
End Function
Private Sub ComboBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim DeviceID As Integer = ComboBox1.SelectedIndex
midiInOpen(hMidiIn, DeviceID, ptrCallback, 0, CALLBACK_FUNCTION Or MIDI_IO_STATUS)
midiInStart(hMidiIn)
End Sub
Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
midiInStop(hMidiIn)
midiInReset(hMidiIn)
midiInClose(hMidiIn)
Application.Exit()
End Sub
I do not know where "to go" now...!!!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
HI..some help please..
I have changed my code and i am now able to select a MIDI Device and play notes from it!
I am now facing a problem that is - note duration
When i insert the code for note duration it returns me an error that says something like this:
"the code is using a thread for what was not created"
Heres the code i am using...and i am also using a module called clsMIDI
<pre>Public Class Form1
Dim m As New clsMIDI
Dim hMidiIn As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
FillInstrumentCombo()
If midiInGetNumDevs() = 0 Then
MsgBox("No MIDI devices connected")
End If
Dim InCaps As New MIDIINCAPS
Dim DevCnt As Integer
For DevCnt = 0 To (midiInGetNumDevs - 1)
midiInGetDevCaps(DevCnt, InCaps, Len(InCaps))
ComboBox1.Items.Add(InCaps.szPname)
Next DevCnt
midiInStart(hMidiIn)
End Sub
Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
midiInStop(hMidiIn)
midiInReset(hMidiIn)
midiInClose(hMidiIn)
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim DeviceID As Integer = ComboBox1.SelectedIndex
midiInOpen(hMidiIn, DeviceID, AddressOf MidiInProc, 0, CALLBACK_FUNCTION)
midiInStart(hMidiIn)
End Sub
Private Sub FillInstrumentCombo()
For i = 0 To 128
cboInstruments.Items.Add(Instrument.GMInstrumentNames(i))
Next
cboInstruments.SelectedIndex = 0
End Sub
Private Sub cboInstruments_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboInstruments.SelectedIndexChanged
m.CurrentInstrument = cboInstruments.Text
End Sub
Private Sub hsbVolume_ValueChanged(sender As Object, e As EventArgs) Handles hsbVolume.ValueChanged
m.Volume = hsbVolume.Value
End Sub
Function MidiInProc(ByVal hMidiIn As Integer, ByVal wMsg As UInteger, ByVal dwInstance As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
Dim DataByte1 = (dwParam1) >> 8
m.PlayMIDINote(DataByte1, 127)
m.NoteDuration = CInt(cboduration.Text)
m.Pan = 50
End Function
End Class
TIA
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Controls (a Form, ComboBox, TextBox..) can only be accessed by the UI-thread. That's the thread that created them and the thread that executes all your code unless you either explicitly create additional threads or use some kind of event/callback mechanism - the latter you apparently do here:
midiInOpen(hMidiIn, DeviceID, AddressOf MidiInProc, 0, CALLBACK_FUNCTION) So that midi-library you're using seems to call your function MidiInProc(..) on a different thread than your UI-thread and then tries to access cboduration.Text which is one of your controls which may only be accessed by your UI thread. That's the problem.
The easiest solution for you here is this: Read the value of cboduration.Text into a class variable (let's call it duration ) the moment that it is changed by the user. Also initialize that variable with the same value as the control. Then replace this:
m.NoteDuration = CInt(cboduration.Text)
..by this:
m.NoteDuration = duration
Now the UI thread does the reading from the control and the thread that executes MidiInProc doesn't "touch" any controls any more.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
"The easiest solution for you here is this: Read the value of cboduration.Text into a class variable (let's call it duration) the moment that it is changed by the user. Also initialize that variable with the same value as the control."
May you show me the code for this...???
Thank you!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Well? .. i realy would like to have this working?!
Thanks,
Duarte
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Alienoiz wrote: Well? .. i realy would like to have this working?! Please note that we're all volunteers here, answering questions in our free time, not getting paid for it. And there are also other things I enjoy doing in my free time.
You're already doing what would be required for NoteDuration for other settings, like CurrentInstrument . You just need to do the same for the duration.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
sorry..i am too lame for that..and ..i am not understanding...
and btw..i respect you all..i am not making funny of you or anything like that...i ask..if you want to reply the better, if not, i must live with it without complaints...i aprecciate your efforts and etc...
I am not a "sucking" guy..
Thanks,
Duarte
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Alienoiz wrote: sorry..i am too lame for that..and ..i am not understanding...
and btw..i respect you all..i am not making funny of you or anything like that...i ask..if you want to reply the better, if not, i must live with it without complaints...i aprecciate your efforts and etc...
I am not a "sucking" guy.. Let me clarify. Yes, of course I want to be respected. But not by being sucked up to. Eew. No - my idea here of helping people is to teach. So they learn and can do it themselves next time. So the way I want to be respected is by people taking the advice and at least making an effort to implement it by themselves.
One more attempt:
Function MidiInProc(ByVal hMidiIn As Integer, ByVal wMsg As UInteger, ByVal dwInstance As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
Dim DataByte1 = (dwParam1) >> 8
m.PlayMIDINote(DataByte1, 127)
m.NoteDuration = CInt(cboduration.Text)
m.Pan = 50
End Function
The underlined line is the problem. You can't access cboduration inside that function because it's being executed by a different thread that originates from that MIDI-component. But only the UI-thread may access controls.
You already modify other settings (than NoteDuration ) on the UI-thread. Example:
Private Sub cboInstruments_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboInstruments.SelectedIndexChanged
m.CurrentInstrument = cboInstruments.Text
End Sub
You need to do the same for m.NoteDuration .
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
well..thanks..but i still do not understand..
i am not a coder..i just make these small gadgets to keep my head busy...
I know the very basics of VB but normaly i interpret snippets and get them together to create my code on more advanced stuff...
So i may be able to do what you say, but i am not understanding how..if i see the code, i understand it, but creating it is not my strongest point!
I hope i am making myself clear!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Alienoiz wrote: i am not a coder..i just make these small gadgets to keep my head busy... Why don't you start to learn it properly?
Open the form designer. Right-click the CombBox for the note-duration and select Properties. In the properties pane click on the events-icon (small and easy to miss). Search for the SelectedIndexChanged-event in the list and make a double-click into the empty column to the right of it. Visual Studio switches to the source code and you will see a stub for the event-handler-function where you will only have to insert that one line from my previous message. Remove that line I underlined in the other function in my previous message. That should be it.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
ah..OK ..i was complicating cause i wasnt seeing the code..it works but my app seems to Break when i press several keys of the controller!
Thanks anyway!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
![Go to Parent](https://www.codeproject.com/App_Themes/CodeProject/Img/arrow-up24.png) may i ask for your attention once again?
my code has changed....i am now able to do everything i want from it...but i am just having a small problem...
When i press the midi key of my controller it plays the note and when i unpress it it also plays the same note!
I have tried the .StopMIDINote() function but i do not know where to insert it?!!! If i was using a button i would know..mousedown play..mouseup stop..but i am using my MIDI hardware keyboard!
Below i show the code....if you have some advice i would appreciate it?!!?!?
Thanks You!
<pre>Public Class Form1
Dim m As New clsMIDI
Dim hMidiIn As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
FillInstrumentCombo()
If midiInGetNumDevs() = 0 Then
MsgBox("No MIDI devices connected")
End If
Dim InCaps As New MIDIINCAPS
Dim DevCnt As Integer
For DevCnt = 0 To (midiInGetNumDevs - 1)
midiInGetDevCaps(DevCnt, InCaps, Len(InCaps))
ComboBox1.Items.Add(InCaps.szPname)
Next DevCnt
End Sub
Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles Me.Closed
midiInStop(hMidiIn)
midiInReset(hMidiIn)
midiInClose(hMidiIn)
End Sub
Public Declare Function midiInOpen Lib "winmm.dll" (ByRef hMidiIn As Integer, ByVal uDeviceID As Integer, ByVal dwCallback As MidiInCallback, ByVal dwInstance As Integer, ByVal dwFlags As Integer) As Integer
Public Delegate Function MidiInCallback(ByVal hMidiIn As Integer, ByVal wMsg As UInteger, ByVal dwInstance As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
Public ptrCallback As New MidiInCallback(AddressOf MidiInProc)
Public Const CALLBACK_FUNCTION As Integer = &H30000
Public Const MIDI_IO_STATUS = &H20
Public Delegate Sub DisplayDataDelegate(dwParam1)
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim DeviceID As Integer = ComboBox1.SelectedIndex
midiInOpen(hMidiIn, DeviceID, ptrCallback, 0, CALLBACK_FUNCTION Or MIDI_IO_STATUS)
midiInStart(hMidiIn)
Dim duration = CInt(cboduration.Text)
m.NoteDuration = duration
End Sub
Dim DataByte1 As Byte
Function MidiInProc(ByVal hMidiIn As Integer, ByVal wMsg As UInteger, ByVal dwInstance As Integer, ByVal dwParam1 As Integer, ByVal dwParam2 As Integer) As Integer
TextBox1.Invoke(New DisplayDataDelegate(AddressOf DisplayData), New Object() {dwParam1})
m.PlayMIDINote(DataByte1, 127)
End Function
Private Sub DisplayData(dwParam1)
DataByte1 = (dwParam1 And &HFF00) >> 8
TextBox1.AppendText(String.Format("{0:X2}{1}", DataByte1, vbCrLf))
End Sub
Private Sub FillInstrumentCombo()
For i = 0 To 121
cboInstruments.Items.Add(Instrument.GMInstrumentNames(i))
Next
cboInstruments.SelectedIndex = 0
End Sub
Private Sub cboInstruments_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboInstruments.SelectedIndexChanged
m.CurrentInstrument = cboInstruments.Text
End Sub
Private Sub hsbVolume_ValueChanged(sender As Object, e As EventArgs) Handles hsbVolume.ValueChanged
m.Volume = hsbVolume.Value
End Sub
Private Sub cboduration_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboduration.SelectedIndexChanged
Dim duration = CInt(cboduration.Text)
m.NoteDuration = duration
End Sub
End Class
modified 7-Jan-19 21:02pm.
|
|
|
|
|
may you help me or not?..i just wanna know so i can quit the gadget or not!!
Thank you!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
On the page you linked in another post (Visual Basic MIDI Piano[^]) there are these two subs which I assume are still somewhere in your code:
Private Sub Down(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown, Button2.MouseDown, Button3.MouseDown, Button4.MouseDown, Button5.MouseDown, Button6.MouseDown, Button7.MouseDown, Button8.MouseDown, Button9.MouseDown, Button10.MouseDown, Button11.MouseDown, Button12.MouseDown, Button13.MouseDown, Button14.MouseDown, Button15.MouseDown, Button16.MouseDown, Button17.MouseDown, Button18.MouseDown, Button19.MouseDown, Button20.MouseDown, Button21.MouseDown, Button22.MouseDown, Button23.MouseDown, Button24.MouseDown
Jazz.MidiOut(&H90 + chan, Note(sender), 100)
End Sub
Private Sub Up(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseUp, Button2.MouseUp, Button3.MouseUp, Button4.MouseUp, Button5.MouseUp, Button6.MouseUp, Button7.MouseUp, Button8.MouseUp, Button9.MouseUp, Button10.MouseUp, Button11.MouseUp, Button12.MouseUp, Button13.MouseUp, Button14.MouseUp, Button15.MouseUp, Button16.MouseUp, Button17.MouseUp, Button18.MouseUp, Button19.MouseUp, Button20.MouseUp, Button21.MouseUp, Button22.MouseUp, Button23.MouseUp, Button24.MouseUp
Jazz.MidiOut(&H80 + chan, Note(sender), 0)
End Sub
Looks like it's supposed to start playing a note on KeyDown and stop playing it on KeyUp, without a predetermined duration, which you seem to have added. So I'm guessing all you need to do is to either remove the "Up"-sub and the event-wiring for it or comment out the single line it it. If it doesn't work then I have no idea.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
|
|
|
|
|
hi..i am not using the jazzmidi control anymore!
Now i am using a module called clsMIDI!
You can check it in the concorrence : ) (sorry)
https://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=8305&lngWId=10
Thanks!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
I think the solution is somewhere in these lines of code:
Dim DataByte1 = (dwParam1 And &HFF00) >> 8
m.PlayMIDINote(DataByte1, 127)
If i leave like that, when i press the key of my MIDI Controller the note plays and when i unpress it it plays again!
But if i set it like this:
Dim DataByte1 = (dwParam1) >> 8
m.PlayMIDINote(DataByte1, 127)
It only plays when i unpress the key....
Well.... it is the opposite of what i need...i need it to play when i press and silent when i unpress!!
modified 7-Jan-19 21:02pm.
|
|
|
|
|
Well...do you have any tip?
Thanks you!
modified 7-Jan-19 21:02pm.
|
|
|
|
|