itsacoaster

Lowpass + SDwrite

Sep 12th, 2021 (edited)
744
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.29 KB | None | 0 0
  1. //here are the libraries that we need
  2. #include <Tympan_Library.h>
  3. #include "AudioEffectLowpass_FD_F32.h"
  4.  
  5. const static float sample_rate_Hz = 16000.f; ; //24000 or 44117 (or other frequencies in the table in AudioOutputI2S_F32)
  6. const int audio_block_samples = 128;     //for freq domain processing choose a power of 2 (16, 32, 64, 128) but no higher than 128
  7. AudioSettings_F32 audio_settings(sample_rate_Hz, audio_block_samples);
  8.  
  9. //create audio library objects for handling the audio
  10. Tympan                       myTympan(TympanRev::E);                //do TympanRev::D or TympanRev::E
  11. AudioInputI2S_F32            i2s_in(audio_settings);                //Digital audio *from* the Tympan AIC.
  12.  
  13. //the modules that do the work in this program
  14. AudioEffectLowpass_FD_F32   audioEffectLowpassFD(audio_settings);
  15. AudioSDWriter_F32         audioSDWriter(audio_settings); //this is stereo by default but can do 4 channels
  16.  
  17. AudioOutputI2S_F32           i2s_out(audio_settings);               //Digital audio *to* the Tympan AIC.
  18.  
  19. //Make all of the audio connections
  20. AudioConnection_F32       patchCord1(i2s_in, 0, audioEffectLowpassFD, 0);   //connect the Left input to our algorithm
  21. AudioConnection_F32       patchCord2(audioEffectLowpassFD, 0, i2s_out, 0);  //connect the algorithm to the left output
  22. AudioConnection_F32       patchCord3(audioEffectLowpassFD, 0, i2s_out, 1);  //connect the algorithm to the right output
  23. AudioConnection_F32       patchCord4(audioEffectLowpassFD, 0, audioSDWriter, 0); //connect audio to left channel of SD writer
  24. AudioConnection_F32       patchCord5(audioEffectLowpassFD, 0, audioSDWriter, 1); //connect audio to right channel of SD writer
  25.  
  26. // define the setup() function, the function that is called once when the device is booting
  27. float input_gain_dB = 15.0f; //gain on the microphone
  28. float vol_knob_gain_dB = 0.0;      //will be overridden by volume knob
  29.  
  30. void setup() {
  31.   // put your setup code here, to run once:
  32.     //begin the serial comms (for debugging)
  33.   myTympan.beginBothSerial();
  34.  
  35.   delay(10000);
  36.   Serial.println("LowPassAndSDwrite: starting setup() (wait for debug delay)...");
  37.   Serial.print("    : sample rate (Hz) = ");  Serial.println(audio_settings.sample_rate_Hz);
  38.   Serial.print("    : block size (samples) = ");  Serial.println(audio_settings.audio_block_samples);
  39.  
  40.   // Allocate working memory for audio
  41.   //First argument:
  42.   //20 works for N_FFT equal to 128 or 256
  43.   //40 works for 512
  44.   //80 works for 1024
  45.   AudioMemory_F32(40, audio_settings);
  46.  
  47.   // Configure the frequency-domain algorithm
  48.   int N_FFT = 512;
  49.   Serial.print("    : frequency resolution (Hz) = ");  Serial.println(audio_settings.sample_rate_Hz / ((float)N_FFT));
  50.  
  51.   audioEffectLowpassFD.setup(audio_settings,N_FFT); //do after AudioMemory_F32();
  52.   audioEffectLowpassFD.setCutoff_Hz(900.);
  53.  
  54.   //Enable the Tympan to start the audio flowing!
  55.   myTympan.enable(); // activate AIC
  56.  
  57.   //Choose the desired audio input on the Typman...this will be overridden by the serviceMicDetect() in loop()
  58.   //myTympan.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on-board microphones
  59.   //myTympan.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
  60.   myTympan.inputSelect(TYMPAN_INPUT_JACK_AS_LINEIN); // use the microphone jack - defaults to mic bias OFF
  61.  
  62.  
  63.  
  64.  
  65.   //Set the desired volume levels
  66.   myTympan.volume_dB(0);                   // headphone amplifier.  -63.6 to +24 dB in 0.5dB steps.
  67.   myTympan.setInputGain_dB(input_gain_dB); // set input volume, 0-47.5dB in 0.5dB setps
  68.  
  69.   //prepare the SD writer for the format that we want and any error statements
  70.   audioSDWriter.setSerial(&myTympan);         //the library will print any error info to this serial stream (note that myTympan is also a serial stream)
  71.   audioSDWriter.setWriteDataType(AudioSDWriter::WriteDataType::INT16);  //this is the built-in default, but here you could change it to FLOAT32
  72.   audioSDWriter.setNumWriteChannels(2);       //this is also the built-in defaullt, but you could change it to 4 (maybe?), if you wanted 4 channels.
  73.  
  74.   Serial.println("Setup complete.");
  75. }
  76.  
  77. void loop() {
  78.   auto time_ms = millis();
  79.  
  80.   //check the potentiometer
  81.   servicePotentiometer(time_ms, 100); //service the potentiometer every 100 msec
  82.  
  83.   //service the SD recording
  84.   serviceSD();
  85.  
  86.   //getSDstatus(millis(), 1000);
  87.  
  88.   //service the LEDs
  89.   serviceLEDs();
  90.   getSDstatus(time_ms, 1000);
  91.  
  92.   //check to see whether to print the CPU and Memory Usage
  93.   myTympan.printCPUandMemory(time_ms,3000); //print every 3000 msec
  94. }
  95.  
  96. //servicePotentiometer: listens to the blue potentiometer and sends the new pot value
  97. //  to the audio processing algorithm as a control parameter
  98. void servicePotentiometer(unsigned long curTime_millis, unsigned long updatePeriod_millis) {
  99.   //static unsigned long updatePeriod_millis = 100; //how many milliseconds between updating the potentiometer reading?
  100.   static unsigned long lastUpdate_millis = 0;
  101.  
  102.   //has enough time passed to update everything?
  103.   if (curTime_millis < lastUpdate_millis) lastUpdate_millis = 0; //handle wrap-around of the clock
  104.   if ((curTime_millis - lastUpdate_millis) > updatePeriod_millis) { //is it time to update the user interface?
  105.    
  106.     float potentiometer_value = ((float32_t)(myTympan.readPotentiometer())) / 1023.0;
  107.     startOrStopSDRecording(potentiometer_value);
  108.    
  109.     lastUpdate_millis = curTime_millis;
  110.   } // end if
  111. } //end servicePotentiometer();
  112.  
  113. void startOrStopSDRecording(float potentiometer_value) {
  114.  
  115.   //are we already recording?
  116.   if (audioSDWriter.getState() == AudioSDWriter::STATE::RECORDING) {
  117.     //check to see if potentiometer is set to turn off recording
  118.     if (potentiometer_value < 0.45) audioSDWriter.stopRecording();
  119.  
  120.   } else { //we are not already recording
  121.     //check to see if potentiometer has been set to start recording
  122.     if (potentiometer_value > 0.55) audioSDWriter.startRecording();
  123.    
  124.   }
  125. }
  126.  
  127. //for debugging sd state
  128. void getSDstatus(unsigned long curTime_millis, unsigned long updatePeriod_millis) {
  129.   //static unsigned long updatePeriod_millis = 100; //how many milliseconds between updating the potentiometer reading?
  130.   static unsigned long lastStatusUpdate = 0;
  131.  
  132.   //has enough time passed to update everything?
  133.   if (curTime_millis < lastStatusUpdate) lastStatusUpdate = 0; //handle wrap-around of the clock
  134.   if ((curTime_millis - lastStatusUpdate) > updatePeriod_millis) { //is it time to update the user interface?
  135.  
  136.     if (audioSDWriter.getState() == AudioSDWriter::STATE::RECORDING) {
  137.       Serial.println(" == SD RECORDING == ");
  138.     } else if (audioSDWriter.getState() == AudioSDWriter::STATE::STOPPED) {
  139.       Serial.println(" == SD STOPPED == ");
  140.     } else if (audioSDWriter.getState() == AudioSDWriter::STATE::UNPREPARED) {
  141.       Serial.println(" == SD UNPREPARED == ");
  142.     } else {
  143.       Serial.println(" == SD Something Else???? == ");
  144.     }
  145.    
  146.     lastStatusUpdate = curTime_millis;
  147.   } // end if
  148. } //end servicePotentiometer();
  149.  
  150.  
  151. #define PRINT_OVERRUN_WARNING 1   //set to 1 to print a warning that the there's been a hiccup in the writing to the SD.
  152. void serviceSD(void) {
  153.   static int max_max_bytes_written = 0; //for timing diagnotstics
  154.   static int max_bytes_written = 0; //for timing diagnotstics
  155.   static int max_dT_micros = 0; //for timing diagnotstics
  156.   static int max_max_dT_micros = 0; //for timing diagnotstics
  157.  
  158.   unsigned long dT_micros = micros();  //for timing diagnotstics
  159.   int bytes_written = audioSDWriter.serviceSD();
  160.   dT_micros = micros() - dT_micros;  //timing calculation
  161.  
  162.   if ( bytes_written > 0 ) {
  163.    
  164.     max_bytes_written = max(max_bytes_written, bytes_written);
  165.     max_dT_micros = max((int)max_dT_micros, (int)dT_micros);
  166.    
  167.     if (dT_micros > 10000) {  //if the write took a while, print some diagnostic info
  168.      
  169.       max_max_bytes_written = max(max_bytes_written,max_max_bytes_written);
  170.       max_max_dT_micros = max(max_dT_micros, max_max_dT_micros);
  171.      
  172.       Serial.print("serviceSD: bytes written = ");
  173.       Serial.print(bytes_written); Serial.print(", ");
  174.       Serial.print(max_bytes_written); Serial.print(", ");
  175.       Serial.print(max_max_bytes_written); Serial.print(", ");
  176.       Serial.print("dT millis = ");
  177.       Serial.print((float)dT_micros/1000.0,1); Serial.print(", ");
  178.       Serial.print((float)max_dT_micros/1000.0,1); Serial.print(", ");
  179.       Serial.print((float)max_max_dT_micros/1000.0,1);Serial.print(", ");      
  180.       Serial.println();
  181.       max_bytes_written = 0;
  182.       max_dT_micros = 0;    
  183.     }
  184.    
  185.     //print a warning if there has been an SD writing hiccup
  186.     /*
  187.     if (PRINT_OVERRUN_WARNING) {
  188.       //if (audioSDWriter.getQueueOverrun() || i2s_in.get_isOutOfMemory()) {
  189.       if (i2s_in.get_isOutOfMemory()) {
  190.         float approx_time_sec = ((float)(millis()-audioSDWriter.getStartTimeMillis()))/1000.0;
  191.         if (approx_time_sec > 0.1) {
  192.           myTympan.print("SD Write Warning: there was a hiccup in the writing.");//  Approx Time (sec): ");
  193.           myTympan.println(approx_time_sec );
  194.         }
  195.       }
  196.     }
  197.     i2s_in.clear_isOutOfMemory();
  198.     */
  199.   }
  200. }
  201.  
  202.  
  203. void serviceLEDs(void) {
  204.   static int loop_count = 0;
  205.   loop_count++;
  206.  
  207.   if (audioSDWriter.getState() == AudioSDWriter::STATE::UNPREPARED) {
  208.     if (loop_count > 200000) {  //slow toggle
  209.       loop_count = 0;
  210.       toggleLEDs(true,true); //blink both
  211.     }
  212.   } else if (audioSDWriter.getState() == AudioSDWriter::STATE::RECORDING) {
  213.  
  214.     //let's flicker the LEDs while writing
  215.     loop_count++;
  216.     if (loop_count > 20000) { //fast toggle
  217.       loop_count = 0;
  218.       toggleLEDs(true,true); //blink both
  219.     }
  220.   } else {
  221.     //myTympan.setRedLED(HIGH); myTympan.setAmberLED(LOW); //Go Red
  222.     if (loop_count > 200000) { //slow toggle
  223.       loop_count = 0;
  224.       toggleLEDs(false,true); //just blink the red
  225.     }
  226.   }
  227. }
  228.  
  229. void toggleLEDs(void) {
  230.   toggleLEDs(true,true);  //toggle both
  231. }
  232. void toggleLEDs(const bool &useAmber, const bool &useRed) {
  233.   static bool LED = false;
  234.   LED = !LED;
  235.   if (LED) {
  236.     if (useAmber) myTympan.setAmberLED(true);
  237.     if (useRed) myTympan.setRedLED(false);
  238.   } else {
  239.     if (useAmber) myTympan.setAmberLED(false);
  240.     if (useRed) myTympan.setRedLED(true);
  241.   }
  242.  
  243.   if (!useAmber) myTympan.setAmberLED(false);
  244.   if (!useRed) myTympan.setRedLED(false);
  245.  
  246. }
  247.  
Add Comment
Please, Sign In to add comment