Friday, 19 September 2014

Southampton Part II

The amount I learnt in first year of university was ridiculous.  The course touched on almost every area of electronics - maths, physics, solid state, digital design, programming, communications, to name a few.  In second year we were we were trusted to go and hone these new skills, mainly in the form of larger group projects i.e. the D4 project.

Most of the modules were advanced something - continuing on from the work of last year.  One of the most interesting new subjects was a module on computer architecture.  At the start I had a vague idea of things like instructions, but by the end I was up to speed on computer design, concepts such as processor pipelines and caching.

The first major project was designing an integrated circuit (D2).  There was a specification of a few modules we had to implement - things like a 4-bit adder, ring oscillator and an 8-bit counter.  As a team we designed and built the different modules.  Then, at the end we fudged together some kind of final IC and realised it wasn't all going to fit.  This was the first real taste of having to work as a team, and having a fairly tricky deadline.  There were plenty of stressful moments and staying in the lab until 11pm (even on a Sunday...)

The circuit designs were done by hand, although someone in the class discovered an amazing tool - logic Friday - which is a free program that minimises logic for you.  Once we knew which gates we needed, we started simulating in OrCAD.  Simultaneously, we were laying out the designs on an IC using L-Edit, putting down the tracks and trying to cram the designs into the smallest possible space.  The whole work-flow at this point was pretty nasty and clunky.  There was a lot of exporting hundreds of files to use the different tools, for example to simulate the IC design by creating a PSpice model.  Also, the L-Edit middle mouse button fixation was fairly frustrating.  However, this was our first experience with the tools, we all rushed into the design without spending much time to get accustomed to the programs we were using.

Why I had no life for about a week - everything was done by hand
This was early on in Semester 1, fast forward quite a few months (including winter exams) and we had a physical IC with our design etched on.  In Semester 2 we had to test it, this meant writing a set of test vectors (inputs and expected outputs) which could test the chip for any faults.

D2 was tough, but the main highlight of 2nd year at Southampton was the main group project D4.  D4 is a fairly crazy 3 weeks of designing, implementing and presenting, and a traditional part of second year at Southampton for electronics.  D4 is going to need its own write up to do it justice, but in summary we had to build some kind of musical "thing", ideally used by a street performer - meaning it needed to be portable, have built-in amplification and the possibility of being battery powered.  There was a whole range of projects from different people but ours was essentially a (computer) keyboard operated synthesiser, all processing done by a Raspberry Pi.

After D4 it wasn't long before summer exams, which were all fine and there weren't too many surprises.  Generally, I find focussing on exams uninspiring, although it forces you to properly understand all the material you've neglected.  For me, there was a fairly big chunk of knowledge missing where lectures had been going parallel to the group projects.

Sunday, 7 September 2014

First Year Down

It's been ages since I put anything up here, so I'm going to have to account for the last couple of years.  There was some unfinished stuff on my first year at uni, so I guess that should go first.

The most important outcome of last year was definitely passing my first year of university.  First year was awesome I have no regrets about choosing electronics.  The balance between software and hardware is exactly what I was hoping for - there was lots of programming along with circuit theory, semiconductor physics, control theory among other things.  The course was relatively intense; there were often 9-5 days of labs and lectures, and a couple of projects at the end of each semester.  Not only did I have to learn a completely new set of skills, I had to learn to cook, survive student nights out and in general learn to live away from home.  It's crazy to think that in the first lab I barely new how to use an oscilloscope, but by the end of first year we were building and testing complex circuits, designing PCBs and testing solar cells.

ECS - The cause and solution to all my problems
In terms of C and C++ I took a lot out of the embedded programming part of the course, which was an area I hadn't touched before. In one of the first labs we had to build a sturdy microcontroller based off an AVR ATEGA644P chip.  In later labs we were given tasks to do with this board, like make a simple heart rate monitor, or make a tiny speaker play a given tune.  Lots of twiddling was done at the bit level, and hours were spent looking through the monstrous data sheet trying to find what a specific register did.  The final project was definitely satisfying - we had to create a voltage boosting circuit which could take a dynamic load.  To do this we had to use the microcontroller as a control system, constantly adjusting some pulse and monitoring the output voltage.  We also had to have communication between a PC and the board so that a new voltage could easily be set.

One really interesting area that was covered was programmable logic devices (PLDs) and Hardware Description Languages.  We were taught some SystemVerilog and given a few CPLDs to play with in the lab.  Although the stuff we did was basic, it was a completely different way of programming.  We had to start to think in terms of sequential and combinational logic, where combinational logic is all done in parallel.

The biggest worry on doing this course was that I would lose my enjoyment of programming.  When someone is telling you that you have to do something, psychologically that seems to change how we all approach it.  Being spoon fed, made to learn stuff for exams, made to rush some coursework you left too late is not fun, and you get so little out of it.  It did feel a little that when I was doing some programming labs, in the stress of constant marking and assessment, I wanted to do the minimum needed and go home. However, I think that overall, I was given opportunities I wouldn't have had if I hadn't chosen this course. Most importantly, I learnt how to start applying my skills to real-world applications.  I got to see my code make things physically happen, solve real problems, and I guess at the same time get me a few marks towards a degree!

