greenscreen
New member
Hi,
I'm working on a digital multi-effects pedal using a Teensy 4.0 w/ audio shield. I'm having some problems with noise! Specifically, a high-pitched sawtooth kind of buzzing.
For this project, I found Paul's audio library somewhat unsuited, so I stripped it down to just the code that interfaces with the SGTL5000, and wrote my own DSP framework. Having obtained the samples from I2S via the DMA, I then convert to float, put it through my graph-based DSP pipeline infrastructure, then convert back to int and send it back out to the shield. This is all hooked up to 1/4" jacks and input/output with op-amps and etc. All the hardware is confirmed good, and if I run a minimal passthrough using the audio library everything is dandy. Additionally, if I copy the DMA input samples directly to DMA output, everything is good. If I go through a minimal pipeline in my code, which simply copies input to output, there's this horrible buzzing. I've found that if I circumvent everything, and copy the samples to output, but first convert to float and back, the buzzing is present as well! Specifally, in my i2s input function, called when a new block is available from I2S,
if I #define SKIP_EVERYTHING and just copy straight to output, without TRY_CONVERT defined, the audio is clean. However if I #define TRY_CONVERT, and simply convert from int16_t to float and back, via these functions:
the buzing is present. I have no clue how or why this is happening.
Code can be found here. Please excuse the preponderance of printlines and the general mess I have made of the code while pulling my hair out over this. Please note also that any serial output can be disabled by un-def'ing ALLOW_PRINTLINES in m_printf.cpp, which does not fix the buzzing, so it is not a result of long I/O waits messing up the DMA. This is not caused by USB in any way. It occurs when there is no USB anywhere near the device. I have cut the VUSB-VIN trace, and am using an external 9v A/C adaptor, through a L7805CV regulator, with decoupling caps. The buzzing occurs equally through a combo or through a USB interface. Also, I am using a star ground, and it is not switching noise. I have isolated all these factors. Somehow, somehow it is the int -> float -> int conversion where things go wrong.
I'm working on a digital multi-effects pedal using a Teensy 4.0 w/ audio shield. I'm having some problems with noise! Specifically, a high-pitched sawtooth kind of buzzing.
For this project, I found Paul's audio library somewhat unsuited, so I stripped it down to just the code that interfaces with the SGTL5000, and wrote my own DSP framework. Having obtained the samples from I2S via the DMA, I then convert to float, put it through my graph-based DSP pipeline infrastructure, then convert back to int and send it back out to the shield. This is all hooked up to 1/4" jacks and input/output with op-amps and etc. All the hardware is confirmed good, and if I run a minimal passthrough using the audio library everything is dandy. Additionally, if I copy the DMA input samples directly to DMA output, everything is good. If I go through a minimal pipeline in my code, which simply copies input to output, there's this horrible buzzing. I've found that if I circumvent everything, and copy the samples to output, but first convert to float and back, the buzzing is present as well! Specifally, in my i2s input function, called when a new block is available from I2S,
C:
void i2s_in_transmit(m_audio_block_int *block, unsigned char index)
{
#ifdef SKIP_EVERYTHING
#ifdef TRY_CONVERT
float f[AUDIO_BLOCK_SAMPLES];
convert_block_int_to_float(f, block->data);
convert_block_float_to_int(i2s_output_blocks[1 - index].data, f);
#else
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
{
i2s_output_blocks[1 - index].data[i] = block->data[i];
}
#endif
#else
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
{
i2s_input_blocks[index].data[i] = block->data[i];
}
#endif
}
if I #define SKIP_EVERYTHING and just copy straight to output, without TRY_CONVERT defined, the audio is clean. However if I #define TRY_CONVERT, and simply convert from int16_t to float and back, via these functions:
C:
#define MAX_INT 32768.0
int convert_block_int_to_float(float *dest, int16_t *src)
{
if (!dest || !src)
return ERR_NULL_PTR;
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
dest[i] = (float)src[i];
arm_scale_f32(dest, 1.0 / MAX_INT, dest, AUDIO_BLOCK_SAMPLES);
return NO_ERROR;
}
int convert_block_float_to_int(int16_t *dest, float *src)
{
if (!dest || !src)
return ERR_NULL_PTR;
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
{
dest[i] = (int16_t)(max(min((src[i] * MAX_INT), MAX_INT), -MAX_INT));
}
return NO_ERROR;
}
the buzing is present. I have no clue how or why this is happening.
Code can be found here. Please excuse the preponderance of printlines and the general mess I have made of the code while pulling my hair out over this. Please note also that any serial output can be disabled by un-def'ing ALLOW_PRINTLINES in m_printf.cpp, which does not fix the buzzing, so it is not a result of long I/O waits messing up the DMA. This is not caused by USB in any way. It occurs when there is no USB anywhere near the device. I have cut the VUSB-VIN trace, and am using an external 9v A/C adaptor, through a L7805CV regulator, with decoupling caps. The buzzing occurs equally through a combo or through a USB interface. Also, I am using a star ground, and it is not switching noise. I have isolated all these factors. Somehow, somehow it is the int -> float -> int conversion where things go wrong.