Sunday 20 November 2011

Soundbox — what makes it tick

I did have the soundbox device I have built with me at Alternative Party 2011. It did attract a fair amount of interest, though nowhere near what my 32×8 LED screen did. I think I'll have to write a post about that LED screen and how it works some time. For quick info, it's built around an ATmega328, can show 16 different shades of green with gamma ramp and shows some classical effects such as plasma and fire.

Neither one of my projects gained nowhere near the interest that the Chernobyl reactor simulator by Helsinki Hacklab did, but that is only to be expected. That simulator was awesome, even though they didn't quite manage to get it to a playable state during the event.


I'll first describe the high-level workings of the soundbox, then the hardware side and last the software used.

High-level view

The device is a looper: it plays a short loop of sounds over and over again and the sounds can be altered while the device is playing. It provides two channels, each with its own waveform and each separately programmable. The loop is 128 sounds long and the actual length of loop in seconds depends on the setting of tempo knob.


The first sound channel plays sine wave and the second channel plays pitched noise. One of the device controls is a pitch knob that can be used to select the frequency of sine wave of noise to be programmed.

For sine wave there's also second knob — arpeggio — which can be used to alternate between the base pitch and a higher pitch at a high rate. The rate is fixed depending on tempo and the setting of arpeggio knob defines how much higher is the higher pitch.

Also there's a beat LED that flashes four times during every loop through the sound loop — white at the beginning of loop and red the other three times. This is to help the user see how fast a tempo the device is using.

The front panel also features a built-in speaker which is mere 5 cm across but can produce surprisingly high volumes — even at the active party hall it was able to put out enough volume to be clearly audible at close quarters. I've tried some small commercial speaker devices intended to be attached to portable CD/MP3 players and found that they can't put out nearly enough volume in such situations, so I was somewhat surprised that this simple device could.

The hardware design

The  hearth of this device is Atmel ATmega88 microcontroller running at 16 MHz. Sporting 8 kB of flash memory and 8 kB of RAM, this microcontroller is the little brother of ATmega328 that is used in the popular Arduino prototyping board.

Early version of the hardware

With the built-in analog-to-digital converter in ATmega88 it is simple to read the positions of the three 10 kΩ linear potentiometers used for pitch, arpeggio and tempo. The potentiometers are connected across device ground and regulated 5 V lines, so turning a potentiometer changes the voltage at its middle pin linearly between these two voltages. This voltage is read with the ADC in the microcontroller and used to control the sound generation.

The microcontroller outputs the sound using Pulse-width modulation and uses a simple resistor-capacitor low-pass filter so that only frequencies below the Nyquist frequency of the output are passed to amplifier and eventually to speaker. Or at least this was the idea — I don't know quite exactly the frequency response of the filter I built, especially as I ended up swapping some of the capacitors to different value than the one originally planned, since I didn't have any with correct value and could not be bothered to visit the electronics store to get a couple capacitors. Anyhow, it sounds good and looking at the output with an oscilloscope doesn't show modulation frequency passed through, so I guess it's fine.

After the low-pass filter is the volume control: a 10 kΩ logarithmic potentiometer. After it there's a LM386 amplifier chip that drives the speaker or the device connected to the line out jack. One notable thing is that this amplifier chip is not connected to the regulated 5 V line that is being used to drive the ATmega88, but to the unregulated voltage straight from the batteries. This is done to maximize the voltage available to the amplifier chip — which means more volume — and to ease the load on the regulator, which is simple 7805 linear regulator that can generate considerable amounts of heat if heavily loaded or if the difference between its input and output voltages is large.

Speaking of batteries and voltage regulation, the power source for this device is six AA size NiMH cells. With nominal voltage of 1.2 V each, the total voltage is 7.2 V — high enough so that the 7805 can produce stable 5 V supply and well inside the operating voltage range for LM386.

The software

The software for the soundbox is written in C using the AVR libc library.

The sounds to be played are stored in two 128 bytes long arrays, one for each voice. Each byte in these arrays corresponds to one sound to be played, the value defining the pitch of the sound.

At the hearth of the sound generation is a numerically controlled oscillator (NCO). The oscillator for sine voice uses 256 samples long phase-to-amplitude converter array that is filled with sine values at device boot up. The noise channel uses similar table filled with random values with Gaussian distribution, creating a table that contains white noise. The oscillator for noise channel advances in its table 4096 times slower than sine oscillator of same frequency. This value has been chosen experimentally so that sine and noise with same pitch setting would sound like having somewhat similar pitch.

