275 lines
8.4 KiB
Arduino
275 lines
8.4 KiB
Arduino
|
//======================================================================
|
||
|
// audio.ino
|
||
|
//======================================================================
|
||
|
|
||
|
#include "audio.h"
|
||
|
|
||
|
extern IOPConfig iopConfig;
|
||
|
|
||
|
#define DEFAULT_RX_INPUT RIG
|
||
|
#define DEFAULT_RX_OUTPUT SPKR
|
||
|
#define DEFAULT_TX_INPUT MIC
|
||
|
#define DEFAULT_TX_OUTPUT RIG
|
||
|
|
||
|
#include <Audio.h>
|
||
|
#include <Wire.h>
|
||
|
#include <SPI.h>
|
||
|
#include <SD.h>
|
||
|
#include <SerialFlash.h>
|
||
|
|
||
|
// GUItool: begin automatically generated code
|
||
|
AudioInputI2S inLine; //xy=224,194
|
||
|
AudioInputUSB inUSB; //xy=224,303
|
||
|
AudioAnalyzeRMS rmsRX; //xy=399,71
|
||
|
AudioAnalyzePeak peakRX; //xy=403,122
|
||
|
AudioMixer4 mixRX; //xy=460,187
|
||
|
AudioMixer4 mixTX; //xy=460,303
|
||
|
AudioAmplifier calRxUSB; //xy=650,189
|
||
|
AudioAmplifier calRxSpkr; //xy=654,79
|
||
|
AudioAmplifier calRxLine; //xy=657,136
|
||
|
AudioAmplifier calTxLine; //xy=669,272
|
||
|
AudioAmplifier calTxUSB; //xy=670,329
|
||
|
AudioAnalyzePeak peakTX; //xy=685,402
|
||
|
AudioAnalyzeRMS rmsTX; //xy=699,457
|
||
|
AudioOutputAnalog outSpkr; //xy=830,79
|
||
|
AudioOutputUSB outUSB; //xy=839,279
|
||
|
AudioOutputI2S outLine; //xy=842,228
|
||
|
AudioConnection patchCord1(inLine, 0, rmsRX, 0);
|
||
|
AudioConnection patchCord2(inLine, 0, peakRX, 0);
|
||
|
AudioConnection patchCord3(inLine, 0, mixRX, 0);
|
||
|
AudioConnection patchCord4(inLine, 1, mixTX, 0);
|
||
|
AudioConnection patchCord5(inUSB, 0, mixRX, 1);
|
||
|
AudioConnection patchCord6(inUSB, 1, mixTX, 1);
|
||
|
AudioConnection patchCord7(mixRX, calRxSpkr);
|
||
|
AudioConnection patchCord8(mixRX, calRxLine);
|
||
|
AudioConnection patchCord9(mixRX, calRxUSB);
|
||
|
AudioConnection patchCord10(mixTX, calTxLine);
|
||
|
AudioConnection patchCord11(mixTX, calTxUSB);
|
||
|
AudioConnection patchCord12(mixTX, peakTX);
|
||
|
AudioConnection patchCord13(mixTX, rmsTX);
|
||
|
AudioConnection patchCord14(calRxUSB, 0, outUSB, 0);
|
||
|
AudioConnection patchCord15(calRxSpkr, outSpkr);
|
||
|
AudioConnection patchCord16(calRxLine, 0, outLine, 0);
|
||
|
AudioConnection patchCord17(calTxLine, 0, outLine, 1);
|
||
|
AudioConnection patchCord18(calTxUSB, 0, outUSB, 1);
|
||
|
AudioControlSGTL5000 audioCtrl; //xy=407,467
|
||
|
// GUItool: end automatically generated code
|
||
|
|
||
|
RxInput audioRxInput;
|
||
|
RxOutput audioRxOutput;
|
||
|
TxInput audioTxInput;
|
||
|
TxOutput audioTxOutput;
|
||
|
|
||
|
// audioInit()
|
||
|
// Setup the audio subsystem.
|
||
|
void audioInit()
|
||
|
{
|
||
|
audioCtrl.enable();
|
||
|
audioCtrl.muteHeadphone(); // not using the headphone output
|
||
|
audioCtrl.volume(0.0); // not using the headphone output
|
||
|
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio
|
||
|
audioCtrl.unmuteLineout(); // required for RX audio
|
||
|
audioCtrl.lineInLevel(iopConfig.rxRigInLevel, iopConfig.txLineInLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||
|
audioCtrl.lineOutLevel(iopConfig.rxLineOutLevel, iopConfig.txRigOutLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||
|
audioCtrl.micGain(iopConfig.txMicInGain); // superfluous, as I have to do this anytime I switch to mic for some reason
|
||
|
audioCtrl.dacVolumeRamp(); // if this seems too slow, might try dacVolumeRampLinear().
|
||
|
audioCtrl.dacVolume(1.0, 0.0); // we're going to mute TX audio via the DAC unless we're transmitting
|
||
|
|
||
|
// selectTxInput(TX_LINE_IN);
|
||
|
}
|
||
|
|
||
|
inline void updateRxRigIn()
|
||
|
{
|
||
|
audioCtrl.lineInLevel(iopConfig.rxRigInLevel, iopConfig.txLineInLevel);
|
||
|
mixRX.gain(RX_RIG_IN, iopConfig.rxRigInVol * iopConfig.rxRigInCal);
|
||
|
}
|
||
|
|
||
|
inline void muteRxRigIn()
|
||
|
{
|
||
|
mixRX.gain(RX_RIG_IN, 0.0);
|
||
|
}
|
||
|
|
||
|
inline void restoreRxRigIn()
|
||
|
{
|
||
|
mixRX.gain(RX_RIG_IN, iopConfig.rxRigInVol * iopConfig.rxRigInCal);
|
||
|
}
|
||
|
|
||
|
inline void updateRxUSBIn()
|
||
|
{
|
||
|
if (iopConfig.rxUSBInEnable) {
|
||
|
mixRX.gain(RX_USB_IN, iopConfig.rxUSBInVol * iopConfig.rxUSBInCal);
|
||
|
} else {
|
||
|
mixRX.gain(RX_USB_IN, 0.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline void updateRxSpkrOut()
|
||
|
{
|
||
|
calRxSpkr.gain(iopConfig.rxSpkrOutCal);
|
||
|
}
|
||
|
|
||
|
inline void updateRxLineOut()
|
||
|
{
|
||
|
calRxLine.gain(iopConfig.rxLineOutCal);
|
||
|
audioCtrl.lineOutLevel(iopConfig.rxLineOutLevel, iopConfig.txRigOutLevel);
|
||
|
}
|
||
|
|
||
|
inline void updateRxUSBOut()
|
||
|
{
|
||
|
calRxUSB.gain(iopConfig.rxUSBOutCal);
|
||
|
}
|
||
|
|
||
|
inline void updateTxMicIn()
|
||
|
{
|
||
|
audioCtrl.micGain(iopConfig.txMicInGain);
|
||
|
mixTX.gain(TX_LINE_IN, iopConfig.txMicInVol * iopConfig.txMicInCal);
|
||
|
}
|
||
|
|
||
|
inline void muteTxMicIn()
|
||
|
{
|
||
|
mixTX.gain(TX_LINE_IN, 0.0);
|
||
|
}
|
||
|
|
||
|
inline void restoreTxMicIn()
|
||
|
{
|
||
|
mixTX.gain(TX_LINE_IN, iopConfig.txMicInVol * iopConfig.txMicInCal);
|
||
|
}
|
||
|
|
||
|
inline void updateTxLineIn()
|
||
|
{
|
||
|
audioCtrl.lineInLevel(iopConfig.rxRigInLevel, iopConfig.txLineInLevel);
|
||
|
mixTX.gain(TX_LINE_IN, iopConfig.txLineInVol * iopConfig.txLineInCal);
|
||
|
}
|
||
|
|
||
|
inline void muteTxLineIn()
|
||
|
{
|
||
|
mixTX.gain(TX_LINE_IN, 0.0);
|
||
|
}
|
||
|
|
||
|
inline void restoreTxLineIn()
|
||
|
{
|
||
|
mixTX.gain(TX_LINE_IN, iopConfig.txLineInVol * iopConfig.txLineInCal);
|
||
|
}
|
||
|
|
||
|
inline void updateTxUSBIn()
|
||
|
{
|
||
|
mixTX.gain(TX_USB_IN, iopConfig.txUSBInVol * iopConfig.txUSBInCal);
|
||
|
}
|
||
|
|
||
|
inline void muteTxUSBIn()
|
||
|
{
|
||
|
mixTX.gain(TX_USB_IN, 0.0);
|
||
|
}
|
||
|
|
||
|
inline void restoreTxUSBIn()
|
||
|
{
|
||
|
mixTX.gain(TX_USB_IN, iopConfig.txUSBInVol * iopConfig.txUSBInCal);
|
||
|
}
|
||
|
|
||
|
inline void updateTxRigOut()
|
||
|
{
|
||
|
calTxLine.gain(iopConfig.txRigOutCal);
|
||
|
audioCtrl.lineOutLevel(iopConfig.rxLineOutLevel, iopConfig.txRigOutLevel);
|
||
|
}
|
||
|
|
||
|
inline void updateTxUSBOut()
|
||
|
{
|
||
|
if (iopConfig.txUSBOutEnable) {
|
||
|
calTxUSB.gain(iopConfig.txUSBOutCal);
|
||
|
} else {
|
||
|
calTxUSB.gain(0.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void audioSelectTxInput(TxInput input)
|
||
|
{
|
||
|
if (audioTxInput != input) {
|
||
|
audioTxInput = input;
|
||
|
switch(input) {
|
||
|
case TX_MIC_IN:
|
||
|
muteTxUSBIn();
|
||
|
restoreTxMicIn();
|
||
|
break;
|
||
|
|
||
|
case TX_LINE_IN:
|
||
|
muteTxUSBIn();
|
||
|
restoreTxLineIn();
|
||
|
break;
|
||
|
|
||
|
case TX_USB_IN:
|
||
|
muteTxLineIn();
|
||
|
restoreTxUSBIn();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// audioTransmit()
|
||
|
// This should be called anytime transmit mode is entered. It should
|
||
|
// in theory be called BEFORE the actual transmit signal (key/PTT) is
|
||
|
// sent to the Raduino, in order to ensure that any audio source
|
||
|
// transitions occur before transmission begins.
|
||
|
void audioTransmit()
|
||
|
{
|
||
|
if (rigMode == MODE_SSB || rigMode == MODE_DIGI) {
|
||
|
// First we're going to set the RX and TX audio DAC volumes to
|
||
|
// zero while we change other mixer settings, to try to use the
|
||
|
// DAC's volume ramping to minimize pops.
|
||
|
// NOTE: Might need to add a brief delay?
|
||
|
audioCtrl.dacVolume(0.0, 0.0);
|
||
|
|
||
|
// Next mute the incoming RX audio. Can't think of a good reason
|
||
|
// to let RX audio in while we're transmitting.
|
||
|
muteRxRigIn();
|
||
|
|
||
|
if (audioTxInput == TX_MIC_IN) {
|
||
|
// Mute the TX line in in this case, too, because we need to
|
||
|
// switch over to the mic input.
|
||
|
muteTxLineIn();
|
||
|
|
||
|
// Now switch to the mic input, and set the mic gain.
|
||
|
audioCtrl.inputSelect(AUDIO_INPUT_MIC);
|
||
|
updateTxMicIn();
|
||
|
}
|
||
|
|
||
|
// Allow both transmit and receive audio output channels. This is safe
|
||
|
// because the RX input is muted, and we might want to inject something else.
|
||
|
audioCtrl.dacVolume(1.0, 1.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// audioReceive()
|
||
|
// This should be called anytime receive mode is entered. It should
|
||
|
// in theory be called AFTER the actual transmit signal (key/PTT) is
|
||
|
// removed from the Raduino, in order to ensure that any audio source
|
||
|
// transitions occur before receive begins.
|
||
|
void audioReceive()
|
||
|
{
|
||
|
if (rigMode == MODE_SSB || rigMode == MODE_DIGI) {
|
||
|
// First we're going to set the RX and TX audio DAC volumes to
|
||
|
// zero while we switch inputs, because the DAC volumes can be
|
||
|
// smoothly ramped by the SGTL5000 to avoid pops.
|
||
|
audioCtrl.dacVolume(0.0, 0.0);
|
||
|
|
||
|
// Mute the mic, since we're going to be switching back to line
|
||
|
// input for RX and TX.
|
||
|
if (audioTxInput == TX_MIC_IN) {
|
||
|
muteTxMicIn();
|
||
|
|
||
|
// Now switch to the line input, and restore mixer settings.
|
||
|
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||
|
restoreTxLineIn();
|
||
|
}
|
||
|
|
||
|
restoreRxRigIn();
|
||
|
|
||
|
// Now bring back up the DAC volumes. Hopefully this reduced pops...
|
||
|
// When going back to receive, we leave transmit DAC at zero.
|
||
|
audioCtrl.dacVolume(1.0, 0.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//======================================================================
|
||
|
// EOF
|
||
|
//======================================================================
|