July 04, 2008

Receiving OSC from the CLAM Network

CLAM supports OSC as a plugin. You can compile CLAM/plugins/osc just as the other clam modules ("scons [options]").

That, for now, compiles a simply server processing (LibloSource) using the high level API of liblo.

On NetworkEditor (click to see animation):


As you can see on the animation, it have 2 options: osc port number and osc path.
LibloSource print whatever osc pakage it receives on that port in the console[1], and if the package have the config path and contain just 3 floats, the values are sent to the three control outputs[2].

If you configure the processing to get port 7000, you will see in the console:
LibloSource::ConcreteConfigure: STARTING the server. port 7000
So, just run the blender animation and back to the clam console, it will show something like:


That's it! You have three floats from every blender object osc position package! So, you could configure your LibloSource server to receive an object position subpath[3]:





[1] catched with
lo_server_thread_add_method(st, NULL, NULL, generic_handler, this);

[2] catched with
lo_server_thread_add_method(st, _config.GetOscPath().c_str(), "fff", controls_handler, this);
(the tree "f"s are the three typespec: floats...)

[3] at the moment just once at the time, because it create a new thread server on each processing, which make the port slot be busy and clam crash. This is an IMPORTANT todo task, when see how to deal with several osc paths/objects... Another bugs in actual implementation: if you duplicate a object with the same parameters it crashes... and if you change the options there is no reload (you actually need to quit and open the file again).
I expect to strike these bugs soon, but that need to define some things: what we want to use? a processing as server with different linked (sub)processings as paths? (this could be implemented using some kind of list control messages to deal with paths) Or just a big but configurable processing to receive all paths from an osc sender (for instance, blender)?

June 24, 2008

Too much?



I like it. :-)


ACTUALIZATION:
I had some troubles with LADSPA/FAUST support on my usual customized UbuntuStudio Feisty... I though that the problem was because some old jack/alsa packages, so I rebooted on Hardy to test it. Not only all the problems dissapeared, but also I noted this impressive graphics difference. A network like the previous is showed here:


Isn't it beautiful? :-D

June 22, 2008

NetworkEditor Copy & Paste

One of the NE improvements which I worked on is the copy & paste processings boxes selections functionality.

You select the processings, copy (or cut) them from the processings context menu (or CTRL-C/X) and then paste it from the canvas context menu (or CTRL-V).

A graphical demonstration:



BTW, David added very nice icons to the menu items, so actually it look like this:

June 15, 2008

What do users essentially want?

DSCN1482I attended Google Developer day 2008. How colorful the day is~

One of the most impressive speech is given by Xiaosheng Tan, CTO of MySpace.cn. This guy is so funny, hehehe, that the last thing on earth I'll do is to write his joke down on my blog.??

MySpace.cn is an OpenSocial website, where users can embed all sorts of gadgets in their web pages. There is a gadget code competition on MySpace.cn. A lot of nice works are received and two of them are extraordinary.
One is "a clock that can stretch". One guy developed it in an afternoon when he got bored of his daily work and just wanna have fun for a while.
The other is "E-Album" by MagicBox, which is developed by a team of molihe.com, and is very versatile, powerful, and with profound technics of photoshop, 3D effects, etc.
It turns out the winner is "a clock that can stretch", whose user-setup amount achieves 10683 till now, far beyond the number of 8577 of "E-Album".

          StretchingClock2               E_Album_MagicBox                       
Why does the little pink lazy clock beat the brilliant magic E-Album down? Mr.Tan gave us a vivid illustration about what do users essentially want:

  • If users are the mass, simpleness and intuitive are especially crutial.
  • The tool must appear as CUTE as possible, always!
  • Fancy& design> Technic.
As to the myspace.cn users, one big bonus of the clock is-- "Emm, it apears cool!".

June 14, 2008

Getting Blender positions in CLAM via OSC

A very first attempt to access Blender parameters within CLAM, via Open Sound Control. A sphere traveling around the origin of coordinates in Blender, and CLAM printing the values. Nothing new, but... IT WORKS! :-)

Just a screenshot. It would be better to capture a video, but I don't know how to do it.

June 09, 2008

Network Scalability

Let's start describing a little of my CLAM GSoC first main area: the Network Scalability.

