It's a beautiful bug. I have reduced the test.
Besides the problem of the latency, the instrument 1
immediately start and not after 100 seconds!
sr = 44100
ksmps = 10
nchnls = 1
gilisten OSCinit 47120
instr 1
kfrq init 440
nxtmsg:
kk OSClisten gilisten, "/test", "f", kfrq
if (kk == 0) goto ex
kgoto nxtmsg
ex:
aout oscil 10000, kfrq, 1
socksend aout, "127.0.0.1", 12001, 1456
endin
f1 99 2 2 0 1
i1 100 36000
Tested with GNU/Linux + PulseAudio + Jack
tito
On Fri, Nov 25, 2011 at 12:34:33PM -0800, Justin Glenn Smith wrote:
> Yeah, UDP implements no error detection, it is very lightweight and low level compared to TCP. OSC uses UDP, and implements no error detection, so yeah, that goes for OSC as well. When you start a UDP connection, you can start the sending process before the receiving process, and until the receiver is running and interpreting data, the control data is silently thrown in the bit bucket, with no errors or complaints. This is also why it is so easy and (network/CPU) efficient to do UDP multicast - just send the exact same packets to every destination, no need for handshakes or confirmations or resending damaged packets.
>
> Maybe the system call to allocate a UDP socket is blocking?
>
> Perhaps the initial latency is a question of loading csound, and its shared libraries, into RAM? At least on Linux a program and its shared libraries are kept in RAM after exit, counting on the likelihood that the same program will be launched again, or at the very least another process will want to use the same shared libs (this is also one reason that Linux programs don't typically ship with their own versions of shared libraries).
>
> Rory Walsh wrote:
> > Is that the same with OSC? I should probably step aside now and let
> > some of the more experienced programmers enter the fray!
> >
> >
> > On 25 November 2011 19:32, Anders Genell wrote:
> >> Aha?
> >> My very limited knowledge of network protocols lead me to believe that UDP does not necessarily need to wait for a confirmed connection, but rather just sends packets and hope for the best...
> >> But that does not mean it doesn't take time to initialize, I suppose.
> >>
> >> The interesting thing is it only happens the first time we run it, even if the thread is killed and Compile() is called again before next run.
> >>
> >> Curiouser and curiouser...
> >>
> >> /A
> >>
> >>
> >> 25 nov 2011 kl. 17:15 skrev Rory Walsh :
> >>
> >>> I'd imagine it's more likely to be something with the OSC/socksend
> >>> initialisation. The tables should be created in no time at all.
> >>> However, it's probably best to see what others think before ruling out
> >>> the tables completely.
> >>>
> >>> On 25 November 2011 15:57, Anders Genell wrote:
> >>>> We generate one ordinary sine table, and three empty tables for adsynt2 (and
> >>>> initialize an incoming OSC port for rpm and torque sent from the vehicle
> >>>> simulator where this is used):
> >>>> ; Sine wave
> >>>> giwave ftgen 1, 0, 4096, 10, 1
> >>>> ; Generate three empty tables for adsynt...
> >>>> gifrqs ftgen 2, 0, 32, 7, 0, 32, 0
> >>>> ; ...for freqency
> >>>> giamps ftgen 3, 0, 32, 7, 0, 32, 0
> >>>> ; ...amplitude
> >>>> giphas ftgen 4, 0, 32, 7, 0, 32, 0
> >>>> ; and phase parameters
> >>>>
> >>>> gilisten OSCinit 47120
> >>>>
> >>>> the tables are then filled at k-rate by:
> >>>>
> >>>> krpm init 0
> >>>> kvel init 0
> >>>> kload init 0
> >>>>
> >>>> nxtmsg:
> >>>>
> >>>> ; Recieve OSC messages from sim kernel and put into initiated varables
> >>>> kk OSClisten gilisten, "/3/xy", "fff", krpm, kvel, kload
> >>>>
> >>>> ; if no new packet is received during a k-cycle exit loop for that cycle
> >>>> if (kk == 0) goto ex
> >>>>
> >>>> ; loop every k-cycle
> >>>> kgoto nxtmsg
> >>>>
> >>>>
> >>>> ; loop exit
> >>>> ex:
> >>>>
> >>>> icnt = 0
> >>>> kindex = 0
> >>>> loop:
> >>>>
> >>>> ;Calculate harmonics from rpm and torque
> >>>> ; Order 0.8
> >>>> if (kindex == 0) then
> >>>> kfreqharmonic = 0.8
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.0050248 * krpm + 0.0102156 * kload + 47.7983)
> >>>> / 20)
> >>>> ; Order 1.0
> >>>> elseif (kindex == 1) then
> >>>> kfreqharmonic = 1
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.00333679 * krpm + 0.00158462 * kload + 42.963)
> >>>> / 20)
> >>>> ; Order 1.6
> >>>> elseif (kindex == 2) then
> >>>> kfreqharmonic = 1.6
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.00212791 * krpm + 0.00484493 * kload +
> >>>> 29.5378) / 20)
> >>>> ; Order 1.8
> >>>> elseif (kindex == 3) then
> >>>> kfreqharmonic = 1.8
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.00200162 * krpm + 0.0129004 * kload + 31.0708)
> >>>> / 20)
> >>>> ; Order 2.0
> >>>> elseif (kindex == 4) then
> >>>> kfreqharmonic = 2
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((0.00147358 * krpm + 0.000183555 * kload +
> >>>> 24.3956) / 20)
> >>>> ; Order 2.2
> >>>> elseif (kindex == 5) then
> >>>> kfreqharmonic = 2.2
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.000803212 * krpm + 0.00189542 * kload +
> >>>> 24.1317) / 20)
> >>>> ; Order 3.0
> >>>> elseif (kindex == 6) then
> >>>> kfreqharmonic = 3
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((0.00030711 * krpm + 0.00235111 * kload + 20.2667)
> >>>> / 20)
> >>>> ; Order 3.2
> >>>> elseif (kindex == 7) then
> >>>> kfreqharmonic = 3.2
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.000250113 * krpm + 0.00157579 * kload +
> >>>> 20.0479) / 20)
> >>>> ; Order 3.4
> >>>> elseif (kindex == 8) then
> >>>> kfreqharmonic = 3.4
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.00104358 * krpm + -2.63367e-05 * kload +
> >>>> 20.6522) / 20)
> >>>> ; Order 3.6
> >>>> else (kindex == 9) then
> >>>> kfreqharmonic = 3.6
> >>>> kphase = 2
> >>>> kampharmonic pow 10, ((-0.000766148 * krpm + -0.00175425 * kload +
> >>>> 19.2014) / 20)
> >>>>
> >>>>
> >>>> ; Write amps to table for adsynt.
> >>>> tablew kampharmonic, kindex, giamps
> >>>> ; Write freqs to table for adsynt.
> >>>> tablew kfreqharmonic, kindex, gifrqs
> >>>> ; Write phase to table for adsynt
> >>>> tablew kphase, kindex, giphas
> >>>>
> >>>> kindex = kindex + 1
> >>>> ; Do loop.
> >>>> if (kindex < icnt) then
> >>>> kgoto loop
> >>>> endif
> >>>>
> >>>> aengineout adsynt2 0.001, kfreqfund, giwave, gifrqs, giamps, icnt, giphas
> >>>>
> >>>> socksend aengineout, "127.0.0.1", 12001, 1024
> >>>>
> >>>>
> >>>>
> >>>> Regards,
> >>>> Anders
> >>>>
> >>>> On Fri, Nov 25, 2011 at 4:06 PM, Rory Walsh wrote:
> >>>>> I'm not sure table creation would cause such a noticeable latency.
> >>>>> What size tables are you using and how many?
> >>>>>
> >>>>> On 25 November 2011 12:06, Anders Genell wrote:
> >>>>>> I am sorry for 'stealing the thread', but as the sought answer seems to
> >>>>>> have
> >>>>>> been provided, I'll take the opportunity to ask a somewhat related
> >>>>>> question:
> >>>>>>
> >>>>>> We have a program in which we have created a plugin to handle calls to
> >>>>>> the
> >>>>>> Csound API.
> >>>>>> I am not a programmer myself, so I have not written this code myself,
> >>>>>> but
> >>>>>> need to use it quite often...
> >>>>>> This snippet of interest is:
> >>>>>> ---
> >>>>>> CsoundThread::CsoundThread(std::string path) :
> >>>>>> m_path(path), m_csound(new Csound())
> >>>>>> {
> >>>>>> m_csound->Compile((char*)m_path.c_str());
> >>>>>> }
> >>>>>>
> >>>>>> void CsoundThread::run() {
> >>>>>> m_csound->Perform();
> >>>>>> }
> >>>>>>
> >>>>>> int CsoundThread::quit() {
> >>>>>> m_csound->Stop();
> >>>>>> return 0;
> >>>>>> }
> >>>>>> ---
> >>>>>> As probably is obvious to anyone acquainted with C++, this creates a
> >>>>>> thread
> >>>>>> running an instance of Csound. When the plugin is loaded, we call
> >>>>>> Compile(),
> >>>>>> and when (an external) call to "run()" is issued, we call Perform().
> >>>>>> At (external) call to "quit()" we call Stop().
> >>>>>> The first time we call the "run()"-funtion, there is a substantial
> >>>>>> latency
> >>>>>> in audio (we receive it from the socksend opcode and push it to OpenAL
> >>>>>> buffers for playback), but after calling "quit()" and the "run()" again,
> >>>>>> the
> >>>>>> latency is satisfactory.
> >>>>>> Having followed this discussion about tables, I assume it might be due
> >>>>>> to
> >>>>>> that tables are created at first Perform(), also when using ftgen, so at
> >>>>>> first run there is a delay while tables etc (we use adsynt2 with 10
> >>>>>> harmonics) are created.
> >>>>>> My question is if there is a way to perform the table initialization
> >>>>>> when
> >>>>>> the plugin is loaded, so that the first "run()" does not have the large
> >>>>>> latency?
> >>>>>>
> >>>>>> Regards,
> >>>>>> Anders
> >>>>>>
> >>>>>> On Fri, Nov 25, 2011 at 12:12 PM, Rory Walsh wrote:
> >>>>>>> Thanks Tito. That's the information I was looking for!
> >>>>>>>
> >>>>>>> On 25 November 2011 09:32, Tito Latini wrote:
> >>>>>>>> `csoundTableLength' is -1 before `csoundPerformKsmps', because
> >>>>>>>>
> >>>>>>>> `csoundScoreEvent' calls `insert_score_event_at_sample' that puts the
> >>>>>>>> events in the `csound->OrcTrigEvts' list. Stop.
> >>>>>>>>
> >>>>>>>> Instead, `csoundTableLength' calls `csound->GetTable' that looks for
> >>>>>>>> in `csound->flist'. Stop.
> >>>>>>>>
> >>>>>>>> `csoundPerformKsmps' calls `sensevents', that calls
> >>>>>>>> `process_score_event',
> >>>>>>>> that calls `hfgens' that sets csound->flist.
> >>>>>>>>
> >>>>>>>> So csoundTableLength "sees" csound->flist only after
> >>>>>>>> csoundPerformKsmps,
> >>>>>>>> that calls me, that call `cheers'.
> >>>>>>>>
> >>>>>>>> tito
> >>>>>>>>
> >>>>>>>> On Fri, Nov 25, 2011 at 08:31:19AM +0000, Rory Walsh wrote:
> >>>>>>>>> Great, thanks Tito. I wonder would you mind replacing the score
> >>>>>>>>> event
> >>>>>>>>> stuff with printf("%d", csoundTableLenght(csound, 1));
> >>>>>>>>> I just want to confirm that tables aren't valid until after
> >>>>>>>>> performKsmps() is called. Don't worry if it's too much hassle, I can
> >>>>>>>>> try it myself later! Cheers,
> >>>>>>>>>
> >>>>>>>>> Rory.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> On 25 November 2011 08:22, Tito Latini
> >>>>>>>>> wrote:
> >>>>>>>>>> Yes Rory, here is a test
> >>>>>>>>>>
> >>>>>>>>>> /* csound_test.c */
> >>>>>>>>>> #include
> >>>>>>>>>>
> >>>>>>>>>> int main(int argc, char **argv)
> >>>>>>>>>> {
> >>>>>>>>>> void *csound = csoundCreate(0);
> >>>>>>>>>> int result = csoundCompile(csound, argc, argv);
> >>>>>>>>>> /* f1 0 8192 10 5 4 3 2 1 */
> >>>>>>>>>> MYFLT pFields[] = {1,0,8192,10,5,4,3,2,1};
> >>>>>>>>>> csoundScoreEvent(csound, 'f', pFields, 9);
> >>>>>>>>>> if(!result) {
> >>>>>>>>>> while(csoundPerformKsmps(csound) == 0){}
> >>>>>>>>>> csoundCleanup(csound);
> >>>>>>>>>> }
> >>>>>>>>>> csoundDestroy(csound);
> >>>>>>>>>> return result;
> >>>>>>>>>> }
> >>>>>>>>>>
> >>>>>>>>>> ;; test.csd
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> sr = 44100
> >>>>>>>>>> ksmps = 10
> >>>>>>>>>> nchnls = 1
> >>>>>>>>>>
> >>>>>>>>>> instr 1
> >>>>>>>>>> aout oscil 15000, 1000, 1
> >>>>>>>>>> out aout
> >>>>>>>>>> endin
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> f1 0 8192 10 1
> >>>>>>>>>> i1 0 1
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> cc -lcsound -o csound_test csound_test.c
> >>>>>>>>>> ./csound_test -g test.csd
> >>>>>>>>>> ...
> >>>>>>>>>>
> >>>>>>>>>> .''-
> >>>>>>>>>> . '
> >>>>>>>>>> '
> >>>>>>>>>> - '
> >>>>>>>>>> '
> >>>>>>>>>> - '_
> >>>>>>>>>> ._
> >>>>>>>>>> . '-----._
> >>>>>>>>>> '-._
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> _____________________________'''------._________________________________________
> >>>>>>>>>> '--......__
> >>>>>>>>>> '-._
> >>>>>>>>>> -
> >>>>>>>>>> '-......_
> >>>>>>>>>> '.
> >>>>>>>>>> .
> >>>>>>>>>> -
> >>>>>>>>>>
> >>>>>>>>>> -
> >>>>>>>>>> _
> >>>>>>>>>>
> >>>>>>>>>> -
> >>>>>>>>>>
> >>>>>>>>>> -
> >>>>>>>>>> .
> >>>>>>>>>>
> >>>>>>>>>> - _
> >>>>>>>>>>
> >>>>>>>>>> '__.
> >>>>>>>>>>
> >>>>>>>>>> ...
> >>>>>>>>>>
> >>>>>>>>>> tito
> >>>>>>>>>>
> >>>>>>>>>> On Thu, Nov 24, 2011 at 07:56:28PM +0000, Rory Walsh wrote:
> >>>>>>>>>>> I did some digging and now I have another question. I'm showing
> >>>>>>>>>>> my
> >>>>>>>>>>> inner Csound workings ignorance here, but do any of the table API
> >>>>>>>>>>> functions work before performKsmps() is first called? As in
> >>>>>>>>>>> straight
> >>>>>>>>>>> after compile() is called?
> >>>>>>>>>>>
> >>>>>>>>>>> On 24 November 2011 18:11, Rory Walsh wrote:
> >>>>>>>>>>>> D'oh! He can send a score statement using csoundScoreEvent().
> >>>>>>>>>>>> But
> >>>>>>>>>>>> can
> >>>>>>>>>>>> the score statement be sent before performKsmps()?
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> On 24 November 2011 17:54, Rory Walsh wrote:
> >>>>>>>>>>>>> A student of mine was asking if there is an API function that
> >>>>>>>>>>>>> can
> >>>>>>>>>>>>> be
> >>>>>>>>>>>>> used to dynamically create function tables, a
> >>>>>>>>>>>>> csoundTableCreate()
> >>>>>>>>>>>>> per
> >>>>>>>>>>>>> say. Am I right in saying this is not possible? Well, at least
> >>>>>>>>>>>>> within
> >>>>>>>>>>>>> the current framework of the API.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Rory.
>
> ------------------------------------------------------------------------------
> All the data continuously generated in your IT infrastructure
> contains a definitive record of customers, application performance,
> security threats, fraudulent activity, and more. Splunk takes this
> data and makes sense of it. IT sense. And common sense.
> http://p.sf.net/sfu/splunk-novd2d
> _______________________________________________
> Csound-devel mailing list
> Csound-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/csound-devel
------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure
contains a definitive record of customers, application performance,
security threats, fraudulent activity, and more. Splunk takes this
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
Csound-devel mailing list
Csound-devel@lists.sourceforge.net