Help Understanding FFT Analysis and analogRead()?
Nick Gammon already gave a very fine answer about the meaning of the
mysterious numbers you were wondering about. Here I am trying to answer
only your last question:


  why manipulate these directly in the first place, because if you
  reference the source code for analogRead() they look awfully similar.


One of the reasons is, as Dave X said in a comment, to get a higher
sample rate. Assuming this is an Arduino Uno or similar (ATmega328P @
16 MHz), the Arduino core normally configures the ADC prescaler to 128.
This gives a conversion time of 104 µs (equal to 13 × prescaler ÷
F_CPU), and a maximum sample rate of about 9.6 kHz. This is fine for
telephone quality audio, but insufficient for hi-fi applications. This
example code sets the prescaler to 32 for a conversion time of 26 µs and
a maximum sample rate around 38 kHz. According to Atmel, the ADC should
work fine with this kind of sample rate, except that you should not
expect to get the full resolution.

The main reason, however, is not to get a fast sample rate, but rather
to get a consistent sample rate. The problem with analogRead() is
that it is a blocking function. If you look at its source code you
will see a busy wait like this:

// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));


This means that the CPU is not doing anything useful while waiting for
the ADC to finish the conversion. If you do analogRead() in a loop,
the CPU will wait for the ADC, then the ADC will be idle while the CPU
completes the loop and so on. The conversion period is then the time
required by the ADC plus the time taken by the CPU to loop. And the
CPU time is hard to predict because it can be influenced by interrupts
and by conditional branches inside the loop.

This code, in contrast, configures the ADC to work in free running
mode. In this mode, the ADC starts a new conversion as soon as the
previous one is done. This way you get a steady sample rate while the
ADC and the CPU work in parallel. In the loop you see these lines:

while(!(ADCSRA &amp; 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc


The comments are a bit misleading. The first line (which I would rather
write loop_until_bit_is_set(ADCSRA, ADIF);) waits for a flags that is
set when the current conversion is done and the data register updated.
The next line does not restart the ADC (it restarted itself, as it is in
free running mode): it only clears the flag so that it can be
meaningfully tested on the next iteration.

Now, I have a few comments on this code that are not directly related to
your question, but may be useful if you are going to build your program
on this basis.

First, it should be noticed that the whole ADC-reading loop is done with
interrupts disabled. This is not normally needed, as the free running
mode gives you a steady sampling even if the CPU timing is somewhat
jittery. The only valid reason I see for disabling interrupts is if
one of your ISRs takes so long to execute that you may miss one sample.
This could very well be the case with such a high sampling frequency.
But still, there is no point in keeping the interrupts disabled during
the FFT processing. And there is no point in turning off Timer 0 if you
are disabling interrupts anyway.

My second point is about the three lines starting with byte m = ADCL;.
Those are meant to read the ADC data register in the proper order: low
byte first. However, the C compiler is well aware of the proper way to
do read a 16-bit I/O register (see “Accessing 16-bit Registers” in the
datasheet chapter about Timer 1). Thus, these three lines can be
simplified to just int k = ADC;.

My last point is that having the CPU left adjust the result (k &lt;&lt;= 6)
takes some time, as it is implemented as a loop. There is no point in
doing this when the ADC can do it for free: you just have to set the
ADLAR bit when configuring ADMUX in setup(). Then the 5 lines starting
with byte m = ADCL; would be reduced to

int k = ADC - 0x8000;  // ADC reading as a 16 bit signed int