-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Examples: Calibrate input: first commit
- Loading branch information
1 parent
def5445
commit 1a59d08
Showing
2 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
133 changes: 133 additions & 0 deletions
133
examples/02-Utility/Calibration/02-CalibrateInput/02-CalibrateInput.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
CalibrateInput | ||
Created: Chip Audette, OpenAudio, Oct 2024 | ||
Purpose: Measure the signal level of the left analog input (pink jack). If you know | ||
the voltage of the input signal, then you can compare it to the Tympan-reported | ||
digital signal level, which will allow you to compute the calibration coefficient! | ||
This example also lets you record the audio to the SD card for analysis on your | ||
PC or Mac. | ||
Remember that the Tympan's audio codec chip (AIC) can provide both filtering | ||
and additional gain before it digitizes the analog sigal. So, if using this | ||
example to calibrate the Tympan inputs, be sure that you know whether your own | ||
program is using the AIC's filtering and gain differently than being used here. | ||
For Tympan Rev D, program in Arduino IDE as a Teensy 3.6. | ||
For Tympan Rev E and F, program in Arduino IDE as a Teensy 4.1. | ||
MIT License. use at your own risk. | ||
*/ | ||
|
||
// Include all the of the needed libraries | ||
#include <Tympan_Library.h> | ||
#include "SerialManager.h" | ||
|
||
//set the sample rate and block size | ||
const float sample_rate_Hz = 44100.0f ; //24000 or 44117 or 96000 (or other frequencies in the table in AudioOutputI2S_F32) | ||
const int audio_block_samples = 128; //do not make bigger than AUDIO_BLOCK_SAMPLES from AudioStream.h (which is 128) Must be 128 for SD recording. | ||
AudioSettings_F32 audio_settings(sample_rate_Hz, audio_block_samples); | ||
|
||
// Create the audio objects and then connect them | ||
Tympan myTympan(TympanRev::F,audio_settings); //do TympanRev::D or TympanRev::E or TympanRev::F | ||
AudioInputI2S_F32 i2s_in(audio_settings); //Digital audio input from the ADC | ||
AudioCalcLeq_F32 calcInputLevel(audio_settings); //use this to measure the input signal level | ||
AudioSDWriter_F32 audioSDWriter(audio_settings); //will record the input signal | ||
AudioOutputI2S_F32 i2s_out(audio_settings); //Digital audio output to the DAC. Should always be last. | ||
|
||
//Connect the audio input to the level monitor | ||
AudioConnection_F32 patchcord01(i2s_in, 0, calcInputLevel, 0); //Left input to the level monitor | ||
|
||
//Connect the audio inputs to the SD recorder | ||
AudioConnection_F32 patchcord02(i2s_in, 0, audioSDWriter, 0); //Left input to the SD writer | ||
AudioConnection_F32 patchcord03(i2s_in, 1, audioSDWriter, 1); //Right input to the SD writer | ||
|
||
//Connect the audio inputs to the audio outputs (to enable monitoring via headphones) | ||
AudioConnection_F32 patchcord10(i2s_in, 0, i2s_out, 0); //Left input to left output | ||
AudioConnection_F32 patchcord11(i2s_in, 1, i2s_out, 1); //Right input to right output | ||
|
||
|
||
// ///////////////// Create classes for controlling the system, espcially via USB Serial and via the App | ||
SerialManager serialManager; //create the serial manager for real-time control (via USB or App) | ||
bool flag_printInputLevelToUSB = true; | ||
|
||
// ///////////////// Functions to control the audio | ||
float input_gain_dB = 0.0; // default value of analog gain in the AIC | ||
float setInputGain_dB(float val_dB) { return input_gain_dB = myTympan.setInputGain_dB(val_dB); } | ||
|
||
// ///////////////// Main setup() and loop() as required for all Arduino programs | ||
|
||
// define the setup() function, the function that is called once when the device is booting | ||
void setup() { | ||
//begin the serial comms (for debugging) | ||
myTympan.beginBothSerial(); delay(500); | ||
while (!Serial && (millis() < 2000UL)) delay(5); //wait for 2 seconds to see if USB Serial comes up (try not to miss messages!) | ||
myTympan.println("CalibrateInput: Starting setup()..."); | ||
Serial.println("Sample Rate (Hz): " + String(audio_settings.sample_rate_Hz)); | ||
Serial.println("Audio Block Size (samples): " + String(audio_settings.audio_block_samples)); | ||
|
||
//allocate the dynamically re-allocatable audio memory | ||
AudioMemory_F32(100, audio_settings); | ||
|
||
//activate the Tympan audio hardware | ||
myTympan.enable(); // activate the flow of audio | ||
|
||
//Choose the desired audio input on the Tympan | ||
//myTympan.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on-board micropphones | ||
//myTympan.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V | ||
myTympan.inputSelect(TYMPAN_INPUT_JACK_AS_LINEIN); // use the microphone jack - defaults to mic bias OFF | ||
|
||
//Setup the input on the AIC | ||
myTympan.setHPFonADC(true,25.0,audio_settings.sample_rate_Hz); //setup a highpass filter at 25 Hz to remove any DC | ||
myTympan.setInputGain_dB(input_gain_dB); | ||
|
||
//Setup the level measuring algorithm | ||
calcInputLevel.setTimeWindow_sec(0.125); //average over 0.125 seconds | ||
|
||
//Setup the output of the Tympan | ||
myTympan.volume_dB(0.0); // AIC's output gain | ||
|
||
//prepare the SD writer for the format that we want and any error statements | ||
audioSDWriter.setSerial(&myTympan); //the library will print any error info to this serial stream (note that myTympan is also a serial stream) | ||
audioSDWriter.setNumWriteChannels(2); //this is also the built-in defaullt, but you could change it to 4 (maybe?), if you wanted 4 channels. | ||
Serial.println("Setup: SD configured for " + String(audioSDWriter.getNumWriteChannels()) + " channels."); | ||
|
||
//End of setup | ||
Serial.println("Setup: complete."); | ||
serialManager.printHelp(); | ||
} //end setup() | ||
|
||
|
||
// define the loop() function, the function that is repeated over and over for the life of the device | ||
void loop() { | ||
|
||
//respond to Serial commands | ||
if (Serial.available()) serialManager.respondToByte((char)Serial.read()); //USB Serial | ||
|
||
//service the SD recording | ||
audioSDWriter.serviceSD_withWarnings(i2s_in); //For the warnings, it asks the i2s_in class for some info | ||
|
||
//service the LEDs...blink slow normally, blink fast if recording | ||
myTympan.serviceLEDs(millis(),audioSDWriter.getState() == AudioSDWriter::STATE::RECORDING); | ||
|
||
//periodically print the input signal levels | ||
if (flag_printInputLevelToUSB) printInputSignalLevels(millis(),1000); //print every 1000 msec | ||
|
||
} //end loop() | ||
|
||
// //////////////////////////////////////// Other functions | ||
void printInputSignalLevels(unsigned long cur_millis, unsigned long updatePeriod_millis) { | ||
static unsigned long lastUpdate_millis = 0UL; | ||
if ( (cur_millis < lastUpdate_millis) || (cur_millis >= lastUpdate_millis + updatePeriod_millis) ) { | ||
Serial.print("Input gain = " + String(input_gain_dB,1) + " dB"); | ||
Serial.print(", Measured Input = "); | ||
Serial.print(calcInputLevel.getCurrentLevel_dB(),2); | ||
Serial.print(" dB re: input FS"); | ||
Serial.println(); | ||
|
||
lastUpdate_millis = cur_millis; | ||
} | ||
} | ||
|
||
|
76 changes: 76 additions & 0 deletions
76
examples/02-Utility/Calibration/02-CalibrateInput/SerialManager.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
|
||
#ifndef _SerialManager_h | ||
#define _SerialManager_h | ||
|
||
#include <Tympan_Library.h> | ||
|
||
|
||
//Extern variables from the main *.ino file | ||
extern Tympan myTympan; | ||
extern AudioSDWriter_F32 audioSDWriter; | ||
extern float input_gain_dB; | ||
extern float setInputGain_dB(float val_dB); | ||
extern bool flag_printInputLevelToUSB; | ||
|
||
class SerialManager : public SerialManagerBase { // see Tympan_Library for SerialManagerBase for more functions! | ||
public: | ||
SerialManager(void) : SerialManagerBase() {}; | ||
|
||
void printHelp(void); | ||
bool processCharacter(char c); //this is called automatically by SerialManagerBase.respondToByte(char c) | ||
|
||
float inputGainIncrement_dB = 5.0; //changes the input gain of the AIC | ||
private: | ||
}; | ||
|
||
void SerialManager::printHelp(void) { | ||
Serial.println("SerialManager Help: Available Commands:"); | ||
Serial.println("General: No Prefix"); | ||
Serial.println(" h: Print this help"); | ||
Serial.println(" i/I: Input: Increase or decrease input gain (current = " + String(input_gain_dB,1) + " dB)"); | ||
Serial.print( " p/P: Printing: start/Stop printing of input signal levels"); if (flag_printInputLevelToUSB) {Serial.println(" (active)");} else { Serial.println(" (off)"); } | ||
Serial.println(" r/s: SD: Start recording (r) or stop (s) audio to SD card"); | ||
Serial.println(); | ||
} | ||
|
||
|
||
//switch yard to determine the desired action | ||
bool SerialManager::processCharacter(char c) { //this is called by SerialManagerBase.respondToByte(char c) | ||
bool ret_val = true; //assume at first that we will find a match | ||
switch (c) { | ||
case 'h': | ||
printHelp(); | ||
break; | ||
case 'i': | ||
setInputGain_dB(input_gain_dB + inputGainIncrement_dB); | ||
Serial.println("SerialManager: Increased input gain to: " + String(input_gain_dB) + " dB"); | ||
break; | ||
case 'I': //which is "shift i" | ||
setInputGain_dB(input_gain_dB - inputGainIncrement_dB); | ||
Serial.println("SerialManager: Decreased input gain to: " + String(input_gain_dB) + " dB"); | ||
break; | ||
case 'p': | ||
flag_printInputLevelToUSB = true; | ||
Serial.println("SerialManager: enabled printing of the input signal levels"); | ||
break; | ||
case 'P': | ||
flag_printInputLevelToUSB = false; | ||
Serial.println("SerialManager: disabled printing of the input signal levels"); | ||
break; | ||
case 'r': | ||
Serial.println("SerialManager: starting recording of input sginals to the SD card..."); | ||
audioSDWriter.startRecording(); | ||
break; | ||
case 's': | ||
Serial.println("SerialManager: stopping recording of input signals to the SD card..."); | ||
audioSDWriter.stopRecording(); | ||
break; | ||
default: | ||
Serial.println("SerialManager: command " + String(c) + " not recognized"); | ||
break; | ||
} | ||
return ret_val; | ||
} | ||
|
||
|
||
#endif |