Wow! You’re a cultivated guy… “Royal Conservatory” makes me think you’re Dutch…I don’t know exactly why, but I thought you were German your name sounded more like it (at least in my head, I don’t much of the Netherlands)…the group has become extremely silent… no more arithmetic bombs nor unwanted choicepoints lately
cheers
I’m learning something of Python lately, so that the janus interface might make some sense…
(hopefully, at least)
Lots of things are named “Royal” in Canada My name isn’t Dutch; it’s Plattdüütsch, which was my father’s first language (but I don’t speak Platt); the “ü” became a “u” somewhere between Germany-UK-Canada.
@Remifa - is there a “MIDI for idiots” guide? I’ve often thought about exploring my piano’s MIDI interface (assuming I can figure out which kind of cable is suitable and can get it to work with my Chromebook) - both for recording what I play and for playing back. Is this how you’re thinking of using MIDI with Prolog?
Ludemann did sound more German than Dutch to my ears, but I don’t know whether the difference between a German family name and a Dutch one is so straightforward even for native speakers or whether there are cases where it could be both. In any case you’re Canadian, which is a rather different matter
<digression>
Seeing as we’ve strayed far from the original topic, I might as well finish it.
As far as I know (I no longer have a native Plattdüütsch speaker to consult), the “lüde” part of my name is “läute” in standard High German, meaning “to ring” or “to chime” (compare Swiss German “Sächsilüüte” festival, which is “Sechseläuten” in High German). I think that Dutch spelling rules would write “mann” as “man” (different rules between Dutch and German spelling for short vowels); I don’t know how to spell the “ü” sound in Dutch (“ui” or “y”? - and it would be a long vowel). So, a translation to English might be “Bellman” or “Sexton”, I suppose.
(For those who have read this far and are unfamiliar with the West Germanic languages, “high” and “low” refer to height of land - Low German is in the north and High German is in the mountainous south; Swiss German has undergone one set of sound shifts from Low German, and High German has an additional sound shift: High German consonant shift - Wikipedia … there are also some vowel shifts but I couldn’t find references for them; but I’ve noticed that Low German and Swiss German like “ü” sound)
</digression>
There are many MIDI resources, but it depends on what you want to do. I’ve learned MIDI by reading a bible written by Christian Braut called “The Musician’s Guide to Midi” (+1000 pages). I still use it as a reference. It might be dated for the part on MIDI gear; therefore If you want to understand your keyboard or synthesiser a technical manual with MIDI implementation chart is necessary.
For your keyboard you can use a MIDI (5 pin DIN plugs) to USB interface adapter cable. Something like https://www.amazon.com.be/dp/B0719V8MX1
I don’t know exactly what I’m going to do with Prolog, but I would like to use it in areas that are difficult to program in procedural programming languages. Rules, pattern matching, backtracking, grammars, and other declarative problem solving techniques. Why not include blackboards and agents as well?
Before I can start this I need to have a method for receiving MIDI messages in Prolog. The Python road seems to be a dead end ATM as I can’t install the necessary software on my offline PC. I’m now learning Java in order to be able to run a simple persistent program that sends MIDI to Prolog, using the JPL interface. Any help in that area is welcome as I’m still struggling with syntactical issues in Java itself.
The idea if the (still emerging) Python interface is that it must provide an answer to such situations. Could you be more specific about the environment in which you like to have SWI-Prolog and Python connected by means of Janus? That would include the Python version (not so much the 3.x number, but mostly is it CPython binary downloaded from Python.org, Anaconda, MSYS2, … All these things have their own ways of doing things. That makes it a little complicated
You’ll code a class whose constructor finds your MIDI device and attaches, to each of its transmitters, instances of a receiver class which passes a term representation of each event into Prolog, perhaps to a message queue. Create one instance of your class with jpl_new(). StackOverflow has examples of the pre-JPL Java-side part of this; I shall verify and develop these when my adaptor cable arrives
This is the prompt I get when starting python interactively:
Python 3.11.1 (tags/v3.11.1:a7a450f, Dec 6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)] on win32
The versions on my USB stick and that on my PC are the same.
Since I can’t change the environment on my ‘work’ and Internet connected PC I can’t add environment variables.
I hope this helps.
I started with this Java code : audio - Getting midi messages from Receiver in Java - Stack Overflow but it doesn’t compile.
I already learned that I had to install JDK and that every class has to go to a separate file.
The CustomReceiver class compiles without errors, but Main gives 4 similar errors. Both java/class files are in the same directory.
C:\...\Main.java:11: error: cannot find symbol
public static Receiver synthRcvr = new CustomReceiver();
^
symbol: class CustomReceiver
location: class Main
C:\...\Main.java:18: error: cannot find symbol
sequencer = MidiSystem.getSequencer();
^
symbol: variable sequencer
location: class Main
C:\...\Main.java:19: error: cannot find symbol
sequence = MidiSystem.getSequence(new File("test.midi"));
^
symbol: variable sequence
location: class Main
C:\...\Main.java:26: error: cannot find symbol
sequencer.setSequence(sequence);
^
symbol: variable sequence
location: class Main
4 errors
error: compilation failed
As a Java novice I don’t understand what I’m doing wrong and I hope you can identify the problem.
I’m still a bit puzzled. As is, after installing SWI-Prolog and the Python binaries as downloaded from Download Python | Python.org should allow using Janus from SWI-Prolog out of the box. This does not install the Python package janus_swi
, so you can’t start Python and load Prolog into the Python project. Is that what you are after? If so, why is that needed? You can initiate any Python code from Prolog.
Possibly you are trying to put SWI-Prolog and Python together on a USB stick, stick it into some PC and hope to have all the above working? As is, SWI-Prolog finds Python by looking for python3.dll
in %PATH%
. So, if Python is not in PATH, but in some other known directory, we can extend PATH in some startup .bat
file or in Prolog before loading library(janus)
. In Prolog you can prepend something to %PATH%
as below.
getenv(PATH, P0),
atom_concat('D:\\mydir\\subdir;', P0, P),
setenv(PATH, P).
Hope this helps. If not, could you give more info on your configuration?
I can initiate Python code from Prolog, but not the other way. I’m not able to install janus_swi with the setup.py script. Now I’m asking whether it is really needed, because the Janus package might do the job as well. If these Prolog calls in Python can be done without installing janus_swi my problem is solved.
I refer to your script
SWI-Prolog is not yet installed on the USB-stick. The Python on my USB-stick was used to download packages with their dependencies.
I’ll try to install Janus this weekend as I already downloaded it.
I think that should suffice. If not, let us know what goes wrong.
? Just install SWI-Prolog 9.1.16 and you should be fine. You write your Python stuff in some xyz.py
, make sure to add the directory holding xyz.py
in Python’s module search path using py_add_lib_dir/2 or some other way and you call
?- py_call(xyz:some_function_in_there()).
to get the ball running. Janus implicitly loads Python modules. If you just want to load it without calling anything specifically you can abuse one of the built-ins to force the load but do nothing specific, e.g.,
?- py_call(xyz:'__file__').
xyz.py
may load janus
or janus_swi
, which are the same. These files are in the SWI-Prolog installation and added to the Python module search path when the Prolog library janus
is loaded.
Sorry, it may all sound confusing … It is supposed to be as simple as it can be …
Thanks for explaining these matters.
It was my misunderstanding that I needed janus_swi instead of janus.
It is a little confusing We want to call the module
janus
, which is fine if we start from Prolog and push the directory holding janus.py
to the start of the Python search path. In this case we know which Prolog to use.
If we start from Python though, we must allow janus for SWI-Prolog, janus for XSB, etc. to coexist. That is where janus_swi
comes in: it is the Python package that allows loading SWI-Prolog, while janus_xsb
will be the same loading XSB. You can use
import janus_swi as janus.
when starting from the Python site. To ensure best compatibility, if you start from the Prolog side, these are equivalent
import janus
import janus_swi as janus
Indeed not: one of the compile errors is a simple linking issue (unnecessary, as this can be done in a single .java file); the rest are clumsy bugs in the (presumably untested) Main.java in the Stack Overflow answer :-/ which is unworthy of further discussion in this group, as is (some might say) Java code in general
A private correspondence with paul at jbgb dot com will get you a cleaner example to let you concentrate on MIDI voodoo rather that Java voodoo…
I successfully installed janus. The only dependency was typing_extensions-4.8.0-py3-none-any.
When I try to import janus_swi I get an error :
>>> import janus_swi as janus
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'janus_swi'
>>> import janus
>>>
I can import janus though, but it has no once() method.
It smells like you installed the other Python janus package. That has no relation to janus_swi.
The theory was that you have Python and Prolog installed (on the USB stick) , you can start Prolog and call Python (e.g., ?- py_version.
). Does that work? If it does, the next idea is to load the Python MIDI stuff from Prolog. You do that either using py_call/2 or (test) it interactively using ?- py_shell.
and work in the embedded Python shell. From here you should be able to do all the usual Python stuff and use janus
.
I would like to have MIDI message reception in Prolog. It doesn’t matter how. Do you suggest working from a slow USB memory stick, because the current Python-janus_swi solution won’t work on the gapped PC?
I still have big problems understanding how things are setup and what the limitations are. All I know is that you never really need the Python janus_swi
package because with a (compatible) Python binary and SWI-Prolog installation you can do anything you can do in the Python interpreter through the embedded Python-in-Prolog. So my question is whether calling Python from Prolog works for you? And, if it does, why you can(not) do what you wanted to do in Python through Prolog?
I can also produce a “wheel” for janus_swi
, but I don’t know whether that solves your problem. I think it should not be needed. If you think it solves your problem, I’m happy to give it a try.
I’m not sure how to get out of this loop Maybe you can write a more detailed description of your setup and what you try to achieve how? Maybe someone else here understands what is going on and can step in?
I can call mido functions from Prolog. I published a Prolog script in this thread showing how I test a sound bank.
Then I published a Python script in this thread with the question how I would be able to call Prolog in the callback function. With your help I added the janus.once() call. That was 2 weeks ago. Here is the result :
import janus
def print_message(message): # callback function
janus.once("writeln(Msg)", {'Msg':message})
import mido
mido.open_input('loopMIDI Port 0', callback=print_message)
import time
while True: # keep the script running
print(".")
time.sleep(60) # sleep for 1 minute
This is what I have now. It doesn’t work because I can’t import the proper janus.
The next step is to be able to call any Prolog predicate (not only writeline/1) that handles the MIDI messages.
Does this sound feasible or do I misinterpret your suggestion of 2 weeks ago ?