Audio Shield Buzz

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,

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.
 

Attachments

  • buzz.jpeg
    buzz.jpeg
    133.8 KB · Views: 31
Well I solved the problem, but I'm not exactly sure how. Some combination of redoing my wiring with better soldering and improved shielding, and (more likely, although results from this alone are inconsistent) some active noise-cancelling code I added. I took this thing to rehearsal last week and had a lot less noise coming from my amp than my guitarist did, so problem solved. My next problem is I want a decent sized touch screen to control effects. I've got pots and switches but I've also got big dreams. I bought this thing but I haven't managed to get anything but garbage to show, even using the ST7735_t3 big-scteen-t4 branch. Anyone have any advice there?
 
I bought this thing but I haven't managed to get anything but garbage to show, even using the ST7735_t3 big-scteen-t4 branch. Anyone have any advice there?
As an alternative to controlling your own graphics you might want to consider a Nextion display. Basically they are LCD displays with built in intelligence. They can be programmed via their own high level language.
I have built a Teensy library for the Nextions and also produced a (rubbish) YouTube video as an example.

Not saying you should go this way, just offering an alternative path.
By the way the 4.3" Nextion Edge looks like a nice device.
 
Back
Top