To be honest, one of the things that I dislike about visual object oriented DSP designers like Network Editor, Pd, etc, is the (visual) complexity that a network/patch sometimes can reach with a simple design that uses so many objects and correspondent "cables" connections, when the same design in a text code language could be a lot simpler to write, read and understand. That is the main reason to had choosen the network scalability proposed idea, because I think is one of the best ways to solve that issue. Beyond it seems to be a good solution because its logic, several years of similar implementations on both Max/MSP and Pd can prove that it really is. And that is the reason because my ideas about the implementation are closer to the Pd models. [1]

Subnetworks will allows the users to encapsulate networks onto new single processings. Once they finish a functional block, they can simplify it onto new "black boxes", improving the networks in a modular way.

To do that, I think to use network's level audio and control "sinks" and "sources" processings boxes, which will be appear as inlets and outlets on the newer encapsulated network-processings. [2]
A first approach could be making some "wireless" processings boxes, which can interconnect distant processings (at first) on the same network, using a key name as identifier, like a "variable". [3]

Those improvements are close related with the networks flow task of the proposed idea on the wiki. Once done that, and defined the infrastructure to use for recursive networks [4], I'll need to search a way to finish the integration of composite objects-subnetworks within the Network Editor.

As an intermediate task I though to allow some kind of grouping management on a same-level network. For now, the user can only selects objects in NE canvas to move, delete and copy/cut to clipboard. So, managing the processings as groups could be extended then to layers and later to subnetworks.

Well, this is an overview of the scalability area. Insofar as I involve further on developing these ideas I'll found more issues. For now, I'd been dedicated to make NE canvas interface improvements, so I think those related tasks don't be difficult. Let's see about the CLAM specific flow management...

[1] But of course, any suggestion against, or improving these models are welcome.
[2] Like "inlet" and "outlet" Pd objects.
[3] Like "send" and "receive" Pd objects.
[4] Writing this, I realize that my previous question on the devel-list has no much sense, because we are not talking about a defined limited levels, but recursion...

June 08, 2008

Standards for 3D Scene Description

What can you do if you want to describe a 3D scene including audio and graphics using some kind of standard? This is the result of a quick survey we did for CLAM, feedback is welcomed!

There are several standards and open languages to describe 3D graphics, but what if you want to add 3D audio description into the scene? Well, that limits your choices but there are still some possibilities.

First, you can take a look at MPEG4's BIFS and AudioBIFS. BIFS is in fact an extension of VRML. MPEG4's SAOL (Structured Audio Orchestra Language) can also be included inside AudioBIFS. Unfortunately I don't know of any Open Source reference implementation of this, although parts of it have been implemented, for instance, in Ross Bencina's Audio Mulch.

X3D is a W3 standard that is also a sucessor of VRML (with the advantage of using an new XML format), in which the sound is integrated too. There are no complete implementations of X3D available and all of them are written in Java. X3D shares a lot with BIFS. As a matter of fact the MPEG standard already includes a link to X3D.

Another possibility is using VML from the Verse project. This project is very much related to Blender. Using VML can tie you into their data model. However Verse is released with a BSD license.

Finally, SpatDIF, is an extension of the SDIF format for sound interchange. It uses OSC for real-time communication and SDIF as the intermediate file format. There are no available implementations yet and it is unclear whether it can be easily extended to include 3D graphics. However, SDIF can be transcoded into SAOL and, as already mentioned, SAOL can be included inside MPEG4's BIFS.

So, in summary, it looks as there are several competing and complementary efforts but none is sufficiently mature yet. Again, any feedback on related experiences will be appreciated.

June 07, 2008

Introducing CLAM

As I announced previously in the blog, I will start writing write about my CLAM Google Summer of Code project.[1]

My proposed project is focused in two main areas:
All right then, but... what does it means?

Let's introduce the subject describing very quickly some CLAM basic concepts: a network is a main central platform which manage and coordinate the use of black boxes signal and control processors units called processings. You can edit the networks very easily with the tool called Network Editor. Within the Network Editor (NE) you have a graphical canvas where you can put graphical instances of the processings (called processings boxes), and interconnect them as you want.



As you can see, a network within a NE canvas is some kind similar to a Pd, Max/MSP or Reaktor patch. But in certain aspects is more powerful because their expandability, as you can easily make your own processings just as your own graphical interfaces using the Qt Designer.[2]

So... after this quickly introduction the next post will start talking about the project itself.


