altering the speed control for wave shield

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

Everything from this line to the end of the file:

Code: Select all

void play(FatReader &dir)
(Also, please use the 'Code' button when submitting large amounts of code.)

tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

Im not understanding where to stop as I think there is code which ive added on later mixed in with it and dont want to delete that?
And not sure what you call the end of the file, Im sorry!!!

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

And not sure what you call the end of the file,
The end of the file is the last line of code.
Try this:

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

uint8_t dirLevel; // indent level for file/dir names    (for prettyprinting)
dir_t dirBuf;     // buffer for directory reads

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

// Function definitions (we define them here, but the code is below)
void lsR(FatReader &d);
void play(FatReader &dir);

/// *** Add these lines before the "setup" in your waveshield sketch
int potPin = 0; // Analog input pin that the potentiometer is attached to
int potValue = 0; // value read from the pot

int16_t lastpotval = 0;
#define HYSTERESIS 3



void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps for debugging
  
  putstring_nl("\nWave test!");  // say we woke up!
  
  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());

  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  
  //  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("Files found:");
  dirLevel = 0;
  // Print out all of the files in all the directories.
  lsR(root);
}

//////////////////////////////////// LOOP
void loop() { 

  root.rewind();
  play(root);
}

/////////////////////////////////// HELPERS


// 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; 
} 

/*
* print error message and halt if SD I/O error, great for debugging!
*/
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);
}
/*
* print dir_t name field. The output is 8.3 format, so like SOUND.WAV or FILENAME.DAT
*/
void printName(dir_t &dir)
{
  for (uint8_t i = 0; i < 11; i++) {     // 8.3 format has 8+3 = 11 letters in it
    if (dir.name[i] == ' ')
        continue;         // dont print any spaces in the name
    if (i == 8) 
        Serial.print('.');           // after the 8th letter, place a dot
    Serial.print(dir.name[i]);      // print the n'th digit
  }
  if (DIR_IS_SUBDIR(dir)) 
    Serial.print('/');       // directories get a / at the end
}
/*
* list recursively - possible stack overflow if subdirectories too nested
*/
void lsR(FatReader &d)
{
  int8_t r;                     // indicates the level of recursion
  
  while ((r = d.readDir(dirBuf)) > 0) {     // read the next file in the directory 
    // skip subdirs . and ..
    if (dirBuf.name[0] == '.') 
      continue;
    
    for (uint8_t i = 0; i < dirLevel; i++) 
      Serial.print(' ');        // this is for prettyprinting, put spaces in front
    printName(dirBuf);          // print the name of the file we just found
    Serial.println();           // and a new line
    
    if (DIR_IS_SUBDIR(dirBuf)) {   // we will recurse on any direcory
      FatReader s;                 // make a new directory object to hold information
      dirLevel += 2;               // indent 2 spaces for future prints
      if (s.open(vol, dirBuf)) 
        lsR(s);                    // list all the files in this directory now!
      dirLevel -=2;                // remove the extra indentation
    }
  }
  sdErrorCheck();                  // are we doign OK?
}
/*
* play recursively - possible stack overflow if subdirectories too nested
*/
void play(FatReader &dir)
{
  FatReader file;
  while (dir.readDir(dirBuf) > 0) {    // Read every file in the directory one at a time
    // skip . and .. directories
    if (dirBuf.name[0] == '.') 
      continue;
    
    Serial.println();            // clear out a new line
    
    for (uint8_t i = 0; i < dirLevel; i++) 
       Serial.print(' ');       // this is for prettyprinting, put spaces in front

    if (!file.open(vol, dirBuf)) {       // open the file in the directory
      Serial.println("file.open failed");  // something went wrong :(
      while(1);                            // halt
    }
    
    if (file.isDir()) {                    // check if we opened a new directory
      putstring("Subdir: ");
      printName(dirBuf);
      dirLevel += 2;                       // add more spaces
      // play files in subdirectory
      play(file);                         // recursive!
      dirLevel -= 2;    
    }
    else {
      // Aha! we found a file that isnt a directory
      putstring("Playing "); printName(dirBuf);       // print it out
      if (!wave.create(file)) {            // Figure out, is it a WAV proper?
        putstring(" Not a valid WAV");     // ok skip it
      } else {
        Serial.println();                  // Hooray it IS a WAV proper!
        wave.play();                       // make some noise!
       
        while (wave.isplaying) {
        int potval = analogRead(0);
        if ( ((potval - lastpotval) > HYSTERESIS) || ((lastpotval - potval) > HYSTERESIS)) {
          int newsamplerate = wave.dwSamplesPerSec;  // get the original sample rate
          newsamplerate *= potval;                       // scale it by the analog value
          newsamplerate /= 512;   // we want to 'split' between 2x sped up and slowed down.
          wave.setSampleRate(newsamplerate);  // set it immediately!
          Serial.println(newsamplerate, DEC);  // for debugging
          lastpotval = potval;
        }
        delay(100);
      }
        sdErrorCheck();                    // everything OK?
//        if (wave.errors)Serial.println(wave.errors);     // wave decoding errors
      }
    }
  }
}


tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

Sorry thought it meant the end of a certain line in the code.

This plays it all really fast and makes no change with Pot. There are changes made when turning pot but only blocks of interference like sound then into song and out again.

tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

oh it just went back to begining of track and played normal speed, it changed to fast when turned pot but then it stays in fast mode and you cant change it.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

What do you see in the serial monitor when you turn the pot?

tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

Sorry, serial monitor?

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

In the Arduino IDE, the rightmost icon on the toolbar is the Serial Monitor. If you click on that while your sketch is running, all of the 'Serial.println()' statements will show up in the window. This is very useful for debugging programs as it can show you what your program is doing.

tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

Ok sorry didnt know about that.
Following is what it says while it was playing in high speed:

Wave test!
Free RAM: 670
Using partition 1, type is FAT16
Files found:
05-JON~1.WAV

Playing 05-JON~1.WAV
34
-18
-50
24
-50
27
51
34
-41

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

Interesting. Your sample rate is going negative.

I don't have a wave-shield handy to check it at this end. Try adding the following debug statements to see what is going on:

Find this line near the end of the file:

Code: Select all

          Serial.println(newsamplerate, DEC);  // for debugging
And replace it with these four debug statements:

Code: Select all

          Serial.print("Pot = ");  // for debugging
          Serial.println(potval, DEC);  // for debugging
          Serial.print("Rate = ");  // for debugging
          Serial.println(newsamplerate, DEC);  // for debugging

tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

Code: Select all

Wave test!
Free RAM: 654
Using partition 1, type is FAT16
Files found:
05-JON~1.WAV

Playing 05-JON~1.WAV
Pot = 71
Rate = -14
Pot = 67
Rate = -58
Pot = 44
Rate = -25
Pot = 0
Rate = 0
Pot = 10
Rate = 46
Pot = 18
Rate = 7
Pot = 29
Rate = -31
Pot = 40
Rate = 58
Pot = 64
Rate = -59
Pot = 91
Rate = -48
Pot = 116
Rate = 3
Pot = 106
Rate = -42
Pot = 66
Rate = 26
Pot = 72
Rate = 28
Pot = 94
Rate = -47

Wave test!
Free RAM: 654
Using partition 1, type is FAT16
Files found:
05-JON~1.WAV

Playing 05-JON~1.WAV
Pot = 94
Rate = -47

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

Looks like an integer overflow problem. Change this line:

Code: Select all

          int newsamplerate = wave.dwSamplesPerSec;  // get the original sample rate
to this:

Code: Select all

          uint32_t newsamplerate = wave.dwSamplesPerSec;  // get the original sample rate

tateman
 
Posts: 34
Joined: Wed Dec 01, 2010 7:18 pm

Re: altering the speed control for wave shield

Post by tateman »

Heyyyyyyyyyyy thats done it!!!
Wow thats brilliant.
Cant thank you enough!!!

This is so hard to understand all the coding I dont know as Id ever understand it all!!! lol
Ill have to try out the PIR in 2 rooms sometime and see if I can suss that out for the student.
Thanks for your fantasic support!!!!
andy

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: altering the speed control for wave shield

Post by adafruit_support_bill »

Great! :D

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

Return to “Arduino Shields from Adafruit”