<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-36421488</id><updated>2009-11-05T14:51:22.309-08:00</updated><title type='text'>Voki Codder</title><subtitle type='html'>Joyful bits</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default?start-index=26&amp;max-results=25'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36421488.post-5157882817413690996</id><published>2009-05-31T18:31:00.000-07:00</published><updated>2009-06-01T05:27:10.613-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-of-the-day'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Command of the day: git svn (Using git over a subversion repository)</title><content type='html'>This may be the end of a long quest for a tool to do 'offline commits on subversion'. That is, being able to work with small commits when you are not able to commit because you are off-line (on-flight or on-train hacking) or you are not a commiter yet (menthorship).&lt;br /&gt;&lt;br /&gt;The fact is that, we can benefit of some nice features of &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; without having to migrate from subversion. I found a very interesting &lt;a href="http://flavio.castelli.name/howto_use_git_with_svn"&gt;blog entry&lt;/a&gt; explaining that. I compiled my own notes for CLAM:&lt;br /&gt;&lt;br /&gt;Install the required packages:&lt;br /&gt;&lt;tt&gt;sudo apt-get install git-svn&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Configure your user:&lt;br /&gt;&lt;tt&gt;git config --global user.name 'David García Garzón'&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;git config --global user.email 'yo@alli.com'&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Create a git clone of the svn:&lt;br /&gt;&lt;tt&gt;git svn clone http://dgarcia@clam-project.org/clam --stdlayout -r HEAD&lt;/tt&gt;&lt;br /&gt;Notice that i skiped the 'trunk' part of the url we normally use. '--stdlayout' is to interpret trunk/ branches/ tags/ as such. '-rHEAD' avoids cloning the whole history which is faster.&lt;br /&gt;&lt;br /&gt;Work with the repository &lt;a href="http://git.or.cz/course/svn.html"&gt;as with a normal git one&lt;/a&gt;, avoiding remote operations (push/pull). Git can fustrate SVN users with a lack of shortcuts (ci, di, up...). &lt;a href="http://git.or.cz/gitwiki/Aliases"&gt;You can define them at will&lt;/a&gt;:&lt;br /&gt;&lt;tt&gt;git config --global alias.ci "commit -a"&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;git config --global alias.di diff&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;git config --global alias.stat status&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;git config --global alias.up "svn rebase"&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;git config --global alias.rci "svn dcommit"&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;To update your git repository to server changes:&lt;br /&gt;&lt;tt&gt;git svn rebase&lt;/tt&gt;&lt;br /&gt;If you have uncommited local changes you have to 'stash' them first.&lt;br /&gt;&lt;br /&gt;To apply all the local commits to subversion, once rebased:&lt;br /&gt;&lt;tt&gt;git svn dcommit&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To generate, instead, an incremental set of patches:&lt;br /&gt;&lt;tt&gt;git format-patch -M -C -s --inline --stdout remotes/trunk &gt; mypatch.mbox&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Note that this is not a regular patch file but an mbox file containing several mails, one per commit, each with the patch attached and some aditional information such as the commit message.&lt;br /&gt;&lt;br /&gt;Those commits can be sent to the menthor and applied to git sandbox with svn write access.&lt;br /&gt;&lt;tt&gt;git am mypatch.mbox&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;An then the menthor can commit using previous command 'dcommit'. That easy... or not so.&lt;br /&gt;&lt;br /&gt;Some other highlights i would do on git: Nice programmer oriented subcomands such as &lt;a href="http://www.kernel.org/pub/software/scm/git-core/docs/git-bisect.html"&gt;git bisect&lt;/a&gt;, to help bug hunting by doing a dicotomic search on revisions, or &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-stash.html"&gt;git stash&lt;/a&gt;, to discard temporarily uncommited changes and recovering them later, or 'git grep', which executes grep ignoring git control files and generated files. Tools like &lt;a href="http://www.procode.org/stgit/doc/tutorial.html"&gt;StGit&lt;/a&gt; and &lt;a href="http://www.kernel.org/pub/linux/kernel/people/jsipek/guilt/man/"&gt;guilt&lt;/a&gt; that allows to edit the order of the local commits considering them a serie of patches similarly to &lt;a href="http://savannah.nongnu.org/projects/quilt"&gt;quilt&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-5157882817413690996?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/5157882817413690996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=5157882817413690996' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/5157882817413690996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/5157882817413690996'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2009/05/command-of-day-git-svn-using-git-over.html' title='Command of the day: git svn (Using git over a subversion repository)'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-5072536586239534264</id><published>2009-04-06T00:33:00.000-07:00</published><updated>2009-06-01T06:14:49.869-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='mingw'/><category scheme='http://www.blogger.com/atom/ns#' term='multiplatform'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='vst'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='crosscompilation'/><title type='text'>VST plugins with Qt user interface</title><content type='html'>I recently did an &lt;a href="https://llistes.projectes.lafarga.cat/pipermail/clam-devel/2009/003065.html"&gt;spike&lt;/a&gt; on what we need to make &lt;a href="http://en.wikipedia.org/wiki/Virtual_Studio_Technology"&gt;VST&lt;/a&gt; plugins first class &lt;a href="http://clam-project.org"&gt;CLAM&lt;/a&gt; citizens. CLAM allows to visually build &lt;a href="http://jackaudio.org/"&gt;JACK&lt;/a&gt; and &lt;a href="http://www.portaudio.com/"&gt;PortAudio&lt;/a&gt; based applications with Qt interfaces as well as &lt;a href="http://clam-project.org/clam/trunk/NetworkEditor/src/vst/"&gt;GUI-less VST&lt;/a&gt; and &lt;a href="http://clam-project.org/wiki/Building_a_LADSPA_plugin"&gt;LADSPA&lt;/a&gt; plugins. The more flashy feature of VST is user interfaces that are mostly built using &lt;a href="http://vstgui.sourceforge.net/"&gt;VSTGUI&lt;/a&gt;. We are using Qt as interface for JACK and Portaudio based apps because we are using the nice features of Qt toolkit to dynamically bind the UI elements and the underlaying processing. Moreover, &lt;a href="http://doc.trolltech.com/4.4/stylesheet.html"&gt;Qt styling&lt;/a&gt; features enables shinning designer-made interfaces. Why not being able to reuse the same interface for VST and JACK? That has been a long standing TODO in CLAM so now is time to address it.&lt;p&gt;In summary, we fully solved croscompiling vst's from linux and we even started using qt interfaces as vst gui. In that last point, there still is a lot of work to do, but the basic question on whether you can use qt to edit a vst plugin is now out of any doubt.&lt;p&gt;To make the spike simpler, and in order not to collide with other CLAM developers, currently working on it, i just left apart all the CLAM wrapping part, just addressing vst crosscompiling and Qt with the sdk examples.&lt;p&gt;Cross compilation was &lt;a href="http://clam-project.org/wiki/Devel/Windows_MinGW_cross_compile#VST_development"&gt;pretty easy&lt;/a&gt;. This time I found lot more documentation on &lt;a href="http://learnvst.wordpress.com/"&gt;mingw and even scons&lt;/a&gt;. Just by adding the &lt;a href="http://clam-project.org/clam/trunk/CLAM/scons/sconstools/crossmingw.py"&gt;crossmingw scons tool&lt;/a&gt; we are already using for the apps and i managed to get Linux cross-compiled plugins running on Wine. &lt;img src="http://clam-project.org/w/images/3/3c/Vst-crosscompiling.png" /&gt;&lt;p&gt;Adding a regular vstgui user interface is just a matter of compiling vstgui sources along with the example editor that comes in the sdk.&lt;br /&gt;&lt;img src="http://clam-project.org/w/images/4/4c/Vst-vstgui.png" /&gt;&lt;p&gt;Once there, we should address Qt. VSTGUI is just a full graphical toolkit implementing the 'editor interface' plus a toolkit with some provided widgets and, i guess, a way of automating the binding of controls to processing. So what we need for qt is to implement the AEffEditor interface using the qt toolkit instead. The first problem is about the graphical loop. You have to create a QApplication and calling &lt;a href="http://doc.trolltech.com/4.5/qcoreapplication.html#processEvents"&gt;qApp::processEvents()&lt;/a&gt; on the editor's idle method so that qt widgets get responsive. The problem then is that, if you don't provide a QWidget as parent to  your interface, it becomes a top level window ignoring the host provided window that still appears as an empty one. &lt;p&gt;&lt;img src="http://clam-project.org/w/images/9/97/Vst-qttoplevel.png" /&gt;&lt;p&gt;VST host provides such window as a native Windows handle. How do you create a widget on an existing window handle? Months ago trolls redirected me to a &lt;a href="http://www.qtsoftware.com/products/appdev/add-on-products/catalog/3/Windows/qtwinmigrate"&gt;commercial solution&lt;/a&gt;. Not such a 'solution' for us, a FLOSS project. So i was digging in windows qt source code for a hack when i found the answer just at the public and multiplatform QWidget api. &lt;a href="http://doc.trolltech.com/4.5/qwidget.html#create"&gt;QWidget::create&lt;/a&gt; works like a charm. The following simple class is a native window wrapper you can use as a regular QWidget.&lt;pre&gt;&lt;br /&gt;class QVstWindow : public QWidget&lt;br /&gt;{&lt;br /&gt;        Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;        QVstWindow(WId handle) {create(handle);}&lt;br /&gt;        QVstWindow::~QVstWindow() {}&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Still there are some issues: focus handling, reopening, drag&amp;drop... But the basic mouse clicking and resizing works&lt;p&gt;&lt;img src="http://clam-project.org/w/images/f/fb/Vst-qt.png" /&gt;&lt;p&gt;Once i got that, loading a designer ui file was very easy.&lt;p&gt;&lt;img src="http://clam-project.org/w/images/4/47/Vst-designer.png" /&gt;&lt;p&gt;As I said there are still many caveats to solve. A matter of playing with it and refining things. Here is a list of TODO's:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Communicate controls from and to the interface&lt;/li&gt;&lt;li&gt;Handle focus and other events properly&lt;/li&gt;&lt;li&gt;Build a CLAM network wrapper which reensembles more the one for LADSPA&lt;/li&gt;&lt;li&gt;Wiki documentation on how to build your own plugin&lt;/li&gt;&lt;li&gt;One button plugin generator like the one we have for LADSPA ;-)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I feel that there is more people around other projects &lt;a href="http://lists.trolltech.com/qt-interest/2006-01/thread00332-0.html"&gt;interested in using Qt for VST plugins&lt;/a&gt; so this is also a call for collaborative research on pending issues, at least the generic ones. Contact us on the &lt;a href="https://llistes.projectes.lafarga.org/cgi-bin/mailman/listinfo/clam-devel"&gt;CLAM development list&lt;/a&gt; or for a broader audience in the &lt;a href="http://lad.linuxaudio.org/"&gt;Linux Audio Developers list&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-5072536586239534264?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/5072536586239534264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=5072536586239534264' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/5072536586239534264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/5072536586239534264'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2009/04/vst-plugins-with-qt-user-interface.html' title='VST plugins with Qt user interface'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-4261635377770084453</id><published>2009-04-05T06:48:00.001-07:00</published><updated>2009-04-05T06:55:14.177-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-of-the-day'/><category scheme='http://www.blogger.com/atom/ns#' term='interdiff'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Command of the day: interdiff</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Often, when working in code projects, I have to keep some local changes uncommited because I am offline or because i am doing some experiment and i am not sure that it will be successful. In those cases you end up doing a big commit with has very low grain to rollback any regressive change. Sure new distributed VCS allow offline commits but we are working with subversion. So I was glad when i recently discovered how to use interdiff command. &lt;br/&gt;&lt;br /&gt;If you plan to make a set of offline changes, on each point you would commit, just take an 'svn diff' on a file. Given those accomulative diffs respect the BASE revision, interdiff knows how to extract the incremental ones from one state to the next one so. When you are back online, you revert all changes, apply and commit each patch separately. &lt;br/&gt;&lt;br /&gt;Other interesting commands to manage patches (available in the patchutils package):&lt;br/&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;combinediff: the reverse, joins two patches together &lt;/li&gt;&lt;li&gt;recountdiff: very useful when you want to reapply a patch but the state of the code has changed. &lt;/li&gt;&lt;li&gt;flipdiff: exchanges the order of two pages &lt;/li&gt;&lt;li&gt;filterdiff: remove the changes affecting a set of files from an existing patch &lt;/li&gt;&lt;/ul&gt;No excuses for coarse commits after on-flight coding to Parma!&lt;br/&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-4261635377770084453?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/4261635377770084453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=4261635377770084453' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4261635377770084453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4261635377770084453'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2009/04/command-of-day-interdiff.html' title='Command of the day: interdiff'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-3011399310863914303</id><published>2008-11-19T06:35:00.000-08:00</published><updated>2008-11-19T06:49:07.096-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='refactor'/><title type='text'>Refactoring script for CLAM networks</title><content type='html'>Now that the &lt;a href='http://clam.iua.upf.edu'&gt;CLAM&lt;/a&gt; &lt;a href='http://iua-share.upf.edu/wikis/clam/Network_Editor_tutorial'&gt;NetworkEditor&lt;/a&gt; has become such a convenient tool to define audio processing systems, we started to use it massively instead of C++ code to integrate processings. Even thought, we started to find that whenever we change a configuration structure, a port/control name, or even a processing class name, the networks xml had to be edited by hand because they didn't load. That problem led us to avoid such kind of changes, which is not a sane option. 'Embrace change', agile gurus said, and so we did. &lt;br /&gt; &lt;br /&gt;We have developed a &lt;a href="http://iua-share.upf.es/svn/clam/trunk/CLAM/scripts/clamrefactor.py"&gt;python tool to support network refactoring&lt;/a&gt;. It can be used, both as a python module, or as a command line tool, to batch modify CLAM network files using high level operations such as: &lt;br /&gt;&lt;ul&gt; &lt;br /&gt;&lt;li&gt; Renaming a processing class name&lt;br /&gt;&lt;li&gt; Renaming a processing name&lt;br /&gt;&lt;li&gt; Renaming processing ports or controls&lt;br /&gt;&lt;li&gt; Renaming a processing configuration parameter&lt;br /&gt;&lt;li&gt; Removing/adding/reorder configuration parameters&lt;br /&gt;&lt;li&gt; Setting configuration parameters values&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt;The script just does &lt;a href="http://www.w3.org/TR/xpath"&gt;XPath&lt;/a&gt; navigation and DOM manipulations in order to know which pieces need to be changed. Each high level command is just a couple of lines in python.&lt;br /&gt; &lt;br /&gt; We are starting to use it to: &lt;br /&gt;&lt;ul&gt; &lt;br /&gt;&lt;li&gt; Adapt to changes in the C++ code&lt;br /&gt;&lt;li&gt; Change network configuration parameters in batch&lt;br /&gt;&lt;li&gt; Provide migration scripts for user's networks&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt; About the last point, we plan the next release to provide network migration scripts containing a command set such as: &lt;br /&gt;&lt;pre&gt;  &lt;br /&gt;ensureVersion 1.3&lt;br /&gt;renameClass OutControlSender NewClassName&lt;br /&gt;renameConnector AudioMixer inport "Input 0" "New Port Name 0"&lt;br /&gt;renameConfig AudioMixer NumberOfInPorts NInputs&lt;br /&gt;setConfigByType AudioMixer NInputs 14&lt;br /&gt;upgrade 1.3.2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt; Still some short term TODO's: &lt;br /&gt;&lt;ul&gt; &lt;br /&gt;&lt;li&gt; Include the clam version in the network xml so that the ensureVersion and upgrade commands work.&lt;br /&gt;&lt;li&gt; Integrating also Qt Designer UI files in the refactorings&lt;br /&gt;&lt;li&gt; Add some other commands as they are needed&lt;br /&gt;&lt;/ul&gt; &lt;br /&gt; Happy CLAM networks &lt;a href='http://www.refactoring.com'&gt;refactoring&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-3011399310863914303?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/3011399310863914303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=3011399310863914303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3011399310863914303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3011399310863914303'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/11/refactoring-script-for-clam-networks.html' title='Refactoring script for CLAM networks'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-2657665349411773809</id><published>2008-11-14T15:47:00.001-08:00</published><updated>2008-11-14T16:36:23.432-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>Managing Audio Back2Back Tests</title><content type='html'>So long since last post, and a lot of things to explain (GSoC results, GSoC Mentor Submit, QtDevDays, CLAM network refactoring script, typed controls...). But, let's start explaining some work we did on a &lt;a href="http://iua-share.upf.edu/svn/clam/trunk/CLAM/scripts/audiob2b.py"&gt;Back-to-back system&lt;/a&gt; we recently deployed for &lt;a href="http://clam.iua.upf.edu"&gt;CLAM&lt;/a&gt; and our &lt;a href="http://www.barcelonamedia.org/linies/10/ca"&gt;3D acoustic project in Barcelona Media&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Back-to-back testing background&lt;/h2&gt;&lt;br /&gt; &lt;br /&gt; You, extreme programmer, might want to have unit tests (white box testing) for every single line of code you write. But, sometimes, this is a hard thing to achieve. For example, canonical test cases for audio processing algorithms that exercise a single piece of code are very hard to find. You might also want to take control of a piece of untested code in order to refactor it without introducing new bugs. In all those cases back-to-back tests are your most powerful tool. &lt;br /&gt; &lt;br /&gt; Back-to-back tests (B2B) are black box tests that compare the output of a reference version of an algorithm with the output of an evolved version, given the same set of inputs. When a back-to-back test fails, it means that something changed but normally it doesn't give you any more information than that. If the change was expected to alter the output, you must revalidate the new output again and make it the new reference. But if the alteration was not expected, you should either roll-back the change or fix it. &lt;br /&gt; &lt;br /&gt; In back-to-back tests there is no truth to be asserted. You just rely on the fact that the last version was OK. If b2b tests get red because an expected change of behaviour but you don't validate the new results, you will loose any control on posterior changes. So, is very important to keep them green or validating any new correct result. Because of that, B2B tests are very helpful to be used in combination of a continuous integration system such as &lt;a href="http://www.iua.upf.edu/~parumi/testfarm/"&gt;TestFarm&lt;/a&gt;, that can point you to the guilty commit even if further commits have been done. &lt;br /&gt; &lt;br /&gt; CLAM's OfflinePlayer is very convenient to do back2back testing of CLAM networks. It runs them off-line specifying some input and outputs wave files. Automate the check by subtracting the output with a reference file and checking the level against a threshold, and you have a back-to-back test. &lt;br /&gt; &lt;br /&gt; But still maintaining the outputs up-to-date is hard. So, we have developed a python module named &lt;a href="http://iua-share.upf.edu/svn/clam/trunk/CLAM/scripts/audiob2b.py"&gt;audiob2b.py&lt;/a&gt; that makes defining and maintaining b2b test on audio very easy. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;Defining a b2b test suite&lt;/h2&gt; &lt;br /&gt; A test suite is defined by defining back-to-back data path, and a list of test cases, each one defining a name, a command line and a set of outputs to be checked:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span class="c"&gt;# back2back.py&lt;/span&gt;&lt;br /&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;audiob2b&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;runBack2BackProgram&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;data_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;b2b/mysuite&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;back2BackTests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;br /&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;testCase1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;   &lt;span class="s"&gt;&amp;quot;OfflinePlayer mynetwork.clamnetwork b2b/mysuite/inputs/input1.wav -o output1.wav output2.wav&amp;quot;&lt;/span&gt;&lt;br /&gt;   &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;br /&gt;    &lt;span class="s"&gt;&amp;quot;output1.wav&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="s"&gt;&amp;quot;output2.wav&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;   &lt;span class="p"&gt;]),&lt;/span&gt;&lt;br /&gt;  &lt;span class="c"&gt;# any other testcases there&lt;/span&gt;&lt;br /&gt; &lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;runBack2BackProgram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back2BackTests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Notice that this example uses OfflinePlayer but, as you write the full command line, you are not just limited to that. Indeed for 3D acoustics algorithms we are testing other programs that also generate wave files. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;Back-to-back work flow&lt;/h2&gt; &lt;br /&gt; When you run the test suite the first time (./back2back.py without parameters) there is no reference files (expectation) and you will get a red. Current outputs will be copied into the data path like that: &lt;br /&gt; b2b/mysuite/testCase1_output1_result.wav&lt;br /&gt; b2b/mysuite/testCase1_output2_result.wav&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; After validating that the outputs are OK, you can accept a test case by issuing: &lt;br /&gt;$ ./back2back.py --validate testCase1&lt;br /&gt; The files will be moved as: &lt;br /&gt;b2b/mysuite/testCase1_output1_expected.wav&lt;br /&gt;b2b/mysuite/testCase1_output2_expected.wav&lt;br /&gt;...&lt;br /&gt; &lt;br /&gt; And the next time you run the tests, they will be green. At this point you can add and commit the 'expected' files on the data repository. &lt;br /&gt; &lt;br /&gt; Whenever the output is altered in a sensible way and you get a red, you will have again the '_result' files and also some '_diff' files so that you can easily check the difference. All those files will be cleaned as soon you validate them or you get back the old results. &lt;br /&gt; So the main benefit of that is that the expectation files management is almost automated so it is easier to maintain them in green. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;Supporting architecture differences&lt;/h2&gt;&lt;br /&gt; Often the same algorithm provides slightly different values depending on the architecture you are running on, mostly because different precision (ie. 32 vs. 64 bits) or different implementations of the floating point functions. &lt;br /&gt; &lt;br /&gt; Having back-to-back tests changing all the time depending on which platform you run them is not something desirable. The audiob2b module generate platform dependant expectations by validating them with the --arch flag. Platform dependant expectations are used instead the regular ones just if the ones for the current platform are found.&lt;br /&gt; &lt;br /&gt;&lt;h2&gt;Future&lt;/h2&gt;&lt;br /&gt; The near future of the tool is just being used. We should extend the set of controlled networks and processing modules in CLAM. So I would like to invite other CLAM contributors to add more back2back's. Place your suite data in 'clam-test-data/b2b/'. We should decide where the suite definitions themselves should be placed. Maybe somewhere in CLAM/test but it won't be fair because dependencies on NetworkEditor and maybe in plugins.&lt;br /&gt; &lt;br /&gt; Also a feature that would extend the kind of code we control with back-to-back, would be supporting file types other than wave files such as plain text files, or XML files (some kind smarter than just plain text). Any ideas? Comments?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-2657665349411773809?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/2657665349411773809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=2657665349411773809' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/2657665349411773809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/2657665349411773809'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/11/managing-audio-back2back-tests.html' title='Managing Audio Back2Back Tests'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-470460574143863624</id><published>2008-07-22T15:38:00.000-07:00</published><updated>2008-07-22T18:38:15.986-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='sigslot'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='vmqt'/><category scheme='http://www.blogger.com/atom/ns#' term='annotator'/><title type='text'>Exterminating signals and slots</title><content type='html'>I recently posted at the &lt;a href="http://clam.iua.upf.edu"&gt;clam&lt;/a&gt; &lt;a href="http://clam.iua.upf.edu/wikis/clam/Devel"&gt;devel wiki&lt;/a&gt; some advices, conventions, traps and tips on &lt;a href="http://iua-share.upf.edu/wikis/clam/index.php/Devel/Programming_with_Qt"&gt;programing with Qt within CLAM&lt;/a&gt; addressed to the &lt;a href="http://iua-share.upf.es/wikis/clam/index.php/GSoC_2008"&gt;GSoC&lt;/a&gt; students. The most painful trap is the one of gratuitous &lt;a href="http://doc.trolltech.com/4.4/signalsandslots.html"&gt;signals and slots&lt;/a&gt; usage. Signals and slots is a very powerful way of designing independent components that comunicate each other with low coupling. Is that powerful that it is very tempting for novices to use them everywhere and this can turn very harmful for you.&lt;br /&gt;&lt;br /&gt;If a connected slot doesn't exist, you just get an error console on run-time, checks on slots are that soft, and this is bad. Also the signal slot resolution is more expensive than just a method call. But the main reason to avoid them is that they make the code very hard to follow. When you see a signal 'emit' you have to find where such signal is connected in order to find which are the objects and slots that will be called. Multiply this process by nearly 200 signal emisions that were done at the &lt;a href='http://iua-share.upf.edu/svn/clam/trunk/Annotator/vmqt/'&gt;vmqt&lt;/a&gt; library &lt;a href='http://iua-share.upf.es/wikis/clam/index.php/Music_Annotator'&gt;Annotator&lt;/a&gt; is using and you'll understand why such components although very smartly designed in structure, they are very hard to maintain and use.&lt;br /&gt;&lt;br /&gt;You should emit signals just when you don't know which is the receiver of an event. If you can guess the receiver, there is no use for signals. On the other side, if you cannot access the emitter code, or you don't want to couple it, then there is room for a 'connect'.&lt;br /&gt;&lt;br /&gt;A bad smell for noticing that you are over using sigslots is having in a class you are writting a connection like this:&lt;br /&gt;&lt;pre&gt;connect(this, signal, knownWidget, slot)&lt;/pre&gt;&lt;br /&gt;and later, maybe in a different method:&lt;br /&gt;&lt;pre&gt;emit signal()&lt;/pre&gt;&lt;br /&gt;When that known, and later forgotten, object is the only one you are connecting to the slot you might want to just keep a reference to it and just call the slot instead of emitting  the signal.&lt;br /&gt;&lt;pre&gt;knownWidget-&gt;slot()&lt;/pre&gt;&lt;br /&gt;which is faster, compile time checked and much more traceable.&lt;br /&gt;&lt;br /&gt;Given that bad smell locator at hand i decided to do a fast review of vmqt module. vmqt is the successor of the many Visualization Modules we had in CLAM, just annother definitive VM rewrite. I tried to use it several times, but it is very hard to have a global view of what it does because all the program flow is driven by signal connections. No joke: 180 signal emissions and a similar number of 'connect's in 30 classes.&lt;br /&gt;&lt;br /&gt;After a first review, 110 signals emisions have been avoided just by having a pointer to the Plot2D at the Renderers (the objects that represent drawing layers of the plot such as the lines, the playhead, the grid...). Having a pointer to it, Renderers can do a direct call to the Plot2D slots (now regular functions) instead of emitting a signal whose only receiver is the plot.&lt;br /&gt;&lt;br /&gt;70 'emit's are still wandering around. Some of them communicate the plot with the wplot (a widget containing the plot and other elements such as the sliders, the rulers...) so they are used to syncronize. Those are likely to be removed in a similar way than for renderers.&lt;br /&gt;&lt;br /&gt;The rest are specific renderer signals that are connected and propagated by the specific wplot. Those are harder to remove and indeed they are very convenient to keep.&lt;br /&gt;&lt;br /&gt;As the extermination goes on, one can better see how to really take profit of the nice vmqt module structure and which aspects can be enhanced.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-470460574143863624?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/470460574143863624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=470460574143863624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/470460574143863624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/470460574143863624'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/07/externinating-signals-and-slots.html' title='Exterminating signals and slots'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-3592852685731135246</id><published>2008-05-21T10:00:00.000-07:00</published><updated>2008-05-21T11:14:49.555-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='idioms'/><title type='text'>A configuration idiom for Python scripts</title><content type='html'>For our Python scripts we have used a fair number of idioms and variations such as importing a config.py file with the parameters as module global vars or importing the content of a dictionary. A different one we used lately is very useful and simple:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# This should be your program using the config&lt;br /&gt;&lt;br /&gt;import os&lt;br /&gt;class config :&lt;br /&gt;    #Here we define the default parameters&lt;br /&gt;    paramA = "value A"&lt;br /&gt;    paramC = "value C"&lt;br /&gt;    class category1 :&lt;br /&gt;        paramC="value sub C"&lt;br /&gt;&lt;br /&gt;    #Here we load new values from files, if they exist&lt;br /&gt;    for configFile in [&lt;br /&gt;        "/usr/share/myprog/defaultconfig",&lt;br /&gt;        "/etc/myprog.conf",&lt;br /&gt;        "~/.myprog/config",&lt;br /&gt;        "myconfig.conf",&lt;br /&gt;    ] :&lt;br /&gt;        if not os.access(configFile,os.R_OK) : continue&lt;br /&gt;        execfile(configFile)&lt;br /&gt;&lt;br /&gt;# That's the config params usage. Pretty!&lt;br /&gt;print config.paramA&lt;br /&gt;print config.paramB&lt;br /&gt;print config.paramC&lt;br /&gt;print config.category1.paramC&lt;br /&gt;print "This is a template: %(paramC)s" % config.category1.__dict__&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you write in the config file this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# myconfig.conf&lt;br /&gt;paramA="new value A"&lt;br /&gt;paramB="new value B"&lt;br /&gt;category1.paramC="new subCvalue"&lt;br /&gt;paramB+=" extension " + paramA&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;you'll get this&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;new value A&lt;br /&gt;new value B extension new value A&lt;br /&gt;value C&lt;br /&gt;new subCvalue&lt;br /&gt;This is a template: new subCvalue&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The config file is read as you were adding code at the same indentation level you have on the 'execfile' call.&lt;br /&gt;&lt;br /&gt;Notice the advantages:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Your config file looks like var assignations&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can use inner classes to build up categories&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can have a list of configuration locations with different precedence&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can include almost whatever python code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can do templating with the params getting a dictionary like config.__dict__ or config.category1.__dict__&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can put config checking code after loading.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Be carefull on unreliable contexts:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Malicious config files can include almost whatever python code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Config syntax errors crash the program (i guess that can be solved)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Config files may add any new attribute, category, or method you didn't have&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;But if you are just managing your own utility scripts like us, that idiom is fantastic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-3592852685731135246?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/3592852685731135246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=3592852685731135246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3592852685731135246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3592852685731135246'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/05/configuration-idiom-for-python-scripts.html' title='A configuration idiom for Python scripts'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-2130113029708339587</id><published>2008-03-18T11:56:00.000-07:00</published><updated>2008-03-18T12:12:47.625-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-of-the-day'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='profiling'/><title type='text'>Command of the day: hotspot2calltree</title><content type='html'>Today, the command of the day is &lt;tt&gt;hotspot2calltree&lt;/tt&gt;.&lt;p&gt;I do like a lot using &lt;a href="http://kcachegrind.sourceforge.net"&gt;kcachegrind&lt;/a&gt; to tune my C++ code. You can use KCacheGrind to navigate through the actual function calls in a given execution of your program and seeing very graphically where the time is spent.&lt;p&gt;Today i needed to optimize some python code but that's not C++ code. No problem. Add in your code this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import hotshot&lt;br /&gt;prof = hotshot.Profile("profile.hotspot")&lt;br /&gt;prof.runcall(myFunction)&lt;br /&gt;prof.close()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And then, at the shell:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sudo apt-get install kcachegrind-converters&lt;br /&gt;hotspot2calltree -o profile.callgrind profile.hotspot&lt;br /&gt;kcachegrind profile.callgrind&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And now you get a nice kcachegrind profile you can navigate on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-2130113029708339587?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/2130113029708339587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=2130113029708339587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/2130113029708339587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/2130113029708339587'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/03/command-of-day-hotspot2calltree.html' title='Command of the day: hotspot2calltree'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-6483721114622565834</id><published>2008-03-05T16:33:00.000-08:00</published><updated>2009-06-01T06:19:50.801-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='gsoc'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Preparing for GSoC 2008</title><content type='html'>&lt;p&gt;&lt;a href='http://code.google.com/soc/2008/'&gt;GSoC 2008&lt;/a&gt; is already here! We are preparing our submision for &lt;a href='http://clam.iua.upf.edu'&gt;CLAM&lt;/a&gt; as organization and I hope we are as lucky as last year. For GSoC 2007 we got 6 fervent students who pushed CLAM a big step forward. We still don't know whether we will be selected as organization or not. We haven't even filled the submision data. But it is time to trigger some resorts. So, what to do now?&lt;br /&gt;&lt;p&gt;If you are an experienced CLAM developer, please consider becoming a mentor. The more mentors the more students we can cope with.&lt;br /&gt;&lt;p&gt;If you are a user, is the time to push your favourite feature into the &lt;a href="http://clam.iua.upf.edu/wikis/clam/index.php/SoC_ideas"&gt;GSoC project proposals&lt;/a&gt;.&lt;br /&gt;&lt;p&gt;If you are an student wanting to be part of the program, I advice you to &lt;a  href="http://clam.iua.upf.edu/wikis/clam/index.php/Devel#Getting_involved"&gt;get involved&lt;/a&gt; with the project from now as we will consider early involvement a big plus for eligibility.&lt;br /&gt;&lt;p&gt;If you are Xavi, Pau or myself, then you should fill CLAM submision instead of blogging ;-)&lt;br /&gt;&lt;p&gt;I love summer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-6483721114622565834?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/6483721114622565834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=6483721114622565834' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/6483721114622565834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/6483721114622565834'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/03/preparing-for-gsoc-2008.html' title='Preparing for GSoC 2008'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-452460113905826338</id><published>2008-02-10T18:05:00.000-08:00</published><updated>2008-02-10T20:02:11.935-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wiko'/><category scheme='http://www.blogger.com/atom/ns#' term='command-of-the-day'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>Comand of the day: kig</title><content type='html'>Each task has a tool. With graphics and figures too. If i want to edit a photograph or to perform some nice effects on an existing image, that's a task for &lt;a href='http://www.gimp.org'&gt;Gimp&lt;/a&gt;. If I need some cute artwork for icons, banners, web... I prefer to vector with my so loved &lt;a href='http://www.inkscape.org'&gt;Inkscape&lt;/a&gt;. When such drawings are not so artistical and need some related and formal figures and diagrams, i normally consider &lt;a href='http://www.gnome.org/projects/dia/'&gt;dia&lt;/a&gt;, limited but correct. If i want to plot a complex graph i let the task to &lt;a href="http://www.graphviz.org/"&gt;graphviz's dot&lt;/a&gt; and i just &lt;a href="http://www.iua.upf.es/~dgarcia/Codders/DotUmlUseCases.html"&gt;declare the vertexs&lt;/a&gt;. If I want to plot some program data output,  &lt;a href="http://www.python.org"&gt;python&lt;/a&gt; plus &lt;a href='http://matplotlib.sourceforge.net/'&gt;matplotlib&lt;/a&gt; is the faster way to process and render it. Automating execution to visualization process is very convenient. Some time ago I used &lt;a href="http://www.gnuplot.info/"&gt;gnuplot&lt;/a&gt; for that but python is more flexible towards data formats. Often what you need is to explore such data, interactive visualization can be revealing with tools such as &lt;a href="http://soft.proindependent.com/qtiplot.html"&gt;qtiplot&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But my problem today wasn't none of the above but drawing some geometric diagrams (angles, vectors, tangents...) to illustrate some trigonometric equations. I was thinking on &lt;a href="http://www.qcad.org/"&gt;QCad&lt;/a&gt; but &lt;a href="http://edu.kde.org/kig/"&gt;Kig&lt;/a&gt; did perfectly. Kig is about doing geometrical manipulation: intersections, angle transportation, angle mesurements, solidarized elements, &lt;a href="http://edu.kde.org/kig/manual/scripting-api/"&gt;python scripting&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;&lt;img  src="http://upload.wikimedia.org/wikipedia/en/thumb/1/1e/Kig-screenshot.png/250px-Kig-screenshot.png"/&gt;&lt;br /&gt;&lt;br /&gt;I was to integrate kig png exporting into &lt;a href="http://wiko.sourceforge.net"&gt;WiKo&lt;/a&gt; figure generation but i found two show-stoper problems: Command line options for batch exporting seems not to work and there is no way to control the viewport but by resizing the windows and controlling the zoom. While the concept of limited size canvas exists, I didn't find a way to resize it :-( Anyway is worth to dig in such a tool even doing patches to have batch exporting working.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-452460113905826338?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/452460113905826338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=452460113905826338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/452460113905826338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/452460113905826338'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/02/comand-of-day-kig.html' title='Comand of the day: kig'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-1309122215938562131</id><published>2008-01-31T09:50:00.000-08:00</published><updated>2008-01-31T09:52:11.098-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Impressions on Django (II): Development environment</title><content type='html'>&lt;p&gt; &lt;img style='float:right; padding:1ex' src="http://media.djangoproject.com/img/site/hdr_logo.gif" /&gt; On my previous post, I explained some basic ideas on how Django works.  The post explained, mostly the programming model which is a clever implementation of the classical &lt;a href='http://en.wikipedia.org/wiki/Model-view-controller'&gt;Model-View-Controller pattern&lt;/a&gt;.  Not that new.  But compared to other web development environments I worked with (&lt;a href='http://www.php.net'&gt;PHP&lt;/a&gt;, &lt;a href='http://www.zope.org'&gt;Zope&lt;/a&gt;/&lt;a href='http://www.plone.org'&gt;Plone&lt;/a&gt; or plain &lt;a href='http://www.modpython.org'&gt;mod_python&lt;/a&gt;), Django is a clear improvement because is both simple and pragmatical.  &lt;/p&gt; &lt;p&gt; The programming model is something that has a direct impact on how you design the product, but there are other factors that determine how easy a developer can develop within a platform.  In this post I arge about such factors, how Django afects the development workflow.  &lt;/p&gt; &lt;h2 id='toc_7'&gt;Editing and controlling source code&lt;/h2&gt; &lt;p&gt; Compared to &lt;a href='http://www.zope.org'&gt;Zope&lt;/a&gt;, another python web application environment I've been fighting against, Django is a clear step forward to control your work.  &lt;/p&gt; &lt;p&gt; First of all, the developer has the control of the source.  Files are stored on the file system!  It may seem an obvious assertion, but, if you have been using Zope you will know why I am so happy with that: Zope forces you to store all the code into a large binary file which acts as virtual filesystem.  You cannot use a regular version control system such subversion to control your changes.  ...and worst, it forces you to input code in web forms!! Argh!!  Django ends with such a nightmare.  Files are back to the file system and to your preferred editor.  &lt;/p&gt; &lt;h2 id='toc_8'&gt;Modularity&lt;/h2&gt; &lt;p&gt; Still Django applications are modular in the same sense that Zope: you can combine several applications (modules) on a single site.  For example, the administration interface is an application itself that can be used to edit any model of any installed application.  You can disable it or enable it as a whole or for specific models.  There is also an authentication application that can be used to transversally control the access to your application features.  Every other application can use the authentication application to obtain information about validated users and to limit the access to certain features depending on the user profile.  Session management and per-session storage, RSS feeds, SiteMap files, data mining interface...  they all come for free, provided as applications.  Besides the &lt;a href='http://www.djangoproject.com/documentation/add_ons/'&gt;included applications&lt;/a&gt;, a nice &lt;a href='http://djangoapps.org/'&gt;application repository&lt;/a&gt; is available.  &lt;/p&gt; &lt;h2 id='toc_9'&gt;Debug cycle and exploration&lt;/h2&gt; &lt;p&gt; Debugging your code is also very straight forward.  While developing with Django, you are deploying a development Web Server not related to Apache, that you start from the console, and it is not visible from the outside.  This enables each developer having her own instance of the web site.  No administration passwords are needed and reloading is easier.  Every message you &lt;em&gt;print&lt;/em&gt; you'll get it in the console so it is ideal for debugging by tracing compared to using plain mod_python which runs on the apache server and you are to monitor the apache error log.  Also, when some code fails with an exception, Django constructs a very handy web page with a lot of information: the back-trace enriched with code context, parameters and local variables inspection, all the environment values, the request values...  All that available in a collapsible error web page.  Lately I've been tempted of importing a failing python code into Django just to get such a big amount of information.  &lt;/p&gt; &lt;p&gt; Also by running './manage.py shell' you get a python shell executed in the same conditions your code will be.  Indeed the 'manage.py' script has very useful subcommands to infer model definitions from existing databases, to see database definitions from models, to import and export test data fixtures...  &lt;/p&gt; &lt;h2 id='toc_10'&gt;The next post&lt;/h2&gt; &lt;p&gt; So yes, Django is a mod_python with gears and a Zope without the fat.  However, while I don't regret choosing Django, it is not that perfect.  On my next post, the last one on those first impressions on Django series, I will explain the problems we found while using the framework.  The limitations we found and how it could be (is being) improved.  &lt;/p&gt; &lt;p&gt; Well, maybe not the next post.  Some other topics have appeared while writing this series of posts and they are likely to require an entry.  &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-1309122215938562131?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/1309122215938562131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=1309122215938562131' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1309122215938562131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1309122215938562131'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/01/impressions-on-django-ii-development.html' title='Impressions on Django (II): Development environment'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-6977854140892923705</id><published>2008-01-20T15:25:00.000-08:00</published><updated>2008-01-21T08:07:59.689-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Impressions on Django (I)</title><content type='html'>&lt;img style='float:right; padding:1ex' src="http://media.djangoproject.com/img/site/hdr_logo.gif" /&gt; During the last months, I've been involved in a project on (text) information retrieval. The project required to develop a web interface over a python core and we chose &lt;a href='http://www.djangoproject.com/'&gt;Django&lt;/a&gt; as framework.  Other option was using plain &lt;a href='http://www.modpython.org/'&gt;mod_python&lt;/a&gt; as we did for &lt;a href='http://sourceforge.net/projects/efficiencyguard'&gt;EfficiencyGuardian&lt;/a&gt;.  But some time ago,  in the context of the &lt;a href='http://semanticaudio.org/'&gt;SIMAC&lt;/a&gt; project, &lt;a href='http://xev.trastocat.net/blog'&gt;Xavier Oliver&lt;/a&gt;, who was the responsible of implementing &lt;a href='http://simacservices.iua.upf.edu/boca'&gt;BOCA&lt;/a&gt;, CLAM &lt;a href='http://iua-share.upf.edu/wikis/clam/index.php/Music_Annotator'&gt;Annotator&lt;/a&gt;'s collaborative back-end, used Django and he was very enthusiastic on how rapid he had all the web working.  So I wanted to give it a try for our current work.  Here I am posting my first impressions as newbie django user. What Django has to offer?&lt;br /&gt;&lt;h2 id='toc_2'&gt;Database abstraction&lt;/h2&gt;&lt;br /&gt;The most important part of Django is a &lt;a href='http://www.djangoproject.com/documentation/model-api/'&gt;persistent object model&lt;/a&gt; which maps python objects into database entities giving you a nice abstraction on the database layer.  By defining such model classes, you get an &lt;a href='http://www.djangoproject.com/documentation/db-api/'&gt;object oriented programming interface&lt;/a&gt; to query and change related database tables, and even navigating and joining through relations as they were regular connected objects.&lt;br /&gt;&lt;br /&gt;I normally dislike too transparent interfaces when they deal with efficiency sensible things such as database access.  But Django states very clearly when and how such access is done allowing you to control it but using a &lt;a href='http://www.djangoproject.com/documentation/transactions/'&gt;high level object oriented idiom&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2 id='toc_3'&gt;Administration interface&lt;/h2&gt;&lt;br /&gt;You can enable an existing administration module for your site.  That is a web interface to create, edit and remove your model objects.  You can control the way they are edited by adding extra properties to the model classes attributes.&lt;br /&gt;&lt;br /&gt;Attributes have more types than real SQL types.  Fields can be, for example, URL's, emails, telephone numbers or zip codes, and Django gives you for free custom validation and custom administration interfaces for them.&lt;br /&gt;&lt;br /&gt;The administration interface also considers table relations providing, for instance, web interfaces for choosing related objects by foreign key and buttons to add a new related objects.&lt;br /&gt;&lt;br /&gt;&lt;h2 id='toc_4'&gt;Application logic&lt;/h2&gt;&lt;br /&gt;Often, as in our case, the administration interface is pretty close to what the final application will be. But direct manipulation of a model is not enough for most web applications.  Normally you need some additional application logic: Which functionalities are presented to the user, and which is the user dialog with the system to perform such functionalities.&lt;br /&gt;&lt;br /&gt;Three elements are combined to build up such application logic in Django: URL mappings, views and page templates.  URL mappings map regular expressions of requesting URL into calls to python functions.  Such pỳthon functions are the &lt;em&gt;views&lt;/em&gt; which perform the needed actions on the system and construct an output web page.  Views usually inject python data into an HTML skeleton, the page template, to generate the response web page.&lt;br /&gt;&lt;br /&gt;Django provides some convenience views to create, update, delete and listing model objects, also supporting common features such as pagination, date based browsing, validation and destructive action confirmation.&lt;br /&gt;&lt;br /&gt;&lt;h2 id='toc_5'&gt;The next entry&lt;/h2&gt;&lt;br /&gt;Here i explained the basics of Django execution model.  On the next entry i'll write some impressions on Django as development environment compared to other environments i used for web development such as Zope, mod_python and vanilla PHP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-6977854140892923705?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/6977854140892923705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=6977854140892923705' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/6977854140892923705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/6977854140892923705'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/01/impressions-on-django-i.html' title='Impressions on Django (I)'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-4330561551899764060</id><published>2008-01-19T04:35:00.000-08:00</published><updated>2008-01-19T06:30:05.033-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='gpl'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>Qt 3 and Qt4 relicensed as GPL v3</title><content type='html'>&lt;img style='float:right; padding: 1ex;' width='100px' src="http://trolltech.com/images/products/qt/qtlogo/image_preview"/&gt; I read in &lt;a href="http://labs.trolltech.com/blogs/2008/01/19/qt-3-and-4-licensed-under-gplv3/"&gt;Thiago Maceira's blog&lt;/a&gt; that &lt;a href="http://www.trolltech.com"&gt;Trolls&lt;/a&gt; have relicensed Qt3 and Qt4 as &lt;a href="http://gplv3.fsf.org/"&gt;GPL v3&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I still had no time to &lt;a href="http://www.gnu.org/licenses/gpl-faq.html#AllCompatibility"&gt;analyze&lt;/a&gt; how this will affect &lt;a href="http://clam.iua.upf.edu"&gt;clam&lt;/a&gt;. Relicensing CLAM has proven to be a hard political and burocratic problem, but a transition from GPL v2 to GPL v3 is easier since we have the 'or later' notice, so we have the door open to that &lt;a href="http://news.softpedia.com/news/Linus-Torvalds-Says-No-To-GPLv3-75766.shtml"&gt;controversial upgrade&lt;/a&gt;. Definitely, trolls' move to v3 is something that will boost the &lt;a href="http://www.news.com/8301-10784_3-9764119-7.html?part=rss&amp;subj=news&amp;tag=2547-1_3-0-20"&gt;adoption scene&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A nice lateral consequence of this affects directly to one CLAM application, &lt;a href="http://iua-share.upf.es/wikis/clam/index.php/SMSTools_tutorial"&gt;SMSTools&lt;/a&gt;, which still uses Qt3, and not Qt4 (althought Zack Welch started a temptative Qt4 port). Until now, Qt3 didn't enjoyed the same nice dual licensing Qt4 has. Former Qt3 licensing was a modified GPL that had problems on using Qt3 for non-unix platforms such as windows. So with Qt3 relicensing we can now freely distribute SMSTools precompiled binaries for Windows.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; I read in the &lt;a href='http://trolltech.com/company/newsroom/announcements/press.2008-01-18.1601592972'&gt;official announcement&lt;/a&gt; that they didn't droped GPLv2, they just added a third license to the existing &lt;a href="http://en.wikipedia.org/wiki/Dual_license"&gt;dual licensing&lt;/a&gt; so you can use one of three licensing schemes: &lt;a href='http://trolltech.com/products/qt/licenses/licensing/qtlicensing'&gt;non-free&lt;/a&gt;, &lt;a href="http://www.gnu.org/licenses/gpl-2.0.html"&gt;GPLv2&lt;/a&gt; and &lt;a href="http://www.gnu.org/licenses/gpl-3.0.html"&gt;GPLv3&lt;/a&gt;. Definitely they want to make developers live easier, not just by building excellent API's.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-4330561551899764060?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/4330561551899764060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=4330561551899764060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4330561551899764060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4330561551899764060'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/01/qt-3-and-qt4-relicensed-as-gpl-v3.html' title='Qt 3 and Qt4 relicensed as GPL v3'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-3521171617616538633</id><published>2008-01-18T10:03:00.000-08:00</published><updated>2008-01-18T11:35:15.970-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wiko'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='bibtex'/><title type='text'>BiBTeX Tooltip in html WiKo output</title><content type='html'>&lt;img height="300px" style='float:right' src="http://www.iua.upf.edu/~dgarcia/wiko/screenshots/wiko-bibtex-tooltip.png"/&gt;I was busy yesterday on providing better &lt;a href="http://en.wikipedia.org/wiki/Bibtex"&gt;BiBTeX&lt;/a&gt; support for the HTML output in &lt;a href='http://wiko.sourceforge.net'&gt;WiKo&lt;/a&gt;. I was adding bibliography tooltips. They were an original suggestion from Pau Arumi, and i agree with him that they will be very handy for reading an article in electronic format. The former html bibliography page is still available: just click instead of hovering.&lt;br /&gt;&lt;br /&gt;To have it working, you should download the latest wiko version, install 'python-bibtex' debian/ubuntu package and appending to your css style sheet the latest statements of &lt;a href="https://wiko.svn.sourceforge.net/svnroot/wiko/wiko/style.css"&gt;this css&lt;/a&gt; concerning 'bibref' class.&lt;br /&gt;&lt;br /&gt;Then, just place any bibtex files on the same folder the wiki files are and refer a bibliography entry in the wiki files as '@cite:SomeBibtexId'. By 'WiKonpiling' you'll get both normal LaTeX bibliography and this html equivalent.&lt;br /&gt;&lt;br /&gt;Take a look on the final feel at this &lt;a href="http://ocata48124.upf.es/~vokimon/masterThesis-dgarcia/AudioApplications.html"&gt;chapter of my master thesis&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-3521171617616538633?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/3521171617616538633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=3521171617616538633' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3521171617616538633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3521171617616538633'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2008/01/bibtex-tooltip-in-html-wiko-output.html' title='BiBTeX Tooltip in html WiKo output'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-4101449407828912733</id><published>2007-12-15T10:16:00.000-08:00</published><updated>2007-12-15T10:50:51.780-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Iterating properly in Python</title><content type='html'>After more than a year of python hacking you take a look at the official Python tutorial and still discover new ways of enhancing your code. Just two ways of saving list constructions on our actual code.&lt;p&gt;The first one: In our code, we are currently doing all the time something like this:&lt;pre class='python'&gt;&lt;br /&gt;for key, value in myDictionary.items() :&lt;br /&gt;        doWhatEverWit(key,value)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This is not that appropiate because it creates the tuple list and then iterates. But if you do:&lt;pre class='python'&gt;&lt;br /&gt;for key, value in myDictionary.iteritems() :&lt;br /&gt;        doWhatEverWit(key,value)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You just get fetched keys and values without creating any temporary list.&lt;p&gt;The other thing our code is full of is constructing a list using &lt;a href='http://docs.python.org/tut/node7.html#SECTION007140000000000000000'&gt;list comprehensions&lt;/a&gt;:&lt;pre class='python'&gt;&lt;br /&gt;tempList = [expresionUsing(item) for item in collection]&lt;br /&gt;for item in tempList: doWhatEverWith(item)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I knew about list comprehensions and i knew about &lt;a href='http://docs.python.org/tut/node11.html#SECTION00111000000000000000000'&gt;generator functions&lt;/a&gt;. Generator functions are functions can be a iteration source by doing &lt;tt&gt;yield&lt;/tt&gt; instead of &lt;tt&gt;return&lt;/tt&gt;. &lt;tt&gt;yield&lt;/tt&gt; returns a value but keeps the function execution state for the next call. That is a very interesting feature but i never used it because it is harder to create a function that yields than to create the loop itself.&lt;p&gt;But by reading the tutorial i found a brand new kind of expressions that sum up list comprehensions and generator functions: &lt;a href='http://docs.python.org/tut/node11.html#SECTION00111100000000000000000'&gt;generator expressions&lt;/a&gt;. They have the same syntax than list comprehensions using parethesis instead of brackets, but instead of creating a list they create a source of iteration so that no temp lists are created. Previous code would look like that:&lt;pre class='python'&gt;&lt;br /&gt;iterable = (expresionUsing(item) for item in collection)&lt;br /&gt;for item in iterable: doWhatEverWith(item)&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;There are plenty of places in the code we generated last year (&lt;a href='http://wiko.sourceforge.net'&gt;WiKo&lt;/a&gt;, &lt;a href='http://www.iua.upf.es/~parumi/testfarm'&gt;TestFarm&lt;/a&gt; and build and utility scripts in &lt;a href='http://clam.iua.upf.edu'&gt;CLAM&lt;/a&gt; where we can apply those two ideas. So i am pretty happy on having discovered that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-4101449407828912733?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/4101449407828912733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=4101449407828912733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4101449407828912733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4101449407828912733'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/12/iterating-properly-in-python.html' title='Iterating properly in Python'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-1222704260904840628</id><published>2007-12-06T09:06:00.000-08:00</published><updated>2007-12-06T09:30:57.116-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='command-of-the-day'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Command of the day: svk ls</title><content type='html'>&lt;p&gt; Why not calling them command-of-the-year as the one and only &lt;a href='http://vokicodder.blogspot.com/2006/12/command-of-day-convmv.html'&gt;command-of-the-day&lt;/a&gt; i posted until now was posted one year ago?  Well, they are intended to be commands that saved me the day like the one i explain today.  &lt;/p&gt; &lt;p&gt; On my &lt;a href='http://vokicodder.blogspot.com/2007/12/wiko-wiki-compiler.html'&gt;previous entry&lt;/a&gt;, I explained that Pau and me were publishing on sourceforge a python script, &lt;a href='http://wiko.sourceforge.net'&gt;WiKo&lt;/a&gt;, that we used to edit our latest articles and thesis.  Because we used it in such context, latest version have been commited in a private repository we have for articles and the like.  &lt;/p&gt; &lt;p&gt; I wanted to move the files to a public repository at &lt;a href='http://sourceforge.net'&gt;sourceforge&lt;/a&gt;.  Sadly, &lt;em&gt;svnadmin dump&lt;/em&gt; just works when you are in the same host as the repository is and we have no regular ssh access to the subversion.  We could bother our admin, &lt;a href='http://www.terraquis.net/'&gt;Jordi Funollet&lt;/a&gt;, but he is always very busy and we are always requesting him.  (Thanks, Jordi for your support!!) &lt;/p&gt; &lt;p&gt; Luckily i found a nice entry blog on how to &lt;a href='http://moelhave.dk/2006/07/remote-mirroring-a-subversion-svn-repository/'&gt;use svk to remotely dump a svn repository&lt;/a&gt;.  &lt;/p&gt; &lt;p&gt; You need to install svk, in debian based: &lt;pre&gt; sudo apt-get install svk &lt;/pre&gt; &lt;/p&gt; &lt;p&gt; Then we should create a mirror repository with svk just containing the revisions concerning the selected path &lt;pre&gt; svk ls svn+ssh://username@svn.myserver.com/path/to/repo/sub/path/to/wiko &lt;/pre&gt; &lt;/p&gt; &lt;p&gt; svk will ask you several questions: &lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;em&gt;Choose a base URI to mirror from (press enter to use the full URI):&lt;/em&gt; To filter by path, i recommend to do such filtering on the command line by specifying the full path, so return.&lt;/li&gt; &lt;li&gt; &lt;em&gt;Depot path: [//mirror/wiko]&lt;/em&gt; Is very important here to change the depot name so you can skip that '//mirror' part, so answer &lt;em&gt;//yourproject&lt;/em&gt; &lt;b&gt;beginning with a double slash!!&lt;/b&gt;&lt;/li&gt; &lt;li&gt; To end up, it asks which revisions do you want, normally the answer is 'a' (all)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt; Then dump the local svk repository: &lt;pre&gt; svnadmin dump ~/.svk/local &amp;gt; my-repository-dump &lt;/pre&gt; &lt;/p&gt; &lt;p&gt; And now you can import it into sourceforge as normal: &lt;pre&gt; svnadmin load [the-new-repository]  &amp;lt; my-reposotory-dump &lt;/pre&gt; &lt;/p&gt; &lt;p&gt; With sourceforge the process is more complex.  You should upload the dumpfile to the shell server.  For example, for wiko it was at: sftp://wiko.sourceforge.net/home/groups/w/wi/wiko/ &lt;/p&gt; &lt;p&gt; Then you should specify the uploaded dump file as it was a cvs to svn migration.  It last a while, after that you can checkout wiko code!  &lt;pre&gt; svn co https://wiko.svn.sourceforge.net/svnroot/wiko/wiko &lt;/pre&gt; &lt;/p&gt; &lt;p&gt; I lost the history of the file before a move operation, but at least we recovered some of the history.  &lt;/p&gt; &lt;p&gt; Taking a look at the man page you can see that svk is really helpfull for other purposes, but definitely, its ability of dumping a remote repository saved my day :-) &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-1222704260904840628?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/1222704260904840628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=1222704260904840628' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1222704260904840628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1222704260904840628'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/12/command-of-day-svk-ls.html' title='Command of the day: svk ls'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-1287704562623304898</id><published>2007-12-06T08:06:00.000-08:00</published><updated>2008-01-19T05:57:59.808-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><category scheme='http://www.blogger.com/atom/ns#' term='wiko'/><category scheme='http://www.blogger.com/atom/ns#' term='wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><category scheme='http://www.blogger.com/atom/ns#' term='metablog'/><title type='text'>WiKo, the wiki compiler</title><content type='html'>&lt;p&gt;&lt;img style='float:left;padding: 1ex;' src="http://www.iua.upf.edu/~dgarcia/wiko/wikologo.png"/&gt;&lt;a href='http://parumi.wordpress.com/'&gt;Pau&lt;/a&gt; and me have just released &lt;a href='http://wiko.sourceforge.net'&gt;WiKo&lt;/a&gt; as &lt;a href="http://sourceforge.net"&gt;sourceforge&lt;/a&gt; &lt;a href='http://sf.net/projects/wiko'&gt;project&lt;/a&gt;. &lt;a href='http://wiko.sourceforge.net'&gt;WiKo&lt;/a&gt; is a simple but powerful &lt;a href='http://www.python.org'&gt;Python&lt;/a&gt; script that takes files with &lt;b&gt;wiki&lt;/b&gt; content on a given directory and either builds a web, a LaTeX article or a blog.&lt;/p&gt;&lt;p&gt;The script has a very long history before being branded as WiKo.  It has its roots on the simple script i did to build most of my websites (&lt;a href='http://www.iua.upf.edu/~dgarcia'&gt;Can Voki&lt;/a&gt;, &lt;a href='http://www.iua.upf.edu/~dgarcia/Codders'&gt;Codders&lt;/a&gt;, &lt;a href='http://www.iua.upf.edu/~dgarcia/KKEP'&gt;KKEPerians UNLTD&lt;/a&gt;...) The script eased keeping static a lot of pages sharing the same layout design.  The script was later enhanced to read wiki pages and to build also LaTeX articles.  Even I used it for my &lt;a href='http://www.iua.upf.edu/~dgarcia/masterThesis'&gt;master thesis&lt;/a&gt;. Recently &lt;a href='http://www.parumi.org'&gt;Pau&lt;/a&gt; also started to use it for his PhD thesis and he has added great improvements such as LaTeX formulas in HTML output or bibliography linking. And lately we started to use it as internal wiki for some projects we are involved within &lt;a href='http://www.barcelonamedia.org'&gt;Barcelona Media&lt;/a&gt;.  So we thought that such script deserved a sourceforge project, and that's how WiKo born. I hope it can be useful to you all.&lt;/p&gt;&lt;p&gt;WiKo might be useful to you if:&lt;/p&gt;&lt;ul&gt;&lt;li&gt; You have an static website and you are considering to make it dynamic just to reuse design&lt;/li&gt;&lt;li&gt; You have to write articles to be available in both html and pdf&lt;/li&gt;&lt;li&gt; You are moving content from web, to LaTeX articles and to blogs and you are feed up of translating markup&lt;/li&gt;&lt;li&gt; You love wiki syntax but you hate to edit wikis in web forms&lt;/li&gt;&lt;li&gt; You like LaTeX output but you hate (or don't know) its markup&lt;/li&gt;&lt;li&gt; You like colaborative environments such subversion and want to use it as base for a wiki&lt;/li&gt;&lt;li&gt; You still are considering &lt;a href='http://ikiwiki.info/'&gt;ikiwiki&lt;/a&gt; but you would like it was not written in Perl so you could contribute to it ;-)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Also I am currently working hard on being able to use WiKo to edit this blog.  I am almost there so stay tunned.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-1287704562623304898?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/1287704562623304898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=1287704562623304898' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1287704562623304898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1287704562623304898'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/12/wiko-wiki-compiler.html' title='WiKo, the wiki compiler'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-4821343522325239933</id><published>2007-11-06T09:55:00.000-08:00</published><updated>2007-11-06T10:10:56.544-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='conferences'/><title type='text'>Trolltech Developers Day</title><content type='html'>&lt;p&gt; On my last entry I talked about the trip to San Francisco.  Besides the GSoC mentor submit, we also joined the &lt;a href='http://trolltech.com/'&gt;Trolltech&lt;/a&gt; &lt;a href='http://trolltech.com/company/newsroom/events/allevents/devdays2007/overview/'&gt;developers days&lt;/a&gt;.  The &lt;a href='http://labs.trolltech.com/page/Projects/DevDays/DevDays2007'&gt;slides and examples of the Trolltech event&lt;/a&gt; are available online.  It is worth to take a look at them although slides are not as nice as having some trolls explaining them in live.&lt;/p&gt;&lt;img src='http://labs.trolltech.com/blogs/wp-content/uploads/2007/10/ddm01.jpg'/&gt;&lt;p&gt;  We really learned a lot of such event: &lt;a href='http://labs.trolltech.com/blogs/author/andreas/'&gt;Andreas Aardal Hansen&lt;/a&gt;, a very smart hacker, gave us a nice lesson on how we could exploit the &lt;a href='http://doc.trolltech.com/latest/graphicsview.html'&gt;Graphics View framework&lt;/a&gt; to turn &lt;a href='http://clam.iua.upf.edu'&gt;CLAM&lt;/a&gt; into a cooler environment.  The framework has been massively adopted in just one year since it was published, and the reason is that it is just impressive how easy you can do &lt;a href='http://labs.trolltech.com/page/Graphics/About/Dojo'&gt;complex and cute things&lt;/a&gt; on a snap. The reason why we didn't used it is because we did the full rewrite of the NetworkEditor just before Qt 4.2 which included such framework. Another rewrite at that time would have been too hard.&lt;/p&gt; &lt;p&gt; We also could have a little talk with Thierry Bastian who is responsible of turning KDE's &lt;a href='http://phonon.kde.org/'&gt;Phonon&lt;/a&gt; multimedia interface into a regular cross platform module in Qt.  Unfortunately we were still travelling the first day and we missed his talk on Phonon.  &lt;/p&gt; &lt;p&gt; Another nice session I assisted was the one presented by Girish Ramakrishnan on Qt style sheet support.  Just by taking a look at the latest demos you can realize that Qt application can be very cool and even use such style sheets to let designers enhancing the look and feel of your applications without even programming.  &lt;/p&gt; &lt;p&gt; While I was on the style sheet presentation Pau was on the &lt;a href='http://doc.trolltech.com/4.3/model-view-programming.html'&gt;Model View&lt;/a&gt; talk.  I thought that it was about the old Smalltalk MVC model we failed to generalize in CLAM so many times and in so many flawors.  So I thought it was a mistake on the troll's side to generalized it so much, but I just took a look at the presentation, and maybe is worth a try.  It seems that they did a smart twist to the pattern to make it worth to work with.  &lt;/p&gt; &lt;p&gt; I also nagged Jason Barron, at the support team, with some bugs we found on latest Qt version and some question on how to implement some things for CLAM.  I still have to get in contact with him again to get some solution for some problems.  &lt;/p&gt; &lt;p&gt; As I said we learned a lot, and we are eager to apply such knowledge to CLAM.  A month later we have just applied such knowledge to fix some QtOpenGL bugs but we are planning at some time to port the NetworkCanvas to &lt;a href='http://doc.trolltech.com/latest/graphicsview.html'&gt;QGraphicsView&lt;/a&gt;.  &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-4821343522325239933?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/4821343522325239933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=4821343522325239933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4821343522325239933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4821343522325239933'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/11/trolltech-developers-day.html' title='Trolltech Developers Day'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-4846702429227431300</id><published>2007-10-29T13:57:00.000-07:00</published><updated>2007-10-29T14:23:15.704-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='multiplatform'/><category scheme='http://www.blogger.com/atom/ns#' term='gsoc'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='conferences'/><title type='text'>GSoC 2007 mentor submit</title><content type='html'>A couple of weeks ago, Pau and me were at San Francisco for the &lt;a href='http://code.google.com/soc/2007/'&gt;Google Summer of Code&lt;/a&gt; Mentor Submit. At the submit we joined some interesting sessions on how to improve the next GSoC, but also we met a lot of other hackers of free software projects all around the world: &lt;a href='http://mixxx.sourceforge.net'&gt;Mixxx&lt;/a&gt;, &lt;a href='http://www.inkscape.org/'&gt;Inkscape&lt;/a&gt;, &lt;a href='http://www.kde.org'&gt;KDE&lt;/a&gt;, &lt;a href='http://amarok.kde.org/'&gt;Amarok&lt;/a&gt;, &lt;a href='http://www.pidgin.im'&gt;Pidgin&lt;/a&gt;, &lt;a href='http://www.scummvm.org/'&gt;Scumvm&lt;/a&gt;, &lt;a href='http://haiku-os.org'&gt;Haiku&lt;/a&gt;, &lt;a href='http://www.crystalspace3d.org/'&gt;Crystal Space&lt;/a&gt;, &lt;a href='http://www.ogre3d.org/'&gt;Ogre&lt;/a&gt;, &lt;a href='http://moinmoin.wikiwikiweb.de/'&gt;Moin Moin&lt;/a&gt;, &lt;a href='http://drupal.org'&gt;Drupal&lt;/a&gt;, &lt;a href='http://www.videolan.org'&gt;VideoLan&lt;/a&gt;, &lt;a href='http://wiki.xmms2.xmms.se/'&gt;XMMS2&lt;/a&gt;, &lt;a href='http://audacious-media-player.org/'&gt;audacious&lt;/a&gt;... Well, as you can see in this picture we were pretty much people:&lt;br /&gt;&lt;br /&gt;&lt;img src='http://daniel.haxx.se/rockbox/GSoC2007MentorSummitStairs-MarkedUp.jpg' alt='Family photo of GSoC 2007 mentors' width='100%'/&gt;&lt;br /&gt;&lt;br /&gt;I knew about most of all other projects, but, sadly, nearly no one knew about CLAM. :-( The good news is that most of them get pretty interested as they saw CLAM capabilities on audio processing and application prototyping. We need independently packaged end user tools!!&lt;br /&gt;&lt;br /&gt;I also was glad to confirm the collaboration between projects that one could figure out being competitors:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; People working on desktops (&lt;a href='http://www.kde.org'&gt;KDE&lt;/a&gt;, &lt;a href='http://www.gnome.org'&gt;Gnome&lt;/a&gt;...) are in fact in a very close collaboration.&lt;/li&gt;&lt;li&gt; Wiki implementations (Moin Moin, Wikimedia...) meet there&lt;/li&gt;&lt;li&gt; Also several 3D engines (Crystal Space, Ogre...) met there&lt;/li&gt;&lt;li&gt; Comunity portals such as Drupal, Joomla, Plone...&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;They all share common challenges and solutions and they used the submit to join efforts.&lt;br /&gt;&lt;br /&gt;Related to common issues and efforts, we took a very productive meeting on multiplatform development where some multiplatform projects, including us, shared experiences. We explained how we faced such problem at CLAM: the use of portable 3rd party libraries, &lt;a href="http://vokicodder.blogspot.com/2007/07/deprecating-windows-as-development.html"&gt;crosscompiling&lt;/a&gt; from Linux to other platforms, and the use of &lt;a href="http://testfarm.sourceforge.net"&gt;testfarm&lt;/a&gt; to rapidly detect multiplatform issues. Some projects, such VideoLan had automated third party compilation scripts a step we have not automated at all. We realized that a lot of people was also solving such problems and we compromised to share experiences and results. For example, we talked about having a single repository of precompiled binaries of third party libraries. We also realized about our not-so-open-source mind we most of us realized that we were not reporting back patches we did to external libraries. We compromised to send them to upstream or making them available in a common place for the other project using them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-4846702429227431300?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/4846702429227431300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=4846702429227431300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4846702429227431300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/4846702429227431300'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/10/gsoc-2007-mentor-submit.html' title='GSoC 2007 mentor submit'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-8207308771074649324</id><published>2007-07-20T11:10:00.000-07:00</published><updated>2009-06-01T06:04:52.417-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='spectrum'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>Simplifying Spectral processing in CLAM</title><content type='html'>Current &lt;a href="http://clam.iua.upf.edu"&gt;CLAM&lt;/a&gt; &lt;a href='http://clam.iua.upf.edu/doc/CLAM-doxygen/classCLAM_1_1Spectrum.html'&gt;Spectrum&lt;/a&gt; implementation has four different internal representations: Complex array, polar array, separated magnitude and phase buffers, and separated magnitude and phase break point functions (point controled envelopes). Conversion and synchronization among such representations were handled by the Spectrum class itself and this was intended to be transparent. But processing algorithms had to know which representations were already present to trade off between doing conversion and applying different versions of a given algorithm depending on the representation.&lt;br /&gt;&lt;br /&gt;For instance, spectrum product in polar representation is cheaper by itself than complex product, but if you have to convert incoming or outcomming spectrums it migth be not so cheap. What about having two different representations for each operand? Which one should be converted? Output format could be a discriminant but do the module has information to know which is the convenient output representation? Such decissions make the implemention of processings using spectrums really complex.&lt;br /&gt;&lt;br /&gt;Besides that, algorithms also had to consider different cases for different scales (linear or dB). So the complexity of processing objects having to deal with spectra is very high. A lot of code dealt with querying the presence of a given representation or synchronizing them.&lt;br /&gt;&lt;br /&gt;So, we decided to simplify all that by having several kind of spectrum for each representation and doing any representation change explicit by a converter processing. We are currently considering just two spectrum classes: MagPhaseSpectrum and ComplexSpectrum. We added also converters to the current Spectrum to enable progressive migration. The implementation of FFT and IFFT was highly simplified as we don't need to deal with conversions and prototypes configuration, just to input or output complex spectra.&lt;br /&gt;&lt;br /&gt;This is a setup of a system which perform complex and polar products of two spectra:&lt;br /&gt;&lt;br /&gt;&lt;img width='90%' src='http://iua-share.upf.edu/wikis/clam/images/thumb/5/59/OptimizingSpectral-Setup.png/800px-OptimizingSpectral-Setup.png' /&gt;&lt;br /&gt;&lt;br /&gt;The spectral product has been simplified. Now we have a product for each kind of spectrum in contrast with the previous situation where we had a single module containing implementations for every combinations of inputs.&lt;br /&gt;&lt;br /&gt;Code is really simpler to understand and write this way. After having all that we could do a profiling on comparing which is best, conversions and cheap product or no conversions and expensive product. The option without conversions won but the situation can change on the future depending on the optimizations we could do on the conversion. Having the processing modules factored that way we could change them and doing the benchmark that easy.&lt;br /&gt;&lt;br /&gt;In the process of takin such decission we noticed that some elementary CLAM elements such as the AudioSource, AudioSink and specially AudioMixer were taking too much CPU.&lt;br /&gt;&lt;br /&gt;&lt;img src='http://iua-share.upf.edu/wikis/clam/images/thumb/b/b6/OptimizingSpectral-Before.png/555px-OptimizingSpectral-Before.png' /&gt;&lt;br /&gt;&lt;br /&gt;After fixing that we got a clear profile that highlights which is the proper strategy for spectrum product for our concrete case. Callgrind is a really nice tool:&lt;br /&gt;&lt;br /&gt;&lt;img src='http://iua-share.upf.edu/wikis/clam/images/thumb/f/f6/OptimizingSpectral-After.png/568px-OptimizingSpectral-After.png' /&gt;&lt;br /&gt;&lt;br /&gt;So I hope we can move soon to that new way of doing spectral processing in CLAM but still a lot of code must be updated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-8207308771074649324?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/8207308771074649324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=8207308771074649324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/8207308771074649324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/8207308771074649324'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/07/simplifying-spectral-processing-in-clam.html' title='Simplifying Spectral processing in CLAM'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-6815440394145716359</id><published>2007-07-02T10:16:00.000-07:00</published><updated>2009-06-01T06:04:52.417-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>CLAM Plugins</title><content type='html'>One of the most interesting features of the upcomming CLAM release will be a plugin system that will allow users to add their own processings as a plugin to any CLAM based application.&lt;br /&gt;Just by placing a library on a given folder.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/5/51/ClamPluginInWindows.png" /&gt;&lt;br /&gt;&lt;br /&gt;We provide some cute tutorials on &lt;a href="http://clam.iua.upf.edu/wikis/clam/index.php/Creating_a_minimal_processing_object"&gt;writting simple processings&lt;/a&gt; from scratch, and a &lt;a href="http://clam.iua.upf.edu/wikis/clam/index.php/Building_a_processing_library"&gt;SConstruct&lt;/a&gt; file that will compile and install everything in a given folder as a plugin.&lt;br /&gt;&lt;br /&gt;It has been more easy than we thought as we were frightened by Visual 'mecatxis' and we just dropped it. A &lt;a href="http://iua-share.upf.edu/svn/clam/trunk/CLAM/src/Processing/Plugins/RunTimeProcessingLibraryLoader.cxx"&gt;single class&lt;/a&gt; did the work. There is still some work to do on documenting the registration of the configuration dialogs for the processings and making the Processing Tree of the network editor to populate automatically from the factory content.&lt;br /&gt;&lt;br /&gt;The former can be done very quick by adding the Qt4 configurator as a CLAM library, but we want to provide a more general solution not requiring users linking against Qt4. The later (processing tree population) is something Andreas Calvo is working with. And he is doing nice progresses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-6815440394145716359?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/6815440394145716359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=6815440394145716359' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/6815440394145716359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/6815440394145716359'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/07/clam-plugins.html' title='CLAM Plugins'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-1806878978202284767</id><published>2007-07-02T04:58:00.001-07:00</published><updated>2007-12-16T04:03:05.181-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='mingw'/><category scheme='http://www.blogger.com/atom/ns#' term='multiplatform'/><category scheme='http://www.blogger.com/atom/ns#' term='wine'/><category scheme='http://www.blogger.com/atom/ns#' term='crosscompilation'/><title type='text'>Deprecating Windows as development platform</title><content type='html'>In this entry i will explain how we got ride of Windows as development platform for the CLAM project still providing Windows binaries by using the tandem mingw32 (for Linux) and Wine. We dealt with crosscompilation of most of CLAM dependencies such as Portaudio, Asio, libsndfile, liboggvorbis, pthreads, fftw3, libmad, id3lib, XercesC, libxml++, NSIS and Py2Exe.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/5/5f/MingwWindowsNetEditor.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After a very dissapointing and fustrating effort from &lt;a href="http://parumi.wordpress.com/"&gt;Pau&lt;/a&gt; and me of trying to have a reproducible build environment for &lt;a href="http://clam.iua.upf.edu"&gt;CLAM&lt;/a&gt; based on Visual Express 2005, we decided that the whole thing was foolish and decided give mingw a try.&lt;br /&gt;&lt;br /&gt;I am proud of not having a Windows box available at home ;-) but that doesn't mean i cannot contribute to that part of the development so the last days i did an spike on having &lt;a href="http://www.mingw.org/"&gt;mingw&lt;/a&gt; crosscompiling CLAM from Linux! We succeeded to compile it all, the dependencies, CLAM and the applications. Because some dll conflicts when installing that could not go into the 1.1.0 version of CLAM. After a gutsy update we could compile it all,&lt;br /&gt;so expect rewamped windows binaries for the next release... and maybe development binaries. You can already give a try to the &lt;a href="http://clam.iua.upf.edu/download/win/svnsnapshots/"&gt;latest svn snapshots&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The key point has been using &lt;a href="http://www.winehq.org/"&gt;Wine&lt;/a&gt; to install with their own windows installers some libraries and tools such as &lt;a href="http://trolltech.com/products/qt"&gt;Qt4&lt;/a&gt;, &lt;a href="http://www.gtk.org/"&gt;GTK&lt;/a&gt; (for pkg-config, libxml++ and dependencies), and &lt;a href="http://nsis.sourceforge.net/"&gt;NSIS&lt;/a&gt; to build windows installers from Linux!&lt;br /&gt;&lt;br /&gt;Wine and mingw are a great tandem to compile and test the binaries. Also SConstruct has been a nice tool to hack a quick build environment for third party libraries when the one provided (normally based on autotools) was too messy to get on with.&lt;br /&gt;&lt;br /&gt;We kept a reproducible &lt;a href="http://clam.iua.upf.edu/wikis/clam/index.php/Devel/Windows_MinGW_cross_compile"&gt;log of the mingw crosscompilation&lt;/a&gt; at the clam wiki. This includes how to get all the dependencies working, which may be usefull for you own project. CLAM dependencies we addressed were: Portaudio, Asio, libsndfile, liboggvorbis, pthreads, fftw3, libmad, id3lib, XercesC, libxml++, NSIS and Py2Exe.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-1806878978202284767?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/1806878978202284767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=1806878978202284767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1806878978202284767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/1806878978202284767'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/07/deprecating-windows-as-development.html' title='Deprecating Windows as development platform'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-3868559389262659290</id><published>2007-04-18T14:49:00.000-07:00</published><updated>2009-06-01T06:04:52.418-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='knob'/><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='rosegarden'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='qsynth'/><title type='text'>Enhancing QSynth/Rosegarden/SonicVisualizer knobs for CLAM</title><content type='html'>I am still expanding the widgets toolbox for &lt;a href="http://clam.iua.upf.edu"&gt;CLAM&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/4/43/Qsynth-knobs-shadows1.png"/&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pksampler.sourceforge.net/"&gt;PK Widgets&lt;/a&gt;, the ones in my previos blog entry, are really nice but they don't integrate well with other widgets because the background and the fixed size. So you have to do a mostly PK interface or not. Most standard Qt widgets look nice with a nice theme such plastique, but for some reason QDial is the ugly duck of the collection... well, according &lt;a href="http://www.all-day-breakfast.com/cannam/"&gt;Chris Cannam&lt;/a&gt;, also QLCD. I agree with him. QDial looks like old CDE style in every style you choose:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://doc.trolltech.com/4.2/images/plastique-dial.png"/&gt;&lt;br /&gt;&lt;br /&gt;Besides the look, QDial behaviour is far from optimal. Clicking on any point jumps the pointer which is a bad thing if you want to progressively control a parameter. Also when you move the knob beyond one of the extremes you may switch sharply to the other extreme. Using such a mischievous control in a live performance could be a disaster. So let's look for asthetic and behavioral alternatives.&lt;br /&gt;&lt;br /&gt;Going back to the look, I just liked a lot the knobs in &lt;a href="http://qsynth.sourceforge.net/"&gt;QSynth&lt;/a&gt; a program by &lt;a href="http://www.rncbc.org/drupal/"&gt;Rui Nuno Capella&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://qsynth.sourceforge.net/image/qsynthMainForm1.png"/&gt;&lt;br /&gt;&lt;br /&gt;The knobs indeed were taken from &lt;a href="http://www.rosegardenmusic.com/"&gt;Rosegarden&lt;/a&gt; and Pedro Lopez Cabanillas enhanced the look by adding some nice but expensive gradients. The ones that attracted me.&lt;br /&gt;&lt;br /&gt;I took those widgets with such a long trail and I extended them.&lt;br /&gt;I ported them to Qt4 using QGradients which are faster, and i did some visual improvements: shadows, bumped pointer, configurable colors, angular and linear modes of mouse handling... I added them to the CLAM Widgets plugin and added some configurability so you can change the colors from the designer. And that's how they look now:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/4/43/Qsynth-knobs-shadows1.png"/&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/5/58/Qsynth-knobs-shadows2.png"/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-3868559389262659290?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/3868559389262659290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=3868559389262659290' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3868559389262659290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/3868559389262659290'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/04/enhancing-qsynthrosegardensonicvisualiz.html' title='Enhancing QSynth/Rosegarden/SonicVisualizer knobs for CLAM'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-117614223874732595</id><published>2007-04-09T11:09:00.000-07:00</published><updated>2009-06-01T06:04:52.418-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>PK Widgets integration in CLAM</title><content type='html'>And last but not least, the other important change i added this Easter to CLAM has been integrating &lt;a href="http://www.patrickkidd.com/"&gt;Patrick Kidd&lt;/a&gt;'s PkWidgets. This was a really dormant to-do. A working implemtation was on the 'draft' cvs from 2004.&lt;br /&gt;&lt;br /&gt;On 2004, Patrick &lt;a href="http://lalists.stanford.edu/lad/2004/09/0199.html"&gt;amazed the LAD community&lt;/a&gt; with his nice looking PKSampler. I must confess that I never got PKSampler sounding because a bunch of missing dependencies on Debian/Ubuntu. But, a part from the audio work, the interface was really gorgeous. Something that was not so common on the Linux Audio scene.&lt;br /&gt;&lt;br /&gt;The nice look was mostly due to a clever combination of free technologies: Qt, Python and Povray. Povray rendered 3D widgets with a realistic look, Qt the interface foundation and the resource system and Python to glue it all.&lt;br /&gt;A clever trick allows to load povray images as frames of an interactive animation to render a widget.&lt;br /&gt;&lt;br /&gt;At that time I was starting what is now the Prototyper and I was already messing with designer plugins, i could not stand and I ported some of the Patrick widgets to C++ in order to include them in a Designer plugin.&lt;br /&gt;&lt;br /&gt;I exchanged some mails with him but the code was left on CLAM draft repository... until Saturday. I updated it to Qt4, added some configuration features, merged some of the new pixmaps and i integrated them on the CLAMWidgets plugin. The result, now you can prototype with CLAM interfaces such that one:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/thumb/d/d1/Pkwidgets-fun2.png/800px-Pkwidgets-fun2.png"/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-117614223874732595?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/117614223874732595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=117614223874732595' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/117614223874732595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/117614223874732595'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/04/pk-widgets-integration-in-clam.html' title='PK Widgets integration in CLAM'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36421488.post-117613807226375341</id><published>2007-04-09T10:00:00.000-07:00</published><updated>2009-06-01T06:03:22.012-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clam'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='voice'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='processing'/><title type='text'>Educational Vowel Synth and ControlSurface Widget</title><content type='html'>Some months ago I had the idea of doing a Vowel Synthesizer program which could help children to understand why the vowel triangle has some sense and it also could be used to train foreign language vowels.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/en/thumb/c/c6/VowelTriangle.PNG/350px-VowelTriangle.PNG"/&gt;&lt;br /&gt;&lt;br /&gt;The core of the idea is that axes correspond mostly to the position of the first two formants F1 and F2. So by a simple mapping, given a point on the triangle you could synthesize any vowel even those in the middle. Also by analyzing incoming voice from a microphone, the system could place a point in the triangle that identifies how far one is from the intended vowel.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/thumb/d/d6/Vowels.png/800px-Vowels.png"/&gt;&lt;br /&gt;&lt;br /&gt;I did a first prototype which synthesized something far from human but at least you can identify the vowels when you place the proper frequencies. As i had a proof of concept i stopped there.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://clam.iua.upf.edu/wikis/clam/images/thumb/e/e7/ControlSurface.png/609px-ControlSurface.png"/&gt;&lt;br /&gt;&lt;br /&gt;This easter i improved the prototype by adding a new control widget: The ControlSurface, which control two parameters by moving a single point. It is really more handy than having two sliders and it is perfect for parameter exploration, not just for the Vowel Synthesizer.&lt;br /&gt;&lt;br /&gt;It will also force a change on the way the CLAM Prototyper address the binding of controls as it controls two parameters and our current system binds a widget to a single inlet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/36421488-117613807226375341?l=vokicodder.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://vokicodder.blogspot.com/feeds/117613807226375341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=36421488&amp;postID=117613807226375341' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/117613807226375341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36421488/posts/default/117613807226375341'/><link rel='alternate' type='text/html' href='http://vokicodder.blogspot.com/2007/04/educational-vowel-synth-and.html' title='Educational Vowel Synth and ControlSurface Widget'/><author><name>Vokimon</name><uri>http://www.blogger.com/profile/18314232020593106904</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14341493696444943088'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry></feed>