Low volume with autoVolumeControl in Teensy SDR

Status
Not open for further replies.

w9ran

Member
First let me say I'm new to all this - Teensy and Arduino - so I apologize in advance for any noob errors. But I have been learning a lot from Rich Heslip's excellent work on the Teensy SDR and am blown away by the capabilities of the Teensy Audio Library. One doesn't have to to be a Rembrandt in order to appreciate good art, and I know enough about DSP to know that Paul has created something outstanding here.

My problem is getting a usable amount of audio from the Audio Board with the standard code that Rich developed. Hopefully I've provided the relevant snippets below as the code is set to use hardware AGC and this is the starting point for my troubleshooting.

INITIAL_VOLUME was set to 0.8, but even after I increased it to 1.0 the output is very low (to the point where sound is barely audible with a powered speaker held right to my ear). Of course there are other gains in previous sections of the code that may be responsible, but I thought it made sense to start working backward from the output. I've used example programs such a ToneSweep to prove that the audio board is capable of driving my powered speaker to very loud levels, so it's got to be in the app software somewhere. I'd appreciate pointers to where I can learn more about autoVolumeControl as the comments reproduced below seem to be abbreviated and I haven't found the right place in the library to look for more. What I see, this looks OK except I con't know what the last 3 parameters do. With the initial setting were "wide open", I would expect the audio to blast (like the examples) and then gradually reduce in response to AGC, but audio starts out nearly inaudible and stays that way. I know the software is basically working because I can hear correct audio at a very low level and unfortunately I don't yet have the knowledge to identify potential causes on my own.

A couple more noob questions, if I may:

1. Am I correct that the headphone jack and line outputs get the same signals but headphone audio can be independently controlled? (Right now I hear very weak audio thru line out but nothing at all thru the headphone jack). I'd disable that VOL function if I knew how.

2. Richs's original hardware used a pot connected to the VOL input on the Audio board. I prefer not to have it but have wired it up and can vary the voltage at the VOL pin from 0 to 3.3 but it has no effect on either Line or headphone volume.

If I could get the audio volume from the SDR app close to what I hear with the examples, I'd be happy!

Thanks,
Bob W9RAN



#define INITIAL_VOLUME 1.0 // 0-1.0 output volume on startup

<snip>

AudioConnection c40(Audioselector_I, 0, AGCpeak, 0); // AGC Gain loop measure
AudioConnection c41(Audioselector_I, 0, audioOutput, 0); // Output the sum on both channels
AudioConnection c42(Audioselector_Q, 0, audioOutput, 1);

<snip>

// Enable the audio shield and set the output volume.
audioShield.enable();
audioShield.volume(INITIAL_VOLUME);
audioShield.unmuteLineout();
#ifdef DEBUG
Serial.println("audio shield enabled");
#endif

#ifdef HW_AGC
/* COMMENTS FROM Teensy Audio library:
Valid values for dap_avc parameters
maxGain; Maximum gain that can be applied
0 - 0 dB
1 - 6.0 dB
2 - 12 dB
lbiResponse; Integrator Response
0 - 0 mS
1 - 25 mS
2 - 50 mS
3 - 100 mS
hardLimit
0 - Hard limit disabled. AVC Compressor/Expander enabled.
1 - Hard limit enabled. The signal is limited to the programmed threshold (signal saturates at the threshold)
threshold
floating point in range 0 to -96 dB
attack
floating point figure is dB/s rate at which gain is increased
decay
floating point figure is dB/s rate at which gain is reduced
*/
audioShield.autoVolumeControl(2,1,0,-30,3,20); // see comments above
audioShield.autoVolumeEnable();

#endif
 
What QSD board are you using?

I think Rich was using the Softrock RXTX. IIRC he swapped out a couple of the resistors in the op-amp feedback circuit to increase the gain. I don't remember the values off the top of my head, but I will check my notes when I get home. I did a similar mod on my RX only Softrock board.

I think I may have also turned up the "rf gain" parameter in software, but I can't remember if that was on VE3MKC (rich) or DD4WH (frank) firmware.

Hope that helps,
-Aaron
 
What QSD board are you using?

/QUOTE]

