EngineersGarage

  • Engineers Garage Main Site
  • Visit our active EE Forums
    • EDABoard.com
    • Electro-Tech-Online
  • Projects & Tutorials
    • Circuits
    • Electronic Projects
    • Tutorials
    • Components
  • Digi-Key Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Advertise
You are here: Home / Topics / Reading wave files from RAM

Reading wave files from RAM

|

Microcontroller › Arduino › Reading wave files from RAM

  • This topic has 3 replies, 2 voices, and was last updated 9 years, 8 months ago by Sachin.
Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • June 28, 2016 at 10:45 am #4501
    Sachin
    Participant

    Hii,


    I am working on project on sound generation in electric vehicle. I have stored short audio samples (ranges from 1-5 sec) in SD card and successfully able to read and play the wave files from SD card. 

    1) I am not able to play the wave samples continously instead it just plays once and stops.

    2) Now I want to read the samples from SD card into RAM and play it from RAM. I know the RAM of Arduino Due is 96KB which is enough for my project.

     

    Thanks in advance…..

    Please find the code below

     

    #include <SD.h>

    #include <SPI.h>
     
    #include "sampler1.h"
     
      Sampler sampler1;
      int x=0;
     
    void setup() {
      // debug output at 9600 baud
      Serial.begin(9600);
     
      // setup SD-card
      Serial.print("Initializing SD card…");
      if (!SD.begin(4)) {
        Serial.println(" failed!");
        while(true);
      }
     
      Serial.println(" done.");
     
      
        sampler1.init();
     
     
      //turn on the timer clock in the power management controller
      pmc_set_writeprotect(false);
      pmc_enable_periph_clk(ID_TC4);
     
      //we want wavesel 01 with RC 
      TC_Configure(TC1, 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK2);
      TC_SetRC(TC1, 1, 238); // sets <> 44.1 Khz interrupt rate
     
      TC_Start(TC1, 1);
     
      // enable timer interrupts on the timer
      TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;
      TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;
     
      //Enable the interrupt in the nested vector interrupt controller 
      //TC4_IRQn where 4 is the timer number * timer channels (3) + the channel 
      //number (=(1*3)+1) for timer1 channel1 
      NVIC_EnableIRQ(TC4_IRQn);
     
      analogWrite(DAC1,0);
      
    }
     
    void loop() {
     
     
    if(x<1){
     
     sampler1.load("1.wav");
    sampler1.splay(10);
     
    }
     
    sampler1.buffill();
     
    x++;
     
     
    }
     
    void TC4_Handler() //Interrupt at 44.1KHz rate (every 22.6us)
    { 
     
       TC_GetStatus(TC1, 1); 
     
    // 2048 is the 0 value of audio out.
       int16_t ulOutput=2048;
    //modification of volume
        sampler1.next();
       
        ulOutput += sampler1.output(); //2048+(0-1)
     
        if(ulOutput>4095) ulOutput=4095;
        dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 
    //  analogWrite(DAC1,ulOutput);
    }
     
     
    Sampler.h
     
    #include <arduino.h>
     
    const int chipSelect = 4;         // For Due, the SS of SD Card is on pin 4. 
    const int bufsize = 1024;          // buffer size in bytes. You can change this data.
     
    // Put here the filenames of your samples on SD card
    const char* samplefile[]= {"1.wav","2.wav","3.wav","4.wav","5.wav","6.wav","7.wav"};
     
    // Header of a wave file.
    // Num_channels will tell us if we are in stereo (2) or mono (1)
    typedef struct {
      char RIFF[4]; 
      int32_t chunk_size;
      char WAVE[4]; 
      char fmt_[4]; 
      int32_t subchunk1_size;
      int16_t audio_format;
      int16_t num_channels;
      int32_t sample_rate;
      int32_t byte_rate;
      int16_t block_align;
      int16_t bits_per_sample;
      char DATA[4]; 
      int32_t subchunk2_size;
    } wave_header;
     
     
     
    // Here is our sampler class
    class Sampler
    {
     
    public:
       uint32_t volglobal;         // volume max of the sample (when sustain)
       boolean play;               // is the sample playing or not ?
       int indbuf;                 // buffer number
       uint16_t bufread;           // buffer being read number
       uint16_t lastbuf;           // last buffer read number
       int16_t buf[2][bufsize];    // buffer
       uint32_t possample;         // sample position
       uint32_t endofsample;       // end of sample
       uint32_t decrease;          // decrease speed
       //uint16_t samplenote;        // sample note
       
       File myFile;              // The wave file 
       wave_header header;         // The wave header
       
       boolean openfile ;          // Are we opening file ?
       boolean closefile ;         // Are we closing file ?
       const char* samplen;        // Storing the sample name
       
       int16_t patternplaying;    // The pattern which is currently playing the sample
      
     
    // Init of the sampler object. Here you can put your default values.
       void init()
       {
         indbuf =0;
         bufread = 0;
         lastbuf = 0;
         play = false;
         volglobal = 800;
         openfile = false;
         closefile = false;
         patternplaying = -1;
     
      
       }
     
    // Play the sample, giving volume
       void splay(uint32_t vol)
       {
         
         play=true;
         volglobal = vol; 
     
       }
     
    // load the wave header in the header data, and the beginning of the wave file in the buffer.
       void load(const char* samplename)
       {
         bufread = 0;
         lastbuf = 0;
         possample = 0;
         samplen = samplename;
         closefile = false;
         openfile = true;
       }
     
    //Stop playing the sample
       void sstop()
       {
         if(play)
         {
           closefile = true;
    //       Serial.println("sstop");
         }
       }
     
     
    // Set the volume of the sample
       void setVol(uint32_t vol)
       {
         volglobal = vol;
       }
     
    //Set the end of the sample
       void setEnd(uint32_t theEnd)
      {
         endofsample = (endofsample*theEnd)>>7;
      
     //Serial.println("End");
       }
     
    // Fill the buffer if it has to be. 
    // This method must not be called in the main program loop.
    // The return of the method indicates that it is reading a sound file
     
       boolean buffill()
       {
         boolean ret = false;
         if(play)
         {
           // The buffer must be filled only if the previous buffer was finished to be read
           if(bufread==lastbuf)
           {
    ret = true;
       
            // If we the sample read has arrived to the end of the file, we must stop the sample reading
             if(possample>=(endofsample-bufsize)) 
             closefile=true;
     
             // OPEN FILE
    if(openfile)
    {
         myFile= SD.open(samplen, FILE_READ);
      myFile.read(&header, sizeof(header));
    //     Serial.println(sizeof(header));  //44
      endofsample = header.chunk_size-bufsize;
      
    //     Serial.println(bufsize);  //1024
    //     Serial.println(endofsample);  //792846= 793878-8=793870-1024=792846
      myFile.read(buf[0], sizeof(buf[0]));
          Serial.println(sizeof(buf[0])); //2048??
      possample = sizeof(buf[0]) + sizeof(header);
    //    Serial.println(possample);    //2092 =2048+44
      openfile = false;
    //     Serial.println(openfile);
      }
    else
    {
      // CLOSE FILE
               if(closefile) 
               {
        myFile.close();
        play = false;
    //       Serial.println("CloseFile");
      }
      //READ FILE awapping between buf 0 and 1 takes place
      else
      {
        if(lastbuf==0) lastbuf = 1;
        else 
        lastbuf = 0;
     
        int me = myFile.read(buf[lastbuf], sizeof(buf[lastbuf])); 
    //       Serial.println(me);//2048
    //       Serial.println(sizeof(buf[lastbuf])); //2048
           
        possample += sizeof(buf[lastbuf]); 
    //        Serial.println(possample);  //4140=2048+2092
               
        // If there is an error while reading sample file, we stop the reading and close the file
                 if(me<=0) 
        {
          play = false;
          myFile.close();
     
        }
           
      }
    }
           }
         }
        
         
           Serial.println(lastbuf);
         return ret;
      
       }
     
       
    // Compute the position of the next sample. Must be called in the sound generating loop, before the method "output()"   
       void next()
       {
         if(play)  
         {
           // If the wave file is stereo, we take only one side (left). 
           indbuf += header.num_channels; 
         
           // The reading of the file must stop at the end of file.
          if(possample>=(endofsample-bufsize))
          {
             closefile = true;
     
          }
     
          // If a buffer is finished to be read, we read the other buffer.
         
          if(indbuf>=bufsize)  //indbuf 0-1023
          { 
            
            if(bufread==0) bufread = 1;
            else bufread = 0;
          
            indbuf=0;
          }
        } 
     
      }
     
    // Read the wave file at a position. Returns the volume (12 bits)
      int16_t output()
      {
        int16_t ret=0;
      
        if(play)
        {
          ret = ((buf[bufread][indbuf]>>4)*volglobal)>>7;  //ret value ranges from 0 to 1 bcoz buf[][]=2
        }
     
        return ret;
      
     
      }
    };

     

    June 28, 2016 at 12:33 pm #14027
    Prabakaran P M
    Participant
    void loop() {
     
     
    if(x<1){
     
     sampler1.load("1.wav");
    sampler1.splay(10);
     
    }
     
    sampler1.buffill();
     
    x++;
    }
     
    The if loop in the above code is making it to run only once
    June 28, 2016 at 1:32 pm #14032
    Sachin
    Participant

    Sorry I forget to tell you, I also tried as (x>100) then I get continous sound but not the original sound but wierd sound.

    June 29, 2016 at 11:58 am #14035
    Sachin
    Participant

    Hiii,

    I am able to perform sucessfully the contionus sound. Now, my problem is how to read the samples from RAM?

  • Author
    Posts
Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.
Log In

RSS Recent Posts

  • Phone charger fix March 12, 2026
  • Very Curious Issue With DS3231 RTC Clock March 12, 2026
  • Summing inverting amplifier query March 12, 2026
  • Troubleshoot Wine Enthusiast Model 272 03 12 01 control board FX-108-1 March 12, 2026
  • Motor Getting Hot March 12, 2026

Stay Up To Date

Newsletter Signup
EngineersGarage

Copyright © 2026 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy | Advertising | About Us

Search Engineers Garage

  • Engineers Garage Main Site
  • Visit our active EE Forums
    • EDABoard.com
    • Electro-Tech-Online
  • Projects & Tutorials
    • Circuits
    • Electronic Projects
    • Tutorials
    • Components
  • Digi-Key Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • Advertise