[1] If you don't know what CLAM is, go here. If you don't know what GSoC is, here is an nice article about it. You can find further information about all CLAM selected projects here.
[2] You can read more about the framework advantages in the FAQ.

June 05, 2008

TypePlugin methods

No pain, no gain-- To be generally used, the SchemaAttribute of Clam_annotator has to support all sorts of attribute types: Enumerated, Float, Int, String, Segmentation, FrameDivision, FloatArray.

Why is it a type dependant task over the pool of the annotator? Well, if you are writing a name of an artist such as "Avril" into the pool, you should take the String type; if you are writing a danceability degree of a song, say 9.9, which means that the song is perfect for your dance-party??, you should take the Float type; if an algorithm are writing detected onsets of a song...well, this will mention the Segmentation, which is boring and complicated! I just give up explaining it.?????
All those types have different related methods: to add the new attribute, to validate whether the data is legal and to init the attribute instance.

Emm, as to the Segmentation type attribute initiation, it uses "pool.GetWritePool<CLAM::DataArray>" instead of "pool.GetWritePool<CLAM::Segmentation>", which is different from the other types.

It appears that there is none of CLAM::Segmentation's bussiness with the pool, but only with the SegmentationPane and auralizer. How and where is those segmentation classes converted from the DataArray outside the pool? This is done in the method "refreshSegmentation" of the class "SegmentationPane" by:
const CLAM::DataArray & descriptorsMarks = _pool?
            _pool->GetReadPool<CLAM::DataArray>("Song",currentSegmentation)[0]
            : nullSegmentation;

The Segmentation classes DiscontinuousSegmentation, UnsizedSegmentation, etc., have some validation functions which kinda overlap with the related ValidateData methods of SegmentationTypePlugin. The next Todo is to consider and realize a proper integration of Segmentation classes into the Pool/Schema.







June 01, 2008

Some words about my Google Summer of Code project.

In this post I'm going to talk a bit about what I'm doing at my GSoC project.
Basically it consists of 2 main goals:

  1. Implement MIDI in the Network Editor (NE from here)
  2. Implement Typed Controls.

Since the Typed Controls implementation is necessary for the MIDI stuff I'm giving it some priority.
I'm going to avoid all the CLAM background because it's well explained in the project's page and its tutorials.
CLAM uses Controls to modify Processing's internal parameters.
The basic problem with Controls is that at this moment they only manage float as data type, this hardly limits what you can do with them,
The idea of my project is to extend this functionality to have the possibility to use any data type that the programmer wishes. (float, integers, MIDI, OSC ;) )
For this i'm using the loved (and hated by many) C++ Templates.
Basically i wrote two classes called TypedInControl and TypedOutControl, which will replace InControl and OutControl in the future, but, to avoid compatibility issues, we decided not to touch the existent classes.
I'm using a design pattern for typed data connection that is already implemented in CLAM with the Ports (which are typed streams like audio, etc.). The data pattern has as main goal to let a non typed connector to generate typed connections correctly and with type check. To achieve this we divide the tasks in two clases, a base class (non-typed) and a child typed class, the type cheching is delegated to the child class, while the actual connection is being made with the base class.
At the moment all this is already implemented and working well.
Now I'm in charge of a more advanced step, the control registry for the processings. I'll write about this soon.

