Doubts about dynamic range of the AudioProcessor

Realizing that it didn’t matter how much I increased the gain and I never got clipping (assuming I always had to stay in the [-1,1] range), I decided to check what was going on.

Processing a single sine wave I verified that it was possible to increase its amplitude up to 127.0.

I’m not complaining, but I’m a little confused. Now I do not understand very well in what range of amplitudes I should work, since the most logical and comfortable is in the range -1, 1

I guess I should include a gain control that allows me to multiply up to 127 or a safe value? What is the ideal way to deal with this? I mean, avoid saturating the signal but at the same time not wasting part of the range.

0 dB is 1.0f

32-bit float, as I understand it, will dip into its exponent bits after that and the samples remain valid, as you say with plenty of room to spare. Intermediate audio signals can get away using up lots of that headroom, but ultimately saving to most file formats will do an integer sample conversion which expects the range from -1 to 1

1 Like

So it may be that 127.0 can be reached without clipping because of the 32 bits, 8 bits are room, so there would be no range problem, since it would still be 24-bit quality.

Ok, I think I get it now. With regard to saving files, I think that as long as it is not in real time, all the data could be normalized. and when it comes to recording, adjusting the input gain.

So I shouldn’t worry about exceeding [1,-1] with a synthesizer implementation? I mean, although I design it so that the maximum value is 1, in practice with the different processes and sum of signals, the final amplitude will be several times higher.

It’s OK if a plug-in goes outside [-1, 1], since the DAW has sliders for master volume etc, and may automatically apply limiting to prevent speakers from blowing up. But that doesn’t mean it’s a good idea.

Therefore, if your plug-in can create audio signals that go outside [-1, 1] you should also provide a gain control that lets users dial back the output level.

127 as the limit sounds like some kind of arbitrary limit imposed somewhere in the signal chain, with 32 bit floating point you should be able to go much higher. A gain of 127 is “just” +42 Decibels approximately. Of course sending a signal like that or an even louder one to the actual audio outputs or writing that to an integer audio file is not going sound right. The gain would need to be brought back down in the end.

At first I was suspicious of that number. now I think the range to 1 is 24 bits, and the range to 127 is the remaining 8 bits.

You shouldn’t really think about this in “bits”, it’s just floating point numbers and you’d need to do something quite extreme to really hit the internal signal path limits in plugins and hosts. But like kerfuffle mentioned above, the “recommended” range for the signals is from -1 to 1.

a multiplication by 128 is just shifting 8 bits. so the range between 1 and -1 must necessarily be 24 bits.

In any case, the reason for the post is that I assumed that exceeding 1 meant clipping. But there seems to be a comfortable margin with those “8 bits”. The only thing that is necessary is to control the gain just before recording or saving. Since in that process there could be clipping.

That’s right in case of fixed point integers, but floating point number work completely different. Shifting bits does not work with floats. You might want to read a bit about the IEEE 754 floating point number format and how the number is encoded in bits. One important fact is that floating point number don’t have an equidistant spacing between distinct values, the spacing is more fine grained towards small values, so there is already plenty of numerical precision in the -1 to 1 range which is usually absolutely sufficient for audio.

2 Likes

According to this information, the fraction has 23 bits of precision. I suppose that counting with the value 1, that is 24 bits of precision, which is enough for the high quality standard.

Perhaps this could be checked by someone with a 32-bit A/D system. generate a sine wave in the range of 1.0, and another in the range of 127.0, and check if the second did not saturate the signal, but got a real precision of 32 bits.

In any case, I am not very interested in this debate, for me the important thing is to be able to exceed those 24 bits, that is, values of up to 2, 3, 4… without disastrous clipping. And this is what I have verified

You can also increase its amplitude up to a million and not get clipping. It all depends on the host.

So, what host are you running it in?

That would not reveal that much. You have to keep in mind that a 32 bit A/D converter emits 32 bit integer sample values in a range of - 2,147,483,648 to 2,147,483,647 without any decimal part. In the same way, 24 bit A/D converters emit integer samples in a value range from −8,388,608 to 8,388,607, the same is true for the numerical values stored in a 24 bit wav files. Now the souncard driver or the file I/O code will map those integer values to normalized floating point values by a division/multiplication. So a sample with the integer value 8,388,607 coming in from your audio hardware interface will arrive as a sample with the 32 bit or 64 bit floating point value 1.0 at your audio application and thus at your audio processor. Accordingly, a sample with the value 1.0 leaving your processor will be scaled up by a multiplication so that it is mapped back to integer value 8,388,607.

So what happens if you emit samples with higher values than 1.0? That multiplication will generate integer values that exceed the 24 bit range and you’ll generate an overflow. Depending on the audio driver or file writing implementation this might be handled gracefully by protective saturation/clipping, but in every case this will degrade your audio quality. So: Yes, it’s totally fine to exceed the -1.0 to 1.0 range internally in your audio code, but you should care about not outputting higher values when you interface with integer sample based audio devices or files.

2 Likes

but from the tests I did (in standalone mode), I could reproduce and record the level of the sine wave multiplied up to 127.0 (no more). Deviating considerably from the usual normalized range.

I see no reason why a host, or any device that works at 32 bits, should have problems.

Although I’m thinking that maybe all this complication is unnecessary for me. From the tests I’m doing on my synth, I think I could multiply all my outputs by even 0.0001 without noticing any loss of quality. I guess the best thing is an output gain control, and forget about it, now that I have it more or less cleared up.