Aaron - thanks much for your reply. I'm using a Softrock 6.2 with the Si5351 synthesizer feeding the base of the oscillator buffer stage to drive the TTL divider. I've listened to the receiver using two PC-based SDR programs and they both seem to produce normal gain and volume with minimal Line In gain. Rich mentioned changing out some parts but any details you might have would be appreciated at I haven't found much yet on Softrock mods (probably because of the above). The fact that I see (at night when signals are strong) full-scale indications on the spectrum display suggests that the gain is adequate at least to the input of the fft.

To add confusion, I just connected the mic and started checking out the transmit side, only to discover the feedback from the sidetone is deafening! It probably would be OK if I had normal gain in the normal receive mode as I have to run my audio amplifier wide-open in order to barely hear anything at all. So this tells me it's got to be some gain parameter(s), either the I2S input, the Mixer or Line Output, or something in between. I can't imagine that the Teensy Audio board is that much different than a standard PC line input in terms of sensitivity and since Rich's presumably works as-is, I've got a huge difference somewhere.

Thanks and 73,
Bob W9RAN
 
I found the modification described by Rich in the comment section of his blog.

http://rheslip.blogspot.com/2015/01/teensy-sdr-project-update.html

Here is the text of the mod. (search for "10k" in the above link)

"""Note that I increased the audio gain of my softrocks by changing the RX amplifier feedback resistor to 10k and decreasing the feedback cap to 100p."""

On my SoftRock Lite II that meant going from 4.99k to 10k. I made no real measurements, but I did notice a visual gain on the fft and louder audio as one would expect. I didn't have a 100p so I put in a 150p instead, stock was 390p.

I'm afraid I am no help on the TX side. I haven't hooked that part up yet.

-Aaron
 
Hi Bob,

I am not familiar with the Softrock, so I can not be of much help here, I fear . . .

With the Teensy SDR, I was never satisfied with the AGC and I always used it without AGC. Maybe you also want to try to NOT #define HW_AGC ?

Also try to put this into setup, this gives another 22.5dB of hardware gain from the codec.
sgtl5000_1.lineInLevel(15)
See here for this control:
https://www.pjrc.com/teensy/gui/?info=AudioControlSGTL5000

All the best, have fun, Frank
 
Thanks very much Frank! I've increased the gain in the opamps on the Softrock board and that's definitely helped as I can hear strong signals now without straining and see full-scale spikes on the spectrum display, but the gain is clearly still inadequate, as full volume on my 2 watt amplifier produces the level of audio you'd expect with the volume control barely cracked open. And I still have nothing coming out of the headphone jack, even though I once did, before I tried the software AGC, so I may have broken something without realizing it.

I've read about your receiver and while my interests lie more in the direction of the original Teensy SDR QRP portable, i'm really impressed with your efforts, and it certainly proves the capability of the Teensy and Audioshield. I just wish I knew what I was doing with C ;- If you'd happen to know an example using the SGTL5000 control functions that I could look at, that would be helpful.

