Get the idiots off the planet.

My main problem with my life is in fact not a problem with myself (as many people would have guessed) but with people, or humanity.

I myself live a wonderful life with lots of joy, I’m very close to living my dream, I had a lot of luck in life as for example family, education, social situation and so on. The last big mistake I wish I hadn’t made is very long ago. I like myself, I find myself handsome, I’m happy with how I’m doing with my hobbies, only some details in my PhD studies could be improved, but it’s nothing existential. I might be worried about having kids and a family one day, and I might be a bit worried about what I’m going to do after my PhD, but I have a lot of confidence that I’ll live a decent life. And if everything fails, I can always return to my loving parents and live with them for a few weeks until I get on my feet again. So my life is great, thank you very much, fate.
And now look around you. The average student at my university (which supposedly is one of the worlds top 100) is not interested in what’s going on on the planet, is superficial and doesn’t care at all about what trouble he causes elsewhere with his lifestyle. Heck, even if he just throws the plastic wrapping of his factory-farm-ham-and-egg-sandwich which costs the planet litres of drinking water just on the ground on campus, a cleaner will come and collect it. These people aren’t grown up. And they’re supposed to be the intellectual elite! In a developed country! Now look at an uneducated chinese citizen who will consume much more than his carbon and water footprint just because he doesn’t know – there are millions of them! Look at the idiot who studies for a PhD and is nothing more than a chimpanzee trying to protect his territory of unsustainable lifestyle when it comes to such questions!
And that’s only the stupid people. Now look at the smart people who manage big companies, exploit the third world and wield massive power without being elected by anyone.
And in between a few people who have actual ideas that the earth could profit from – and they end up in blogs, in facebook statuses that get 10 likes and will be forgotten in a few days, since everybody is so incredibly busy all the time.
I ask you and actually every intelligent person:

How can we live like this and not go mad or become depressive?

By not caring. And this is the only thing I start to hate about myself. I stop to care, because there is so much to help and so little I can do. I already do the best I can for the planet with diet, with my style of consumption – but what does it help if everyone else just goes ahead and shovels a burger in his mouth while taking an air-polluting plane from London to Paris because he can’t be bothered to just pay a few pounds more for the train. And as soon as you try to say anything, people will either get angry at you or smile and not listen.
Best of luck for the future, dear planet.

Comments (3) »

Little PyJack tutorial

If you do Linux and audio seriously, you will already have found out about JACK. If you know how to program and you like fast development, you might have already fallen in love with Python. This tutorial aims at combining the two worlds. Let us write a simple JACK client in Python which connects to system output and produces an audible sine wave.

I’ll assume you have the JACK server installed, set up and running as well as a version of Python 2 installed. You will also need to install the Python bindings to JACK, which you’ll get here. Unfortunately, they aren’t yet available for Python 3, and I encourage you to bug the developer team to port it or to port it yourself. (Also, the included examples are – in my opinion – very old fashioned and/or poorly written.)
The numpy library is also needed.

Let’s start. Fire up an interactive console and get going:

>>> import jack
>>> my_test_client = jack.Client("my_test_client")

So far, we have imported the jack bindings and created an unactivated client called my_test_client. Before anything happens, we have to activate it, which means it will start to talk to the JACK server.

>>> my_test_client.activate()

If you get errors here, then it’s because the JACK server is not running properly.
If everything went well, JACK’s log will tell you that there is a New client 'my_test_client' with PID ###.

The new client can’t receive or send sound yet because it lacks ports. We’ll have to grant them to it, and specify whether they’re input or output ports:

>>> my_test_client.register_port("in", jack.IsInput)
>>> my_test_client.register_port("out", jack.IsOutput)
>>> my_out_port_name = my_test_client.get_client_name() + ":out"
>>> my_out_port_name
'my_test_client:out'
>>> for system_playback_port_number in (1, 2):
...     my_test_client.connect(my_out_port_name, "system:playback_{}".format(system_playback_port_number))

If you’re using a GUI tool to manage JACK like QJackCtl, you will notice that my_test_client will now have shown up in the respective lists of both input and output clients and the out port is connected to both system playback ports.

Let us now generate the sound we want to make. JACK works sample based, so we need to generate samples, for which in turn we need to know the sample rate.

