element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
RoadTests & Reviews
  • Products
  • More
RoadTests & Reviews
Review Blogs GIGA WAV Player
  • Blogs
  • RoadTest Forum
  • Documents
  • RoadTests
  • Reviews
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join RoadTests & Reviews to participate - click to join for free!
  • Share
  • More
  • Cancel
  • Author Author: dougw
  • Date Created: 2 Nov 2025 12:48 AM Date Created
  • Views 75 views
  • Likes 10 likes
  • Comments 3 comments
Related
Recommended
  • dougw
  • WAV Player
  • arduino giga r1
  • USB audio files

GIGA WAV Player

dougw
dougw
2 Nov 2025

Intro

Previously I investigated how to use the GIGA Display's microphone, but now it is time to explore the audio out put, This blog demonstrates how the Arduino GIGA R1 can read a WAV audio file from a USB memory device and play it using its DAC output via its audio connector.

Audio files can be large so it is useful to be able to store them on external USB memory. It is also useful to have a display available to show the status of audio activity.

WAV Player Video

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

WAV Player Sketch

/*
 * GIGA WAV Player
 * GIGA R1 - Audio Playback of a wav file store on a USB memory device
 * Simple wav format audio playback via 12-Bit DAC output by reading from a USB drive.
 * This sketch assumes the USB memory device is named "USB"
 * This sketch assumes the audio file is named "GIGAchorus.wav"
 * by Doug Wong 2025
*/

#include <Arduino_AdvancedAnalog.h>
#include <DigitalOut.h>
#include <Arduino_USBHostMbed5.h>
#include <FATFileSystem.h>
#include "Arduino_GigaDisplay_GFX.h"

#define WHITE 0xffff
#define BLACK 0x0000
#define YELLOW 0xFFE0
#define CYAN 0x07FFF
#define PURPLE 0x8010

AdvancedDAC dac0(A12);

USBHostMSD msd;
mbed::FATFileSystem usb("USB");

GigaDisplay_GFX display;

FILE * file = nullptr;
int sample_size = 0;
int samples_count = 0;


void setup()
{
  Serial.begin(115200);
  while (!Serial);

  display.begin();
  display.setRotation(1); // Landscape mode
  display.fillScreen(PURPLE);
  display.setTextColor(YELLOW);
  display.setTextSize(8);
  display.setCursor(35, 200);
  display.println("GIGA WAV Player");
  delay(4000);
  display.fillScreen(PURPLE);
  display.setTextSize(4);
  display.setCursor(10, 10);
  display.println("Reading USB...");

  /* Enable power for HOST USB connector. */
  pinMode(PA_15, OUTPUT);
  digitalWrite(PA_15, HIGH);

  if (!msd.connect()) {
    display.println("Insert USB memory device");
    while (!msd.connect()) delay(100);
  }
  display.println("Mounting USB...");
  int const rc_mount = usb.mount(&msd);
  if (rc_mount)
  {
    display.println("Error mounting USB device ");
    display.println(rc_mount);
    return;
  }

  display.println("Opening audio file ...");

  /* 16-bit PCM Mono 16kHz realigned noise reduction */
  file = fopen("/USB/GigaChorus.wav", "rb");
  if (file == nullptr)
  {
    display.print("Error opening audio file: ");
    display.println(strerror(errno));
    return;
  }

  display.println("Reading audio header ...");

  delay(200);
  display.fillScreen(PURPLE);
  display.setTextSize(3);
  display.setCursor(10, 1);

  struct wav_header_t
  {
    char chunkID[4]; //"RIFF" = 0x46464952
    unsigned long chunkSize; //28 [+ sizeof(wExtraFormatBytes) + wExtraFormatBytes] + sum(sizeof(chunk.id) + sizeof(chunk.size) + chunk.size)
    char format[4]; //"WAVE" = 0x45564157
    char subchunk1ID[4]; //"fmt " = 0x20746D66
    unsigned long subchunk1Size; //16 [+ sizeof(wExtraFormatBytes) + wExtraFormatBytes]
    unsigned short audioFormat;
    unsigned short numChannels;
    unsigned long sampleRate;
    unsigned long byteRate;
    unsigned short blockAlign;
    unsigned short bitsPerSample;
  };

  wav_header_t header;
  fread(&header, sizeof(header), 1, file);

  display.println("WAV File Header read:");
  char msg[64] = {0};
  snprintf(msg, sizeof(msg), "File Type: %s", header.chunkID);
  display.println(msg);
  snprintf(msg, sizeof(msg), "File Size: %ld", header.chunkSize);
  display.println(msg);
  snprintf(msg, sizeof(msg), "WAV Marker: %s", header.format);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Format Name: %s", header.subchunk1ID);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Format Length: %ld", header.subchunk1Size);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Format Type: %hd", header.audioFormat);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Number of Channels: %hd", header.numChannels);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Sample Rate: %ld", header.sampleRate);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Sample Rate * Bits/Sample * Channels / 8: %ld", header.byteRate);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Bits per Sample * Channels / 8: %hd", header.blockAlign);
  display.println(msg);
  snprintf(msg, sizeof(msg), "Bits per Sample: %hd", header.bitsPerSample);
  display.println(msg);

  /* Find the data section of the WAV file. */
  struct chunk_t
  {
    char ID[4];
    unsigned long size;
  };

  chunk_t chunk;
  snprintf(msg, sizeof(msg), "id\t" "size");
  display.println(msg);
  /* Find data chunk. */
  while (true)
  {
    fread(&chunk, sizeof(chunk), 1, file);
    snprintf(msg, sizeof(msg), "%c%c%c%c\t" "%li", chunk.ID[0], chunk.ID[1], chunk.ID[2], chunk.ID[3], chunk.size);
    display.println(msg);
    if (*(unsigned int *) &chunk.ID == 0x61746164)
      break;
    /* Skip chunk data bytes. */
    fseek(file, chunk.size, SEEK_CUR);
  }

  /* Determine number of samples. */
  sample_size = header.bitsPerSample / 8;
  samples_count = chunk.size * 8 / header.bitsPerSample;
  snprintf(msg, sizeof(msg), "Sample size = %i", sample_size); display.println(msg);
  snprintf(msg, sizeof(msg), "Samples count = %i", samples_count); display.println(msg);

  /* Configure the advanced DAC. */
  if (!dac0.begin(AN_RESOLUTION_12, header.sampleRate * 2, 256, 16))
  {
    display.println("Failed to start DAC1 !");
    return;
  }

  delay(1500);
  display.fillScreen(PURPLE);
  display.setCursor(50, 50);
  display.setTextSize(5);
  display.println("Playing ......");
  display.setCursor(50, 200);
  display.setTextSize(7);
  display.println("GIGAchorus.WAV");
}

