Author Topic: Implementing Midi  (Read 933 times)

Huub

  • Posts: 17
Implementing Midi
« on: 10 Jul '14 - 09:54 »
Hello guys,

I'm trying to implement MIDi in my application, to use a MIDI launchpad to start audio. I'm new with MIDI and Bass so I tried the examples in the helpfile. I have one MidiDevice in my computer (device 0)  and in another application (FruityLoops) it is working just fine.

This is my code (in VB):

I've created a private inputdevice in my form

Code: [Select]
Private _midiDev As MidiInputDevice

 In my form.shown event I open and start the inputdevice:

Code: [Select]
Private Sub frmMidi_Shown(sender As Object, e As EventArgs) Handles Me.Shown
         If Midi.MIDI_InGetNumDevs() > 0 Then
            _midiDev = New MidiInputDevice(0)
            AddHandler _midiDev.MessageReceived, AddressOf InDevice_MessageReceived
             If _midiDev.Open() Then
                If Not _midiDev.Start() Then
                    Msgbox("Midi device could not be started! Error " + _midiDev.LastErrorCode.ToString(), "Midi Error")
                End If
            Else
                Msgbox("Midi device could not be opened! Error " + _midiDev.LastErrorCode.ToString(), "Midi Error")
            End If
        End If
    End Sub


In my FormClosing-event I stop and close the device:

Code: [Select]
Private Sub Me_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        Try
            ' when not needed anymore...stop the device
            If _midiDev.IsStarted Then
                _midiDev.Stop()
            End If
            ' and close the device
            If _midiDev.IsOpened Then
                _midiDev.Close()
            End If
        Catch
            Msgbox("Midi device could not be stopped or closed! Error " + _midiDev.LastErrorCode.ToString(), "Midi Error")
        End Try



This is my call-back-function, it's just the beginning here, there is yet some work to be done ;)

Code: [Select]

 Private Sub InDevice_MessageReceived(sender As Object, e As MidiMessageEventArgs)
        Dim data1 As Integer
        Dim data2 As Integer
        sleChannel.Text = e.ShortMessage.Channel
        If e.IsShortMessage Then
            Select Case e.ShortMessage.Status
                Case 0
                    sleP2.Text = "None"
                Case 128
                    sleP2.Text = "NoteOff"
                    data1 = e.ShortMessage.Data1
                    data2 = e.ShortMessage.Data1
                    sleData1.Text = data1
                    sleData2.Text = data2
                Case 144
                    sleP2.Text = "NoteOn"
                    data1 = e.ShortMessage.Data1
                    data2 = e.ShortMessage.Data1
                    sleData1.Text = data1
                    sleData2.Text = data2
                Case 160
                    sleP2.Text = "Aftertouch"
                Case 176
                    sleP2.Text = "ControlChange"
                    data1 = e.ShortMessage.Data1
                    data2 = e.ShortMessage.Data1
                    sleData1.Text = data1
                    sleData2.Text = data2
                Case 192
                    sleP2.Text = "ProgramChange"
                Case 208
                    sleP2.Text = "ChannelPressure"
                Case 224
                    sleP2.Text = "PitchBend"
                Case 240
                    sleP2.Text = "SystemMsgs"
                Case 241
                    sleP2.Text = "MidiTimeCode"
                Case 242
                    sleP2.Text = "SongPosition"
                Case 243
                    sleP2.Text = "SongSelect"
                Case 246
                    sleP2.Text = "TuneRequest"
                Case 247
                    sleP2.Text = "EOX"
                Case 248
                    sleP2.Text = "Clock"
                Case 249
                    sleP2.Text = "Tick"
                Case 250
                    sleP2.Text = "Start"
                Case 251
                    sleP2.Text = "Continue"
                Case 252
                    sleP2.Text = "Stop"
                Case 254
                    sleP2.Text = "ActiveSense"
                Case 255
                    sleP2.Text = "Reset"
            End Select
            sleP1.Text = e.ShortMessage.ID.ToString + " | " + e.ShortMessage.ToString()
        Else
            If e.IsSysExMessage Then
                sleP1.Text = e.SysExMessage.ID.ToString() + " | " + e.SysExMessage.ToString()
            End If
        End If

    End Sub

My problem is, whenever i try to open and start the device, I get errormessage ERROR_MIDI_ALLOCATED. But I've never initialized the device before in my application and there is no other application running with MIDI.

Can anybody give me a hint, where I'm wrong or what to do, to get the device running in Bass??

Ian @ un4seen

  • Administrator
  • Posts: 20389
Re: Implementing Midi
« Reply #1 on: 10 Jul '14 - 14:15 »
It looks like you are currently using BASS.Net's own MIDI input functions. Perhaps you could try the BASSMIDI add-on's MIDI input functions (BASS_MIDI_InInit/etc), and see if you have more luck with them?

radio42

  • Posts: 4573
Re: Implementing Midi
« Reply #2 on: 10 Jul '14 - 21:32 »
Have you tried enumerating the available Input devices like this:
Code: [Select]
int[] inPorts = MidiInputDevice.GetMidiPorts();
foreach (int port in inPorts)
{
  string name = MidiInputDevice.GetDeviceDescription(port);
  Console.WriteLine("{0}={1}", port, name);
}

Huub

  • Posts: 17
Re: Implementing Midi
« Reply #3 on: 11 Jul '14 - 07:54 »
I found the mistake. Watch this code from my first post:

Code: [Select]
   Private Sub InDevice_MessageReceived(sender As Object, e As MidiMessageEventArgs)
        Dim data1 As Integer
        Dim data2 As Integer
        sleChannel.Text = e.ShortMessage.Channel
        If e.IsShortMessage Then
            Select Case e.ShortMessage.Status
                Case 0
                    sleP2.Text = "None"
........

I just took channel-info from e.shortmessage without checking the passed parameter really IS a shortmessage.

Checking IsShortmessage before taking channel info, sloved the problem. This is the new code:

Code: [Select]
Private Sub InDevice_MessageReceived(sender As Object, e As MidiMessageEventArgs)
        Dim data1 As Integer
        Dim data2 As Integer
        If e.IsShortMessage Then
            sleChannel.Text = e.ShortMessage.Channel + 1
            Select Case e.ShortMessage.Status
                Case 0
                    sleP2.Text = "None"
.....

Thanks to Ian and Bernd for their suggestions. Now I can go on implementing a midi-launchpad in my application.