• Stars
    star
    107
  • Rank 317,262 (Top 7 %)
  • Language
    C
  • Created over 3 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

USB Audio DAC using inexpensive STM32F411 / 401 "Black Pill" and PCM5102A modules

STM32F4xx "Black Pill" + PCM5102A USB DAC

  • Uses inexpensive STM32F4xx "Black Pill" and PCM5102A modules
  • USB Full Speed Class 1 Audio device, no driver installation required
  • USB Bus powered
  • Supports 24-bit audio streams with Fs = 44.1kHz, 48kHz or 96kHz
  • USB Audio Volume (0dB to -96dB, 3dB steps) and Mute support
  • Isochronous with endpoint feedback (3bytes, 10.14 format) to synchronize sampling frequency Fs
  • STM32F4xx I2S master output with I2S Philips standard 24/32 data frame
  • Makefile build support for STM32F401CCU6 or STM32F411CEU6 modules
  • Optional MCLK output generation on STM32F411

When the USB Audio DAC device is enumerated on plug-in, it reports its capabilities (audio class, sampling frequency options, bit depth). If you configure the host audio playback settings optimally, a native 96kHZ 24bit audio file will play unmodified, while a 44.1kHz or 48kHz 16bit stream will be resized to 24bits and resampled to 96kHz.

I now understand why there is a market for audiophile DACs with higher end headphones. I was given a pair of used Grado SR60 headphones a long time ago and was unimpressed. With my laptop and smartphone headphone outputs they didn't sound particularly remarkable. In fact, they were lacking in bass response. And they are bulky, with a heavy cable. So they've been in a cupboard for the past 16-17 years.

I retrieved the Grado headphones and tried them out with the USB DAC. The difference is astonishing. I'm no golden-ears audiophile, but the amount of detail and frequency response is impressive. Have a look at this Cambridge Audio website comparing a dedicated USB Audio Class 1 DAC to a laptop headphone output. I have to agree with them.

Even 44.1kHz/16bit MP3 files sound much better when played back via the USB DAC. The PCM5102A isn't marketed as an "audiophile" component, but it obviously can drive high-quality headphones much better than standard laptop/smartphone DAC components.

I normally re-cycle my prototype modules for new projects, but I am now using this setup as a permanent headphone driver.

For a "budget audiophile" experience, try the Venus Electronics Monk Plus in-ear phones with the USB DAC. These headphones are (and look) really cheap, but the sound is amazing.

Credits

Software Development Environment

  • Ubuntu 22.04 AMDx64
  • STM32CubeIDE v1.12.0
  • STM32 F4 library v1.27.1
  • Makefile project. Edit makefile flags to
    • Select STM32F411 or STM32F401
    • Enable MCLK output generation (STM32F411 only)
    • Enable diagnostic printout on serial UART port

Hardware

  • WeAct STM32F411CEU6 or STM32F401CCU6 "Black Pill" development board
    • I2S_2 peripheral interface generates WS, BCK, SDO and optionally MCK
    • external R,G,B LEDs indicate sampling frequency
    • On-board LED for diagnostic status
    • UART2 serial interface for diagnostic information
  • PCM5102A I2S DAC module
    • configured to generate MCK internally
    • 100uF 6.3V tantalum capacitor across VCC and ground
F4xx    PCM5102A    LED     UART2   Description
--------------------------------------------------------------------
5V      VCC
-       3V3
GND     GND
GND     FLT                         Filter Select = Normal latency
GND     DMP                         De-emphasis off
GND     SCL                         Generate I2S_MCK internally
B13     BCK                         I2S_BCK (Bit Clock)
B15     DIN                         I2S_SDI (Data Input)
B12     LCK                         I2S_WS (LR Clock)
GND     FMT                         Format = I2S
B8      XMT                         Mute control
A6      -                           I2S_MCK (not used)
--------------------------------------------------------------------
B3                 RED              Fs = 96kHz
B6                 GRN              Fs = 48kHz
B9                 BLU              Fs = 44.1kHz
C13             on-board            Diagnostic
--------------------------------------------------------------------
A2                         TX       Serial debug
A3                         RX
GND                        GND
PA0                                 KEY button. Triggers endpoint  
                                    feedback printout if enabled with  
                                    DEBUG_FEEDBACK_ENDPOINT
--------------------------------------------------------------------

Checking USB Audio device on Ubuntu 20.04

  • Execute lsusb with and without the USB-Audio DAC plugged in, you should see the new USB device

  • Execute aplay -L and look for PCM5102 DAC

  • Run the Sound application without the USB-Audio DAC plugged in and check the Speaker/Headphone output options
  • Plug in the USB-Audio DAC and check again, you should see at least one new option. Select this for playing sound output via the USB-Audio DAC
  • Execute cat /proc/asound/DAC/stream0 when a song is playing

Optimizing Pulseaudio on Ubuntu 20.04

Edit /etc/pulse/daemon.conf as root

  • Force re-sampling to 96kHz
  • Resize to 24bits
  • Use highest quality re-sampling algorithm
  • Save file, log out and log in again for the changes to take effect

Optimizing Windows 10

Control Panel Sound playback device properties dialog

Optimizing Android

After using customization settings in Poweramp music player on a Samsung Galaxy F62 :

Endpoint Feedback mechanism

Unfortunately, we do not have any means of measuring the actual Fs (accurate to 10.14 resolution) generated by the PLLI2S peripheral on an SOF resolution interval of 1mS. So we calculate a nominal Fs value by assuming the HSE crystal has 0ppm accuracy (no error), and use the PLLI2S N,R, I2SDIV and ODD register values to compute the generated Fs value. For example when MCLK output is disabled, the optimal register settings result in a value of 96.0144kHz.