>>> sample_rate = my_test_client.get_sample_rate()
>>> sample_rate
48000

Your value may differ slightly.

The samples are numpy arrays. Let us create the sample we will output:

>>> seconds_to_play = 3
>>> number_of_samples = seconds_to_play * sample_rate # Make sure to int this if seconds_to_play is not an int
>>> import numpy
>>> time_index = numpy.linspace(0, seconds_to_play, number_of_samples)
>>> frequency = 440
>>> _output_samples = numpy.sin(2*numpy.pi * frequency * time_index)

_output_samples is not yet in the correct format.

First of all, PyJack internally needs to make sure that the samples are of type float. (_output_samples.astype("f"))

Second, we need to change the shape of the sample array for the following reason: In principle, output and input can be many more channels than 1. It could be stereo (2 channels) or even some Surround system (5, 7 or more channels). PyJack needs the samples in a two-dimensional array where the first index counts the channels and the second counts the samples. Since we’re happy to output mono, we only need the 1 channel. (numpy.reshape with shape (1, number_of_samples))

>>> output_samples = numpy.reshape(_output_samples.astype("f"), (1, number_of_samples))

We will also need to provide an input array (of appropriate shape and type) where the JACK callback can store the incoming data. We will conveniently make it the size of the JACK buffer size since every JACK process run we’ll exchange just that amount of data.

>>> buffer_size = my_test_client.get_buffer_size()
>>> input_samples = numpy.zeros((1,buffer_size), 'f')

In this example, the input_samples array really is just a dummy. If we were recording sound, we might actually use the values it contains.

We are now ready to send the data to the JACK Server. JACK will only exchange data chunks of the size of the buffer at a time, so we need to take slices of our output_samples. The complete slice operator will be [:,i:i+buffer_size], where the first colon is for copying all channels and the second slice is one particular slice of length buffer_size.
i ranges over the complete number_of_samples in steps of buffer_size where care is taken that i + buffer_size is still inside the output_samples.

>>> for i in range(0, number_of_samples - buffer_size, buffer_size):
>>> 	output_sample_chunk = output_samples[:,i:i+buffer_size]
>>> 	my_test_client.process(output_sample_chunk, input_samples)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    my_test_client.process(output_sample_chunk, input_samples)
jack.InputSyncError: Input data stream is not synchronized.

Oops, something went horribly wrong. Or did it? Remember that JACK is a low-latency sound server and that it will not forgive you for offering your buffer-sized chunks of samples too late. But at least our first buffer swap will not have a chance of coming in time since we waited seconds or minutes from activating and connecting the client until sending the samples because we are in interactive mode. That’s much longer than the length of one buffer, which will be \frac{1024}{48000} \text{s} \approx 20 \text{ms} or even much shorter on a lot of systems.
“No problem”, you’ll say, “let’s just put all the code in a script, run it and the error will disappear.” Unfortunately not: There are so many functions we called that running them all directly after each other that they already take longer than one buffer swap. A typical candidate for such a thing is the calculation of the output buffer, which will certainly take several milliseconds for every second of generated sample. In a good program, such tasks have to be done before the client connects to the server or ideally even in a separate thread.

But even disregarding the fact that we might have to face an input synchronisation error at the beginning of our sending the samples, we should be prepared for such errors just in the middle as well, as the system might become busy and the Python interpreter doesn’t get enough processor time to offer the buffers. In such situations, playback should not just interrupt, but display an error message and carry on immediately. We’ll do that by just catching the exception:

for i in range(0, number_of_samples - buffer_size, buffer_size):
>>> 	print("durchlauf an Stelle {0}".format(i), clock.tick())
>>> 	try:
>>> 		output_sample_chunk = output_samples[:,i:i+buffer_size]
>>> 		my_test_client.process(output_sample_chunk, input_samples)
>>> 	except jack.InputSyncError:
>>> 		print("InputSyncError")
InputSyncError
InputSyncError

And that’s it! You should already hear a nice “a” from both speakers now.
And in order to be kind to the JACK server, we will neatly disconnect:

>>> my_test_client.deactivate()

And the JACK log will show something like:

