I noticed that its range can vary depending on the format (16 bit vs 32 bit) of the recording.
yes, it depends on FFT length and sample resolution (bits). You're need to normalize FFT result by divide magnitudes with FFT length multiplied by half of the sample max value power(2, N)/2, where N is sample resolution in bits. Also, you can do it by translate your magnitude to decibels:
magnitude = sqrt(re*re + im*im);
db = 20 * log10(magnitude);
and then you can substract constant to normalize it and get power relative to maximum (full scale):
dbNormalized = db - 20 * log10(fftLength * pow(2,N)/2)
after that you will get normalized value in decibels.
For example, if you get FFT for the recording length 10000 samples, and 16 bits per sample, then calculations will be the following:
dbNormalized = 20 * log10(magnitude) - 20 * log10(10000 * pow(2, 16)/2) = 20 * (log10(magnitude) - log10(10000 * 32768))
0 dB means maximum allowed (full scale) amplitude for ADC.
-20 dB means 10 times smaller amplitude than maximum.
-40 dB means 100 times smaller amplitude than maximum.
-60 dB means 1000 times smaller amplitude than maximum.
etc
If you know the power of maximum allowed amplitude in dBm, you can add it and get absolute value of the power.
For example, if your 16 bit ADC has 10 dBm power for maximum allowed amplitude (full scale), then:
absolute power in dBm = dbNormalized + 10 dBm
I want to take the audio data and convert it to a A-weighted decibel reading much like those given in handheld decibel meters. Is this something I can do from the FFT? A simple example would be nice.
I'm not familiar with A-weighting scale, but as I understand, you're need to correct normalized decibels with some correction table. Just substract some value taken from the table. I don't know how to calculate this correction table.