Again, unsure running Csound in Python - allowing input vs. allowing output
Date | 2015-05-04 13:19 |
From | Chuckk Hubbard |
Subject | Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Hi again.
I have a big Python program that runs its output through Csound. It opens a second Python process when it's necessary to start audio, so it can run with a higher priority. I tried using the main process long ago but audio was interrupted by mouse movements. When audio is running, the UI communicates with the CppSound object through sockets. It sends a particular message when the user wants to stop playback. The audio process reads socket input from the main process in a thread, and runs yet another thread to send playback position to the main process/UI. I was using a CsoundPerformanceThread object to run the score, because this allowed itself to be interrupted by the command input thread. Unfortunately, I was unable to call Python callables from inside the score using the pycall opcodes; they just didn't work. Now I've modified my audio process to use PerformKsmps, as per Oeyvind's suggestion, which allows Csound to call Python functions in the main interpreter. Unfortunately, now this always runs until the end of the score without stopping, no matter what I do. I need some way of running a Csound score inside Python that allows both: 1. pycall opcodes inside an orchestra 2. interruption of rt playback from another thread. Can anyone tell me a way to run a score in Python that allows these? The documentation of the csnd6 module inside Python is pretty empty. I've already read numerous tutorials and looked at the examples, but they all seem to use different commands and classes, without explaining the choice of one over the other. Like I said, my program is big. I will try to distill an example. Thanks! |
Date | 2015-05-04 13:52 |
From | Oeyvind Brandtsegg |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Hi, I recognize some hassles of stopping performance before score ends when using py opcodes under windows. The details are a bit hazy right now, but I seem to recall making it work by using the exitnow opcode in an otherwise empty instrument, then calling this instrument from the score (score event from python) when I want to stop. Have you tried the exitnow opcode? best, Oeyvind 2015-05-04 14:19 GMT+02:00 Chuckk Hubbard |
Date | 2015-05-04 15:23 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Hi, Oeyvind. I looked at the exitnow opcode, but this would still involve triggering an event from outside the running Csound instance; the way I was doing that was also through socket messages received and processed in the same thread that appears to freeze during performance. It has to come from a keypress captured by a different process, since the UI process is in the foreground at the time. I suppose the UI process isn't frozen during performance, and PerformKsmps would process that opcode without having to pause, so I'd just need a way for a separate process to generate a score event, wouldn't I? But I'm not sure how. -Chuckk On Mon, May 4, 2015 at 3:52 PM, Oeyvind Brandtsegg <oyvind.brandtsegg@ntnu.no> wrote: Hi, |
Date | 2015-05-04 15:36 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
I have an idea - I can create an always-on instrument with the exitnow opcode hidden in a conditional statement, and use chnget to change the trigger value to make it execute. Update soon... On Mon, May 4, 2015 at 5:23 PM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2015-05-04 16:19 |
From | Justin Smith |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Another option is using the event opcode to generate an "e" event. On Mon, May 4, 2015 at 7:36 AM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2015-05-04 16:45 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Thank you. My question is how to pass any kind of value - channel setting, instrument invocation, score events, anything - to a running instance if it's not using PerformanceThread. From what I'm reading, I'm starting to believe this is impossible, which means I have to go back to looking for a way to make the pycall opcodes work from within a PerformanceThread. -Chuckk On Mon, May 4, 2015 at 6:19 PM, Justin Smith <noisesmith@gmail.com> wrote:
|
Date | 2015-05-04 17:27 |
From | Steven Yi |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Hi Chuckk, I'm not quite sure how you're using PerformKsmps(), but if you're calling it in a loop, you should have freedom to do things between PerformKsmps() calls. For example, in example 10 from the csoundAPI_examples project: https://github.com/csound/csoundAPI_examples/blob/master/python/example10.py It's updating channel values between PerformKsmps() calls. If you have another thread, you can manage your own message queue in the thread running Csound and process them between PerformKsmps() calls. Granted, I may have completely misunderstood what you're after. Either way, if you could post some python code, that would help (me at least) understand the picture better. Thanks! steven On Mon, May 4, 2015 at 11:45 AM, Chuckk Hubbard |
Date | 2015-05-04 17:32 |
From | Victor Lazzarini |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Not sure what you mean. If the perfomKsmps is running in a loop in the main thread, you will need dome sort of event signalling that is polled at every iteration through a callback etc. The UI is checked for events by this and an action is dispatched. Or otherwise you have to start a separate thread and run performKsmps there. Or start a thread to check for UI actions, put them in a queue and read these in between performKsmps calls in the main thread. Victor Lazzarini Dean of Arts, Celtic Studies, and Philosophy Maynooth University Ireland
|
Date | 2015-05-04 18:13 |
From | Michael Gogins |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
It's not impossible. The channel API is already thread safe. The input message API also. But Python has its own issues with its own global interpreter lock, and this is why the performance thread routine is useful in Python. I suspect it's the GIL that is preventing pycall from working in your project. If you use csoundPerformKsmps in your main thread, then other threads, from Python or not from Python, should be able to call the channel or input message APIs at will. But if a lot of processing happens in one of those calls, that could block csoundPerformKsmps long enough to cause a glitch in the sound. Still, it's worth a try. In your Csound performance loop, you can place a flag "keepRunning" and when some other thread sets this to False, the performance thread will exit and the Csound performance will stop. Also, it's possible use the Csound performance thread class in a Python program, which will run Csound in a separate C thread. Then you can use the regular Csound channel and input message APIs as well as the ones in the thread performance class. I hope this is clear, if not, please ask. In addition to this, if you are committed to Python, you could still "roll your own" Csound performance thread class that would have a native C thread running Csound, by using Python's ctypes module to call into both the PThread library and the Csound library. Also, since what you are trying to do is moderately complex and is running into threading issues, you might want to switch your project to C++ (it sounds like you are on a desktop platform, is that correct?). Then you will have much, much more control over what is happening. Regards, Mike |
Date | 2015-05-04 19:41 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | csdex-audio.py csdex-ui.py None None |
Thanks for all of the responses. None of it is very clear to me. Here is a very stripped-down version of my program. The main program is csdex-ui.py, which, when you press the spacebar, opens csdex-audio.py and pipes to it the info to run a Csound instance. While that Csound instance is running, it successfully calls pycalli, but if you hit the spacebar during playback to stop it (with the program window in the foreground), it will not stop. When it reaches the end of the score, it responds to that earlier keypress. I had the exact same formula before, but using a Csound Performance Thread, and it stopped when I hit spacebar, but the pycall opcodes had no effect. I've attempted every combination of threads I can think of and none of them will allow both the pycall opcode and user input during playback. You can see there are in fact two extra threads, one for input from the main program, and one for sending score location (its result isn't visible here). I also tried putting the work of the input loop inside the score location loop, no luck. I tried putting the input loop inside the PerformKsmps loop, no luck. To my understanding, the input and the PerformKsmps loop are already in separate threads. I will try to implement your suggestions as my wife permits. -Chuckk On Mon, May 4, 2015 at 8:13 PM, Michael Gogins <michael.gogins@gmail.com> wrote:
|
Date | 2015-05-05 00:31 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Hi, Victor. I posted an example earlier of 2 files. The incoming messages are handled in a loop in a separate thread. If I put a print command at the beginning of the function in question, it prints until the moment that PerformKsmps starts. The loading and initiation of the Csound score depends on this input loop, and that all happens as expected, but when PerformKsmps starts, that "inputloop" thread freezes solid. I tried using a queue, as you suggested, which sounds like a perfect solution, but as soon as Csound starts performing, it ignores it. Any illumination is appreciated! -Chuckk On Mon, May 4, 2015 at 7:32 PM, Victor Lazzarini <Victor.Lazzarini@nuim.ie> wrote:
|
Date | 2015-05-05 00:42 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Mike, RE the keepRunning flag, I thought of that too; but, even if I set the flag to 1 and there is no statement anywhere changing it, simply adding the condition "while self.keepRunning == 1:" causes the PerformKsmps loop to stop! -Chuckk On Mon, May 4, 2015 at 8:13 PM, Michael Gogins <michael.gogins@gmail.com> wrote:
|
Date | 2015-05-05 00:58 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
Wow, I've found the problem! Cluttered code, in the first place; more specifically, the user's input is handled in a loop in a thread; the user's input from that thread directly starts the Csound instance running, so in fact my PerformKsmps is already not in the main thread, it's in the same thread that processes the user's input. I separated it, put it in its own thread, and it works as intended! Thanks again to all of you. -Chuckk On Tue, May 5, 2015 at 2:31 AM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2015-05-05 01:22 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
But in my actual program it doesn't work the same. Good night! -Chuckk On Tue, May 5, 2015 at 2:58 AM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2015-05-05 11:51 |
From | Chuckk Hubbard |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Attachments | None None |
I had other problems. My program is now working! -Chuckk On Tue, May 5, 2015 at 3:22 AM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2015-05-05 11:56 |
From | Victor Lazzarini |
Subject | Re: Again, unsure running Csound in Python - allowing input vs. allowing output |
Good to know. ======================== Dr Victor Lazzarini Dean of Arts, Celtic Studies and Philosophy, Maynooth University, Maynooth, Co Kildare, Ireland Tel: 00 353 7086936 Fax: 00 353 1 7086952 > On 5 May 2015, at 11:51, Chuckk Hubbard |