Playing More Than Two Audio Files Simultaneously Using Arduino MEGA

Hello,

I am working on a project where I need to play at least four audio files simultaneously and independently. I tried the TMRpcm library for playing audio files. While going through the features of the library I came to know that I can play two audio files simultaneously and independently if I use Arduino MEGA. I followed the example code of "Multi-Track 4pins" and customized that as per my style and I found that it is working. Now I can play and stop two audio files whichever I want. I am sharing my code blew:

/*
This sketch demonstrates playing 2 audio tracks simultaneously using two timers. (Mega etc ONLY)

Steps:
1. Edit pcmConfig.h
    a: Uncomment #define ENABLE_MULTI
    b: Uncomment #define MODE2

2. Usage is as below. See https://github.com/TMRh20/TMRpcm/wiki/Advanced-Features#wiki-multi-mode for
   additional informaiton.

*/

#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>

#define SD_ChipSelectPin 53  //example uses hardware SS pin 53 on Mega2560
//#define SD_ChipSelectPin 4  //using digital pin 4 on arduino nano 328, can use other pins

TMRpcm music;   // create an object for use in this sketch 

void setup() {
  
  music.speakerPin = 11; //5,6,11 or 46 on Mega, 9 on Uno, Nano, etc
  pinMode(12,OUTPUT);  //Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45
  
  music.speakerPin2 = 5; //Enable the second set of timer pins
  pinMode(2,OUTPUT);
  
  Serial.begin(115200);
  
  if (!SD.begin(SD_ChipSelectPin)) {  
    return;
  }else{
    Serial.println("SD OK"); 
  }

  //Setting the volume and quality of music
music.setVolume(5);    //   0 to 7. Set volume level
music.quality(1);        //  Set 1 for 2x oversampling Set 0 for normal
  
}


void loop() {

  if (Serial.available())
  {
    char c = Serial.read();
      if (c == 'a')
      {
      Serial.println ("Play Button Pressed for speaker1");
      music.play("2.wav",0);
      }
      if (c == 'm')
      {
      Serial.println ("Play Button Pressed for speaker2");
      music.play("3.wav",1);
      }
      if (c == 'q')
      {
        Serial.println ("Pause Button Pressed. Music paused");
        music.pause();
      }
      if (c == 'b')
      {
        Serial.println ("Stop Button Pressed for speaker1");
       music.stopPlayback(0);
      }
      if (c == 'n')
      {
        Serial.println ("Stop Button Pressed for speaker2");
       music.stopPlayback(1);
      }
  }

}

My questions are, "Will it be possible to play more than two audio files simultaneously using Arduino (MEGA or any other boards)? if not then what is the main reason behind this? Would you please explain the exact reason? Is there any other way to play multiple audio files independently and simultaneously rather than Arduino platform?"

I am a beginner with Arduino and audio. I am looking for expertise suggestion of my queries.

saddam2k9:
My questions are, "Will it be possible to play more than two audio files simultaneously using Arduino (MEGA or any other boards)?

Short answer: No (unless you somehow manage to adapt the library to your needs).

saddam2k9:
if not then what is the main reason behind this? Would you please explain the exact reason?