Wednesday, 31 October 2012

Return to the Mandelbrot Win32 API Project

For a presentation that I've got to do for university I've returned to the project I did writing a Windows application to show the Mandelbrot set.  Because I couldn't cram everything into 7 minutes of Powerpoint presentation, I wrote up a little background.

The document can be found here.

The code can also be found here.  Enjoy!

Wednesday, 17 October 2012

The Magic Behind the Phase Vocoder Part A

Hopefully you've seen my post on my phase vocoder project.  Otherwise there won't be much motivation for this slog at the theory; when you have this much maths and theory there better be a good reason for it.  Fortunately, the phase vocoder can do some extremely cool stuff, like shift the pitch of some audio while keeping it at the same speed. If you haven't read about Fourier's theory, or the Fourier transform, look back to simpler times.  Without understanding this you really won't understand the next bit.

A FFT is pretty useful for breaking down the frequencies in a snapshot of audio.  However, a snapshot is just a snapshot - capturing an instance in time.  Generally we'd be talking a transform size of 1024, up to maybe 4096 samples.  You might wonder why you can't just take a transform of an entire 3-4 minutes of audio, and then use that for all your spectral needs.  While that transform will have astounding number of spectral points - i.e. really super "spectral resolution" it will have awful "time resolution" - i.e. you have no way of seeing how the frequencies change over time.  You wouldn't be able to pick out the distinct thumps of a bass drum or the squeal of a 30 second guitar solo, because it's squished down into a generic spectral mush over the whole song.

What would the intuitive next step be, if we want to see how the frequencies change in time?  What about taking two transforms, with the first transform of the first half of the audio and the second transform the second half.  Now we have half the number of spectral points but we do have some time resolution i.e. can see how the spectrum changes over the audio.  Moving on, the natural progression is to make the transforms smaller and have more of them.  You could make the transform size 1024 samples big and then just split the audio into tiny sections.  After taking loads of Fourier transforms, you end up with a load of spectral data.  You will now be able to see how the frequencies change over time, with good enough time and spectral resolution.  This is the beginnings of the STFT - the Short Term Fourier Transform.  A good visual way to imagine this process, is as a spectrogram (often a set of bars that light up, indicating frequency levels) on a CD player or in a Digital workstation.

It would be nice if the STFT was as simple as slicing up audio and shifting the magical FFT along, but there are catches.  Because the FFT abruptly slices audio, but then assumes that snapshot is periodic, you get some nasty spectral leakage.  The phenomona is illustrated below.

How the Fourier transform mauls your signal
Spectral leakage is the bane of DFT processing.   Discontinuities are pretty much guaranteed when transforming an arbitrary signal.  There is no perfect solution to this, but there is a very good one.  Often you'll here mention of the "transform window"; the window is the samples that the DFT is currently “looking at”.  Leaving the samples alone, this window is called a rectangular window.  Ultimately we want to get rid of those jumps at the sides of the window.  To do this we use a windowing function, a function designed to smooth out discontinuities while not affecting the frequencies too much.

To apply the window you simply multiply the input sample with the corresponding sample of the windowing function.  There are many other windowing functions e.g. Blackman, triangular, Gaussian.  The two most popular windowing functions are the Hann window and the Hamming window.  They’re almost identical, apart from a slightly different constant.  The formula and pictures of what they look like are given nicely on Wikipedia

Windowing however ruins the audio a bit, and on reconstruction the audio will sound like it's coming in and out really quickly (amplitude modulation), not really what you wanted.  The solution is to overlap the snapshots enough, so on reconstruction the original signal can be rebuilt fine.  For most windows the overlap required is an overlap of 75%.  Often, for the STFT we refer to the "hop size", i.e. how many samples you "hop" the window over each time.  If N is the transform size, a common hop size is N/4 or maybe, if you can affort the extra data, N/8. 

The STFT, pictorially (drawn badly)
The STFT is useful for some spectral things, for example the cross synthesis project I did earlier, but not capable of shifting pitch or stretching time without distortion.  However, with only a small modification of the spectral data, we can – this operation is the heart of the phase vocoder algorithm.   All will be revealed in the next installment.

Saturday, 13 October 2012

DSP Notes

I find that when I learn stuff, a good way to not forget the stuff is to write notes.  I write notes on the things that took a long time to get, the things I found interesting and the answers to the questions in my head at the time.

As a result, I've written a pretty ridiculous amount of notes for all the stuff I've learnt on Digital Signal Processing (DSP) - about 10,000 words or 37 pages, done in a window of extreme boredom in the summer holidays.

I'm not sure how useful these notes will be to anyone else, as the notes won't be as thorough as a well written textbook.  Anyway, here they are.  Enjoy.

