/* Audio Frequency Inverter by Roland Hall, based on an idea by Phil Arnold * using a Teensy 3.2 and audio adapter board * It is intended to be used with an audio transformer to provide * a differential mic signal output, and an earpiece amplifier * PTT (Pressel) line is low for Tx * Mic In for microphone input from handset * Line In Left for receive audio from radio * Line Out left to transmitter via transformer. Can be inverted or thru. * Line Out right to Handset earpiece amplifier. Can be inverted or thru. * Handset earpiece signal may be inverted on Rx, but is always thru on Tx for sidetone. * LED indication is provided on pin 2 if approaching clipping on peak input signal * Note: Adapter board headphone output is not used */ #include #include #include #include #include #define PTT 0 //PTT (Pressel) pin, low for Tx #define MODE 1 //Mode pin, high for invert #define CLIP 2 //CLIP pin indicates input clipping. N.B. Onboard LED pin13 used for shield //Global variables int audiomem; //sets memory available for audio processing byte conf = 5; //configuration case of signal paths and gains byte old_conf = 6; //there is no case 5 or 6. Selected conf is set up in loop // Once the correct values have been established set these appropriately int mic = 30; //0 to 63dB is available int lineIn = 0; //0 to 15: 3.12 to 0.24V p-p in steps of divide by 1.2 (1.6dB) int lineOut = 13; //13 to 31: 3.16 to 1.16V p-p in steps of divide by 1.06 (0.5dB) // GUItool: begin automatically generated code AudioInputI2S i2s1; //xy=242.85711669921875,250.85711669921875 AudioFilterFIR fir1; //xy=429.4287109375,244.42849731445312 AudioAnalyzePeak peak1; //xy=430,343.4284973144531 AudioSynthWaveformSine sine1; //xy=431,136.42855834960938 AudioEffectMultiply multiply1; //xy=604,171.14285278320312 AudioFilterFIR fir2; //xy=742.5713500976562,170.57135009765625 AudioMixer4 mixerHandset; //xy=938.4285278320312,318.7142639160156 AudioMixer4 mixerTxAF; //xy=939.0000610351562,219.57150268554688 AudioOutputI2S i2s2; //xy=1109.4288330078125,268.28570556640625 AudioConnection patchCord1(i2s1, 0, fir1, 0); AudioConnection patchCord2(i2s1, 0, peak1, 0); AudioConnection patchCord3(fir1, 0, multiply1, 1); AudioConnection patchCord4(fir1, 0, mixerTxAF, 1); AudioConnection patchCord5(fir1, 0, mixerHandset, 1); AudioConnection patchCord6(sine1, 0, multiply1, 0); AudioConnection patchCord7(multiply1, fir2); AudioConnection patchCord8(fir2, 0, mixerTxAF, 0); AudioConnection patchCord9(fir2, 0, mixerHandset, 0); AudioConnection patchCord10(mixerHandset, 0, i2s2, 1); AudioConnection patchCord11(mixerTxAF, 0, i2s2, 0); AudioControlSGTL5000 shield; //xy=249.28573608398438,161.42857360839844 // GUItool: end automatically generated code extern const short tapCoefs[200]; void setup() { pinMode(PTT, INPUT_PULLUP); pinMode(MODE, INPUT_PULLUP); pinMode(CLIP, OUTPUT); Serial.begin(9600); AudioMemory(10); audiomem = 10; shield.enable(); shield.inputSelect(AUDIO_INPUT_LINEIN); shield.volume(0.8); shield.unmuteLineout(); sine1.amplitude(1.0); sine1.frequency(3000.0); fir1.begin(tapCoefs,200); fir2.begin(tapCoefs,200); } void loop() { bool dir = digitalRead(0); //check if Tx is called for - true for Rx bool mode = digitalRead(1); //check if invert is called for - true for invert // Set the signal paths and gains if (dir && !mode) conf = 1; //Rx thru config if (dir && mode) conf = 2; //Rx invert config if (!dir && !mode) conf = 3; //Tx thru config if (!dir && mode) conf = 4; //Tx invert config //Serial.println (conf); if (old_conf != conf) //run switch function if a new config has been requested { shield.muteLineout(); switch(conf) //start of switch function { case 1: //conf 1 is Rx thru shield.inputSelect(AUDIO_INPUT_LINEIN); shield.lineInLevel(lineIn); mixerTxAF.gain(0,0); mixerTxAF.gain(1,0); mixerHandset.gain(0,0); mixerHandset.gain(1,1); break; case 2: //conf 2 is Rx invert shield.inputSelect(AUDIO_INPUT_LINEIN); shield.lineInLevel(lineIn); mixerTxAF.gain(0,0); mixerTxAF.gain(1,0); mixerHandset.gain(0,2); //gain of 2 compensates for mixer loss mixerHandset.gain(1,0); break; case 3: //conf 3 is Tx thru shield.inputSelect(AUDIO_INPUT_MIC); shield.micGain(mic); mixerTxAF.gain(0,0); mixerTxAF.gain(1,1); mixerHandset.gain(0,0); mixerHandset.gain(1,0.8); //gain adjust for sidetone break; case 4: //conf 4 is Tx invert shield.inputSelect(AUDIO_INPUT_MIC); shield.micGain(mic); mixerTxAF.gain(0,2); mixerTxAF.gain(1,0); mixerHandset.gain(0,0); mixerHandset.gain(1,0.8); //gain adjust for sidetone break; } //end of switch function shield.unmuteLineout(); old_conf = conf; } float peakInput = peak1.read(); // Serial.print("In pk: "); Serial.println(peakInput,3); if (peakInput>0.9) { //set clip pin high if nearly clipping digitalWrite(CLIP,HIGH); } else { digitalWrite(CLIP,LOW); } delay(100); }