You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 line
5.2KB

  1. // Record sound as raw data to a SD card, and play it back.
  2. //
  3. // Requires the audio shield:
  4. // http://www.pjrc.com/store/teensy3_audio.html
  5. //
  6. // Three pushbuttons need to be connected:
  7. // Record Button: pin 0 to GND
  8. // Stop Button: pin 1 to GND
  9. // Play Button: pin 2 to GND
  10. //
  11. // This example code is in the public domain.
  12. #include <Bounce.h>
  13. #include <Audio.h>
  14. #include <Wire.h>
  15. #include <SPI.h>
  16. #include <SD.h>
  17. // GUItool: begin automatically generated code
  18. AudioInputI2S i2s2; //xy=105,63
  19. AudioAnalyzePeak peak1; //xy=278,108
  20. AudioRecordQueue queue1; //xy=281,63
  21. AudioPlaySdRaw playRaw1; //xy=302,157
  22. AudioOutputI2S i2s1; //xy=470,120
  23. AudioConnection patchCord1(i2s2, 0, queue1, 0);
  24. AudioConnection patchCord2(i2s2, 0, peak1, 0);
  25. AudioConnection patchCord3(playRaw1, 0, i2s1, 0);
  26. AudioConnection patchCord4(playRaw1, 0, i2s1, 1);
  27. AudioControlSGTL5000 sgtl5000_1; //xy=265,212
  28. // GUItool: end automatically generated code
  29. // Bounce objects to easily and reliably read the buttons
  30. Bounce buttonRecord = Bounce(0, 8);
  31. Bounce buttonStop = Bounce(1, 8); // 8 = 8 ms debounce time
  32. Bounce buttonPlay = Bounce(2, 8);
  33. // which input on the audio shield will be used?
  34. const int myInput = AUDIO_INPUT_LINEIN;
  35. //const int myInput = AUDIO_INPUT_MIC;
  36. // Remember which mode we're doing
  37. int mode = 0; // 0=stopped, 1=recording, 2=playing
  38. // The file where data is recorded
  39. File frec;
  40. void setup() {
  41. // Configure the pushbutton pins
  42. pinMode(0, INPUT_PULLUP);
  43. pinMode(1, INPUT_PULLUP);
  44. pinMode(2, INPUT_PULLUP);
  45. // Audio connections require memory, and the record queue
  46. // uses this memory to buffer incoming audio.
  47. AudioMemory(60);
  48. // Enable the audio shield, select input, and enable output
  49. sgtl5000_1.enable();
  50. sgtl5000_1.inputSelect(myInput);
  51. sgtl5000_1.volume(0.5);
  52. // Initialize the SD card
  53. SPI.setMOSI(7);
  54. SPI.setSCK(14);
  55. if (!(SD.begin(10))) {
  56. // stop here if no SD card, but print a message
  57. while (1) {
  58. Serial.println("Unable to access the SD card");
  59. delay(500);
  60. }
  61. }
  62. }
  63. void loop() {
  64. // First, read the buttons
  65. buttonRecord.update();
  66. buttonStop.update();
  67. buttonPlay.update();
  68. // Respond to button presses
  69. if (buttonRecord.fallingEdge()) {
  70. Serial.println("Record Button Press");
  71. if (mode == 2) stopPlaying();
  72. if (mode == 0) startRecording();
  73. }
  74. if (buttonStop.fallingEdge()) {
  75. Serial.println("Stop Button Press");
  76. if (mode == 1) stopRecording();
  77. if (mode == 2) stopPlaying();
  78. }
  79. if (buttonPlay.fallingEdge()) {
  80. Serial.println("Play Button Press");
  81. if (mode == 1) stopRecording();
  82. if (mode == 0) startPlaying();
  83. }
  84. // If we're playing or recording, carry on...
  85. if (mode == 1) {
  86. continueRecording();
  87. }
  88. if (mode == 2) {
  89. continuePlaying();
  90. }
  91. // when using a microphone, continuously adjust gain
  92. if (myInput == AUDIO_INPUT_MIC) adjustMicLevel();
  93. }
  94. void startRecording() {
  95. Serial.println("startRecording");
  96. if (SD.exists("RECORD.RAW")) {
  97. // The SD library writes new data to the end of the
  98. // file, so to start a new recording, the old file
  99. // must be deleted before new data is written.
  100. SD.remove("RECORD.RAW");
  101. }
  102. frec = SD.open("RECORD.RAW", FILE_WRITE);
  103. if (frec) {
  104. queue1.begin();
  105. mode = 1;
  106. }
  107. }
  108. void continueRecording() {
  109. if (queue1.available() >= 2) {
  110. byte buffer[512];
  111. // Fetch 2 blocks from the audio library and copy
  112. // into a 512 byte buffer. The Arduino SD library
  113. // is most efficient when full 512 byte sector size
  114. // writes are used.
  115. memcpy(buffer, queue1.readBuffer(), 256);
  116. queue1.freeBuffer();
  117. memcpy(buffer+256, queue1.readBuffer(), 256);
  118. queue1.freeBuffer();
  119. // write all 512 bytes to the SD card
  120. elapsedMicros usec = 0;
  121. frec.write(buffer, 512);
  122. // Uncomment these lines to see how long SD writes
  123. // are taking. A pair of audio blocks arrives every
  124. // 5802 microseconds, so hopefully most of the writes
  125. // take well under 5802 us. Some will take more, as
  126. // the SD library also must write to the FAT tables
  127. // and the SD card controller manages media erase and
  128. // wear leveling. The queue1 object can buffer
  129. // approximately 301700 us of audio, to allow time
  130. // for occasional high SD card latency, as long as
  131. // the average write time is under 5802 us.
  132. //Serial.print("SD write, us=");
  133. //Serial.println(usec);
  134. }
  135. }
  136. void stopRecording() {
  137. Serial.println("stopRecording");
  138. queue1.end();
  139. if (mode == 1) {
  140. while (queue1.available() > 0) {
  141. frec.write((byte*)queue1.readBuffer(), 256);
  142. queue1.freeBuffer();
  143. }
  144. frec.close();
  145. }
  146. mode = 0;
  147. }
  148. void startPlaying() {
  149. Serial.println("startPlaying");
  150. playRaw1.play("RECORD.RAW");
  151. mode = 2;
  152. }
  153. void continuePlaying() {
  154. if (!playRaw1.isPlaying()) {
  155. playRaw1.stop();
  156. mode = 0;
  157. }
  158. }
  159. void stopPlaying() {
  160. Serial.println("stopPlaying");
  161. if (mode == 2) playRaw1.stop();
  162. mode = 0;
  163. }
  164. void adjustMicLevel() {
  165. // TODO: read the peak1 object and adjust sgtl5000_1.micGain()
  166. // if anyone gets this working, please submit a github pull request :-)
  167. }