The sound generation itself is done inside the overflow interrupt of an pulse width modulation timer that's built-in in ATmega88. Each time the timer overflows — every 256 processor ticks in my configuration — a new sound amplitude is computed from the two NCOs and written in pulse width control register.

Reading inputs and setting the frequencies of the two NCOs is done in the main program loop. Each loop of the main program moves one step forward in sound arrays, reads inputs, writes new sound values to sound arrays if needed and sets the frequency controls of NCOs according to the values in sound arrays. After this it runs NOP command in a loop a suitable number of times to wait until new sound is to be played.

That's it for this time. I'm thinking of posting something about how I made the enclosure, especially the labels on the panel and buttons. Maybe some recording of the sounds I get from the device, too.

Thursday 20 October 2011

Soundbox project and Alternative party

I've been building a digital instrument that has been inspired by the Luna Mod which was presented in the Make magazine some while ago. It is a two-voice software synthesizer implemented on an Atmel ATmega88, an eight-bit microcontroller. It plays a short loop of sounds which are programmable by selecting suitable pitch and amount of arpeggio and pressing a programming button.


I will present this device for the first time at Alternative party 2011 which starts in less than 24 hours. It's a festival for many sorts of digital art, especially demos (as in demoscene, not short versions of games) and there have been many electronics enthusiasts – such as KOELSE - Association of Experimental Electronics and Helsinki Hacklab – in the last years. I'm confident this project will fit right in there.

I'll write more about this project soon, at least something about the electronics and software design in this device and about how the control panel was made.

The source files and an electronics design drawing made in Fritzing are available at a GitHub repository.

Saturday 6 August 2011

Drawing for Assembly 2011

I created this image on Inkscape for the Fast Graphics competition at Assembly 2011. The theme for this year was Last minute and there was one and half hours time to make the image, from when the theme was published to submission deadline. Sadly, this didn't make it past jury and thus wasn't show on big screen.


Not the best of my drawings, I admit. In 2009 I did manage to get my drawing on big screen. That time the theme was "Over the edge" or something like that and time limit again 1½ hours. Here's the result, drawn in Inkscape.


The SVG source files are available at my GitHub reposistory.

Wednesday 13 July 2011

Blender M3G export error

I'm attempting to build a game atop Kajak3D framework. For that I'm creating models in Blender and exporting them to M3G format.

Well, exporting my very first model failed with "Python script error: Check console". After figuring out that this doesn't mean any Blender-internal console, but plain old console output, I closed Blender and started it from a terminal window. So, I received this message:
translate mesh ...[Object "Body"]
1 material(s) found.
Traceback (most recent call last):
  File "/usr/share/blender/scripts/export_m3g.py", line 3068, in file_callback_m3g
    exporter.start()
  File "/usr/share/blender/scripts/export_m3g.py", line 2680, in start
    world = Translator.start()
  File "/usr/share/blender/scripts/export_m3g.py", line 2022, in start
    self.translateMesh(obj)
  File "/usr/share/blender/scripts/export_m3g.py", line 2296, in translateMesh
    if material.getMode() & Material.Modes.TEXFACE: createUvs = True;
AttributeError: 'NoneType' object has no attribute 'getMode'

My first thought of that was that the first "material" is likely typed with wrong capitalization and should have been "Material". But it is not so: both capitalized and non-capitalized version are actually valid in that script at that point...

Google search didn't find anything on fixing that error, just one unanswered forum post asking how to fix it. Anyhow, I found the solution and decided to post it here, in case anyone else bumps into same issue.

The solution
Link the object material to object mesh, not to whole object.
Note the circled area: your settings should look like this. You can click on "OB" to see if there are any materials linked to the object and to remove them.

Thursday 28 April 2011

Making buttons with Inkscape


During my university studies I've made several buttons for TKO-äly, the organization for computer science students at Helsinki University. Here I'll describe my method for creating these buttons. The usual process is that I first sketch the button on paper, then draw the main image on paper or with Inkscape. Finally I composite the image with background and place several complete images on a single A4 sheet for printing, both using Inkscape. The printed images are then cut out from the paper sheet and made into buttons using a hand-operated button tool.

This post will be rather image-heavy, so it'll continue after the jump.

Tuesday 19 April 2011

Filter effects: Gaussian blur

