Csound API (Python) - SetInputChannelCallback()
Date | 2016-04-20 07:15 |
From | sjakops |
Subject | Csound API (Python) - SetInputChannelCallback() |
Dear all (sorry if I am reposting, my first message didn't seem to get through) I really need some help to get started with SetInputChannelCallback() on Csound API, using Python - I couldn't find any examples so I'm trying the following little test, which doesn't work. import csnd6 def foo(a, b, c, d): c[0] = 440.0 print "hello" c = csnd6.Csound() c.SetOption("-odac") c.CompileOrc(""" sr=44100 ksmps=32 nchnls=2 0dbfs=1 instr 1 kfreq invalue "freq" kenv linsegr 0, .05, 1, .05, 0 aout vco2 kenv, kfreq outs aout, aout endin """) c.SetInputChannelCallback(foo) c.ReadScore("i1 0 0.2 \n i1 0.5 0.2") c.Start() while (c.PerformKsmps() == 0): pass c.Stop() -- View this message in context: http://csound.1045644.n5.nabble.com/Csound-API-Python-SetInputChannelCallback-tp5749083.html Sent from the Csound - General mailing list archive at Nabble.com. Csound mailing list Csound@listserv.heanet.ie https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND Send bugs reports to https://github.com/csound/csound/issues Discussions of bugs and features can be posted here |
Date | 2016-04-20 14:37 |
From | Francois PINOT |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
1) I slightly modified your example but it does not work: import csnd6 def foo(csound, channelName, channelValuePtr, channelTypePtr): valArray = csnd6.CsoundMYFLTArray() valArray.SetPtr(channelValuePtr) valArray.setValue(0, 440.0) print("hello") c = csnd6.Csound() c.SetOption("-odac") c.CompileOrc(""" sr=44100 ksmps=32 nchnls=2 0dbfs=1 instr 1 kfreq invalue "freq" kenv linsegr 0, .05, 1, .05, 0 aout vco2 kenv, kfreq outs aout, aout endin """) c.SetInputChannelCallback(foo) c.ReadScore("i1 0 0.2 \n i1 1 2") c.Start() while (c.PerformKsmps() == 0): pass c.Stop() It does not even call foo. So it seems there's a problem in csnd6 with Csound.SetInputChannelCallback... 2) The same example in C++ works fine:#include <csound/csound.hpp> void foo(CSOUND* csound, const char *channelName, void *channelValuePtr, const void *channelType) { MYFLT *pVal = (MYFLT *)channelValuePtr; *pVal = 440.0; printf("hello %s\n", channelName); } int main(int argc, char **argv) { char *orc, *sco; orc = "sr=44100\n" "ksmps=32\n" "nchnls=2\n" "0dbfs=1\n" "instr 1\n" " kfreq invalue \"freq\"\n" " kenv linsegr 0, .05, 1, .05, 0\n" " aout vco2 kenv, kfreq\n" " outs aout, aout\n" "endin\n"; sco = "i1 0 0.2 \n i1 1 2"; Csound *cs = new Csound(); cs->SetOption("-odac"); cs->CompileOrc(orc); cs->SetInputChannelCallback(foo); cs->ReadScore(sco); cs->Start(); while (cs->PerformKsmps() == 0); cs->Stop(); } import ctcsound import ctypes def foo(csound, channelName, channelValuePtr, channelTypePtr): name = ctcsound.pstring(channelName) valPtr = ctypes.cast(channelValuePtr, ctypes.POINTER(ctcsound.MYFLT)) valPtr[0] = ctcsound.MYFLT(440.0) print("hello", name) c = ctcsound.Csound() c.setOption("-odac") c.compileOrc(""" sr=44100 ksmps=32 nchnls=2 0dbfs=1 instr 1 kfreq invalue "freq" kenv linsegr 0, .05, 1, .05, 0 aout vco2 kenv, kfreq outs aout, aout endin """) c.setInputChannelCallback(foo) c.readScore("i1 0 0.2 \n i1 1 2") c.start() while (c.performKsmps() == 0): pass c.stop() 2016-04-20 8:15 GMT+02:00 sjakops <sorenkj@gmail.com>: Dear all (sorry if I am reposting, my first message didn't seem to get |
Date | 2016-04-20 22:33 |
From | Søren Jakobsen |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
Thank you all for the replies! (and sorrry again for the SPAM..) I was not aware of Francois' work with ctcsound but very pleased that this issue is being addressed. I was not yet able to run the working Python example because of the dependency on numpy (they stopped providing Windows binaries and the older version only includes 32-bit binaries), but I'll try again tomorrow.. Thanks, Søren On 4/20/16, Francois PINOT |
Date | 2016-04-20 23:00 |
From | Victor Lazzarini |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
This works perfectly, no issues “to be addressed”. The problem was that the callback had the wrong signature. It only takes a single argument, the channel name, and it places its return value. Here’s the correct code: import csnd6 def foo(name): return 440.0 c = csnd6.Csound() c.SetOption("-odac") c.CompileOrc(""" sr=44100 ksmps=32 nchnls=2 0dbfs=1 instr 1 kfreq invalue "freq" kenv linsegr 0, .05, 1, .05, 0 aout vco2 kenv, kfreq outs aout, aout endin """) c.SetInputChannelCallback(foo) c.ReadScore("i1 0 0.2 \n i1 1 2") c.Start() while (c.PerformKsmps() == 0): pass c.Stop() ======================== 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 20 Apr 2016, at 22:33, Søren Jakobsen |
Date | 2016-04-21 14:18 |
From | Francois PINOT |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
I didn't understand why the signature is different from the one in the C API. Then Looking at csound/interfaces/python_interface.i (lines 156 to 164), I got it. It's a bit confusing for normal Python users because this information is not in csnd6.py and reading csound.h, we see a reference to a channelCallback_t type which has definitively a different signature than the one you mentioned.Francois 2016-04-21 0:00 GMT+02:00 Victor Lazzarini <Victor.Lazzarini@nuim.ie>: This works perfectly, no issues “to be addressed”. |
Date | 2016-04-21 14:22 |
From | Victor Lazzarini |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
yes, it is not very well documented. The trouble was that the C API function is not easy to handle in Python, so I wrapped it specially. There is an experimental Directors class to wrap callbacks, but that’s really unwieldy. We need to document it better. But it might be superseded by your work. Regards ======================== 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 21 Apr 2016, at 14:18, Francois PINOT |
Date | 2016-04-21 14:47 |
From | Francois PINOT |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
I think that ctypes is more versatile than swig to handle C functions in Python. This allowed me to stay very close to the original C API in ctcsound. Actually, there are only five functions of the C API that I did not wrapped in ctcsound: CsoundInitializeCscore2016-04-21 15:22 GMT+02:00 Victor Lazzarini <Victor.Lazzarini@nuim.ie>: yes, it is not very well documented. The trouble was that the C API function is not easy to handle in Python, so I wrapped it specially. |
Date | 2016-04-21 17:02 |
From | Søren Jakobsen |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
I would suggest including this info as one of the official examples. Best, Søren On 4/21/16, Francois PINOT |
Date | 2016-04-21 19:31 |
From | Victor Lazzarini |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
Francois, how do you handle C pointers, e.g. in the input value callback? Victor Lazzarini Dean of Arts, Celtic Studies, and Philosophy Maynooth University Ireland > On 21 Apr 2016, at 17:02, Søren Jakobsen |
Date | 2016-04-21 19:51 |
From | Francois PINOT |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
ctypes has a POINTER function for creating a new pointer type to a known ctype type. For example ctypes.POINTER(ctcsound.MYFLT) is a pointer type to MYFLT. Then ctypes has a cast function similar to the cast pointer in C. Using these functions, Søren's foo function becomes: def foo(csound, name, valuePtr, typePtr): name = ctcsound.pstring(name) valPtr = ctypes.cast(valuePtr, ctypes.POINTER(ctcsound.MYFLT)) valPtr[0] = ctcsound.MYFLT(440.0) print("hello", name) In fact, valuePtr is a void * in C, and Python receives it as an integer value. We have to inform Python of the real type of this value and then it can be dereferenced with the [] operator. Francois 2016-04-21 20:31 GMT+02:00 Victor Lazzarini <Victor.Lazzarini@nuim.ie>: Francois, |
Date | 2016-04-21 21:47 |
From | Søren Jakobsen |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
Regarding documentation of csnd6, it is actually also unclear for me how to use SetStringChannel() - it seems the following is not correct? (I get some compile error) import csnd6 c = csnd6.Csound() c.SetStringChannel("test", "test") On 4/21/16, Francois PINOT |
Date | 2016-04-21 23:58 |
From | Francois PINOT |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
The SetStringChannel and SetControlChannel methods are not implemented in the csnd6.Csound class. You have to call the simple functions csoundSetStringChannel and csoundSetControlChannel instead, with an opaque pointer to the Csound instance as first argument. Here is an example: These methods are implemented in the ctcsound.Csound class and so the example becomes:import csnd6 c = csnd6.Csound() c.SetOption("-odac") c.CompileOrc(""" sr=48000 kr=480 nchnls=2 0dbfs=1 instr 1 Sval chnget "mystring" ktrig chnget "mytrigger" printf "Got this string: %s\n", ktrig, Sval endin """) c.ReadScore("i1 0 2") c.Start() n, i, k = 0, 0, 0 while (c.PerformKsmps() == 0): n += 1 if n >= 80: i += 1 s = "String #{}".format(i) csnd6.csoundSetStringChannel(c.GetCsound(), "mystring", s) csnd6.csoundSetControlChannel(c.GetCsound(), "mytrigger", k+1) k = 1 - k n = 0 c.Stop() import ctcsound c = ctcsound.Csound() c.setOption("-odac") c.compileOrc(""" sr=48000 kr=480 nchnls=2 0dbfs=1 instr 1 Sval chnget "mystring" ktrig chnget "mytrigger" printf "Got this string: %s\n", ktrig, Sval endin """) c.readScore("i1 0 2") c.start() n, i, k = 0, 0, 0 while (c.performKsmps() == 0): n += 1 if n >= 80: i += 1 s = "String #{}".format(i) c.setStringChannel("mystring", s) c.setControlChannel("mytrigger", k+1) k = 1 - k n = 0 c.stop() 2016-04-21 22:47 GMT+02:00 Søren Jakobsen <sorenkj@gmail.com>: Regarding documentation of csnd6, it is actually also unclear for me |
Date | 2016-04-22 11:38 |
From | Søren Jakobsen |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
Thanks for tip! I wonder how I can figure out if a method is supported or not? It seems InputMessage() may also not be supported? (in the following test InputMessage() itself gives no error, but there is another error suggesting that the input message has not been accepted) import csnd6 orc = """ sr=44100 ksmps=32 nchnls=2 0dbfs=1 instr 1 aL, aR loscil 1, 1, p4, 1 aEnv madsr 0.001, 0.001, 1.0, 0.08 outs aL*aEnv, aR*aEnv endin """ c = csnd6.Csound() c.SetOption("-odac") c.CompileOrc(orc) c.InputMessage('f 1 0 0 1 "test.wav" 0 0 0)') c.ReadScore('i 1 0 2 1') c.Start() while (c.PerformKsmps() == 0): pass c.Stop() On 4/21/16, Francois PINOT |
Date | 2016-04-22 13:41 |
From | Francois PINOT |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
Just look in the csnd6.py file. Depending on how you installed Csound it can be found in different places. For example, when you build Csound on linux, it's in ~/.local/lib/python2.7/site-packages/ InputMessage is supported as a single function, as a method of csnd6.Csound, as a method of csnd6.CppSound, and as a method of CsoundPerformanceThread.import csnd6 orc = """ sr=44100 ksmps=32 nchnls=2 0dbfs=1 instr 1 aL, aR loscil 1, 1, p4, 1 aEnv madsr 0.001, 0.001, 1.0, 0.08 outs aL*aEnv, aR*aEnv endin """ c = csnd6.Csound() c.SetOption("-odac") c.CompileOrc(orc) c.ReadScore('f 1 0 0 1 "test.wav" 0 0 0\ne 2') c.Start() c.InputMessage('i 1 0 2 1') c.Perform() 2016-04-22 12:38 GMT+02:00 Søren Jakobsen <sorenkj@gmail.com>: Thanks for tip! I wonder how I can figure out if a method is supported |
Date | 2016-04-22 15:09 |
From | Søren Jakobsen |
Subject | Re: Csound API (Python) - SetInputChannelCallback() |
Actually InputMessage() does seem to work on Windows - I just found that my original code works perfectly, if only I set the starting time for instrument 1 to 0.1 instead of 0 (and fix the typo in the input message). But ofcourse your approach is better, as I will be then probably be certain that the sample has finished loading before I play it (and I don't have to try to guess the loading time). Best regards, Søren On 4/22/16, Francois PINOT |