void loop()
{
  if (dac0.available() && !feof(file))
  {
    /* Read data from file. */
    uint16_t sample_data[256] = {0};
    fread(sample_data, sample_size, 256, file);

    /* Get a free buffer for writing. */
    SampleBuffer buf = dac0.dequeue();

    /* Write data to buffer. */
    for (size_t i = 0; i < buf.size(); i++)
    {
      /* Scale down to 12 bit. */
      uint16_t const dac_val = ((static_cast<unsigned int>(sample_data[i])+32768)>>4) & 0x0fff;
      buf[i] = dac_val;
    }

    /* Write the buffer to DAC. */
    dac0.write(buf);
  }
}

Discussion

It took me a while to get my little audio amplifier together and the cabling took even longer. There is potential to introduce audio noise if the power supplies are noisy or the cables aren't very good. I had a bit of an issue finding an audio cable connector that would fit beside my USB memory stick, which is old and big. When I finally got everything working I was surprised at how good it sounded.

The purple background on the display worked great to allow the display to be captured well on camera. The system was set up near my computer - not my workbench/studio area, so lighting was not ideal, but this blog is about audio, so I can live with non-ideal lighting.

It is taking a while to get through testing the myriad features of the GIGA kit, partly because I am trying to expand on the existing demo software and show how features combine to provide system level performance. This demo used the Audio output DAC and jack in combination with external USB memory capability and the GIGA Display to create an audio file player. 

Links:

Unboxing and display demo

Touch Screen and USB memory demo

GIGA display of an Arducam video camera

GIGA VU Meter and Spectrum Analyzer

GIGA WAV Player

Giga R1 Road Test page

  • Sign in to reply
  • DAB
    DAB 1 hour ago

    Nice update Douglas.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • dougw
    dougw 1 day ago in reply to Stuart_S

    I'm sure the GIGA could do it (there are examples that show how to do this for any Arduino) but the ESP32 can convert wav to I2S by itself:

    https://www.youtube.com/watch?v=cnBDMpMSeQI

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Stuart_S
    Stuart_S 1 day ago

    Having recently extracted a PCM1716 (DAC) from an early model DVD player that I might eventually use in making a bluetooth player from an ESP32, how hard would it be to code the GIGA to output the I2S stream (for the WAV file) and a sampling clock for an external DAC?. 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube