Finally dry feet: New alloy fenders
Surly Cross Check with new Electra Ticino Ribbed Alloy fenders.
The fenders originally are intended for the Electra Ticino line of frenchy cruising bikes. They are very well made and come with almost all hardware but most importantly: I can buy (or at least order) them in the shops here in Germany, as Electra has a wide network of selling partners. Honjo are more expensive and VO stuff seems to be hard to get over here.
Ticino fenders have been available for a while in a hammered structure, but I used the new ribbed version. IMO hammered fenders are visually too attractive and direct the view to the fender instead of the whole bike. I prefer the more restrained look of this ribbed version.
Mounting them was a lot of fun but it also took a lot of time. It was the first time I mounted metal fenders. I followed Jan Heine's excellent instructions in Bicycle Quarterly (Vol. 9, No. 2). I still needed two evenings or about 8 hours to do it. Jan mentions all the tools you need (round and fat files, drill with small drill bits, scratch awl etc.) but let me tell you, the most important tool you need is a bicycle repair stand to hold the bike without wheels in it! So if you don't have a repair stand, buy one! If you can't afford one, borrow one! If you can't find one to borrow, let a shop do the installation. It's no fun without a repair stand!
Rear fender line. Pasela 700x32 doesn't need to be deflated but it's close!
The Ticino fenders came predrilled in almost all places except under the front rack. This is both a blessing and a curse. Being predrilled means that you can basically mount them without drilling a single hole. On the rear this is fine, but it will not be perfect on the front. Because the original Electra Ticino has a much flatter steering angle of 67° compared to the about 72° on my Surly Cross Check, the fender will sit higher than is ideal. Your feet still will get wet!
So I drilled a new fork crown hole about 5 cm to the front, which brought the fender's bottom end about 13-15 cm from the ground, which is fine for me. The old hole now needs to be filled, e.g. by a screw and caphead or just use your favourite sticker over it - "No nukes!" or "Make Banks Pay!" are recommended!
Front fender line with mudflap from "Gummi Grün", a unique shop in the heart of Cologne that's specialized in all things made from rubber. The flap is squeezed into the filed open, rolled edges of the fender.
Thankfully the fork crown daruma screw is long enough for the Cross Check's huge fork clearance and 32 mm Paselas. The rubber cushioning piece is rounded so denting the fender under the fork is not necessary - very thoughtful of the people at Electra.
The fork crown daruma connection has been spacered up a bit. You need at to add at least a 1 1/8 inch (3cm) spacer anyway as the Ticino hardware includes only a 1 inch spacer.
The black tape covers the hole already drilled for the front rack connection. I was missing a hex head screw of proper length at that day. I bought several hex head screws for the installation, as the Ticino fender hardware only includes Allen screws, which fill with dirt on the inside of a fender and may not provide enough torque. Some days later, the rack connection is finished as well:
A piece of aluminium tube acts as a spacer to connect to the high front rack.
Aluminium tube makes fine spacer material. I was a bit too enthusiastic when filing the tube to the correct length, so for now there are two of the many leather spacers on top of the fender here. Electra provides many leather spacers in their package - probably to install them at the (dual!) fender stay connections. They are not necessary there, so don't put any there and you get four free leather spacers for free! VO charges $5 for a sixpack!
A piece of aluminium tube was used as a spacer at the chainstay.
I did the hex head screw, leather spacer and alloy tube dance again at the chainstay. As I wrote above, the 32mm Pasela tires can be removed without deflating and with some brute force, but wider tires must be without air inside. Which is fine, as usually the only time I remove the rear wheel is when it has a flat and there is no air inside anyway. Just remember to inflate it again only when it's mounted again, not before, otherwise you need to pump twice.
The fenders with mudflap do an excellent job so far. They are very stiff, much better than any plastic SKS I have used before. My feet stay dry even when going through puddles at high speed, and the installation wasn't as hard as I had feared before. Now autumn and winter can come!
Chord
"Chord" is a "drone metal" piece I wrote for the Cologne Music Night 2011, where it was performed in a very nice location, the Kunststation St. Peter, an old romanic church from around 1500. So far I don't have a recording of the performance, so here you get one of the final rehearsals I did with the piece on the day before the concert:
Actually the concert was recorded as well by the local radio station WDR and may be played on WDR3 on 9/11/2011 somewhen between 20pm and 2am.
Being up-front
First it got a new handlebar: the Grand Bois French Rando, kindly delivered including a pack of "schokohagel" via M-gineering. This handlebar is only 41 cm wide, which is a bit narrow for the Cross-Check geometry, but I got used to it. I may go back to a straight bar in winter, when I need more steering leverage on ice and snow.
The bar required new brake levers, these are Tektro v-brake-compatible levers that feel and work great.
The next addition was a front rack. I got a good deal on a Electra Ticino rando front rack, which is similar to the Nitto M12: It mounts to the cantilever brake posts and the fork crown hole. Where the M12 uses a screw that passes all the way through the fork crown, the Electra rack has a much shorter "brake-bolt" and comes with a recessed bolt to be inserted into the back of the fork. Sheldon Brown calls this recessed mounting. On a Surly fork, widening the brake bolt hole on the back (only there!) is necessary. I think, it now is drilled to 8 mm. Actually this looks very clean. The Ticino rack fits the Surly well, not much bending necessary, but because the Surly has such a huge clearance between tires and fork crown, it also sits very high above the front fenders.
In the rack picture you can also see the mount for my B&M Ixon front light on the left. The rack has two braze-ons with M6 thread, one on each side in the center of the brake stay. I have used a steel spacer to mount a Busch & Müller lamp holder intended for fork crown mount (B&M part-no.: 475D/492GAPB, I got it without the fork holder at Cycle Basar). The holder is 10 mm wide, the braze-on is 5 mm, the lamp itself needs 25 mm clearance to one side, so the spacer has a length of 20 mm and the M6 allen bolt is 40 mm long (35 mm would be fine, too, but I couldn't find one in that size). Here's how it looks with the lamp:
Now what good is a front rack without a front bag. The most affordable good one is made by Velo Orange and called "Campagne". Velo Orange stuff is a bit hard to get in Germany. I had good luck ordering from Meißner Raeder who not only have a funky way of avoiding umlauts ("ae") at the same time as promoting ligatures ("ß"), but have been very nice to deal with. I also ordered the fork mounted decaleur kit - and that's where the trouble started.
When mounted in its original shape, there was no way the decaleur could clear my 100mm stem: It simply is too short. Mounting it lower in the spacer stack moved it a bit to the front, but then it was too low to properly support the bag and it was in the way when trying to wrap the leather loop of the bag around the rack loop.
After much fiddling I found a decent solution, which you can see on the pictures: The decaleur was mounted upside down and bent a lot in the opposite direction. (Btw.: I did this on the bike, and didn't use a vise because I like living on the edge. :) I hope it won't fall apart but at least now I can mount the bag securly and easily.
After the loops are married to each other, the metal rods can be inserted as well:
And even the B&M light fits under the bag - nice and easy and bye for today.
Digital Culture and Design Practices Workshop
I will be teaching a two-day course on Pure Data at the Digital Culture and Design Practices Workshop in Holon/Tel Aviv (Israel) on Nov 17-18 in 2010. I'm looking forward a lot to visit Israel for the first time, and my hotel has free bicycles rental, too!
Backlash - Raummusik und so
Wie in jedem Jahr probiert die Reihe Raummusik eine ungewöhnliche Lautsprecheraufstellung aus und hat junge Komponisten aus den Sparten der E- und U-Musik eingeladen, eigene neue Werke für diese Situation zu präsentieren. In 2010 lautet das Motto Backlash. Die Komponisten waren aufgerufen, sich in ihren Werken nicht nur formal sondern auch inhaltlich mit der Bedeutung des Mottos auseinander zusetzen. Dazu Wikipedia: "Als Backlash (dt. Gegenbewegung) bezeichnet man gegen die als fortschrittlich erachtete Entwicklungen gerichtete Bestrebungen oder auch die Rückkehr konservativer Wertvorstellungen, sowie die Einflussgewinnung von dahingehend orientierten Kräften."
Wo und wann: SONNTAG 31. Oktober | 16.00 UHR | AUSSTELLUNGSHALLE Alte Feuerwache Köln
Veranstaltet und gefördert von KunstWerk Köln e.V.
I will play a piece called "\" ("Backslash")
Noise of Cologne
"Noise of Cologne" is a CD compilation series presenting a new breed of Cologne noise musicians and sound artists. Over the last decades, Cologne has given birth to many "schools" of electronic music, starting of course with the WDR Studio for Electronic Music where K.-H. Stockhausen created his influential works, the minimal house sounds of the KOMPAKT label or the crowd gathering around the a-Musik and Mouse on Mars labels.
Cover of compilation CD: "Noise of Cologne 1". Picture by Frank Dommert
"Noise of Cologne 1" presents 17 pieces and sound miniatures by artists living in or around Cologne, including a piece by me. It's not adding another "school" to the existing list - the participating artists actually are very different and independent from each other. See Joachim Ody's booklet liner notes for more on that topic.
The project came to life when Hermann-Christoph Müller, then freshly installed new head of the music department in the Cultural Office, the "Kulturamt", of Cologne, invited sound artists to a round table. His goal, I suppose, was get to know the electronic musicians at his new place of work and to make sure, that the Kulturamt's funding money is distributed in a useful way.
One of the results of these meetings was the concert series Reihe M and the idea to collect a CD of works by this disparate bunch of musicians showing up at the table - the Noise of Cologne. These included both "academic" musicians, composers like Michael Beil working and teching at the Hochschule für Musik und Tanz Köln, alumni of the Academy of Media Arts Cologne, or internationally reknowned sound artists like Hans W. Koch or Marcus Schmickler. Frank Dommert of a-Musik/Sonig selected the content for Noise of Cologne and oversaw the production process. (He also shot the nice booklet pictures of discplaced places in Cologne, perfectly illustrating the often disparate sounds digitized on the CD.)
Actually I have no real clue how I found my way onto this CD or even to the round table that started it some years ago. I am not really that active in the Cologne music scene directly. Of course I know a lot of the participants, but in general my musical collaborations happen through the internets and are not specifically located in a physical town. My work at RjDj is just the latest example, but as can be seen in my working with GOTO10 or inside the global Pure Data network, virtual cities have always been more important.
So, for the virtual cities, here's my track "Beauty", no. 3 on the CD, as a preview Ogg file:
Anyway this actually is my first release in hardware and I'm pretty proud of it appearing next to the wonderful work of really great artists. "Noise of Cologne 1" will be available in October 2010, distribution is handled by a-Musik.
Update: "Noise of Cologne" now has a website at: http://noiseofcologne.blogspot.com/
Sorry for Cross-Checking ... my new Surly!
Here's my new bicycle, a Surly Cross Check intended for commuting to work. That's why it only needs one gear (flat area around here), fenders (sometimes rainy), fat Kojak slicks (comfortable on cobblestone) and leather grips (good looks). Other than that the components are low to mid end Taiwanese bike parts. I've built this bike myself with lots of help from my man Jens Massel (known in music cirlces as Senking on rasternoton, among other project names. Buy his stuff, it rocks), while bottom bracket and headset was mounted by Peter of Schaltwerk cycle shop fame.
The bench in the background is my morning rest place where I like to take a little break if time allows on my way to work and watch boats on the river, people jogging and dog owners with their pets.
Surly Cross-Check viewed from front so you can see the nice SQ-lab leather grips.
Yeah, that's me in the shadow.
RYUKYUDISKO playing Rj Voyager
The awsomeness: Okinawa house act RYUKYUDISKO playing Rj Voyager:
Hackers and Bikers
Many Free Software hackers and programmers also are big bicyle geeks. Paul Davis of Ardour fame is a road racer and I saw my first modern fixie several years ago in the hands of Chun Lee of pure:dyne/GOTO10. There is a lot of overlap in the mindset of cyclists and hackers developing Free Software. Both communities have a strong DIY ethic: They like to be able to take things apart, fix stuff on their own, share knowledge with other community members and like to evangelize their faith to outsiders.
I guess, most modern human beings own a bicycle just like all internet inhabitants use software. But while most people just use the software that other people wrote or installed for them, the hackers know that software can be written or changes and adapted by the common people, not just by companies. Same for bikes: real bike heads build their own bikes, of course using parts made by other companies, but the best bike to them is a heavily customized, unique and personal bike.
My own bike love was a bit on hold for a while but recently I got more interested in bicycles again and I'm actually in the process of build a new bike currently - of course a customized, unique and personal bike, in the limits of my technical and financial capabilities. And this time it's going to be a single-speed bike in addition to the nice mountain bike I already own for more than a decade.
Show me your bike and I tell you what software you write
Now the interesting thought I had today: Can you tell the hacking preferences of a programmer by the bike (s)he rides? Or the other way around: Do e.g. fixed gear riders write different software in different languages than road racers? While it's probably not all black or white, I do believe that there are parallels. Lets take the fixed gear crowd for example. I would guess, that bikers riding fixies would be hackers that also prefer minimal programming languages. They will probably write programms in Lua or Scheme, or when needed use C instead of C++ or Java. These languages have a similar barebone, lean and minimal approach, avoid any cruft and bloat, and they are not useable in all circumstances. Just as a Fixie is a pain in the legs when going uphill, languages like Lua are limited in certain areas.
Single-speed Pd
I'm probably not the perfect person to compare programming languages any further, but in my little Pure Data world, I see a similar analogy. What would be a distinguishing feature of a fixie biker creating software with Pd? I would presume that a fixie or single-speed biker would be one that limits himself to a minimal set of Pd objects. Okay, you see I'm talking about myself here. A single-speed or even fixed gear bike is about as minimal as a bicyle can get. And with Pd, using only vanilla objects would be the equivalent to ride a single-speed bike. Throwing [expr] out as well is the fixie approach.
At the other end of the scale is the Pd-extended user: He will use all of the objects written by the Pd community and in many cases this will make him reach his goal much faster than with single-speed Pd. Externals are like a 24-speed drivetrain. Most of the time they are faster than vanilla abstractions and they are readily available in Pd-ext. But they also add complexity to your Pd patches just like a 24-gear system with gear shifters, more cables and more bolts is heavier and more likely to break than the minimized single-speed approach.
So, if you want to simplify your life, go with a single-speed bike and vanilla Pd - if you want to reach your goal fast, add gears and use externals.
My life is simple.
Vuvuzela-Drone
Here's a reply I posted on the nice Berliner Gazette blog as a reply to a post that worked out the racist undertone in some anti-Vuvuzela articles on the web or in German media. Sorry, it's in German only.
Ich empfehle als weiterführende Literatur das Kapitel zu "Drone (bourdon)" aus Sonic Experience von J.-F Augoyard und H. Torgue. Zu lang, um es hier zusammenzufassen, aber natürlich fällt das Dröhnen der Vuvuzelas in diese Kategorie, wie auch das des Straßenverkehrs, der im 50/60-Hz-Stromnetz angeschlossenen Geräte, des Computerlüfters, des Zementmischers, der Hintergrundberieselung durch TV/Radio, der Tinnitus usw.
Drone ist allgegenwärtig, und gerade deshalb auch eine Klangwirkung, an die man sich gewöhnen kann bzw. muss. Denn die meisten Drones kann man eben nicht ausfiltern oder verbieten. Drones, an die man gewöhnt ist, werden psychologisch ausgeblendet und sind deshalb nicht mehr "störend". Taucht aber ein neuer, ungewohnter Drone auf, so stört er umso mehr, er erzeugt eine Abwehrhaltung. Das passiert gerade mit der Vuvuzela.
Auch die Fußballübertragung im TV zeichnet sich schon immer durch einen Drone aus, den das Publikum erzeugt. Vuvuzela sind hier eine neue Variante, ein Super-Dröhnen über dem Gewohnten. Das ist keinesfalls neu, man denke nur an die "Go West"-Gesänge (berühmt in der "Hier kommt der BVB!"-Version), mit denen man in den 90ern ebenfalls einen neuen Klangeffekt dem bekannten Dröhnen hinzugefügt hatte. Solche Stadionklänge haben vor allem den Zweck: zu nerven, und zwar am besten den Gegner. Ihnen das Nerven vorzuwerfen, ist also zwecklos. Wobei "Go West" selbst natürlich kein Drone ist, der sich gerade durch eine konstante Frequenz auszeichnet, sondern als repetitive Melodie über dem Grunddrone hervortritt. (S.a. "Repetition"-Effect bei Augoyard/Torque)
Weil bei den WM-Spielen mehrere Drones zusammenkommen, ist es auch so schwierig, den "störenden" neuen Drone gesondert auszufiltern. Es wird immer auch etwas der gewünschten Drones erwischt, die für die "Atmosphäre" des Spiels sorgen. Man könnte natürlich den gesamten Publikumssound ausfiltern - einfach den Moderator in eine schalldichte Kapsel setzen und nur seinen Ton übertragen. Bei der öffentlichen Fußball-Leichenschau ("Public Viewing") gibt es ja genug lokalen (nationalen?) Drone, der übrig bliebe.
Jetzt kann man natürlich kulturphilosophisch werden und dieses Filtern und Aussondern unerwünschter ausländischer Klänge auf die Migrationspolitik umbrechen. Das hat was für sich, sind doch bestimmte Einwanderer hierzulande erwünscht (wie Kanzler Schröders Green-Card-Computer-Inder), andere werden an den heute ja jubiläumswürdigen Schengener Außengrenzen Europas aufgehalten.
Diese gedankliche Route überlasse ich mal den Experten.
HDMI output with ALSA and Intel
My laptop has an HDMI output which I've never tried because I didn't have a display so far that accepts HDMI signals. But now I used it with a Toshiba LCD TV. Getting an image was easy, just plug in the cable, fire up (l)xrandr and select the HDMI output. Also select the correct HDMI input on the TV and you're set to go.
But alas, playing movies with mplayer was silent. Isn't HDMI supposed to transport audio as well? Yes, it is, but you have to tell mplayer which ALSA device to use. With my Intel-based graphics card this turned out to be surprisingly easy.
First I had to find the right ALSA virtual device for HDMI. The output of "aplay -L" (uppercase L!) helps:
$ aplay -L
default:CARD=Intel
HDA Intel, ALC269 Analog
Default Audio Device
front:CARD=Intel,DEV=0
HDA Intel, ALC269 Analog
Front speakers
surround40:CARD=Intel,DEV=0
HDA Intel, ALC269 Analog
4.0 Surround output to Front and Rear speakers
surround41:CARD=Intel,DEV=0
HDA Intel, ALC269 Analog
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Intel,DEV=0
HDA Intel, ALC269 Analog
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Intel,DEV=0
HDA Intel, ALC269 Analog
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Intel,DEV=0
HDA Intel, ALC269 Analog
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=Intel,DEV=0
HDA Intel, ALC269 Digital
IEC958 (S/PDIF) Digital Audio Output
hdmi:CARD=Intel,DEV=0
HDA Intel, INTEL HDMI 0
HDMI Audio Output
null
Discard all samples (playback) or generate zero samples (capture)
Did you spot the "hdmi" device shown? Yes, that's the one we need. So here's the mplayer command line:
$ mplayer -ao alsa:device=hdmi file.avi
Because I tend to forget mplayer command line options, I've put this into a shell script: ~/bin/hdmiplayer:
#!/bin/sh mplayer -ao alsa:device=hdmi "$@"
But it still was silent! Turns out, I had to unmute the control named "IEC958 1" in alsamixer. Then I got sound!
If you have a different card or if you want to know more about digital out with ALSA in general, head over to the ALSA wiki: http://alsa.opensrc.org/index.php/DigitalOut
Fast power-of-two modulo
Here's a fast way to do power-of-two modulos that i found on the Wikipedia entry on power of two: If you want to "calculate the modulos of a non-negative integer (x) with a power of two (y) very quickly", just AND it with the desired modulo number minus one.
So if y is a power of two, then this formula applies:
x modulo y <=> (x & (y − 1))
This is pretty useful in Pure Data if you do music that is based on powers of two. Quite often you have a global counter running that just counts up. But then you want to get a "modulo 4" of this number to find the current beat in quarter notes. Or you want to get some "mod 32" to get even finer divisions. Generally for "four-to-the-floor" music your "mod X" number will be a power-of-two. In that case instead of [mod X] you can use [& X-1] instead. So replace [mod 32] with [& 31] or replace [mod 4] with [& 3] and so on. Here's how it looks like in Pd:
Note that we use the binary AND here, which in Pd is the object with just a single ampersand: [&] and not [&&].
More tricks with power of two on Chris' site.
sssad
Visit: http://pure-data.svn.sourceforge.net/viewvc/pure-data/trunk/abstractions/footils/sssad/
Do Androids Dream of Apple?
The open development platform style of Android is like evolution, whilst the closed Apple platforms are more like intelligent design.
— Chris McCormick
footils at github
With the recent server move I had to find a new place to manage my code (mostly Pd things) which was previously hosted on a semi-private subversion repository on this site. As I lost access to a big part of this repo's history (don't ask how and why, it's a bit embarrassing), I wanted to use a more distributed versioning system. So no more svn.
So I evaluated some of the popular alternatives. At RjDj we use Bazaar internally, so this was my first software to look at. While bzr is very nice and comfortable, it also has a lot of dependencies on a Debian system. Probably some Ubuntu issue, but why does apt want to make me install libpango or libthai just for a versioning software? [1] At the LAC2010 IOhannes zmoelnig at some point joked that everyone should use git and the world would be an easier place. As I think a great deal of IOhannes, it was clear that git deserved a close look as well. To my great relief, dependencies for git-core on Debian are absolueley minimal. It's fast even on this small VHost that powers footils.org and it is distributed. Getting to grips with git was very easy, so I started to use it to convert my old SVN stuff.
And then I "discovered" github. Of course I knew it as the home of several other projects already, but I'm always a bit reluctant to let others host important stuff. Call me a control freak. But as git is distributed, hosting stuff on github is not like giving away control, it's more like an additional backup and an invitation to others to fork and use my code. And decentralization in this way is a good thing.
Currently only the new physigs objects and the older pdx7 are hosted over at github, but you can expect more projects by me to move there.
| [1] | Update: Chris McCormick pointed out, that I was hit by automatic installation of "recommended" packages here. When I disabled this in aptitude, the added cruft magically disappeared and I could just install bzr without Thai language support. |
Coming back soon
Beginner's Guide to the FFT-objects in Pd
The Fourier transformation (FFT) is a powerful operation in digital signal processing. Pd includes objects that can be used to apply FFT, modify signals in the frequency domain, and transform the data back. This guide will try a hands-on explanation of how to use the [rfft~] and [rifft~] objects and give you at least a basic understanding of the process. This guide however is not meant to be a deep explanation of the underlying math, it will just give you enough knowledge to get started. For a deeper explanation I would recommend the wonderful DSP-Guide.
A spectral delay built with 98 Pd objects and free of charge.
So lets first have a look at what [rfft~] does: It will give you two signals. One is called the real, the other the imaginary part, but lets forget about this for now and look at it from a bit afar:
Generally a FFT will do a spectral analysis. It will calculate, what sine waves you need to add up to get the same signal as that played in the current signal block. Basically it will tell you the frequencies and phases (first and second inlets) and amplitudes of a lot of [osc~] objects that, if you add them all up, would resynthesize your current signal. (You cannot directly use these [osc~] objects to resynthesize what comes from rfft~ but lets for a moment assume that we could.)
How many [osc~] objects you can control, will depend on the block-size: The FFT will generate control data for blocksize/2 oscillators. So with a blocksize of 64, you get frequencies, phase and amplitudes for 32 osc~s.
Now for some deep mathematical reasons all these [osc~] objects have fixed tunings: They all are multiples (harmonics) of Samplerate/Blocksize. So it starts at f0 = 0 Hertz, the next [osc~] would have a frequency f1= 1 * SR/BS, the next at f2=2*SR/BS up to the final one: f_final = (BS/2) * SR/BS == SR/2 or the Nyquist-frequency. For a blocksize of 16 and a samplerate of 48000 Hz this would be:
f0: 0 f1: 1 * 48000/16 = 3000 f2: 2 * 48000/16 = 6000 ... f8: 8 * 48000/16 = 24000
(Actually of course these are bs/2 + 1 frequencies, but 0 and Nyquist are special anyway so I thought I could cheat a bit. ;))
Because the frequencies are fixed and known, the rfft~ object doesn't need to specify them explicitly. It only needs to calculate the amplitude and the phase of every partial [osc~].
Now the tricky parts to understand are these:
[rfft~] will not directly output the amplitudes and the phases, but this strange thing called real and imaginary part. These carry exactly the same information about amplitude and phase, but encoded a bit differently than you are probably used to from working with [osc~]:
They are specified in a kind of polar coordinate system, where the amplitude is the radius (or distance from origin) and the phase is the angle of the polar coordinates. Re and Im however are cartesian coordinates (in the complex plane).
You can convert re/img-pairs to amplitude and phase using these formulas:
amp = sqrt(re^2 + im^2) phs = arctan(im/re)
This is a standard cartesian to polar conversion, which you can read a bit more about in the wonderful DSP-Guide Chapter 8.
Most of the time you can skip calculating the phase, but more on that later.
The amplitude calculation in Pd lingo looks like this:
amp [rfft~] |\ |\ [*~] [*~] | / | / [+~ ] <= just inserted for clarity, you can also directly go to sqrt~ | [sqrt~] or [q8_sqrt~], which is much faster.
The real and imaginary part (or the phase and amplitudes) are encoded inside the signal blocks, that [rfft~] outputs. The first pair of samples of the left and right outlet~s of [rfft~] contains the info about amplitude and phase for the first [osc~] in our big oscillator bank, that has frequency f0. Each second sample pair contains info for the next osc~ with frequency f1 and so on up to the sample pair number "blocksize/2", which contains the amp and phase for the final oscillator at Nyquist frequency. The rest of the block always is zero, as we don't have oscillators for that.
Some real world data might be useful: Assume we have a blocksize of 8. Then a block of samples might look like this, when print~ed:
orig: 0.13004 0.26951 0.40352 0.52934 0.64446 0.74649 0.83341 0.90344
If you send this through [rfft~] you will get this:
img: 0 1.0317 0.41679 0.17191 0 0 0 0 re: 4.4602 -0.58717 -0.46243 -0.44167 -0.43737 0 0 0
Sending these two to [rifft~] and dividing by blocksize 8 will give you the the original signal block back.
You can also calculate the amplitudes like above, which of course is easy for our first sample:
amp = sqrt(4.4602^2 + 0^2) = 4.4602
For the next two, lets use the handy calculator that is the Python command line:
>>> import math >>> math.sqrt(1.0317 * 1.0317 + -0.58717 * -0.58717) 1.1870861379445048 >>> math.sqrt(0.41679 * 0.41679 + -0.46243 * -0.46243 ) 0.62253948388837155
and so on.
Actually to get the correct amplitudes you would need to normalize the re/im pairs here as well, I just skipped that. (Normalizing the amplitude needs to take into account that we added both imaginary and real part in sqrt(re^2 + im^2) so we need to dividing them by an additional 2, which in our example is: 4 == 8/2)
Here's the full scoop as reported by Pd:
amp: 4.4602 1.1871 0.62254 0.47394 0.43737 0 0 0
See attached fft-up-close.pd to try this on your own.
This means, that resynthesizing this signal at SR=48000 would be similar to using oscillators like this:
[osc~ 0] | [*~ 4.4602] [osc~ 6000] | [*~ 1.1871] [osc~ 12000] | [*~ 0.62254] [osc~ 18000] | [*~ 0.47394] ...
and so on (Note that without normalizing these values are too loud.)
However: All these oscillators would also need to have their phases set accordingly, so you cannot just use above oscillator bank directly in real life.
The inverse FFT objects like [rifft~] will accept the amplitude and phase information in the real/imaginary format directly. This means, you can think of the [rifft~] as a resynthesis bank of blocksize/2 oscillators like above with real and imaginary inputs instead of amplitude and phase input, and every oscillator inside [rifft~] is spaced Samplerate/Blocksize Hertz apart.
As fft~-help.pd and my calculation above shows, connecting an [rfft~] to a [rifft~] will just pass the signal practically unchanged (it's just a bit louder afterwards, that's why you normally normalize it by dividing the output by the blocksize like [/~ 64]). Depending on Windowing and Overlap you need to use a different normalization factor.
Of course it will only get interesting if we wreck havoc to the re/im frequency data in the meantime.
A simple FFT-based modification is shown in I03.resynthesis.pd: Here every re/im sample pair (or every amplitude/phase-info for the respective "oscillator" in rifft~) is multiplied by some value retrieved from the gain table through tabreceive~. If this table has a 1 at a certain sample, this data is passed unchanged, if it has a 0 at another sample, than that oscillator is muted. This is a filter operation, and it only affects the amplitudes of the internal oscillators.
You might ask: "Why only the amplitudes? What about the phases? You said, they are also encoded in the re/im data? Are you cheating again?!" Read on.
If we scale the re/im pair by a (positive) value x, then the amplitudes will be scaled by (the absolute of) x as well:
amp(x*re,x*im) = sqrt((x * re)^2 + (x * im)^2)
= sqrt (x^2 * (re^2+im^2))
= sqrt(x^2) * sqrt(re^2+im^2)
= |x| * amp(re,im)
However the phases will stay the same! Proof:
phs(x*re,x*im) = atan(x*im/x*re) = atan(im/re) = phs(re,im)
Get it? That's why for such modifications you can omit the phase calculation with atan etc.
Note that you need to do this multiplication on every block again and again, because the data coming out of [rfft~] is constantly updated - it still is an audio signal! That's why a [tabreceive~] is used: Although the table received is not changing all the time, we still need to read it again on every block and make a signal out of it.
Now for a simple, amplitude-dependent gating or filtering, you first need to calculate the actual amplitude using the formula above. Then compare it to a value and multiply the original re/im-pairs with 0 or 1 depending on the result to change the amplitudes used in the resynthesis.
Spectral gating in Pd, unwindowed version.
Attached specgate.pd illustrates this and also has a comparison of the windowed and unwindowed fft, that affects the quality of the result and also your normalization factors.