Programming a Phase Vocoder and University Life

I've recently moved to university (college for Americans) and so life has been a bit hectic for the last 3 weeks.  The course is great (electronics) and I'm sure now that engineering suits me better than computer science.  Anyway, the result of settling is I've done hardly no programming, apart from the introductory C labs they give to everyone.

A side note is I can appreciate how hard the programming aspect will be to a complete newcomer.  I'm not completely sure about lectures on programming and how much people will get out, but who knows?  The practicals seem to throw people in the deep end a little, and there doesn't seem to be much critical feedback - the staff are teaching good style and methods, but I'm not sure what will stop people developing bad habits. 

The lack of activity will finally let me catch up to where I am in (audio) programming.  I've only just briefly started looking at Csound, which is kind of like learning a new language in itself.  The last major project I did though was creating a phase vocoder.  This was probably the most exciting thing I've done with C++.

In short, the phase vocoder takes breaks some audio down into the frequencies that make it up (spectral data), using a STFT, and then converts the data to a form which means the data is independent of time.  Once you have data independent of time, you can play the audio back at any speed you want and keep the pitches all the same (time stretch).  Once you can time stretch, you can resample, bringing the audio back to speed but now with the pitch raised or lowered.

Maybe as motivation for the theory, here is the output of my phase vocoder on some audio samples.
I'm going to follow up with the theory and pseudocode in the near future.  Another pretty cool application of the phase vocoder is performing a "spectral freeze", where you hold onto a single spectral frame of data.  The result sounds pretty unnatural.  The phase vocoder can also cross two spectra, and even interpolate between spectral data.

I got a fair number of hitches in the design process.  "The Audio Programming Book" has quite a compact implementation, in typical C style.  I wanted to use C++, and I wanted to create something much more general, and expandable.  I created classes to encapsulate audio signal data and spectral data - this worked well because it followed the RAII (Resource Allocation Is Initialisation) principle, and as a result I got no memory leaks in my program.  However, this layer of complexity did have a performance impact every time you wanted to actually access the data.  The solution was to make a function that passed the internals out (sounds like bad practice but I'm pretty sure it's okay for that kind of object) and allow the buffer array to be accessed normally.  I also had a class for the phase vocoder itself,

Once I'd fudged something together, obviously the output was nothing like it was meant to be.  I searched for more answers online, but was met mostly with inpenetrable articles from journals.  I intensely debugged my code, fixed some problems but still wasn't getting output of any value.  Probably the most frustrating part of debugging is when you find a bug but then the program still doesn't work.

In true programmers' fashion, after testing every function in turn and stepping through almost every line, comparing different outputs with manually calculated values I pinned down the problem and slapped myself.  In the tiny function "phase_unwrap", which brings the phase (just an angle in radians) down to the range -pi to +pi instead of adding / subtracting twopi, I was adding / subtracting pi.  This changed the phase and this tiny change was ruining the output.  I guess this acts as yet another reminder to always, always, check every single function you write and run some expected input and output through.  The moment you assume a function is too trivial to get wrong is the moment you set yourself up for hours of debugging!

Thursday, 20 September 2012

Trying to Understand Laplace('s Transform)

The Laplace transform is a commonly used tool in engineering and digital signal stuff e.g. filter design.  I think my first encounter with it was watching a Khanacademy video.  The title looked cool, I was procrastinating for an exam, and I raised myself the challenge of trying to understand it.

The khanacademy video is brilliant, and Khan is an excellent teacher.  For someone who's been exposed to a lot of calculus in school, given the basic transform rule, it's just a matter of integration (by parts usually) to derive any of the transforms and rules.  The process of doing it clicked straight away.

However, the only thing lacking was a more fundamental explanation of what the transform actually represents.  What is the mysterious "s-domain"?  It just comes across as some magical tool that somehow simplifies evil differential equations into pathetic algebraic ones. I like to have a deeper understanding of difficult concepts, because once they're broken down I can relate them to other concepts I already understand.  I also like to think, how did the inventor(s) come to invent this formula or process?  To me this makes it much more intuitive.

More recently I came across the Laplace transform and even weirder z-transform again in filter design.  So I decided to really hunt for a better explanation for the Laplace transforms.  I was met with many forum posts with indecipherable replies with mentions of "infinite vector space" and "complex frequency domain".  I'm sure they're perfectly valid explanations, but as a simple minded engineer I like things broken down into more English and relatable terms before I can go on to describe it mathematically.  There was really one video - an MIT lecture - that blew my mind and answered all the questions.

(There are two parts to the video, this is the first part)

This video connects Laplace transforms with the more straightforward power series.  When I questioned myself on why a power series should work I realised I didn't know, so I had to backtrack a little.   After quite a few hours though I am now satisfied with the explanations of power series, Laplace transforms and z-transforms I found.  I compiled it all into a single document which I'll use later to prompt my memory.  I however release it into the wild for similarly confused people to share!

Here it is.