wave shield volume control noise

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
fadhil
 
Posts: 4
Joined: Thu Apr 24, 2014 3:14 am

wave shield volume control noise

Post by fadhil »

Hi everyone, I've been a waveshied user for 1 month, and it sounds great! But the problem is appeared when I want to change the volume.
So if I play sound,with high volume and then change it to low volume , the sound will play with low volume. but for a short period of time in the beginning of the sound, there's a hum/noise mixed with the sound

Actually the real problem is when I change syntax wave.volume in my arduino uno program

Code: Select all

if(piezo_result >= limit) 
    {

        if(piezo_result>=720) piezo_result=720;
        wave.volume=12- (piezo_result/12);
        playfile("sp1.WAV");
        
    }
the volume is controlled by piezo (my input sensor). If you hit the piezo hard, it will produce loud volume, and vice versa. But if the variable wave.volume is change, it wil produce the noise like I mention above, even if its just change for 1 value, from 0 to 1 for example.
Any idea how can I eliminate that problem? Any answer will help.
Thank's

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: wave shield volume control noise

Post by adafruit_support_mike »

Noise in audio circuits often has some connection to the wiring. Could you post a photo of your hardware please?

fadhil
 
Posts: 4
Joined: Thu Apr 24, 2014 3:14 am

Re: wave shield volume control noise

Post by fadhil »

I think wiring might not be a problem, because I'd tried to play the sound just with arduino and wave shield (of course with speaker and usb cable to laptop), and still the problem is the same, every time I change variable wave.volume, especially from high value to low value while the sound is playing, the noise or "pop" will exist
Should I post the video to make it more clear?

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: wave shield volume control noise

Post by adafruit_support_mike »

Thank you for the offer, but a video probably wouldn't show us anything we couldn't see in a photo. If you have oscilloscope traces of the output during a change that would be great, but most people don't have access to a 'scope.

Post the code you're using and I'll see if I can replicate the issue on my own hardware.

fadhil
 
Posts: 4
Joined: Thu Apr 24, 2014 3:14 am

Re: wave shield volume control noise

Post by fadhil »

Im sorry, unfortunately the oscilloscope doesn't have waveform storing, so I use my mobile phone to capture the waveform.
Now I suspect that the problem is when the volume change, the offset will exist. If it is true, How can I eliminate offset during the change?
and this is my program

Code: Select all

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 5  // button debouncer
int masukan = 0;         // incoming serial byte
int cinta=1;
int piezo = 0;    // first analog sensor
int volum = 0;  
unsigned long waktu, waktu_old,waktu_div;
//int piezo_data[10],piezo_sum,piezo_avg,piezo_result,piezo_avg_old,piezo_result_old;
unsigned char i,sign,sign_old,z,x;


#define limit 30 
#define range 5

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {2, 4, 7, 8, 11, 13};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end; 
  extern int  *__brkval; 
  int free_memory; 
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end); 
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval); 
  }
  return free_memory; 
} 

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {
  byte i;
  
  
  // set up serial port
  Serial.begin(57600);
 // Serial.begin(115200);
  putstring_nl("WaveHC with ");
  Serial.print(NUMBUTTONS, DEC);
  putstring_nl("buttons");
  
  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
  
  
  
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!)  
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
  
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
 
// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part)) 
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
  
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
  
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
  
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
  }

void loop() {

    play_music();
}



// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
}

void play_music()
{
   
  
    if (Serial.available() > 0) {

    masukan = Serial.read();
    cinta=masukan-48;

     switch(cinta)
     {

         case 1: {wave.volume=1;playfile("sp1.WAV");} break;
         case 2: {wave.volume=5;playfile("sp1.WAV");} break;
         case 3: {wave.volume=10;playfile("sp1.WAV");} break;
         case 4: {wave.volume=30;playfile("sp1.WAV");} break;
         case 5: {wave.volume=40;playfile("sp1.WAV");} break;
         case 6: {wave.volume=50;playfile("sp1.WAV");} break;
         case 7: {wave.volume=60;playfile("sp1.WAV");} break;
         case 8: {wave.volume++;} break;
         case 9: {wave.volume--;} break;
         case 0: {wave.stop();} break;
         
         
     }
              
  }

}


Attachments
this is the waveform when wave.volume=1 change to wave.volume=5
this is the waveform when wave.volume=1 change to wave.volume=5
vol 1 to vol 5.jpg (208.27 KiB) Viewed 594 times
this is the waveform when wave.volume  is constant=1
this is the waveform when wave.volume is constant=1
vol 1.jpg (250.63 KiB) Viewed 594 times

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: wave shield volume control noise

Post by adafruit_support_mike »

Those are excellent photos, thank you.

They show both a DC pop and a lot of ringing afterward. I'll have to do some testing on my own hardware to see if I can isolate the causes.

Do post a photo of your hardware please. The DC offset shouldn't happen with capacitive coupling to the speakers, and there's an output capacitor built into the Wave Shield to prevent such a thing.

fadhil
 
Posts: 4
Joined: Thu Apr 24, 2014 3:14 am

Re: wave shield volume control noise

Post by fadhil »

I think I have overcome the problem.
the problem is the library, this is program to change volume in original library:

Code: Select all

#if DVOLUME

 uint16_t tmp = (dh << 8) | dl;
  tmp >>= playing->volume;
  dh = tmp >> 8;
  dl = tmp;
#endif //DVOLUME
  
the wave sound in my project is traditional instrument sound, and the data that i test if I'm not mistaken is in c note with 12 seconds duration. in analog domain we expected that the soundwave will sing in 0 value right?but in digital domain with tmp is declared with unsigned int, the wave will not swing in 0 value, So I modify the program like this

Code: Select all

#if DVOLUME
 uint16_t tmp = (dh << 8) | dl;
  tmp >>= playing->volume;
playing->tmp_x=tmp;
  dh = tmp >> 8;
  dl = tmp;
#endif //DVOLUME
I create variabel tmp_x so i can read the wave data value in serial monitor. and I set the wave.volume equal to 0
and finally the tmp_x value in serial monitor tell me that the data swing in 0x8000, its logical because 0x8000 is the half value of 65536 (16 bit).
the problem with the original program in library is when i want to decrease the volume, for example I change the wave.volume to 2, that means the sound data will not swing in 0x8000 anymore, but in 0x4000, so that's why the offset is exist.
And this is the modified program in waveHC.cpp to solve the offset, and now the annoying "pop" is gone :) :

Code: Select all

#if DVOLUME

   uint16_t tmp = (dh << 8) | dl;
  tmp= (tmp>>(playing->volume)) + 0x8000 - (0x8000>>(playing->volume)); 
  playing->tmp_x=tmp;
  dh = tmp >> 8;
  dl = tmp;
  
 #endif //DVOLUME
But theres still one problem: increasing wave.volume will make the frequency of wave sound increasing too. So to the original c note of my wave file, will not c anymore if i increase wave.volume.
Maybe you have any idea about this?
anyway, thanks for your reply.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”