Talking about the MIDI implementation, the mail idea is to create 2 basic processings: MIDISource and MIDISink. MIDISource will be the one in charge of getting external MIDI messages and letting them flow in the CLAM network. Inversely, MIDISing will send MIDI messages generated (or modified) in CLAM to the external world. Both are going to use the Typed Controls, instantiated with MIDI messages as data type.
Besides these basic processings I've planned to create some processings that use them to have usefull functionality for musicians. For example, I'm already working on a MIDINote to Frequency and Amplitude translator called MIDINoteOutControlSender (I'll talk about this soon). At the beginning of the project I coded the MIDIMon, which basically reads MIDI messages and translates them into floats to see that MIDI is working.
I'm planning to code the MIDIControlSender, which will be in charge to read the MIDI control messages and translate them into floats to control parameters of existing processings.
Also I've a MIDIArp in mind, it's a MIDI arpeggiator (very useful to be used in MIDI controlled synths) and some other things i think will be interesting (maybe delays and that kind of stuff).

May 27, 2008

Agile Methodologies in Telefonica R&D

Some time ago I started having interesting but informal conversations with a manager in Telefonica R&D who was also interested in Software Engineering and methodologies. My point was that in a company like ours where innovation is a key issue and almost all development is geared toward bleeding edge products, Agile methodologies should be used. Besides, development teams are usually small, requirements are not clear at the beginning, and there is a need for having working prototypes soon in the development cycle... there was no doubt.

After not much we managed to convince some key people, including our Methodologies Division (who had had bad experiences in the past with Agile).
Although I was much for starting with eXtreme Programming and do a bottom up approach it soon became obvious for them that in such a large organization as ours they needed a slightly more structured approach with a focus more on management and less on development. That is why we chose to go for Scrum.

Actually, what we are deploying is a mixture of Scrum for the management layer and xP practices on the development layer. This seems to be a favored approach nowadays in many companies (see here, here or here, for example).

Just a couple of months afterwards we have more than 10 projects that are successfully working Agile. And so far everything seems to be positive: developers feel better and even some of our clients are now turning to us for implementing agile methodologies in their companies. It is still a bit soon but things look bright!

Bottom line, be careful with informal conversations you have by the coffee machine at work... they might become true and end up having a huge impact :-)

ps. I hope I have some time to blog a bit more about how to combine xP and Scrum but I have many posts in the queue right now.

May 25, 2008

CLAMs GSoC 08 Projects Announced


We are very happy to announce the final list of this year’s projects in the Google Summer of Code. We have been extremely fortunate to have a large number of great students apply for CLAM this year and we are confident that the 5 projects outlined below will have a huge impact on the project and the CLAM “family”:

Natanael Olaiz UNQ, Argentina
“Network scalability and Blender integration”
This is a two sided project. The first part will improve the usability of CLAM networks allowing users to hierarchically embed networks as a processing units. The second part consists in developing a set of Blender plugins and CLAM networks to drive audio spacialization based on direct
sound from Blender 3D geometries.

Yushen Han (Indiana University, US)
“Real-time woodwind instrument synthesizer using SMS models”
The project consists in building a real-time synthesizer based on CLAM processing plugins, using SMS models, allowing flexible sound timber manipulation. This project is a continuation to Greg Kellum’s 2007 GSoC project.

Francisco Tufro (UBA, Argentina)
“MIDI Implementation for Network Editor”
This project is both about developing all the needed and most common MIDI processings and also about doing all the required refactorings to the Framework in order to achieve this (i.e. Typed Controls).

Pawel Bartkiewicz (AGH University, Poland)
“Standalone chord extractor application”
This project is about adapting CLAM’s chord extraction technology into an standalone application focusing on usability for instrument players. This project will integrate existing visual and processing components and it will have impact on the interaction between realtime and offline CLAM components.

Wang Jun (Chinese Academy of Science, China)
“AnnMerger-to stand on the shoulders of the masses”
This project goal is add into Annotator the ability of combining several sources of several kinds (webservice, database, files, extractors) into a single project. Secondary goals are providing new data sources and polishing the program workflow.

Read here for more details on the projects:

May 24, 2008

Translanting MIDI Notes to frequencies in the diatonic scale using the central A (440hz) as reference

One of the plug-ins that i'm programming for my GSoC project is a MIDI Note to frecuency and velocity translator.
Beyond the technical background of the problem, i'm writing down the theoretical aspects of it, nothing hard, but usefull to have as a reference for the future.

It's not even a mystery to know that to obtain the frequency of a note in the diatonic scale separated by n semitones from the reference frequency we can use the next formula:

Freq_{Note} = Freq_{Ref} + 2^{(\frac{n}{12})}