This is part of my Filter effects tutorial series.

Gaussian blur makes objects appear softer and less clearly defined. Even by itself it is so useful that it was the first filter effect to be implemented in Inkscape. It also has received an own place in the Fill and Stroke editor:

When you use that slider, it creates a filter effect that contains a single Gaussian blur primitive and attaches that to selected object.

There are different kinds of blur. In Gaussian blur the colour from any pixel spreads out according to the Gaussian function (aka. bell curve). That means that the colour of any pixel stays mostly near itself, but some colour spreads out to a large area – in fact the colour spreads out to an infinitely large area, but in practise the contribution can't be seen quite far away. Another example of blur would be bokeh, the depth of field effect seen when some objects in a photo are out-of-focus. It is quite different from Gaussian blur: bokeh depends on the camera lens used, but usually spreads colour evenly to a circular area.

Gaussian blur is also useful as part of more complex filters. Many of the pre-defined filters in Inkscape distribution include blur. Here I'll show a couple examples. First up is drop shadow:

Here the Flood primitive is used to set the shadow colour, Gaussian blur to make the shadow softer and Offset to move the shadow.

Next up is filter that shows only object edges:

The Composite is in mode "out", meaning that we take parts of original image that are not in blurred image.

Last up is lighting filter, which requires a height map. Gaussian blur can be used to create an easy height map.


The SVG sources for the images are available from my filter tutorials repository at GitHub.

Sunday 17 April 2011

Filter effects: Flood

This is part of my Filter effects tutorial series.

Flood may be the most simple filter primitive there is. It simply fills the whole filter area with one colour. By itself it's mostly useless, but it's often handy as part of more complex filters.

Here's a simple – almost stupid – example to show what Flood does by itself:

When you have a filter like this, the result will look like this:


Of course, this is probably the most inefficient way of using Inkscape to create a solid-coloured rectangle. So let's take a more interesting example. If you have ever tried to add a thick stroke to a text, you will have noticed that the result doesn't look too good. One way around this problem is to create a filter as follows:

Here I use the Morphology filter primitive in Dilate mode to create a thicker version of the text and Flood filter primitive to create the stroke colour. With Composite I do the operation "stroke colour in thick text", essentially colouring the thick text with my intended stroke colour. Finally, I take this thick, coloured text and composite the original text on top of it with Merge.

As you can see here, the version using stroke paint has certain problems, especially with the small holes in 'a', 'e' and 'f'. The filter produces a much nicer look, preserving the outline shape of the letters.

In a similar fashion you can use Flood in other filters to add in colours that don't exist in the original image.

The SVG sources for the images are available from my filter tutorials repository at GitHub.

Thursday 14 April 2011

Filter effects: Displacement map

This is part of my Filter effects tutorial series.

Displacement map is used to warp images in different fashions. For example many of you may have seen a screen saver that warps a small, moving area of the desktop. That warping effect is done with a displacement map.

The displacement map filter primitive takes two input images: the image to be warped and a displacement map. The colour in displacement map defines, where the colour for this pixel should come from: you can pick one of the red, green, blue and alpha colour channels for vertical displacement and one for horizontal displacement. Light colours in selected channel make the filter take colours from below or right (or moves the image up or left). Likewise dark colours get the filter to pick colours from above and left. Mid-grey means zero displacement.



Here are some examples what filters can do. The top two cases show how solid colour displacement map simply moves the image (Offset filter is better for that, though). Interesting results come from using gradients (3rd example) or noise (4th example, using Turbulence filter)


These examples used filter set up as follows:

The Image filter primitive is used to grab the bunny as source image and then displacement map filters that using its own colours as the displacement map. This is for top two examples, the bottom two are similar but use scale of 28.8.

The meaning of displacement map setting is as follows:

  • First input image specifies the image to warp

  • Second input image specifies the displacement map

  • Scale specifies how large displacement should be

  • X and Y displacement specify the colour channels to use for horizontal and vertical displacement, respectively





There are some gotchas in building displacement map filters. It is best to use only completely opaque colours or only different levels of opacity to specify the displacements: on low opacities the colour information may be partially or even completely lost and this'll cause problems. The second thing is that the filter effects editor in Inkscape has occasional problems: on new displacement map primitive it may be needed to explicitly change X and Y displacement to non-default values (and back again, if you want the default)

The SVG sources for the images are available from my filter tutorials repository at GitHub.