[Csnd] Running Python opcodes from a CSD running from the Python API
Date | 2014-09-01 20:36 |
From | Chuckk Hubbard |
Subject | [Csnd] Running Python opcodes from a CSD running from the Python API |
Attachments | pycall-test.py |
The manual tells me, if I understand correctly, that pyinit is not needed to run the Python opcodes when Python is using csnd6, but I'm sure that I don't understand how it's all supposed to work. Does this mean I can "cheat" around using API callback functions by telling the Python interpreter what to do from within an orchestra, all while running Csound from that same Python interpreter? |
Date | 2014-09-01 21:48 |
From | forrest curo |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Not sure about the need (or lack) for pyinit -- but your example uses pycalli which should run exactly once when the instrument is initialized.San Diego On Mon, Sep 1, 2014 at 12:36 PM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2014-09-01 22:01 |
From | Chuckk Hubbard |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Right, but in the output I get, it doesn't run at all. Python stops when it gets there: >python pycall-test.py .............................initializing csd_tester virtual_keyboard real time MIDI plugin for Csound 0dBFS level = 32768.0 Csound version 6.03.2 (double samples) May 12 2014 libsndfile-1.0.25 BEGAN CppSound::compile()... BEGAN CppSound::compile(2, 0213E890)... rtaudio: PortAudio module enabled ... using callback interface rtmidi: PortMIDI module enabled --Csound version 6.03.2 (double samples) May 12 2014 displays suppressed 0dBFS level = 32768.0 orch now loaded audio buffered in 4096 sample-frame blocks writing 16384-byte blks of shorts to test.wav (WAV) SECTION 1: ENDED CppSound::compile. ENDED CppSound::compile. .............................Running CSD instr 1: p1 = 1.000 <--------------------- This should be followed by a pycalli opcode, followed by another print command. inactive allocs returned to freespace end of score. overall amps: 0.0 0.0 overall samples out of range: 0 0 0 errors in performance 8192 16384 sample blks of shorts written to test.wav (WAV) On Mon, Sep 1, 2014 at 11:48 PM, forrest curo <treegestalt@gmail.com> wrote:
-- http://www.badmuthahubbard.com |
Date | 2014-09-01 23:17 |
From | forrest curo |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Rather than "print" (which might be 'printing' to anywhere) how about sending out some kind of network message to some other program listening for it...? That would be an easier test, received vs not-received. [A python print statement inside an instance of csound inside a python api -- Where _does_ that print to, anyway? Running the pycode examples in csoundqt didn't put the output anyplace I could find it either! Native csound print opcodes print to the console in a running instance of [csound6~] but I'm guessing that the python command wouldn't.]Right now you know that csound was happy enough with your code to sucessfully compile it -- and noticed no errors in running it. Probably something happened in there, but didn't connect with anything you were watching. Forrest Curo (still guessing.) On Mon, Sep 1, 2014 at 2:01 PM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
|
Date | 2014-09-01 23:24 |
From | forrest curo |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Or if you put the example from Python Opcodes Orchestra Syntax into your script? The instrument there pulls a value out of pycalli and then sends it out via printk. On Mon, Sep 1, 2014 at 3:17 PM, forrest curo <treegestalt@gmail.com> wrote:
|
Date | 2014-09-02 07:48 |
From | Chuckk Hubbard |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
That's a good point. Obviously, printing is not my final goal. Let me try something else. Thanks for the suggestion! -Chuckk
On Tue, Sep 2, 2014 at 1:17 AM, forrest curo <treegestalt@gmail.com> wrote:
-- http://www.badmuthahubbard.com |
Date | 2014-09-02 15:37 |
From | Chuckk Hubbard |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Attachments | csd-direct.py |
Hello again. -ChuckkI've tried several methods of checking whether the csnd6 module is calling the Python callable, and I see no sign that it is. Here is a pared-down version that crashes Python about 50% of the time for me. If I include "pyinit" in the orchestra header, it prints the "........40000000" message, if I don't include pyinit it doesn't print. The Csound manual explicitly says that 'pyinit' isn't necessary if Csound is run from the Python API. Regardless, it would be much less disturbing if it didn't crash Python. Can anyone confirm? Thanks. On Tue, Sep 2, 2014 at 9:48 AM, Chuckk Hubbard <badmuthahubbard@gmail.com> wrote:
-- http://www.badmuthahubbard.com |
Date | 2014-09-02 21:07 |
From | Oeyvind Brandtsegg |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
I haven't read evverything in the thread, so sorry if I'm answering the wrong question, but it seems to me the crash may have to do with the combination of performanceThread and py opcodes. My hunch is that the threading goes haywire. But you could run pyinit in Csound, still using Python as the host like this: (merged your example with Steven Yi's example3.py from his talk in Boston) #!/usr/bin/env python import csnd6 import os import time def increment(counter): counter += 1 return counter def counterprint(counter): print 'counter = %d%s' % (counter, os.linesep) counter = 0 counterprint(counter) csdorc = ''' sr = 44100 ksmps = 16 nchnls = 2 pyinit instr 1 print p1 pyruni "message = 400000000" pyruni "print message" print p2 endin ''' csdsco = ''' f0 10 10 1 i1 0 5 ''' c = csnd6.Csound() c.SetOption("-m0d") # Using SetOption() to configure Csound # Note: use only one commandline flag at a time c.CompileOrc(csdorc) # Compile the Csound Orchestra string c.ReadScore(csdsco) # Compile the Csound SCO String c.Start() # When compiling from strings, this call is necessary before doing any performing counterprint(counter) print "........................ Perf Thread" counter = increment(counter) counterprint(counter) while (c.PerformKsmps() == 0): pass #c.Perform() # Run Csound to completion c.Stop() print '** stopping csound' counter = increment(counter) counterprint(counter) #*** eof*** best Oeyvind 2014-09-02 16:37 GMT+02:00 Chuckk Hubbard |
Date | 2014-09-02 21:30 |
From | forrest curo |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
My output from Oeyvind Brantsegg's script: counter = 0 virtual_keyboard real time MIDI plugin for Csound 0dBFS level = 32768.0 Csound version 6.02.0 (double samples) Jan 25 2014 libsndfile-1.0.25 rtaudio: ALSA module enabled rtmidi: ALSA Raw MIDI module enabled Csound version 6.02.0 (double samples) Jan 25 2014 displays suppressed 0dBFS level = 32768.0 orch now loaded audio buffered in 256 sample-frame blocks writing 1024-byte blks of shorts to test.wav (WAV) SECTION 1: counter = 0 ........................ Perf Thread counter = 1 instr 1: p1 = 1.000 400000000 instr 1: p2 = 0.000 Score finished in csoundPerformKsmps(). ** stopping csound counter = 2 inactive allocs returned to freespace end of score. overall amps: 0.0 0.0 overall samples out of range: 0 0 0 errors in performance 512 1024 sample blks of shorts written to test.wav (WAV) [had never tried this, but output looks right to me.] -------------- On Tue, Sep 2, 2014 at 1:07 PM, Oeyvind Brandtsegg <oyvind.brandtsegg@ntnu.no> wrote: I haven't read evverything in the thread, so sorry if I'm answering |
Date | 2014-09-02 22:24 |
From | Chuckk Hubbard |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Thanks, Oeyvind. I've taken a long hiatus from working on my program. I've been taken on as banjo player for a Romanian pop star (Loredana Groza), so I've kind of moved in a different direction than anyone would ever have expected! But not at all a bad direction.-Chuckk On Tue, Sep 2, 2014 at 11:07 PM, Oeyvind Brandtsegg <oyvind.brandtsegg@ntnu.no> wrote: I haven't read evverything in the thread, so sorry if I'm answering -- http://www.badmuthahubbard.com |
Date | 2014-09-02 23:28 |
From | Oeyvind Brandtsegg |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Hi Chuck, I do recognize this kind of problem, and I've struggled with similar problems in my own work. I think there is no hard and fast method to solve it, it depends on your priorities, what is most important (timing precision vs performance could be one such dimension). One possible solution could be to use Csound as the main/host, then send OSC from Csound (to Python or to another Csound instance). This way you could get access to more midi ports even from Csound (by multiple instances). Also, the processes would run separately, allowing each one to get a different priority if you need to do that. However, when things run in the same thread it is much easier to synchronize. For example using performKsmps, as you then have a clock source that is tightly synchronized to the audio loop. The bad thing is of course if you have a method call that takes a long time to return you get dropouts. If you split into different processes, you will still have pretty good synchronization as long as nothing processor heavy is going on. When that happens, the CPU-heavy process could lag behind temporarily. For example playing some notes late. For me, audio dropouts are worse than getting a few note events late. Both are very bad indeed, but if I have to choose what to do in the worst case scenario, I'd go for a late note. So my latest take on it is sending OSC from Csound to Python, (each running as separate programs) calculating whatever needs calculating, then sending OSC back to Csound to trigger new note events. You might get timing jitter of a few ksmps periods for new events. So perhaps one could imagine a tight loop sync (e.g. using py opcodes, still running Csound as the host) and another loose timing loop (based on OSC). There are many options, and the specific needs of your application would determine what compromises you can live with. Btw, Forest, I've never experienced lost events between Csound and Python. If you have several writes to a control channel during one ksmps loop, you would lose control data items (only keeping the last one as far as I understand. But if you have several events (e.g. csound.inputMessage()), all of them will be kept, and all instantiated on the next k-rate boundary. best Oeyvind 2014-09-02 23:24 GMT+02:00 Chuckk Hubbard |
Date | 2014-09-03 13:38 |
From | Chuckk Hubbard |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Thanks a lot, Oeyvind. The way my program works, the score is all determined before hitting "play", so I was thinking either Python or separate instances of Csound could have all the relevant messages already stored in a list; and the main Csound instance could simply send timing info to tell the other instances when to step through the list, so most of the calculation is done before starting. I suppose Csound with OSC would require the least extra baggage. -Chuckk On Wed, Sep 3, 2014 at 1:28 AM, Oeyvind Brandtsegg <oyvind.brandtsegg@ntnu.no> wrote: Hi Chuck, -- http://www.badmuthahubbard.com |
Date | 2014-09-03 22:53 |
From | Oeyvind Brandtsegg |
Subject | Re: [Csnd] Running Python opcodes from a CSD running from the Python API |
Yes,... but my use case with OSC was made for a realtime situation. I haven't tried using OSC messaging for creating an offline score/midifile. You could give it a go, ...but my initial hunch would be to use performKsmps, allowing calls to py opcodes if needed. 2014-09-03 14:38 GMT+02:00 Chuckk Hubbard |