Since the USB host is asynchronous to the PLLI2S Fs clock generator, the incoming Fs rate of audio packets will be slightly different. We use a circular buffer of audio packets to accommodate the difference in incoming and outgoing Fs.

The USB driver writes incoming audio packets to this buffer while the I2S transmit DMA reads from this buffer. We start I2S playback when the buffer is half full, and then try to maintain this position, i.e. the difference between the write pointer and read pointer should optimally be half of the buffer size.

Any change to this pointer distance implies the USB host and I2S playback Fs values are not in sync. To correct this, we implement a PID style feedback mechanism where we report an ideal Fs feedback frequency based on the deviation from the nominal pointer distance. We want to avoid the write process overwriting the unread packets, and we also want to minimize the oscillation in Fs due to unnecessarily large corrections.

This is a debug log of changes in Fs due to the implemented mechanism. The first datum is the SOF frame counter, the second is the pointer distance in samples, the third is the feedback Fs. As you can see, the feedback is able to minimize changes in pointer distance AND oscillations in Fs frequency.

More Repositories

1

ESP32_IMU_BARO_GPS_VARIO

GPS altimeter/variometer with LCD display, routes with waypoints, data/gps track logging, bluetooth NMEA sentence transmission, wifi AP + webpage configuration
Jupyter Notebook
90
star
2

ESP32-LCD-I2S

Espressif ESP32 driving a controller-less monochrome lcd with parallel I2S bus
C
59
star
3

Kalmanfilter_altimeter_vario

Kalman filter to estimate altitude and climbrate(sinkrate) by fusing altitude and acceleration sensor data
C++
34
star
4

ESP32-WROOM32-Eagle-Breakout

Breakout board for ESP32 WROOM32 module
Prolog
18
star
5

ESP8266_BLUETOOTH_AUDIO_VARIO

A bluetooth audio vario with zero-lag climb/sink rate feedback. Configurable and firmware upgradable via WiFi. Uses off-the-shelf modules. Schematic and PCB layout provided.
C++
18
star
6

ESP32_MULTI_METER

ESP32 Multi-meter : Current and voltage meter using an INA226 sensor, frequency counter and generator
C++
15
star
7

ESP32_IMU_BARO_GPS_LOGGER

ESP32 high-speed flash data logger for IMU (accelerometer+gyro+magnetometer), GPS, pressure sensor readings.
C
14
star
8

ESP8266_MPU9250_MS5611_VARIO

DIY friendly, cheap, accurate, fast responding WiFi-configurable audio variometer using easily available modules
C++
12
star
9

SIPEED_TANG_PRIMER

Projects using the Sipeed Tang Primer FPGA development board
Verilog
11
star
10

STM32_CODE_EXAMPLES

Code examples demonstrating usage of peripherals and features on STM32 Cortex micro-controllers
C
11
star
11

FPGA_STEREO_CROSSOVER

Stereo digital 2-way crossover filters processing I2S audio (16bit or 24bit) streams
C++
11
star
12

ESP32C3_BLUETOOTH_AUDIO_VARIO

ESP32-C3 audio vario using Kalman filter to fuse acceleration and pressure sensor data. Bluetooth transmission of LK8EX1 sentences.
C++
10
star
13

ov7670fifo

ESP32 web server displaying frames from a 'OV7670+AL422 FIFO' camera module
C
10
star
14

ESP32_WROVER_BREAKOUT

Breadboard compatible breakout PCB for ESP32-WROVER with TPS82140 power supply
8
star
15

ESP32_ASYNC_WEB_SERVER_SPIFFS_OTA

Demo of ESP32 Async Web Server for webpage access and OTA firmware updates, SPIFFS hosted html and css files, DNS for user friendly webpage url. Visual Studio Code + PlatformIO project.
C++
7
star
16

ESP8266_MAX30102_SPO2_PULSE_METER

ESP8266 SPO2 and Pulse meter using MAX30102 sensor
C++
6
star
17

ESP8266_SPO2_PULSE_LOGGER

Displays SPO2 & heart-rate measurements from a MAX30102 sensor on an OLED display and logs the data in real-time to a Thingspeak channel
C++
6
star
18

VhARIO-ESPC3

Kicad schematic and layout for ESP32-C3 + MPU9250 + MS5611 audio vario
4
star
19

STM32F103_MAX21105_MS5611_VARIO

Basic altimeter/variometer that fuses accelerometer and barometric sensor data to minimize response lag.
C
4
star
20

ms5611

MEAS MS5611 pressure sensor library for altitude / variometer applications, uses floating point for better resolution
C++
4
star
21

FT2232H_CODE_EXAMPLES

Ubuntu and Windows 10 console applications using FT2232HL USB adapter to communicate with SPI and I2C slave devices
C
4
star
22

ESP32_AUTO_WATER

ESP32-C3 automatic plant watering system using capacitive moisture sensor and DS3231 real-time clock. Logs watering history to Google Sheets document. Configurable and firmware upgradable via standalone WiFi Access Point and webserver.
C++
4
star
23

ESP8266_ARDUINO_AP_OTA

OTA firmware update of ESP8266 by setting up as WiFi AP
C++
3
star
24

MS5611_I2C_ARDUINO

Arduino compatible MS5611 class using I2C interface and floating point pressure and altitude computation
C++
1
star