awinograd

Lab 6 - Pause Button

May 24th, 2012
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.09 KB | None | 0 0
  1. /*
  2.  * example sketch to play audio file(s) in a directory, using the mp3 library
  3.  * for playback and the arduino sd library to read files from a microsd card.
  4.  * pins are setup to work well for teensy 2.0. double-check if using arduino.
  5.  *
  6.  * originally based on frank zhao's player: http://frank.circleofcurrent.com/
  7.  * utilities adapted from previous versions of the functions by matthew seal.
  8.  *
  9.  * (c) 2011 david sirkin [email protected]
  10.  *          akil srinivasan [email protected]
  11.  */
  12.  
  13. // first step is to include (arduino) sd, eeprom, and (our own) mp3 and lcd libraries.
  14.  
  15. #include <SD.h>
  16. #include <EEPROM.h>
  17.  
  18. #include <mp3.h>
  19. #include <mp3conf.h>
  20.  
  21. #include <nokia_5110_lcd.h>
  22.  /*IF we are not using the Graphics or Bitmap capabilities
  23.  of the LCD, save code space with these #defines*/
  24. #define NO_GRAPHICS
  25. #define NO_BITMAP
  26.  
  27. // setup microsd, decoder, and lcd chip pins
  28.  
  29. #define sd_cs         12         // 'chip select' for microsd card
  30. #define mp3_cs        21         // 'command chip select' to cs pin
  31.  
  32. #define dcs           20         // 'data chip select' to bsync pin
  33. #define rst           18         // 'reset' to decoder's reset pin
  34. #define dreq          19         // 'data request line' to dreq pin
  35.  
  36. //LCD PINS
  37. #define LCD_PWR   10
  38. #define LCD_SCE   9
  39. #define LCD_RESET 8
  40. #define LCD_DC    4
  41.  
  42. // read_buffer is the amount of data read from microsd, then sent to decoder.
  43.  
  44. #define read_buffer   512        // size of the microsd read buffer
  45. #define mp3_vol       175        // default volume: 0=min, 254=max
  46.  
  47. // file names are 13 bytes max (8 + '.' + 3 + '\0'), and the file list should
  48. // fit into the eeprom. for example, 13 * 40 = 520 bytes of eeprom are needed
  49. // to store a list of 40 songs. if you use shorter file names, or if your mcu
  50. // has more eeprom, you can change these.
  51.  
  52. #define max_name_len  13
  53. #define max_num_songs 40
  54.  
  55. // next steps, declare the variables used later to represent microsd objects.
  56.  
  57. Sd2Card  card;                   // top-level represenation of card
  58. SdVolume volume;                 // sd partition, not audio volume
  59. SdFile   sd_root, sd_file;       // sd_file is the child of sd_root
  60.  
  61. // declare lcd object as well
  62. Nokia_5110_lcd lcd(LCD_PWR, LCD_DC, LCD_SCE, LCD_RESET);
  63.  
  64. // store the number of songs in this directory, and the current song to play.
  65.  
  66. unsigned char num_songs = 0, current_song = 0;
  67.  
  68. // an array to hold the current_song's file name in ram. every file's name is
  69. // stored longer-term in the eeprom. this array is used for sd_file.open().
  70.  
  71. char fn[max_name_len];
  72.  
  73. // the program runs as a state machine. the 'state' enum includes the states.
  74. // 'current_state' is the default as the program starts. add new states here.
  75.  
  76. enum state { DIR_PLAY, MP3_PLAY, IDLE };
  77. state current_state = DIR_PLAY;
  78.  
  79. // you must open any song file that you want to play using sd_file_open prior
  80. // to fetching song data from the file. you can only open one file at a time.
  81.  
  82. void sd_file_open() {
  83.   map_current_song_to_fn();
  84.   sd_file.open(&sd_root, fn, FILE_READ);
  85.  
  86.   // if you prefer to work with the current song index (only) instead of file
  87.   // names, this version of the open command should also work for you:
  88.  
  89.   // sd_file.open(&sd_root, current_song, FILE_READ);
  90. }
  91.  
  92. void mp3_play() {
  93.   unsigned char bytes[read_buffer]; // buffer to read and send to the decoder
  94.   unsigned int bytes_to_read;       // number of bytes read from microsd card
  95.  
  96.   // send read_buffer bytes to be played. Mp3.play() tracks the index pointer
  97.   // within the song being played of where to get the next read_buffer bytes.
  98.  
  99.   bytes_to_read = sd_file.read(bytes, read_buffer);
  100.   Mp3.play(bytes, bytes_to_read);
  101.  
  102.   // bytes_to_read should only be less than read_buffer when the song's over.
  103.  
  104.   if(bytes_to_read < read_buffer) {
  105.     sd_file.close();
  106.     current_state = IDLE;
  107.   }
  108. }
  109.  
  110. // continue to play the current (playing) song, until there are no more songs
  111. // in the directory to play.
  112.  
  113. void dir_play() {
  114.   if (current_song < num_songs) {
  115.      mp3_play();
  116.      
  117.      // if current_state is IDLE, then the currently playing song just ended.
  118.      // in that case, increment to get the next song to play, open that file,
  119.      // and return to the DIR_PLAY state (which will then play that song).
  120.      // if we played the last part of the last song, we don't do anything,
  121.      // and the current_state is already set to IDLE from mp3_play()
  122.  
  123.      if (current_state == IDLE && current_song < (num_songs - 1)) {
  124.        current_song++;
  125.        sd_file_open();
  126.        current_state = DIR_PLAY;
  127.      }
  128.    }
  129. }
  130.  
  131. // setup is pretty straightforward. initialize serial communication (used for
  132. // the following error messages), microsd card objects, mp3 library, and open
  133. // the first song in the root library to play.
  134.  
  135. void setup() {
  136.   Serial.begin(9600);
  137.   pinMode(SS_PIN, OUTPUT);  //SS_PIN must be output to use SPI
  138.   pinMode(5, INPUT_PULLUP);
  139.   attachInterrupt(0, pause, RISING);
  140.  
  141.   // the default state of the mp3 decoder chip keeps the SPI bus from
  142.   // working with other SPI devices, so we have to initialize it first.
  143.   Mp3.begin(mp3_cs, dcs, rst, dreq);
  144.  
  145.   // initialize the microsd (which checks the card, volume and root objects).
  146.   sd_card_setup();
  147.  
  148.   //initialize the LCD
  149.   lcd.init(40); //parameter is contrast value, between 0 [low] and 127 [high]
  150.   lcd.clear();
  151.  
  152.   // initialize the mp3 library, and set default volume. 'mp3_cs' is the chip
  153.   // select, 'dcs' is data chip select, 'rst' is reset and 'dreq' is the data
  154.   // request. the decoder raises the dreq line (automatically) to signal that
  155.   // it's input buffer can accommodate 32 more bytes of incoming song data.
  156.   // we need to set the SPI speed with the mp3 initialize function since
  157.   // it is the limiting factor, so we call its init function again.
  158.  
  159.   Mp3.begin(mp3_cs, dcs, rst, dreq);
  160.   Mp3.volume(mp3_vol);
  161.  
  162.   // putting all of the root directory's songs into eeprom saves flash space.
  163.  
  164.   sd_dir_setup();
  165.  
  166.   // the program is setup to enter DIR_PLAY mode immediately, so this call to
  167.   // open the root directory before reaching the state machine is needed.
  168.  
  169.   sd_file_open();
  170.  
  171.   //Test that LCD still works with other SPI devices
  172.   lcd.writeString( 0, 0, "Barebones Mp3!", MODE_NORMAL);
  173. }
  174.  
  175. // the state machine is setup (at least, at first) to open the microsd card's
  176. // root directory, play all of the songs within it, close the root directory,
  177. // and then stop playing. change these, or add new actions here.
  178.  
  179. // the DIR_PLAY state plays all of the songs in a directory and then switches
  180. // into IDLE when done. the MP3_PLAY state plays one specified song, and then
  181. // switches into IDLE. this example program doesn't enter the MP3_PLAY state,
  182. // as its goal (for now) is just to play all the songs. you can change that.
  183.  
  184. volatile boolean paused = false;
  185. void loop() {
  186.   if(paused){
  187.     return;
  188.   }
  189.   switch(current_state) {
  190.  
  191.     case DIR_PLAY:
  192.       dir_play();
  193.       break;
  194.  
  195.     case MP3_PLAY:
  196.       mp3_play();
  197.       break;
  198.  
  199.     case IDLE:
  200.       break;
  201.   }
  202. }
  203.  
  204. void pause(){
  205.   paused = !paused;
  206.   Serial.println(paused);
  207. }
Advertisement
Add Comment
Please, Sign In to add comment