Apart from having to adapt the library's code, there are still some other caveats:

  • More simultaneous tracks means more buffers; and more buffers means more RAM usage (ATmega328P-based boards might not handle this due to lack of free RAM memory).
  • Data retrieve overhead is big; specially in a MCU without DMA and a barely fast enough SPI bus. Switching read attempts between files causes SD's handler to seek and read a whole different data block (of 512 bytes), even if a single byte is needed; thus making the overhead even worse. Buffers are created to alleviate this problem; however, having four tracks playing simultaneously and knowing that buffer filling is a sequential process, there would be a problem if the buffer is "consumed" faster than filled (which can cause popping or creaking sounds). You can avoid this by increasing buffer size (memory usage increments by a factor of 2 * n tracks since TMRpcm uses double buffering) or decreasing sample rate on all four files.
  • Running out of DAC-capable (PWM as well) pins; unless some kind of audio mixing algorithm is applied by software. In practice this isn't a problem, because most MCUs have at least four PWM-capable pins; only one 16-bit timer is required to set the playback's sample rate (and trigger the buffer-filling routine in case you don't want it in the main program).

Despite of all this, I won't say it's impossible (only applies to Arduino Mega due to memory issues). It's just matter of will and time (specially figuring out how TMRpcm works) to create the code that satisfies your particular needs.

saddam2k9:
Is there any other way to play multiple audio files independently and simultaneously rather than Arduino platform?

SBCs (e.g. Raspberry Pi), and most of the ARM-based development boards (preferably with DMA capability).

The ESP boards lack of DMA, so they run the same problem as the AVR MCUs (enabling Wi-Fi will create another CPU overhead) and any other interrupt-driven I/O; nevertheless, they are fast and plenty in RAM memory.

PD: to all this, why do you need to play four simultaneous audio tracks?

Thank you so much for your comprehensive explanation of my questions. I think I have got my answers. I will try to dig down details how the TMRpcm library works and try to customize that as per my requirements.

I am not expert in creating and modifying Arduino libraries and my programming skills are in basic level. Would you please give me any reference link or guideline to understand the library and modify as per my need?

PD: to all this, why do you need to play four simultaneous audio tracks?

Actually, I am working on a haptics project. I need to design a vibratory haptic feedback system. I am using LRAs form Tactile Labs as the vibratory actuators. I need to vibrate those LRAs simultaneously and independently. I am using audio files that contain the vibration patterns for the LRAs. The audio files go out from Arduino board and then pass through an amplifier and finally vibrates the LRAs. To have the independent control of LRAs I need to play multiple audio files (contains the haptic pattersn) simultaneously and independently. I am using four LRAs right now so I need to play four audio files simultaneously.

This link has the code for reading more than one file from an SD card and playback through PWM

This is done by the Multi Mode feature described at:-

Grumpy_Mike:
This link has the code for reading more than one file from an SD card and playback through PWM
https://github.com/TMRh20/TMRpcm

This is done by the Multi Mode feature described at:-
https://github.com/TMRh20/TMRpcm/wiki/Advanced-Features

Thank you for providing me the links. I have followed the links and found that in Multi-Mode TMRpcm library can play up to 2 audio files in Arduino Mega.

Currently, I can play 2 audio files (.WAV) simultaneously and independently on Arduino Mega using the Multi-Mode of TMRpcm library. I want to play 4 audio files simultaneously from Arduino Mega. How can I do that?

I want to play 4 audio files simultaneously from Arduino Mega. How can I do that?

After a bit of research I don't think you can.
See https://github.com/TMRh20/TMRpcm/issues/26

I was sure I had seen a demo of three sounds being played at the same time but I can't find it now.

You can do this with a Teensy 3.5 or 3.6 though, it is much faster and has more memory.

Grumpy_Mike:
After a bit of research I don't think you can.
See https://github.com/TMRh20/TMRpcm/issues/26

I was sure I had seen a demo of three sounds being played at the same time but I can't find it now.

I insist that is possible, but only on Arduino Mega. Also adapting the code to such thing isn't that easy, but it's achievable.

I'm currently in an effort on doing just that, because I'm curious in how the ATmega2560 will behave by pushing a bit further its limits on playing 4 tracks (even stereo is still possible) simultaneously. Altough my modification will have some differences compared to the original:

  • No oversampling and volume control: I don't know how oversampling is made on TMRpcm and I remove a little overhead by scraping the volume feature (the sample is used as it is).
  • SPI is always in full speed: since SD card reading is relatively slow.
  • Output pins are fixed: if you wanna play four stereo tracks, you would need quite a lot PWM outputs anyway (and "chew up" at least 4 timers). I will leave only the possibility of saving timer2/5 or timer1 (timer3 will handle sample rate in this mode); timer0 is never used in order to preserve delay(), millis() and micros() functionality.
  • No recording capability: I mean, this is a proof of concept for playback, not for recording.
  • If I can't figure out how looping works (library's way), then I will remove this feature.
  • Probably force usage of SdFat library (performance matters).
  • Maybe add a function that overrides current used sample rate (all tracks will be played at the analyzed rate of the last opened file).

I'll try to keep any non-mentioned already existing feature.

Hi,

saddam2k9:
I am working on a project where I need to play at least four audio files simultaneously and independently.

You could hand over the file playing to a WAV Trigger board - that can play upto 14 WAV files simultaneously.

Yours,
TonyWilk

TonyWilk:
Hi,
You could hand over the file playing to a WAV Trigger board - that can play upto 14 WAV files simultaneously.

Yours,
TonyWilk

Thank you so much for your suggestions. From the features of the component, it seems that I can play multiple audio files simultaneously. I need to study more about this and if I succeed to play multiple audio files I will let you about my progress.

Do you had any progress?

I just saw this on youtube