Disconnecting 'my_test_client:out' from 'system:playback_1'
Disconnecting 'my_test_client:out' from 'system:playback_2'
Client 'my_test_client' with PID ### is out

For further reading, check out the examples that come with PyJack.
If you can’t get rid of synchronisation errors, make ure you have realtime privileges on your system and run python in realtime, for example like this: chrt 20 python ...

Comments (8) »

Matplotlib & Pylab for Python3 under Gentoo

If you want Python3 support for pylab, which is an excerpt of matplotlib, you have to go with version 1.2, which is currently keyword masked in the main portage tree.
So if you fire up Python3 (which is the default in a fairly recent Gentoo installation) and import pylab gives you an ImportError, just add dev-python/matplotlib to your package.accepted_keywords and emerge -avt matplotlib.

Leave a comment »

Small Editors vs. IDEs

I’m mainly coding Python these days, and I’m using the Geany editor with a few Plugins to code. Why? Mainly because Geany starts faster than any other editor I know in a Linux desktop environment. And it doesn’t (yet) lack anything I need for programming. Or is there more to it?

Maybe little editors have their advantages over an IDE. An IDE can help you to code so much that you do code with less discipline.

  • Have a too intelligent code completion? Watch your method names growing and growing.
  • Great refactorisation tool? And suddenly you start copying code all the time because it’s so easy to adapt it to new uses. Don’t repeat yourself, we all know that.
  • Your IDE gives you a structured overview over your file? But how big is it? More than 10 kb? Certainly too large, even if you have the feeling that the IDE somehow manages the content for you.
  • Your IDE magically cross-references tooltips between different files. Great, no need of remembering which class was defined where and where you put what documentation. But have you separated concerns well enough? Each file should use as few information from the other files as possible, that way you’ll find bugs much faster.
  • Your IDE lets you place that button in the tiny, simple dialog window very fast. You call it rapid development. But how does the window behave when you scale it or use it on a mobile device? Maybe the default values for the button placement were quite good ones, but the IDE hardcodes the exact coordinates of where you put that button.

Not all of these comments apply to every IDE. And not all apply to every language and use case. I’m speaking of Python here, and there are awfully big, repetitious C files better left untouched as they are. I’m also not saying that the argument against big IDEs is won. I’m just highlighting some ways how the simplicity of editing tools forces us to write with more simplicity and clarity.

Leave a comment »

Test-forced development

Test-driven development has proven useful. I had a little idea which might prove useful.

The philosophy is along the lines of Know your next commit. How do you enforce working in small enough steps while thinking in big pictures? How do you move your code from a working state to a working state without hacking an hour and ending up with a lot of bugs? You automate the testing locally.

Of course a shared repository should run unit tests on your code before it is merged. But that’s not what I mean. I propose the following:

Run a test on your code every 5 minutes. Literally.
Write a little script that does it for you.
If, after a change from a working state, your code works already after 3 minutes, test immediately and reset the timer.

Here is a little python script that does this for you (assuming you code in python):

#! /usr/bin/python
# -*- coding: utf-8 -*-

import time
from imp import reload # assuming python 3

def test_force():
	import Spielwiese as test_module # change module name here
	reload(test_module)
	try:
		test_module.test_suite()
	except Exception as e:
		print("Test failed: {}".format(e))
	else:
		with open("last_test_time.txt", "w") as last_test_time_file:
			last_test_time_file.write(str(time.time()))

if __name__ == "__main__":
	interruptable_time = 2
	sleep_time = 20 # 5 * 60
	while True:
		test_force()
		print("Interrupt now if you want to quit")
		time.sleep(interruptable_time)
		print("Interrupt now to test manually")
		try:
			time.sleep(sleep_time - interruptable_time)
		except KeyboardInterrupt:
			print("Manual test now")
		else:
			print("Forced test now")
		# Add annoying lines here such as bringing the window to the front or other means of drawing attention to it

Leave a comment »

Some music

Three rather good improvisations of friends and mine that deserve to be uploaded:

Leave a comment »

Improvisation Concert

The recordings of my improvisation concert of the 22nd of May this year are online here:

http://enigmage.de/music/improv2.html

Leave a comment »

Follow

Get every new post delivered to your Inbox.