I'll figure it out eventually although my gut feel is that the gain through the image-cancelling mixer is OK because of the strong peaks I see on the display, and that the loss of gain is happening somewhere closer to the speaker - either in the mixers that select the audio path (which my understanding is just mix, but don't add or subtract any gain), or in the i2S1 output (which also doesn't seem to have any gain controls). So it's probably correct to do this with the SGTL5000 controls, if I can figure out how!

But maybe my visualization of how this thing works is all wrong - it's tough for us old hardware guys who just want to go stage-by-stage with a scope probe!

73, Bob W9RAN
 
Frank,
The snippet below complies without error but has no effect on the audio level. Could you take a look and see if I've got the syntax right? An object was already created so all I did was adde the last line, but I'm guessing as to syntax and since it's not having any effect I must have it wrong. Thanks.

73, Bob W9RAN


AudioMixer4 Summer; // Summer (add inputs)
AudioAnalyzeFFT256 myFFT; // Spectrum Display
AudioSynthWaveform IF_osc; // Local Oscillator
AudioSynthWaveform CW_tone_I; // Oscillator for CW tone I (sine)
AudioSynthWaveform CW_tone_Q; // Oscillator for CW tone Q (cosine)
AudioEffectMultiply Mixer; // Mixer (multiply inputs)
AudioAnalyzePeak Smeter; // Measure Audio Peak for S meter
AudioMixer4 Audioselector_I; // Summer used for AGC and audio switch
AudioMixer4 Audioselector_Q; // Summer used as audio selector
AudioAnalyzePeak AGCpeak; // Measure Audio Peak for AGC use
AudioOutputI2S audioOutput; // Audio Shield: headphones & line-out

AudioControlSGTL5000 audioShield; // Create an object to control the audio shield.

//---------------------------------------------------------------------------------------------------------
// Create Audio connections to build a software defined Radio Receiver
//
AudioConnection c1(audioinput, 0, Hilbert45_I, 0);// Audio inputs to +/- 45 degree filters
AudioConnection c2(audioinput, 1, Hilbert45_Q, 0);
AudioConnection c3(Hilbert45_I, 0, Summer, 0); // Sum the shifted filter outputs to supress the image
AudioConnection c4(Hilbert45_Q, 0, Summer, 1);
//
AudioConnection c10(Summer, 0, myFFT, 0); // FFT for spectrum display
AudioConnection c11(Summer,0, FIR_BPF, 0); // 2.4 kHz USB or LSB filter centred at either 12.5 or 9.5 kHz
// // ( local oscillator zero beat is at 11 kHz, see NCO )
AudioConnection c12(FIR_BPF, 0, Mixer, 0); // IF from BPF to Mixer
AudioConnection c13(IF_osc, 0, Mixer, 1); // Local Oscillator to Mixer (11 kHz)
//
AudioConnection c20(Mixer, 0, postFIR, 0); // 2700Hz Low Pass filter or 200 Hz wide CW filter at 700Hz on audio output
AudioConnection c30(postFIR,0, Smeter, 0); // RX signal S-Meter measurement point
//
// RX is mono output , but for TX we need I and Q audio channel output
// two summers (I and Q) on the output used to select different audio paths for different RX and TX modes
//
AudioConnection c31(postFIR,0, Audioselector_I, ROUTE_RX); // mono RX audio and AGC Gain loop adjust
AudioConnection c32(postFIR,0, Audioselector_Q, ROUTE_RX); // mono RX audio to 2nd channel
AudioConnection c33(Hilbert45_I,0, Audioselector_I, ROUTE_SSB_TX); // SSB TX I audio and ALC Gain loop adjust
AudioConnection c34(Hilbert45_Q,0, Audioselector_Q, ROUTE_SSB_TX); // SSB TX Q audio and ALC Gain loop adjust
AudioConnection c35(CW_tone_I,0, Audioselector_I, ROUTE_CW_TX); // CW TX I audio
AudioConnection c36(CW_tone_Q,0, Audioselector_Q, ROUTE_CW_TX); // CW TX Q audio
// note that last mixer input is unused - PSK mode ???
//
AudioConnection c40(Audioselector_I, 0, AGCpeak, 0); // AGC Gain loop measure
AudioConnection c41(Audioselector_I, 0, audioOutput, 0); // Output the sum on both channels
AudioConnection c42(Audioselector_Q, 0, audioOutput, 1);
//---------------------------------------------------------------------------------------------------------

<snip>

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(16);

// Enable the audio shield and set the output volume.
audioShield.enable();
audioShield.volume(INITIAL_VOLUME);
audioShield.unmuteLineout();

// Set Line Input level gain to max
audioShield.lineInLevel(15);
 
Bob,

I think the volume code you are looking for is in the 50 ms timer check.
Try searching for "ms_50.check()".
The next 3 lines of code read the volume pot, scale the value from 0-1023 => 0.0-1.0 and then calls audioShield.volume(vol).

Code:
  if (ms_50.check() == 1) {
    float vol = analogRead(15);
    vol = vol / 1023.0;
    audioShield.volume(vol);

If you want to disable the volume knob try.

Code:
  if (ms_50.check() == 1) {
    //float vol = analogRead(15);
    //vol = vol / 1023.0;
    audioShield.volume(1.0);

-Aaron
 
Thanks Aaron. I'd done the same thing by setting the value of vol to 1 but either way, same result. Maybe I need to just forget software and warm up the soldering iron ;-)

Bob
 
Aiso - I did discover one effect from increasing the LineInLevel per Franks suggestion - images appeared. Even though there was no apparent change in speaker audio level, I suspect this occurred because with the higher level from the Softrock the added gain resulted in saturation. With it back to the way it was, image cancellation is working as it should.

Bob
 
Status
Not open for further replies.
Back
Top