|
- // Record sound as raw data to a SD card, and play it back.
- //
- // Requires the audio shield:
- // http://www.pjrc.com/store/teensy3_audio.html
- //
- // Three pushbuttons need to be connected:
- // Record Button: pin 0 to GND
- // Stop Button: pin 1 to GND
- // Play Button: pin 2 to GND
- //
- // This example code is in the public domain.
-
- #include <Bounce.h>
- #include <Audio.h>
- #include <Wire.h>
- #include <SPI.h>
- #include <SD.h>
-
- // GUItool: begin automatically generated code
- AudioInputI2S i2s2; //xy=105,63
- AudioAnalyzePeak peak1; //xy=278,108
- AudioRecordQueue queue1; //xy=281,63
- AudioPlaySdRaw playRaw1; //xy=302,157
- AudioOutputI2S i2s1; //xy=470,120
- AudioConnection patchCord1(i2s2, 0, queue1, 0);
- AudioConnection patchCord2(i2s2, 0, peak1, 0);
- AudioConnection patchCord3(playRaw1, 0, i2s1, 0);
- AudioConnection patchCord4(playRaw1, 0, i2s1, 1);
- AudioControlSGTL5000 sgtl5000_1; //xy=265,212
- // GUItool: end automatically generated code
-
- // Bounce objects to easily and reliably read the buttons
- Bounce buttonRecord = Bounce(0, 8);
- Bounce buttonStop = Bounce(1, 8); // 8 = 8 ms debounce time
- Bounce buttonPlay = Bounce(2, 8);
-
-
- // which input on the audio shield will be used?
- const int myInput = AUDIO_INPUT_LINEIN;
- //const int myInput = AUDIO_INPUT_MIC;
-
- // Remember which mode we're doing
- int mode = 0; // 0=stopped, 1=recording, 2=playing
-
- // The file where data is recorded
- File frec;
-
- void setup() {
- // Configure the pushbutton pins
- pinMode(0, INPUT_PULLUP);
- pinMode(1, INPUT_PULLUP);
- pinMode(2, INPUT_PULLUP);
-
- // Audio connections require memory, and the record queue
- // uses this memory to buffer incoming audio.
- AudioMemory(60);
-
- // Enable the audio shield, select input, and enable output
- sgtl5000_1.enable();
- sgtl5000_1.inputSelect(myInput);
- sgtl5000_1.volume(0.5);
-
- // Initialize the SD card
- SPI.setMOSI(7);
- SPI.setSCK(14);
- if (!(SD.begin(10))) {
- // stop here if no SD card, but print a message
- while (1) {
- Serial.println("Unable to access the SD card");
- delay(500);
- }
- }
- }
-
-
- void loop() {
- // First, read the buttons
- buttonRecord.update();
- buttonStop.update();
- buttonPlay.update();
-
- // Respond to button presses
- if (buttonRecord.fallingEdge()) {
- Serial.println("Record Button Press");
- if (mode == 2) stopPlaying();
- if (mode == 0) startRecording();
- }
- if (buttonStop.fallingEdge()) {
- Serial.println("Stop Button Press");
- if (mode == 1) stopRecording();
- if (mode == 2) stopPlaying();
- }
- if (buttonPlay.fallingEdge()) {
- Serial.println("Play Button Press");
- if (mode == 1) stopRecording();
- if (mode == 0) startPlaying();
- }
-
- // If we're playing or recording, carry on...
- if (mode == 1) {
- continueRecording();
- }
- if (mode == 2) {
- continuePlaying();
- }
-
- // when using a microphone, continuously adjust gain
- if (myInput == AUDIO_INPUT_MIC) adjustMicLevel();
- }
-
-
- void startRecording() {
- Serial.println("startRecording");
- if (SD.exists("RECORD.RAW")) {
- // The SD library writes new data to the end of the
- // file, so to start a new recording, the old file
- // must be deleted before new data is written.
- SD.remove("RECORD.RAW");
- }
- frec = SD.open("RECORD.RAW", FILE_WRITE);
- if (frec) {
- queue1.begin();
- mode = 1;
- }
- }
-
- void continueRecording() {
- if (queue1.available() >= 2) {
- byte buffer[512];
- // Fetch 2 blocks from the audio library and copy
- // into a 512 byte buffer. The Arduino SD library
- // is most efficient when full 512 byte sector size
- // writes are used.
- memcpy(buffer, queue1.readBuffer(), 256);
- queue1.freeBuffer();
- memcpy(buffer+256, queue1.readBuffer(), 256);
- queue1.freeBuffer();
- // write all 512 bytes to the SD card
- elapsedMicros usec = 0;
- frec.write(buffer, 512);
- // Uncomment these lines to see how long SD writes
- // are taking. A pair of audio blocks arrives every
- // 5802 microseconds, so hopefully most of the writes
- // take well under 5802 us. Some will take more, as
- // the SD library also must write to the FAT tables
- // and the SD card controller manages media erase and
- // wear leveling. The queue1 object can buffer
- // approximately 301700 us of audio, to allow time
- // for occasional high SD card latency, as long as
- // the average write time is under 5802 us.
- //Serial.print("SD write, us=");
- //Serial.println(usec);
- }
- }
-
- void stopRecording() {
- Serial.println("stopRecording");
- queue1.end();
- if (mode == 1) {
- while (queue1.available() > 0) {
- frec.write((byte*)queue1.readBuffer(), 256);
- queue1.freeBuffer();
- }
- frec.close();
- }
- mode = 0;
- }
-
-
- void startPlaying() {
- Serial.println("startPlaying");
- playRaw1.play("RECORD.RAW");
- mode = 2;
- }
-
- void continuePlaying() {
- if (!playRaw1.isPlaying()) {
- playRaw1.stop();
- mode = 0;
- }
- }
-
- void stopPlaying() {
- Serial.println("stopPlaying");
- if (mode == 2) playRaw1.stop();
- mode = 0;
- }
-
- void adjustMicLevel() {
- // TODO: read the peak1 object and adjust sgtl5000_1.micGain()
- // if anyone gets this working, please submit a github pull request :-)
- }
|