[01:14] < Chong-> got to sleep. good night, all. |
[01:15] *** Chong- has parted #kamaelia |
[08:19] *** orphans has joined #kamaelia |
[08:48] *** Lawouach has joined #kamaelia |
[08:50] < Lawouach> morning |
[08:56] < orphans> morning Lawouach |
[08:57] < Lawouach> hi mate |
[08:57] < orphans> hows it going? |
[08:57] < Lawouach> Good |
[08:58] < Lawouach> My two English friends who came over for the weekend have just departed from St Malo |
[08:58] < Lawouach> We had a good weekend |
[08:58] < orphans> ahh, cool. you get up to much? |
[08:59] < Lawouach> visited a few places, had great food, good wine and beer |
[08:59] < Lawouach> yeah I'd say we did :) |
[09:01] < orphans> sounds like an enjoyable weekend :) |
[09:02] < Lawouach> it was :) |
[09:02] < Lawouach> http://meta.ath0.com/2008/01/18/kde-4-ui-critique/ < -- I feel the same |
[09:03] < Lawouach> That's one of the reason for the first time I've decided to use Gnome rather than KDE |
[09:03] < Lawouach> KDE4 layout is too confusing |
[09:04] < orphans> I've only seen screenies - thought it was beginning to look pretty nice (on a purely aesthetic basis taht is) |
[09:17] < Lawouach> how did the exams go? |
[09:18] < orphans> yeah, not too bad. I'm officially done for exams now (decided not to do the last one yesterday) |
[09:18] < orphans> I've done enough in all of the to get a decent enough pass I think, so I'm pleased enough |
[09:20] < Lawouach> okay that's cool :) |
[09:20] < orphans> don't know if I said, but I got into my masters for next year too, so I'm pretty sorted now :) |
[09:20] < Lawouach> congrats :) |
[09:20] < Lawouach> what will be the subject? |
[09:21] < orphans> ta |
[09:21] < orphans> Creative Technologies - www.ioct.dmu.ac.uk/ |
[09:23] < Lawouach> very nice! |
[09:24] < orphans> yeah - looks like a really interesting course |
[10:22] *** vmlemon__ has joined #kamaelia |
[11:11] < orphans> Lawouach, ping? |
[11:11] < Lawouach> pong |
[11:11] < orphans> you got a minute to look at something? |
[11:11] < Lawouach> yes |
[11:12] < orphans> http://orphans.pastebin.com/d1dc6ea3b |
[11:13] < orphans> I think this code should give results slightly greater than the sleep time (in the region of 0.5-1 ms) |
[11:13] < orphans> for me I get around 3-4ms |
[11:13] < Lawouach> time is never the best way to synchronise code |
[11:14] *** orphans never knew that :) |
[11:14] < orphans> what's better? |
[11:14] < Lawouach> the operating system respects the time request value up to a certain precision only |
[11:14] < Lawouach> what are you trying to do? |
[11:14] < orphans> get the timing code running < 1ms accuracy |
[11:14] < orphans> i.e. on the safe side of human hearing accuracy |
[11:15] < orphans> I put that together as a test to see whether the problem was in the sleeping, threads etc |
[11:15] < orphans> s/threads/thread |
[11:18] < Lawouach> since you're using threads, wouldn't it make sense to use things like mutex to synchronise instead? |
[11:19] < orphans> not done much threaded programming before - do you have an example somewhere? |
[11:19] < Lawouach> The thing is I wonder if there isn't a better way with Kamaelia. I never use threaded components. |
[11:21] < orphans> I think there probably isn't - I was talking to MS- about this sort of thing and he said that there wasn't any timing stuff built into the scheduler |
[11:21] < orphans> at least not the sort of accuracy needed |
[11:22] < orphans> http://yeoldeclue.com/logs/kamaelia2008-05-26_log.html - towards the top of taht |
[11:22] < orphans> s/taht/that |
[11:23] < Lawouach> I see |
[11:25] < Lawouach> http://docs.python.org/lib/event-objects.html |
[11:25] < Lawouach> This is one way of doing things |
[11:25] < Lawouach> The real problem however is not so much which tool to use but what precisely you want to be doing |
[11:27] < orphans> for an idea of what I was working on see http://kamaelia.svn.sourceforge.net/viewvc/kamaelia/trunk/Sketches/JT/Jam/library/trunk/Kamaelia/Apps/Jam/Util/MusicTiming.py?revision=4142&view=markup |
[11:28] < orphans> having components with an inbuilt timer which worked in musical timings |
[11:31] < Lawouach> time.sleep is indeed the wrong way here |
[11:31] < Lawouach> you will never be able to ensure the accuracy you need |
[11:32] < Lawouach> well not only |
[11:32] < Lawouach> hang on |
[11:32] < Lawouach> one idea BTW is to look at how similar products do it :) |
[11:33] *** orphans is on the jokosher svn at the moment |
[11:37] < Lawouach> BTW, why not using pymedia to play out the midi file? |
[11:37] < Lawouach> that would take care of it at a low level no? |
[11:39] < orphans> didn't know pymedia did midi out |
[11:41] < Lawouach> or pygame |
[11:41] < Lawouach> since SDL supports it, pygame might |
[11:41] < Lawouach> ah well pymedia doesn't do midi :) |
[11:41] < Lawouach> pygame then? |
[11:43] < Lawouach> http://www.daniweb.com/code/snippet755.html |
[11:44] < Lawouach> http://www.pygame.org/docs/ref/music.html#pygame.mixer.music.load |
[11:44] < Lawouach> Maybe that would simplify your task? |
[11:45] < orphans> mm, not sure it's really suited to doing stuff in real-time though. |
[11:46] *** orphans delves deeper |
[11:47] < Lawouach> See it uses the clock.tick() to pause the process while the MIDI is playing |
[11:48] < Lawouach> But it's not used as synchronization per-se |
[11:48] < orphans> yeah, and clock.tick() only has about the same accuracy as I've got using time.sleep() |
[11:49] < orphans> from here: http://www.pygame.org/docs/ref/time.html "Times in pygame are represented in milliseconds (1/1000 seconds). Most platforms have a limited time resolution of around 10 milliseconds." |
[11:50] < orphans> but that's not quite true, because I can get latency of ~3ms in both windows and linux (on good days) |
[11:52] < Lawouach> That's the big problem. You're not building a product for your own machine, are you? ;) |
[11:53] < orphans> no, but it's not a complete beast by any stretch of the imagination (3 years old now) |
[12:01] < orphans> mm, I think time.sleep() might actually be the best I can do |
[12:02] < orphans> fwiw jokosher doesn't go any more accurate than 1/256th of a beat (~3ms for an 80bpm tune) |
[12:09] *** Lawouach has joined #kamaelia |
[12:39] *** Uraeus has joined #kamaelia |
[12:39] *** Davbo has joined #kamaelia |
[13:12] *** bcarlyon|laptop has joined #kamaelia |
[14:37] *** vmlemon__ has joined #kamaelia |
[14:37] *** vmlemon__ is now known as vmlemon_ |
[14:38] < vmlemon_> Hi |
[14:41] < bcarlyon|laptop> HI! |
[14:50] < Lawouach> 'lo |
[15:00] < vmlemon_> Medium ;) |
[15:11] *** vmlemon_ has joined #kamaelia |
[15:31] *** vmlemon__ has joined #kamaelia |
[15:43] *** Davbo has joined #kamaelia |
[15:51] *** vmlemon___ has joined #kamaelia |
[15:53] *** vmlemon___ is now known as vmlemon__ |
[16:04] *** Uraeus has joined #kamaelia |
[17:19] *** MS- has joined #kamaelia |
[17:19] < MS-> evening |
[17:39] *** vmlemon_ has joined #kamaelia |
[18:04] < orphans> MS-, evening |
[18:04] *** orphans notes /trunk/Sketches/MPS/JT/timer.py |
[18:05] < orphans> any input on what I should be doing? |
[18:05] *** orphans notes that it isn't the same as what I posted :D |
[18:05] < orphans> reading |
[18:08] < MS-> I had a play with the code you pasted in the pastebin |
[18:11] < orphans> yeah - looks like a more complete version of my test :) |
[18:12] < MS-> The most accurate way is to essentially do this: |
[18:13] < orphans> results are pretty ugly sometimes - 50ms at 95th percentile |
[18:13] < MS-> measure the amount of time you're out |
[18:14] < MS-> and then sleep for the amount of time you wanted to sleep for, less the amount of time you're out |
[18:14] < MS-> And to keep track of the amount you're generally out by |
[18:15] < MS-> It's discussed a fair amount on the pygame list for what its worth |
[18:15] < orphans> ok, I'll have a look there. Any threads in particular or will google make it pretty clear? |
[18:18] < Lawouach> MS-: with audio though this kind of synchronisation is good enough if you have a decent buffer mechanism so you're sure you're never short of data |
[18:19] < MS-> Lawouach: I don't really know :-) |
[18:19] < Lawouach> well the problem with audio is that if you're not synced well enough it impacts immediately the end user experience |
[18:20] < Lawouach> video or games can afford to lose a bit of data along the way usually |
[18:20] < Lawouach> audio is rather more sensitive |
[18:20] < Lawouach> so again it really comes down to what orphans is trying to do |
[18:20] < Lawouach> which I'm still not clear about :) |
[18:21] < orphans> Lawouach, *sigh* sorry :) |
[18:21] < MS-> Indeed. And synchronisation matters (with audio/video), but continuity matters (almost more) |
[18:21] < vmlemon_> Hi |
[18:22] < Lawouach> orphans: not criticising you :) |
[18:23] < vmlemon_> Just make it print "Buffering..." forever, that'll do the trick ;) |
[18:23] < orphans> I guess maybe it'd all be a bit clearer if I was working on a component which depended more heavily on the timing (something like the step sequencer) |
[18:24] < orphans> given that this has come about now perhaps it'd be better for me to rearrange my schedule a little and get that (timing and all) working before the networking stuff? |
[18:25] < Lawouach> not necessarily |
[18:25] < Lawouach> I usually prefer going for a working mockup of the system first |
[18:26] < Lawouach> ensuring the overall design the right one |
[18:26] < Lawouach> adjusting it |
[18:26] < Lawouach> finally optimising wher it needs to be |
[18:26] < Lawouach> that being said, if your optimisation changes the design |
[18:26] < Lawouach> it's not optimisation anymore :) |
[18:27] < Lawouach> it's more refactoring :) |
[18:27] < orphans> yeah. I'll maybe do a really quick mockup of something which has tight timing, then leave it at that until later on (providing it looks OK) |
[18:27] < Lawouach> yes |
[18:28] < Lawouach> I'd rather you having a working application asap than specialized components |
[18:28] < Lawouach> We'll move to that gradually |
[18:28] < orphans> yeah, cool |
[18:29] < orphans> < = off to get food - thanks for the help Lawouach and MS- |
[18:29] *** Uraeus has joined #kamaelia |
[18:29] < Lawouach> np |
[19:18] *** vmlemon___ has joined #kamaelia |
[19:22] *** vmlemon___ is now known as vmlemon__ |
[19:27] *** Uraeus has joined #kamaelia |
[19:41] *** Davbo has joined #kamaelia |
[19:42] < Davbo> Evenin' all |
[19:43] < Davbo> I read quite a bit on LikeFile but i'm not sure if i understand what functionality it has still |
[19:43] < Davbo> Could anyone explain what it does? |
[19:49] < Lawouach> hello Davbo |
[19:50] < Davbo> Hey Lawouach |
[19:50] < Lawouach> Basically it makes Axon components look like a file object |
[19:51] < Davbo> I've not played my guitar for so long it has made my fingers hurt, brings back memories :) |
[19:51] < Lawouach> Not sure if you know it but in Python it is common for an object to pretend it quacks like a file |
[19:51] < Davbo> Ah |
[19:51] < Lawouach> so that you can open it, read/write from and to it |
[19:51] < Davbo> I did not know that |
[19:51] < Lawouach> :) |
[19:52] < Lawouach> for instance the socket module has a .makefile() method that wraps a socket into a file object |
[19:52] < Lawouach> so that you can simple do: |
[19:52] < Lawouach> mysock.read(), mysock.write() |
[19:52] < Davbo> Hmm |
[19:53] < Lawouach> Have you heard the concept of "interface" in programing? |
[19:53] < Davbo> For abstraction? |
[19:53] < Lawouach> yes |
[19:53] < Davbo> Yeah, i know what you mean |
[19:53] < Lawouach> alright |
[19:54] < Lawouach> With OOP you can of course subclass and use inheritance |
[19:54] < Davbo> So if i were to "implement" LikeFile as an interface would i need to provide methods for read() and write() - that kinda thing? |
[19:56] < Lawouach> but more and more subclassing is left out in favour of interfaces as they define a contract without coupling too much objects between themselves |
[19:56] < Lawouach> well, in dynamic languages like Python, interfaces are not really meaningful |
[19:57] < Lawouach> because you can pretend to support a contract just by defining the API you need |
[19:57] < Davbo> I see |
[19:57] < Davbo> hmm |
[19:57] < Lawouach> a file object is a typical interface |
[19:58] < Lawouach> .open(), .read(), .write(), .close() |
[19:58] < Lawouach> That's an interface if you want |
[19:58] < Lawouach> By the way the process of pretending in dynamic languages is called "duck typing" :) |
[19:59] < Davbo> I'm not sure I understand "pretend to support a contract" |
[19:59] < Lawouach> It quacks like a duck, it looks like a duck, so let's take our chances and act as if it was a duck |
[19:59] < Davbo> oh |
[19:59] < Lawouach> well I'll take an example |
[20:00] *** vmlemon_ has joined #kamaelia |
[20:00] < Lawouach> Imagine a class called Clock |
[20:00] < Davbo> yeah |
[20:00] < Lawouach> now you could have the following methods in that class |
[20:00] < Lawouach> getTime() |
[20:00] < Lawouach> setTime() |
[20:01] < Lawouach> imagine now you have a piece of code that doesn't care about the type of objects it processes like this: |
[20:01] < Lawouach> for obj in list_of_varios_objects: |
[20:01] < Davbo> yeah |
[20:01] < Lawouach> imagine you want to put a Clock() instance in that list |
[20:01] < Lawouach> you could simply define the following methods in the Clock class: |
[20:02] < Lawouach> .read() |
[20:02] < Lawouach> .write() |
[20:02] < Lawouach> .read() would be the .getTime() |
[20:02] < Lawouach> .write() would be .setTime() |
[20:02] < Lawouach> for obj in list_of_varios_objects: |
[20:02] < Lawouach> obj.read() |
[20:02] < Davbo> I see, hmm |
[20:02] < Lawouach> that list could contain files, sockets, Clocks objects |
[20:03] < Davbo> Yeah |
[20:03] < Lawouach> you would not need to do: |
[20:03] < Lawouach> for obj in list_of_varios_objects |
[20:03] < Lawouach> if isinstance(obj, Clock): |
[20:03] < Lawouach> obj.getTime() |
[20:03] < Lawouach> See? |
[20:03] < Lawouach> You pretend to ba file |
[20:03] < Davbo> Yeah i see |
[20:03] < Lawouach> s/ba/be |
[20:04] < Davbo> hmm |
[20:04] *** bcarlyon|laptop has joined #kamaelia |
[20:04] < Davbo> so you implement interfaces but you don't really say you're doing it? |
[20:05] < Lawouach> In Python indeed you just declare some methods and let the application process the object independantly from its type |
[20:05] < Lawouach> You duck type it :) |
[20:05] < Davbo> in java you'd say |
[20:05] < Davbo> public class Clock implements File { |
[20:05] < Davbo> public Read() ... |
[20:05] < Lawouach> yeah |
[20:05] < Lawouach> That's the idea. |
[20:06] < Davbo> thanks Lawouach |
[20:06] < Lawouach> Except with dynamic languages it's all very implicit |
[20:06] < Davbo> Yeah |
[20:06] < Lawouach> so |
[20:06] < Lawouach> to come back at your original question |
[20:06] < Lawouach> it could be useful to pretend for a component to be like a file |
[20:06] < Lawouach> so that Axon's components could be used more regularly in Python applications |
[20:06] < Davbo> Yeah |
[20:07] < Davbo> but it's not so simple to make a component act like a file, right? |
[20:07] < Lawouach> Well |
[20:07] < Lawouach> The issue lies in the way you decide how you link boxes. |
[20:08] < Lawouach> For a component like Pipeline it's easy |
[20:08] < Lawouach> inbox < -> outbox |
[20:08] < Lawouach> But for more complex components it becomes a greater challenge. |
[20:09] < Davbo> I see why there was a big problem when i made another box in my program now |
[20:09] < Lawouach> :) |
[20:10] < Davbo> i presume likefile doesn't look at box usage dynamically? / could it ? |
[20:12] < Lawouach> well not really |
[20:12] < Lawouach> when you wrap a component with likefile |
[20:13] < Lawouach> it wraps every boxes in its own internal component |
[20:13] < Lawouach> those wrappers basically use a thread-safe queue |
[20:14] < Davbo> ah right |
[20:14] < Lawouach> when you call .get() on the likefile component |
[20:14] < Lawouach> it blocks on that queue (well the queue for the box you .get() on) |
[20:14] < Davbo> this is where we get the "race hazard" that MS- told me about |
[20:14] < Lawouach> internally the components are running on their own and fill that queue |
[20:14] < Lawouach> yes |
[20:15] < Lawouach> those queues are thread-safe but there are potential problems in the implementation |
[20:15] < Davbo> I see |
[20:16] < Davbo> Thank you Lawouach :-) |
[20:16] < Lawouach> np |
[20:17] < Lawouach> On a side note |
[20:17] < Lawouach> Last year before the student started on that project I was very keen about the end result. |
[20:18] < Lawouach> Then I started using Kamaelia heavily before he finished it so I never actually used it and I've never felt a need for it |
[20:18] < Lawouach> But MS- has shown me uses cases where it'd be handy |
[20:18] < Lawouach> Now, that being siad there is a fundamental difference between regular Axon components and the Likefile design. |
[20:19] < Davbo> well Process stuff seems to use it as that's where i get problems |
[20:19] < Lawouach> The former is all about push |
[20:19] < Lawouach> The later is about pull |
[20:20] < Davbo> right |
[20:20] < Lawouach> This means that traditionnally with Axon and Kamaelia, you write components, link them together and Axon will simply ensure the data arrives where it needs to arrive |
[20:21] < Lawouach> With Likefile, your code polls regularly the likefile component for more data |
[20:21] < Davbo> ah i see |
[20:21] < Lawouach> Although it makes code easier to write and read in many cases, it may also have a great impact on performances |
[20:21] < Davbo> surely that isn't an "ideal" way for it to work? |
[20:22] < Lawouach> It's hard to make it efficient |
[20:23] < Lawouach> MS- could explain further here but I wonder if Python 2.5 generator support wouldn't allow for a more efficient implementation |
[20:24] < Davbo> that sounds like a good idea Lawouach |
[20:25] < Lawouach> But since Axon and Kamaelia do support Python 2.2 onward it won't happen soon I guess :) |
[20:35] < Davbo> Well thanks for explaining those things Lawouach, i'm off to relax for a bit. :-) |
[20:35] < Lawouach> np |
[20:35] < Lawouach> take it easy :) |
[20:52] *** MS- starts reading back |
[20:52] *** vmlemon_ has joined #kamaelia |
[20:54] *** MS- notes that the name "likefile" is probably not as good as it could be (reading the bit about read()/write() ) |
[20:55] *** vmlemon__ has joined #kamaelia |
[21:02] < MS-> It's not meant to say it's "like the (specific) file interface protocol" |
[21:03] < MS-> But more "it's an interface that is used like a file interface is used - ie you have a handle that represents the thing you're talking to & you talk to it" |
[21:03] < Lawouach> yes |
[21:04] < Lawouach> I don't disagree. I think I may have been unclear earlier then |
[21:04] < Lawouach> Because I totally agree with your point here :) |
[21:05] < MS-> Yeah, the misinterpretation it causes is a problem. |
[21:05] < MS-> LikeFile isn't really the same as AsFile |
[21:05] < MS-> which is more the relationship I'd expect |
[21:06] < Lawouach> true. |
[21:07] < MS-> Regarding 2.5's generator support, that's something that I'm really torn with. I have a machine with 2.3 on which I really don't want to have to mess with (a mac mini I use as a home server) |
[21:07] < Lawouach> I can appreciate your point really. |
[21:07] < MS-> And a mobile which has python on which is a derivative of 2.2.< some late number> and hence supports generators (and has run Kamaelia in the past) |
[21:08] < MS-> But, the key benefit that 2.5's generators give is actually the .stop() support |
[21:08] < Lawouach> That being said it could be fun and interesting to try out a LikeFile component using those generators and see what comes out of it |
[21:08] < MS-> since you can pass in any exception you like |
[21:08] < MS-> The ability to do |
[21:08] < MS-> .next(< some value>) wouldn't specifically make the component threadsafe, which is the issue with LikeFile |
[21:09] < MS-> It also would mean you'd need a double nesting of values really |
[21:10] < MS-> There are ways to optimise working with it though |
[21:10] < MS-> But they're independent of 2.5's generator support |
[21:11] < MS-> the whole .next(< some value>) thing doesn't really make much sense with Kamaelia IMO btw |
[21:11] < MS-> since it implies tight code coupling AFAICT |
[21:11] < MS-> It'd be interesting to see, but that was the impression I gained having seen some stuff written using it |
[21:12] < Lawouach> I wouldn't know as I've never used it :) |
[21:17] < MS-> It's just really wierd - you could happily do this: |
[21:17] < MS-> def bla(...): |
[21:17] < MS-> x = yield 1 |
[21:17] < MS-> while 1: |
[21:17] < MS-> if isSomething(x): |
[21:17] < MS-> y = yield 1 |
[21:17] < MS-> else: |
[21:17] < MS-> z = yield 1 |
[21:17] < MS-> if yield 1: |
[21:17] < MS-> break |
[21:17] < MS-> print x, y |
[21:17] < MS-> print x,z |
[21:17] < MS-> You couldn't actually tell upfront if that could ever work |
[21:17] < MS-> In fact you could almost guarantee it never could work |
[21:19] < MS-> In order to talk to it, you actually need to understand how the internal structure works |
[21:19] < MS-> Which is plain *wierd* |
[21:21] < Lawouach> Indeed |
[21:25] *** vmlemon_ has joined #kamaelia |
[21:48] *** bcarlyon|laptop has joined #kamaelia |
[22:09] *** vmlemon__ has joined #kamaelia |
[22:16] *** MS- calls it a night |
[22:16] < MS-> cya |
[22:16] *** MS- has parted #kamaelia |
[23:10] *** bcarlyon|laptop has joined #kamaelia |