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.

220 line
6.1KB

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