Skip to content

Commit

Permalink
Examples: CalibrateOutput: first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
chipaudette committed Oct 2, 2024
1 parent 7382f11 commit 2a82402
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
CalibrateOutput
Created: Chip Audette, OpenAudio, Oct 2024
Purpose: Generates a sine wave and outputs it to the black headphone jack. You can
measure the amplitude of the signal using an external volt meter.
Remember that the Tympan's audio codec chip (AIC) can provide additional
gain (DAC gain and headphone amp gain). So, if your own program deviates from
default Tympan setings for these AIC gains, you will need to re-calibrate
using your exact settings.
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::E,audio_settings); //do TympanRev::D or TympanRev::E or TympanRev::F
AudioInputI2S_F32 i2s_in(audio_settings); //Digital audio input from the ADC...not used in this program
AudioSynthWaveform_F32 sineWave(audio_settings); //generate a synthetic sine wave
AudioOutputI2S_F32 i2s_out(audio_settings); //Digital audio output to the DAC. Should always be last.

//Connect the sineWave to its destinations
AudioConnection_F32 patchcord01(sineWave, 0, i2s_out, 0); //Sine wave to left output
AudioConnection_F32 patchcord02(sineWave, 0, i2s_out, 1); //Sine wave 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)

// ///////////////// Functions to control the audio
float sine_freq_Hz = 1000.0;
float sine_amplitude = sqrt(2.0)*sqrt(pow(10.0,0.1*-20.0)); //(-20dBFS converted to linear and then converted from RMS to amplitude)
float setFrequency_Hz(float freq_Hz) { return sine_freq_Hz = sineWave.setFrequency_Hz(freq_Hz); }
float setAmplitude(float amplitude) { return sine_amplitude = sineWave.setAmplitude(amplitude); }


// ///////////////// 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("CalibrateOutput: 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
myTympan.volume_dB(0.0); // headphone amplifier

//setup the test tone
setFrequency_Hz(sine_freq_Hz);
setAmplitude(sine_amplitude);

//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 LEDs...the "false" tells it to blink slowly (simply to prove that it's alive)
myTympan.serviceLEDs(millis(),false);

} //end loop()



69 changes: 69 additions & 0 deletions examples/02-Utility/Calibration/CalibrateOutput/SerialManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

#ifndef _SerialManager_h
#define _SerialManager_h

#include <Tympan_Library.h>

//Extern variables from the main *.ino file
extern Tympan myTympan;
extern float sine_freq_Hz;
extern float sine_amplitude;

//Extern Functions (that live in a file other than this file here)
extern float setFrequency_Hz(float freq_Hz);
extern float setAmplitude(float amplitude);

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 frequencyIncrement_factor = pow(2.0,1.0/3.0); //third octave steps
float amplitudeIcrement_dB = 1.0; //changes the amplitude of the synthetic sine wave
private:
};

void SerialManager::printHelp(void) {
Serial.println("SerialManager Help: Available Commands:");
Serial.println("General: No Prefix");
Serial.println(" h: Print this help");
Serial.println(" f/F: Sine: Increase or decrease steady-tone frequency (current = " + String(sine_freq_Hz,1) + " Hz)");
Serial.println(" a/A: Sine: Increase or decrease sine amplitude (current = " + String(20*log10(sine_amplitude)-3.0,1) + " dB re: output FS = " + String(sine_amplitude,3) + " amplitude)");
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 'f':
setFrequency_Hz(max(125.0/4,min(16000.0,sine_freq_Hz*frequencyIncrement_factor))); //octave-based incrementing. Limit freuqencies to 31.25 Hz -> 16 kHz
Serial.println("SerialManager: increased tone frequency to " + String(sine_freq_Hz) + " Hz");
break;
case 'F':
setFrequency_Hz(max(125.0/4,min(16000.0,sine_freq_Hz/frequencyIncrement_factor))); //octave-based incrementing. Limit freuqencies to 31.25 Hz -> 16 kHz
Serial.println("SerialManager: decreased tone frequency to " + String(sine_freq_Hz) + " Hz");
break;
case 'a':
setAmplitude(max(0.0,sine_amplitude*sqrt(pow(10.0,0.1*amplitudeIcrement_dB)))); //converting dB back to linear units
Serial.println("SerialManager: increased tone amplitude to " + String(20.f*log10f(sine_amplitude)-3.0,1) + " dB re: output FS");
break;
case 'A':
setAmplitude(max(0.0,sine_amplitude/sqrt(pow(10.0,0.1*amplitudeIcrement_dB)))); //converting dB back to linear units
Serial.println("SerialManager: decreased tone amplitude to " + String(20.f*log10f(sine_amplitude)-3.0,1) + " dB re: output FS");
break;
default:
Serial.println("SerialManager: command " + String(c) + " not recognized");
break;
}
return ret_val;
}


#endif

0 comments on commit 2a82402

Please sign in to comment.