1
\$\begingroup\$

I'm building a USB microphone based on STM32F407 discovery board, it captures audio but produces quiet but noticeable hiss with its spectrum shown below:

enter image description here

I'm using oversampling to get additional 2 bits of resolution but the issue is present without oversampling as well (I just used DMA to write ADC samples directly into the USB output buffer to test this). Here's my current implementation:

DMA settings:

  hdma_adc1.Instance = DMA2_Stream0;
  hdma_adc1.Init.Channel = DMA_CHANNEL_0;
  hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  hdma_adc1.Init.Mode = DMA_CIRCULAR;
  hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
  hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

ADC settings:

  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO;  // runs at 768 kHz for 14 bit @ 48 kHz
                                                               // SYSCLK = 96 MHz, TIM8 ARR = 125 - 1
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

ADC read and oversampling functions:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    USBD_AUDIO_HandleTypeDef *haudio = hUsbDeviceFS.pClassData;
    int16_t *buf_part = haudio->in_buffer + (AUDIO_IN_PACKET / 2) * haudio->in_buffer_half;  // get USB mic buffer pointer
    
    /* Oversample for +2 bits and remove mic amplifier offset */
    for (uint16_t i = 0; i < (AUDIO_IN_PACKET / 2); i++) {
    int32_t avg_value = 0;
        for (uint16_t j = 0; j < ADC_BUF_SIZE; j++) {
            avg_value += adc_buffer[ADC_BUF_SIZE * i + j];
        }
        buf_part[i] = (avg_value / 4) - 6826;
    }
}

void ADC_to_MIC(void)
{
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUF_SIZE * (AUDIO_IN_PACKET / 2));
}

Data IN request handler:

static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
  USBD_AUDIO_HandleTypeDef *haudio;
    
  haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData;
    
    if (epnum == (AUDIO_IN_EP & 0x7F))
  {
        haudio->in_buffer_half = !haudio->in_buffer_half;
        uint16_t prev = (AUDIO_IN_PACKET / 2) * !haudio->in_buffer_half;  
               /* double inversion serves as initialization to 1 or 0  */
        ADC_to_MIC();
        
        USBD_LL_FlushEP  (pdev, AUDIO_IN_EP);
        USBD_LL_Transmit (pdev, AUDIO_IN_EP, (uint8_t*)(haudio->in_buffer + prev), AUDIO_IN_PACKET);
    }
    
  return (uint8_t)USBD_OK;
}

What may cause the hiss to appear? I've ruled out hardware issues by reading the ADC into the I2S DAC, there was just a bit of white noise, no hiss at all. Also when I connect ADC input to ground, hiss persists, so I think that the issue is somewhere in the USB part. 1 kHz peak on the spectrum and its harmonics suggest me that the ADC may be out of sync with DataIn host requests because they happen exactly at 1 kHz rate in the full-speed mode but I don't see how to solve this problem.

\$\endgroup\$
7
  • \$\begingroup\$ How is the microphone biased? How is the MCU powered? How is your PCB layout? Most likely just the USB requests happening at 1 kHz couple into ground or positive MCU supplies and then it's there. Even expensive USB audio interfaces can have this 1kHz disturbance. \$\endgroup\$
    – Justme
    Commented Jul 13, 2021 at 13:38
  • \$\begingroup\$ Have you tried putting the data to USB and to the I2S DAC at the same time? Maybe the hiss will be there then and it is a coupling problem only present when USB is active. \$\endgroup\$
    – Arsenal
    Commented Jul 13, 2021 at 13:39
  • \$\begingroup\$ Did you use an anti-alias filter? Provide a schematic of the audio interface and links to the microphone. \$\endgroup\$
    – Andy aka
    Commented Jul 13, 2021 at 13:40
  • \$\begingroup\$ @Justme I'm using MAX9814 mic amplifier module, connected with 15 cm long jumper wires. I'm not sure about the layout, it's an STM32F4DISCOVERY board. \$\endgroup\$
    – Archimedes
    Commented Jul 13, 2021 at 13:40
  • 1
    \$\begingroup\$ @Archimedes: "Hiss" is white noise. What your spectrum is showing is not what I'd call hiss. You've got some power line hum in there (way down close to zero Hz.) The main thing I see is a 1000Hz signal with some harmonics. \$\endgroup\$
    – JRE
    Commented Jul 13, 2021 at 13:40

1 Answer 1

4
\$\begingroup\$

You are just expecting too much from your setup.

The 1 kHz peaks are the USB data transfers that happens at a rate of 1 kHz. So that is not "hiss", as hiss would be noise.

The STM32F4 Discovery board is a kit to explore and make prototypes, not highly optimized suppressing getting USB bus periodic transactions getting coupled into ADC conversions.

Whenever there are periodic packet transactions at 1kHz, also the board power consumption has periodic increases at a rate of 1kHz. Currents flowing in the board at 1 kHz will couple everywhere unless the whole system is carefully designed.

So that is what is causing the peak at 1kHz, and it also shows that there are both odd (3, 5, 7 kHz etc) and even (2, 4, 6 kHz etc) harmonics, and as the peak at 4 kHz is larger than nearby peaks, it might tell something about the length of the burst or some other periodic thing happening at 250us rate.

It also does not help a bit when the mic amplifier dangles from the Discovery board with 15 cm long jumper wires, instead of having at least some sort of audio cable with at least some kind of shield.

\$\endgroup\$
1
  • \$\begingroup\$ Indeed, I've tested 3V rail noise and it has the exact same spectrum. \$\endgroup\$
    – Archimedes
    Commented Jul 13, 2021 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.