So, also knowing that MIDI notes are represented with integers, in which for consecutive notes have one semitone of difference, and that the 440hz A is the note 69 (so, 69 is A, 70 is A#, and so..), doing some simple replacements we have that:

Freq_{Note} = Freq_{Ref} + 2^{(\frac{n-69}{12})}

And this is just what we were looking for, (n-69 generates an offset from the reference note)
Now, only by replacing the reference frequency for the 440hz we obtain:

Freq_{Nota} = 440hz + 2^{(\frac{n-69}{12})}

Here I give you the C++ code that I used in the MIDINoteOutControlSender:

 
frequency = 440 * pow(2.0,(note-69.0)/12.0)

Hordia wrote last year on his blog the inverse formula to translate from fundamental frequencies to MIDI notes.

May 21, 2008

Some words about my Google Summer of Code project

Since my GSoC project was approved I'll start writing about it. As the world use English universally, that's the language i'll use for my posts and, if I have time, i'll translate them into Spanish so that everyone understands.

For those who do not know what i'm talking about i'll explain this briefly: Google has a program to promote Open Source called Google Summer Of Code. You can read about it on the program FAQ. One of the mentoring organizations selected this year (like last year) to be part of GSoC is CLAM, a C++ framework that helps creating music and audio related applications. My project consists basically in incorporate a class to handle typed controls (at this time it only uses floats) to the framework's core, so in the future CLAM will be able to control parameters with virtually any data type. The idea is to use this with MIDI and OSC, as well as any future control protocol that may become available. This enhancement is necessary for the ultimate goal of my project: achieving a MIDI implementation for NetworkEditor, allowing CLAM to have a big approach towards music.

My idea is to write about my project and to show updates here. I hope this will be useful and enjoyable for you as it is for me!!

A configuration idiom for Python scripts

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:


# This should be your program using the config

import os
class config :
#Here we define the default parameters
paramA = "value A"
paramC = "value C"
class category1 :
paramC="value sub C"

#Here we load new values from files, if they exist
for configFile in [
"/usr/share/myprog/defaultconfig",
"/etc/myprog.conf",
"~/.myprog/config",
"myconfig.conf",
] :
if not os.access(configFile,os.R_OK) : continue
execfile(configFile)

# That's the config params usage. Pretty!
print config.paramA
print config.paramB
print config.paramC
print config.category1.paramC
print "This is a template: %(paramC)s" % config.category1.__dict__


If you write in the config file this:

# myconfig.conf
paramA="new value A"
paramB="new value B"
category1.paramC="new subCvalue"
paramB+=" extension " + paramA

you'll get this

new value A
new value B extension new value A
value C
new subCvalue
This is a template: new subCvalue


The config file is read as you were adding code at the same indentation level you have on the 'execfile' call.

Notice the advantages:

  • Your config file looks like var assignations

  • You can use inner classes to build up categories

  • You can have a list of configuration locations with different precedence

  • You can include almost whatever python code

  • You can do templating with the params getting a dictionary like config.__dict__ or config.category1.__dict__

  • You can put config checking code after loading.


Be carefull on unreliable contexts:

  • Malicious config files can include almost whatever python code

  • Config syntax errors crash the program (i guess that can be solved)

  • Config files may add any new attribute, category, or method you didn't have


But if you are just managing your own utility scripts like us, that idiom is fantastic.

May 13, 2008

Digital Beers

One of the coolest things of "being digital" (i.e. having a blog, twittering...) is how much of that digital activity ends up bleeding into your analog world. Every now and then people that know about me from the web get in touch and tell me that they are going to be around Barcelona. This way I have met really interesting people and projects.

So, if you are going to be around Barcelona (or any other place that I might be visiting) and want to chat while having a non-digital beer please feel free to get in touch. I am always up for that!

April 20, 2008

A Course on Recommender Systems

Last week I gave an internal course on Recommender Systems in Telefonica. Although I only had 12 hours I ended up preparing a course that could well expand over at least 24 hours of class. Except from some details I am pretty happy with the syllabus I came up with. Just in case it might be of any help to anyone, this is the index of the course:

PART I. Introduction to Recommender Systems
  1. The paradox of choice
  2. What is a Recommender System?
    1. The recommender problem
    2. General scheme of a RS
    3. Tools of the trade
  3. Approaches to Recommendation
    1. Collaborative Filtering
      1. User-based
      2. Item-based
    2. Memory-based
    3. Content-based
    4. Other approaches
      1. Demographic Methods
      2. Utility Methods
      3. Knowledge-based
    5. Hybrid approaches
      1. Weighted
      2. Switching
      3. Mixed
      4. Feature Combination
      5. Cascade
      6. Feature Augmentation
  4. Evaluating RS
  5. Personalized Search
Part II. Data mining for RS
  1. Introduction
    1. Why mine data?
    2. Data mining tasks
  2. Data Preprocessing
    1. Types of data
    2. Problems with data
    3. Aggregation
    4. Sampling
    5. Reducing dimensionality (SVD)
    6. Feature Selection
    7. Discretization and Binarization
    8. Variable Transformation
    9. Feature Selection
  3. Distance Measures
  4. Classification
    1. General Approach
    2. Decision Trees
    3. Rule-based
    4. Nearest-Neighbor
    5. Bayesian Classifiers
    6. Artificial Neural Networks
    7. Support Vector Machines
    8. Ensambles of classifyiers
    9. Issues in classifyiers
      1. Model Overfitting
    10. Evaluation of Classifiers
    11. Comparing Classifiers
    12. Metrics for classifyiers
  5. Cluster Analysis
    1. Introduction
    2. K-means
    3. DBSCAN
    4. Cluster Validation
  6. Association Analysis
    1. Frequent Itemset Generation and the Apriori Principle
    2. Rule Generation
PART III. Designing a RS
  1. Defining the problem
  2. Working with the data
  3. Taking context into account
  4. The decision process
  5. Presenting results
  6. Some notes on domain-specific adaptation

April 01, 2008

The Future of Web Search Workshop

Yahoo! Researh Barcelona and the UPF are organizing a very interesting two-day workshop in Andorra starting on Thursday. The workshop is the third of a series that, under the same name of "Future of Web Search", started in 2006. I will be giving a talk entitled "Search and Recommendation: two sides of the same coin?". Below is the abstract that can give you an idea of what I will be talking about:

Recently the field of Recommender Systems has gained growing popularity among the research community with new conferences such as the ACM Recsys going into its 2ond edition and established conferences such as SIGKDD or SIGCHI focusing a great deal of attention on this topic.

The Recommendation field started from a different background than web search, namely Data Mining and HCI versus Information Retrieval. While the goal of Recommendation Systems is to optimize a fitness function between content and users by "discovering" hidden relations in the data, Search Engines focus on "retrieving" pre-existing data.

However there are clear trends that point to both fields coming closer together. On the one hand, web search is becoming more and more personalized, highlighting the need for user profiling and collaborative filtering. On the other hand, it is becoming clear that in many cases search strategies are essential for the performance of Recommender Systems.

As a result, some claim that search is just a "simpler form of recommendation", where the fitness function to be optimized is that of a generic average user (e.g. using algorithms such as Page Rank) Obviously statements in the opposite direction can also be made. In this talk we will assume that the audience is familiar with Web Search systems and therefore we will focus on describing the basic techniques and current research trends in Recommender Systems, highlighting where and how they are similar or different. At the end of the talk, We hope to convey the message that the "Future of Web Search is in Recommendation", hoping that such a claim will spark an interesting discussion and debate throughout the workshop.


Here you can see the detailed workshop program with very interesting speakers including Yahoo's own CDO,
Usama Fayyad.

March 24, 2008

Call for Students: CLAM in Google Summer of Code 08

(Please help distribute)

We are glad to announce that 2008 summer is also going to be a Summer of Code for CLAM . In other words, CLAM has been accepted as a mentoring organization for the Google Summer of Code, a program that offers student developers stipends of 4500 USD to write code for open source projects.

CLAM (C++ Library for Audio and Music) is a project that aims at developing a full-featured application framework for Audio and Music Applications. It offers a conceptual metamodel as well as many different tools for that particular domain. One of its most relevant features is the availability of a visual building dataflow application that allows to develop rapid prototypes without writing code. The project started 7 years ago and, among other highlights, it won the ACM award to the Best Open Source Multimedia Software in 2006.

Now we are looking for smart students who enjoy coding free software so that they can earn some bucks for the summer. Last year, GSoC 2007 was a very fun and productive experience and we are looking forward to repeat it. Take a look at the CLAM GSoC 2008 wiki page for more information on how to apply and some sample ideas for projects.

We are waiting for you!

Application deadline: March 31

If you have any question about any of the information below please
contact clam-info@iua.upf.edu or join the #clam channel at FreeNode
IRC.

March 19, 2008

CLAM in GSoC 2008!


We are glad to announce that 2008 summer is also going to be a Summer of Code for CLAM. Google just announced the list of mentoring organizations for GSoC 2008 and CLAM is in it!

Now we seek smart students who enjoy coding free software so that they can earn some bucks for the summer. Last year, GSoC 2007 was a very fun and productive experience and we are willing to repeat it. Take a look at the CLAM GSoC 2008 wiki page for more information on how to apply and some sample ideas for projects.

We are waiting for you!

soc-clam-flyer_2008 deadline extended