Scanning Midi hardware on RPI ???

Raspberry PI specific forum
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Scanning Midi hardware on RPI ???

Post by Joris »

Scanning Midi hardware doesn't work ?

Hi,

The code below works perfectly under Ubuntu 20, but does not work on the Raspberry PI (both 64 bit Os).
When I run amidi -l the hardware is recognized but my pb code does not.
When I check the imported functions, all existing ones are the same as under Ubuntu.
So what or where is my code wrong ?

Thanks.

Code: Select all

;{*********************************************************************************************
ImportC "-lasound" 
  snd_card_next(*card)
  snd_rawmidi_info_set_stream(*info, device.l)
  snd_rawmidi_info_get_subdevices_count(*info)
  snd_ctl_rawmidi_info(*ctl, *info)
  snd_ctl_rawmidi_next_device(*ctl, device.l)
  snd_rawmidi_info_set_device(*info, idx.l)
  snd_rawmidi_info_set_subdevice(*info, idx.l)
  snd_ctl_open(*ctl, name.p-utf8, mode.l)
  snd_ctl_close(*ctl)
  ;Voorbeeld uit library in C-formaat
  snd_card_get_longname(card.l, *pName)
  snd_card_get_name(card.l, *pName)
  snd_strerror(status.l)
  snd_rawmidi_info_sizeof()
  snd_rawmidi_info_get_name(*info)
  snd_rawmidi_info_get_subdevice_name(*info)
  ;*********************************************************************************************
  snd_seq_queue_tempo_sizeof()
  ;*********************************************************************************************
  ;funkties om midi data te verstufern :
  ;*********************************************************************************************
  ;snd_rawmidi_open_lconf(*input,  *output,  name.p-ascii, mode.l, var.i)
  snd_rawmidi_open(*input,  *output,  name.p-ascii, mode.l)
  snd_rawmidi_write(*output, *buffer, size.l)
  snd_rawmidi_read(*input, *buffer, size.l)
  snd_rawmidi_drain(*output)
  snd_rawmidi_close(*output)
  snd_rawmidi_nonblock(*output, mode.l)
  ;************************************************************************************
EndImport
Structure snd_rawmidi_info Align #PB_Structure_AlignC
  device.l;		/* RO/WR (control): device number */
  subdevice.l;		/* RO/WR (control): subdevice number */
  stream.l   ;			/* WR: stream */
  card.l     ;			/* R: card number */
  flags.l    ;		/* SNDRV_RAWMIDI_INFO_XXXX */
  id.a[64]   ;		/* ID (user selectable) */
  name.a[80] ;		/* name of device */
  subname.a[32];	/* name of active or selected subdevice */
  subdevices_count.l;
  subdevices_avail.l;
  reserved.a[64]    ;	/* reserved for future use */
EndStructure
Enumeration
  #SND_RAWMIDI_STREAM_OUTPUT
  #SND_RAWMIDI_STREAM_INPUT
EndEnumeration
Global NewList io_poort.s()
;}*********************************************************************************************
Procedure Is_Input(*ctl, card.l, device.l, sub.l)
      Protected *info. snd_rawmidi_info, status.l, name.s
      
      *info = AllocateMemory(snd_rawmidi_info_sizeof())  
      snd_rawmidi_info_set_device(*info,  device)
      snd_rawmidi_info_set_subdevice(*info,  sub)
      snd_rawmidi_info_set_stream(*info,  #SND_RAWMIDI_STREAM_INPUT)
      status=snd_ctl_rawmidi_info(*ctl, *info)
      
      If  status<0
        FreeMemory( *info)
      Else
        AddElement(io_poort())
        io_poort() ="I;"+PeekS(@*info\subname, -1, #PB_UTF8)  +  ";hw:"+ Str(*info\card) +","+ Str(*info\device)  + ","+ Str(*info\subdevice)  
        FreeMemory( *info)
      EndIf
      
EndProcedure
Procedure Is_Output(*ctl, card.l, device.l, sub.l)
      Protected *info. snd_rawmidi_info, status.l, name.s
      
      *info = AllocateMemory(snd_rawmidi_info_sizeof())  ;268
      snd_rawmidi_info_set_device(*info,  device)
      snd_rawmidi_info_set_subdevice(*info,  sub)
      snd_rawmidi_info_set_stream(*info,  #SND_RAWMIDI_STREAM_OUTPUT)
      status=snd_ctl_rawmidi_info(*ctl, *info)
      
      If  status<0
        FreeMemory( *info)
      Else    
        AddElement(io_poort())
        io_poort() ="O;"+PeekS(@*info\subname, -1, #PB_UTF8) + ";hw:"+ Str(*info\card) +","+ Str(*info\device)  + ","+ Str(*info\subdevice) 
        FreeMemory( *info)
      EndIf                        
      
EndProcedure
Procedure List_Subdevices_Info(*ctl, card.l, device.l)
      Protected *info. snd_rawmidi_info,  name$,  subname$
      Protected.l subs_in, subs_out, a
      
      *info = AllocateMemory(snd_rawmidi_info_sizeof())   
      snd_rawmidi_info_set_device(*info,  device)
      snd_rawmidi_info_set_stream(*info,  #SND_RAWMIDI_STREAM_INPUT)
      snd_ctl_rawmidi_info(*ctl, *info)
      subs_in  =  *info\subdevices_count       ;Resultaat is idem aan snd_rawmidi_info_get_subdevices_count(*info)
      
      For a=0 To subs_in-1 
        is_input(*ctl, card, device, a)
      Next
      
      snd_rawmidi_info_set_stream(*info, #SND_RAWMIDI_STREAM_OUTPUT)
      snd_ctl_rawmidi_info(*ctl, *info)
      subs_out=*info\subdevices_count       ;Resultaat is idem aan snd_rawmidi_info_get_subdevices_count(*info)
      
      For a=0 To subs_out-1
        is_output(*ctl, card, device, a)
      Next
      
      FreeMemory( *info)
      
EndProcedure
Procedure List_Midi_Devices_On_Card(card.l)
      Protected *ctl, *info. snd_rawmidi_info,  name$,  device.l  
      
      device=-1
      name$ = "hw:" + Str(card)
      
      If snd_ctl_open(@*ctl, name$, 0)<0
        MessageRequester("No Card.","cannot open control for card: " +  name$, #PB_MessageRequester_Ok)
        ProcedureReturn
      EndIf
      
      Repeat
        If  snd_ctl_rawmidi_next_device(*ctl, @device)<0
          MessageRequester("No  Card.","cannot determine device number:: " + Str( device), #PB_MessageRequester_Ok)
        ElseIf  device=>0
          list_subdevices_info(*ctl, card,  device)
        EndIf
      Until  device<0
      
      snd_ctl_close(*ctl)
      
EndProcedure
Procedure Discover_Midi_Ports()            
      Protected.l  card
      
      card = -1                  ;  // use -1 to prime the pump of iterating through card list
      If  snd_card_next(@card)<0
        MessageRequester("No Card.","Cannot determine card number: " + Str(card), #PB_MessageRequester_Ok)
      EndIf
      If card<0
        MessageRequester("No Card.","No sound cards found", #PB_MessageRequester_Ok)
      EndIf
      While card=>0
        list_midi_devices_on_card(card)
        snd_card_next(@card)
      Wend
      
EndProcedure
;*********************************************************************************************
Procedure Show_Midi_Inputs(hnd.i, active.i=-1) 
      
      ForEach io_poort()
        If StringField(io_poort(),1,";")="I"
           ; AddGadgetItem (hnd, -1, StringField(io_poort(),2,";") + #TAB$+StringField(io_poort(),3,";"))
             Debug StringField(io_poort(),2,";")+ #TAB$+StringField(io_poort(),3,";")
        EndIf
      Next
      ;SetGadgetState(hnd, active)
        Debug "--------------------"
EndProcedure
Procedure Show_Midi_Outputs(hnd.i, active.i=-1) 
      
      ForEach io_poort()
        If StringField(io_poort(),1,";")="O"
            ;AddGadgetItem (hnd, -1,  StringField(io_poort(),2,";")+ #TAB$+StringField(io_poort(),3,";"))  
            Debug StringField(io_poort(),2,";")+ #TAB$+StringField(io_poort(),3,";")
        EndIf
      Next
     ; SetGadgetState(hnd, active)
      
EndProcedure
Discover_Midi_Ports()
;Show_Midi_Inputs(0)  
Show_Midi_Outputs(0)  
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
idle
Always Here
Always Here
Posts: 5088
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Scanning Midi hardware on RPI ???

Post by idle »

Did you check you have the developer packages? It seems odd it works by commandline and not through api also compile it from terminal you might get more info why it's not working.
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Scanning Midi hardware on RPI ???

Post by Joris »

Hi idle,

To be sure I checked all install files below, some where indeed missing.
But now I'm sure to have all installed and still no better result.

And what do you mean with "also compile it from terminal" how to do that ?
I run my source from the ide, but also a compiled version has the same problem. I don't now of any other way...

If anyone could check if his midi interface is detected with the source above, there must be something wrong with mine. Yet still it becomes detected by that amidi -l, so.

Thanks.
Update compiler and default libraries
-------------------------------------
sudo apt-get install build-essential gcc g++

Developer Libraries
-------------------
sudo apt-get install libxxf86vm-dev libxine2-dev unixodbc-dev libsdl1.2-dev libsdl2-dev
sudo apt-get install libgtk2.0-dev libgtk-3-dev

* Ubuntu 20.04 / Raspberry PI Desktop
sudo apt-get install libwebkit2gtk-4.0-dev

Developer Libraries For Games
-----------------------------
sudo apt-get install libgl1-mesa-dev libgl1-mesa-glx

* Ubuntu 20.04 / Raspberry PI Desktop
sudo apt-get install libwebkit2gtk-4.0
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Scanning Midi hardware on RPI ???

Post by mk-soft »

Can be compiled here (Arm64) without problems. Of course, it doesn't find Midi for me.
pi@raspberrypi:~ $ amidi -l
Dir Device Name
cannot determine device number: Inappropriate ioctl for device
cannot determine device number: Inappropriate ioctl for device
cannot determine device number: Inappropriate ioctl for device
Compiler Option "Console". Create Executable. Start from Terminal

Code: Select all

Procedure Show_Midi_Inputs(hnd.i, active.i=-1) 
  
  ForEach io_poort()
    If StringField(io_poort(),1,";")="I"
      ; AddGadgetItem (hnd, -1, StringField(io_poort(),2,";") + #TAB$+StringField(io_poort(),3,";"))
      Print( StringField(io_poort(),2,";")+ #TAB$+StringField(io_poort(),3,";"))
    EndIf
  Next
  ;SetGadgetState(hnd, active)
  Debug "--------------------"
EndProcedure
Procedure Show_Midi_Outputs(hnd.i, active.i=-1) 
  
  ForEach io_poort()
    If StringField(io_poort(),1,";")="O"
      ;AddGadgetItem (hnd, -1,  StringField(io_poort(),2,";")+ #TAB$+StringField(io_poort(),3,";"))  
      PrintN( StringField(io_poort(),2,";")+ #TAB$+StringField(io_poort(),3,";"))
    EndIf
  Next
  ; SetGadgetState(hnd, active)
  
EndProcedure

OpenConsole()
PrintN("Discover Midi Ports")
Discover_Midi_Ports()
PrintN("Show Inputs")
Show_Midi_Inputs(0)  
PrintN("Show Outputs")
Show_Midi_Outputs(0)
Input()
CloseConsole()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Scanning Midi hardware on RPI ???

Post by Joris »

Hi,

If I run the code in my first post on Ubuntu I get this result :
MT4 MIDI 1 hw:1,0,0
MT4 MIDI 2 hw:1,0,1
MT4 MIDI 3 hw:1,0,2
--------------------
MT4 MIDI 1 hw:1,0,0
MT4 MIDI 2 hw:1,0,1
MT4 MIDI 3 hw:1,0,2
MT4 MIDI 4 hw:1,0,3
MT4 Broadcast hw:1,0,4
If I run amidi -l on Ubuntu, I get this.
joris@joris:~$ amidi -l
Dir Device Name
IO hw:1,0,0 MT4 MIDI 1
IO hw:1,0,1 MT4 MIDI 2
IO hw:1,0,2 MT4 MIDI 3
O hw:1,0,3 MT4 MIDI 4
O hw:1,0,4 MT4 Broadcast
If I run the same code in my first post on Raspian Os I get this debug result :
If I run amidi -l on Raspian Os, I get this.
joris@joris:~$ amidi -l
Dir Device Name
IO hw:1,0,0 MT4 MIDI 1
IO hw:1,0,1 MT4 MIDI 2
IO hw:1,0,2 MT4 MIDI 3
O hw:1,0,3 MT4 MIDI 4
O hw:1,0,4 MT4 Broadcast
Normally the output is persented in two listviews Input and Output, I extracted the code and did the output to the debug, just because the listviews where kept empty on running the same source there.
So using a console was or is not needed imo.

Yet, why is there no output (in the listviews or whatever) on Raspian Os, with the same source ?
Here is the original C-source I used for all this :
https://ccrma.stanford.edu/~craig/artic ... portlist.c

Thanks
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
idle
Always Here
Always Here
Posts: 5088
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Scanning Midi hardware on RPI ???

Post by idle »

if I run amidi -l this is what I get on manjaro x64
amidi -l
Dir Device Name
cannot determine device number: Inappropriate ioctl for device
cannot determine device number: Inappropriate ioctl for device
Does this assume you have some midi device plugged in or even a virtual device?
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Scanning Midi hardware on RPI ???

Post by Joris »

Idle, you must have a midi interface connected. Otherwhise amidi -l has nothing to search for.

[EDIT]
Idle and mk-soft I don't know if you intended using the console, like you helped me before with that strange command "-p "+ naam +" -r /dev/null -t 1"
Yet now I remembered using the console there and tried now like in your code with that amidi -l command (just a beginning).
It gives a useable result. So maybe I can enable the midi-ports that way and leave the first source behind (for now).

Thanks

Code: Select all

Procedure.i Send_Amidi()   
  ;https://www.purebasic.fr/english/viewtopic.php?p=580721#p580721
  Protected command.s, dir.s,  Compiler.i     

  OpenConsole()
  command = "-l"
  dir = GetCurrentDirectory()
  Compiler = RunProgram("amidi",command, dir, #PB_Program_Open | #PB_Program_Read) 
  If Compiler
    While ProgramRunning(Compiler)
      If AvailableProgramOutput(Compiler)
        PrintN(ReadProgramString(Compiler))
        ;Debug ReadProgramString(Compiler)
      EndIf
    Wend
    PrintN("Exitcode: " + Str(ProgramExitCode(Compiler)))
    ;Debug ("Exitcode: " + Str(ProgramExitCode(Compiler)))   ;geeft 0 bij succes anders 1
    CloseProgram(Compiler)
  EndIf
  CloseConsole()
  
EndProcedure

Send_Amidi()
[/EDIT]
Last edited by Joris on Tue Mar 15, 2022 9:22 am, edited 4 times in total.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
idle
Always Here
Always Here
Posts: 5088
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Scanning Midi hardware on RPI ???

Post by idle »

Sorry I forgot I need to have a device or active virtual device. I will try again later
Post Reply