Numeric Value of signal

toyosm

Well-known member
I'm working on a reverb algorithm, heavily based on Pio's plate reverb techniques plus a bunch of other Audio Blocks for filtering and other effects. I was having some troubles with the levels, the overall output signal becomes too low and I had to compensate (too much in my opinion) when mixing that with an analog signal. So started to go block by block and checking the input and output levels to see where the signal amplitude gets lost and found out that the reverb was one of the lowest. Made a simple test -> Input -> Reverb -> Amplifier block -> Output. If I set the gain of the amplifier block on 2 or more, the output sound stopped. Tried to adjust the input attenuation of the reverb, got better but got clipping. So started to print the signal and plot it and check the numeric values of it to see if I could see any issues there. The values where all negative, with a span of -10000 to -20000 approximately, so when I multiplied by 2 or more with the gain amplifier got out of range.
Got surprised by those numbers, because I thought that it will be something more like a 0 centered signal. I introduced an offset to see if that could be "compensated" and the overall situation got better, got a better range to amplify the signal and get the levels back to something more useful.

In Pio's code uses floating point on the calculations and then converts it back to int16_t for output, so on the input does this:

Code:
arm_q15_to_float((q15_t *)blockL->data, input_blockL, AUDIO_BLOCK_SAMPLES);

Where blockL is an audio_block_t pointer and input_blockL is a float32_t buffer with a size of 128 to accommodate the audio block. If I plot right after that conversion, at the beggining of the code I have an offset set there. On the output, to get back to the int16_t, does this:

Code:
 outblockL->data[i] = (int16_t) (outputLeft * 32767.0f);

Where outputLeft has the output signal and then make transmit(outblockL, 0) to get that output out of the effect block output 0.

Testing another block of effect, the signal is 0 centered, with positive and negative values and I get a decent output level that I can adjust at will.


So, the question is, "what's the correct numerical value that the signal should take?" a 0 centered signal?, is that offset correct or not?, has to be something to the conversion from int to float? how can I correct that?
 
Last edited:
Should be zero centred. The conversions seem ok, not sure why arm_float_to_q15 isn't used for the output conversion though as it is probably faster and does a proper saturating conversion.
 
Well, I managed to "solve" or at least "patch" this issue with a DC Blocker code snippet, now I have the signal centered to 0 as it should be and can change the amplitude way better than before, here's the snippet if someone else wants to use it. Now I unlocked a new paranoia on checking the output offset of every audio block I'm using:

Code:
float32_t dc_prev_input = 0.0f;  // Previous input sample
float32_t dc_prev_output = 0.0f; // Previous output sample
float32_t dc_blocked;            // DC-blocked output sample
const float32_t DC_BLOCKER_R = 0.995f; // Feedback coefficient for the DC blocker

float output = master_lowpass; // Apply DC blocker - master_lowpass is the output of the audio block, in this case is called master_lowpass, but change to whatever is the variable that holds the output samples
float dc_blocked = output - dc_prev_input + DC_BLOCKER_R * dc_prev_output; 
dc_prev_input = output; 
dc_prev_output = dc_blocked; // Store the result 
outblock->data = (int16_t)(dc_blocked * 32767.0f); // change the outblock->data to whatever name you're using for the output block
 
Back
Top