parent
8be3167537
commit
d5427c8a68
@ -0,0 +1,218 @@ |
|||||||
|
/* CESSB1.ino
|
||||||
|
* |
||||||
|
* This INO tests the Dave Hershberger Controlled Envelope Single Sideband |
||||||
|
* transmit generator radioCESSBtransmit_F32. This was developed By W9GR |
||||||
|
* with the aim to "allow your rig to output more average power while |
||||||
|
* keeping peak envelope power PEP the same". The increase in perceived |
||||||
|
* loudness can be up to 4dB without any audible increase in distortion |
||||||
|
* and without making you sound "processed." See radioCESSBTransmit_F32.h |
||||||
|
* for more information and references. |
||||||
|
* |
||||||
|
* Your microSD card must have the WAV file W9GR48.WAV loaded to it. Source: |
||||||
|
* https://github.com/chipaudette/OpenAudio_ArduinoLibrary/blob/master/utility/
|
||||||
|
* |
||||||
|
* The SD card may connect to different pins, depending on the |
||||||
|
* hardware you are using. Configure the SD card |
||||||
|
* pins to match your hardware. It is set for T4.x Rev D PJRC |
||||||
|
* Teensy Audio Adaptor card here. |
||||||
|
* |
||||||
|
* This example code is in the public domain. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Audio.h> |
||||||
|
#include <Wire.h> |
||||||
|
#include <SPI.h> |
||||||
|
#include <SD.h> |
||||||
|
#include "OpenAudio_ArduinoLibrary.h" |
||||||
|
|
||||||
|
// Normal input is from the WAV file with W9GR voice.
|
||||||
|
// An alternative is two tones. Compile that with the following define.
|
||||||
|
// #define USE_TWO_TONE
|
||||||
|
|
||||||
|
// T3.x supported sample rates: 2000, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 44117, 48000,
|
||||||
|
// 88200, 88235 (44117*2), 95680, 96000, 176400, 176470, 192000
|
||||||
|
// T4.x supports any sample rate the codec will handle.
|
||||||
|
const float sample_rate_Hz = 48000.0f; |
||||||
|
const int audio_block_samples = 128; // Always 128, which is AUDIO_BLOCK_SAMPLES from AudioStream.h
|
||||||
|
AudioSettings_F32 audio_settings(sample_rate_Hz, audio_block_samples); |
||||||
|
|
||||||
|
#ifdef USE_TWO_TONE |
||||||
|
AudioSynthWaveformSine_F32 sine3(audio_settings); //xy=231,444
|
||||||
|
AudioSynthWaveformSine_F32 sine4(audio_settings); //xy=259,345
|
||||||
|
AudioMixer4_F32 mixer4_4; //xy=405,427
|
||||||
|
#endif |
||||||
|
AudioSDPlayer_F32 playWav1(audio_settings); //xy=111,51
|
||||||
|
radioCESSBtransmit_F32 cessb1(audio_settings); |
||||||
|
RadioIQMixer_F32 iqMixer2(audio_settings); //xy=100,300
|
||||||
|
AudioFilter90Deg_F32 filter90deg1(audio_settings); //xy=250,300
|
||||||
|
RadioIQMixer_F32 iqMixer1(audio_settings); //xy=250,150
|
||||||
|
AudioAnalyzeRMS_F32 rms1; //xy=300,50
|
||||||
|
AudioMixer4_F32 mixer4_1; //xy=400,310
|
||||||
|
AudioMixer4_F32 mixer4_2; //xy=400,150
|
||||||
|
AudioOutputI2S_F32 audioOutput(audio_settings); //xy=520,250
|
||||||
|
AudioAnalyzeFFT1024_F32 fft1; //xy=550,125
|
||||||
|
|
||||||
|
#ifdef USE_TWO_TONE |
||||||
|
AudioConnection_F32 patchCorda(sine3, 0, mixer4_4, 1); |
||||||
|
AudioConnection_F32 patchCordb(sine4, 0, mixer4_4, 0); |
||||||
|
AudioConnection_F32 patchCordc(mixer4_4, 0, cessb1, 0); |
||||||
|
#else |
||||||
|
AudioConnection_F32 patchCord5(playWav1, 0, cessb1, 0); |
||||||
|
#endif |
||||||
|
AudioConnection_F32 patchCord1(cessb1, 0, iqMixer1, 0); |
||||||
|
AudioConnection_F32 patchCord2(cessb1, 1, iqMixer1, 1); |
||||||
|
AudioConnection_F32 patchCord9(iqMixer1, 0, mixer4_2, 0); |
||||||
|
AudioConnection_F32 patchCord10(iqMixer1, 1, mixer4_2, 1); |
||||||
|
AudioConnection_F32 patchCord13(mixer4_2, fft1); // Transmitter output
|
||||||
|
// mixer4_2 is transmitter SSB output, iqMixer2 is receiver input
|
||||||
|
AudioConnection_F32 patchCord14(mixer4_2, 0, iqMixer2, 0); |
||||||
|
AudioConnection_F32 patchCord3(iqMixer2, 0, filter90deg1, 0); |
||||||
|
AudioConnection_F32 patchCord4(iqMixer2, 1, filter90deg1, 1); |
||||||
|
AudioConnection_F32 patchCord7(filter90deg1, 0, mixer4_1, 0); |
||||||
|
AudioConnection_F32 patchCord8(filter90deg1, 1, mixer4_1, 1); |
||||||
|
AudioConnection_F32 patchCord11(mixer4_1, 0, audioOutput, 0); |
||||||
|
AudioConnection_F32 patchCord12(mixer4_1, 0, audioOutput, 1); |
||||||
|
AudioControlSGTL5000 sgtl5000_1; //xy=582,327
|
||||||
|
|
||||||
|
// Use these with the Teensy 4.x Rev D Audio Shield (NOT for T3.x)
|
||||||
|
#define SDCARD_CS_PIN 10 |
||||||
|
#define SDCARD_MOSI_PIN 11 |
||||||
|
#define SDCARD_SCK_PIN 13 |
||||||
|
|
||||||
|
// Filter for AudioFilter90Deg_F32 hilbert1, for the test receiver.
|
||||||
|
#include "hilbert251A.h" |
||||||
|
|
||||||
|
// This provides information about the current WAV file to this .INO
|
||||||
|
struct wavData* pCurrentWavData; |
||||||
|
struct levels* pLevelData; |
||||||
|
uint32_t writeOne = 0; |
||||||
|
|
||||||
|
uint32_t cntFFT = 0; |
||||||
|
|
||||||
|
void setup() { // ********** SETUP **********
|
||||||
|
Serial.begin(9600); delay(1000); |
||||||
|
Serial.println("*** F32 WAV from SD Card ***"); |
||||||
|
AudioMemory_F32(70, audio_settings); |
||||||
|
|
||||||
|
pCurrentWavData = playWav1.getCurrentWavData(); |
||||||
|
|
||||||
|
sgtl5000_1.enable(); |
||||||
|
|
||||||
|
SPI.setMOSI(SDCARD_MOSI_PIN); |
||||||
|
SPI.setSCK(SDCARD_SCK_PIN); |
||||||
|
Serial.print("SD.begin() returns "); |
||||||
|
Serial.println(SD.begin(SDCARD_CS_PIN)); |
||||||
|
|
||||||
|
#ifdef USE_TWO_TONE |
||||||
|
// Two-tone test, multiples of 48000/1024 Hz
|
||||||
|
sine3.frequency(468.75f); |
||||||
|
sine3.amplitude(0.5f); |
||||||
|
|
||||||
|
sine4.frequency(703.125f); |
||||||
|
sine4.amplitude(0.5f); |
||||||
|
#endif |
||||||
|
|
||||||
|
// Build the CESSB SSB transmitter
|
||||||
|
cessb1.setSampleRate_Hz(48000.0f); // Required
|
||||||
|
// Set input, correction, and output gains
|
||||||
|
float32_t Pre_CESSB_Gain = 1.5f; // Sets the amount of clipping, 1.0 to 2.0f, 3 is excessive
|
||||||
|
cessb1.setGains(Pre_CESSB_Gain, 2.0f, 1.0f); |
||||||
|
cessb1.setSideband(false); // true reverses the sideband
|
||||||
|
pLevelData = cessb1.getLevels(0); // Gets pointer to struct
|
||||||
|
|
||||||
|
// Generate SSB at 15 kHz
|
||||||
|
iqMixer1.useTwoChannel(true); |
||||||
|
iqMixer1.useSimple(false); // enables setGainOut()
|
||||||
|
// Following if cessb1.setSideband(false), otherwise reverse
|
||||||
|
|
||||||
|
// Compensate for window loss in FFT as well as x2 for mixers
|
||||||
|
iqMixer1.setGainOut(2.76f); |
||||||
|
iqMixer1.frequency(13650); // 13650 for LSB, 16350 for USB
|
||||||
|
mixer4_2.gain(1, 1.0f); // 1.0f for LSB, -1.0f for USB
|
||||||
|
|
||||||
|
// A receiver for the SSB transmitter
|
||||||
|
iqMixer2.frequency(15000.0f); |
||||||
|
iqMixer2.useTwoChannel(false); |
||||||
|
|
||||||
|
filter90deg1.begin(hilbert251A, 251); // Set the Hilbert transform FIR filter
|
||||||
|
mixer4_1.gain(0, -1.0f); // LSB + for USB
|
||||||
|
audioOutput.setGain(0.05); // <<< Output volume control
|
||||||
|
fft1.setOutputType(FFT_DBFS); |
||||||
|
fft1.windowFunction(AudioWindowBlackmanHarris1024); |
||||||
|
fft1.setNAverage(16); |
||||||
|
} |
||||||
|
|
||||||
|
void playFile(const char *filename) |
||||||
|
{ |
||||||
|
|
||||||
|
if(playWav1.isPlaying()) |
||||||
|
return; |
||||||
|
Serial.println(""); |
||||||
|
Serial.print("Playing file: "); |
||||||
|
Serial.println(filename); |
||||||
|
// Allow for running the WAV file at a sub-rate from the Audio rate
|
||||||
|
// Two of these are defined above for 1 and 4 sub rates.
|
||||||
|
// playWav1.setSubMult(&wavQuarter);
|
||||||
|
// Start playing the file. This sketch continues to
|
||||||
|
// run while the file plays.
|
||||||
|
playWav1.play(filename); |
||||||
|
// A brief delay for the library read WAV info
|
||||||
|
delay(25); |
||||||
|
|
||||||
|
Serial.print("WAV file format = "); Serial.println(pCurrentWavData->audio_format); |
||||||
|
Serial.print("WAV number channels = "); Serial.println(pCurrentWavData->num_channels); |
||||||
|
Serial.print("WAV File Sample Rate = "); Serial.println(pCurrentWavData->sample_rate); |
||||||
|
Serial.print("Number of bits per Sample = "); Serial.println(pCurrentWavData->bits); |
||||||
|
Serial.print("File length, seconds = "); |
||||||
|
Serial.println(0.001f*(float32_t)playWav1.lengthMillis(), 3); |
||||||
|
} |
||||||
|
|
||||||
|
void loop() { |
||||||
|
// Thanks to W9GR for the test files. These are intended for testing
|
||||||
|
// the CESSB radio transmission system (see CESSB1.ino in the examples)
|
||||||
|
// but work well to provide a voice bandwidth test of WAV file reading.
|
||||||
|
#ifndef USE_TWO_TONE |
||||||
|
playFile("W9GR48.WAV"); // filenames are always uppercase 8.3 format
|
||||||
|
#endif |
||||||
|
|
||||||
|
if(fft1.available() && ++cntFFT>100 && cntFFT<102) |
||||||
|
{ |
||||||
|
for(int kk=0; kk<512; kk++) |
||||||
|
{ |
||||||
|
Serial.print(46.875f*(float32_t)kk); Serial.print(","); |
||||||
|
Serial.println(fft1.read(kk)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(cessb1.levelDataCount() > 300) // Typically 300 to 3000
|
||||||
|
{ |
||||||
|
cessb1.getLevels(1); // Cause write of data to struct & reset
|
||||||
|
|
||||||
|
/* // Detailed Report Uncomment to print
|
||||||
|
Serial.print(10.0f*log10f(pLevelData->pwr0)); |
||||||
|
Serial.print(" In Ave Pwr Out "); |
||||||
|
Serial.println(10.0f*log10f(pLevelData->pwr1)); |
||||||
|
Serial.print(20.0f*log10f(pLevelData->peak0)); |
||||||
|
Serial.print(" In Peak Out "); |
||||||
|
Serial.println(20.0f*log10f(pLevelData->peak1)); |
||||||
|
Serial.print(pLevelData->peak0, 6); |
||||||
|
Serial.print(" In Peak Volts Out "); |
||||||
|
Serial.println(pLevelData->peak1, 6); |
||||||
|
Serial.print("Enhancement = "); |
||||||
|
Serial.print((10.0f*log10f(pLevelData->pwr1) - 20.0f*log10f(pLevelData->peak1)) - |
||||||
|
(10.0f*log10f(pLevelData->pwr0) - 20.0f*log10f(pLevelData->peak0)) ); |
||||||
|
Serial.println(" dB"); |
||||||
|
*/ |
||||||
|
|
||||||
|
/*
|
||||||
|
// CSV Report suitable for entering to spread sheet, Uncomment to print
|
||||||
|
// InAve, InPk, OutAve, OutPk, EnhancementdB
|
||||||
|
Serial.print(pLevelData->pwr0, 5); Serial.print(","); |
||||||
|
Serial.print(pLevelData->peak0, 5); Serial.print(","); |
||||||
|
Serial.print(pLevelData->pwr1, 5); Serial.print(","); |
||||||
|
Serial.print(pLevelData->peak1, 5); Serial.print(","); |
||||||
|
Serial.println((10.0f*log10f(pLevelData->pwr1) - 20.0f*log10f(pLevelData->peak1)) - |
||||||
|
(10.0f*log10f(pLevelData->pwr0) - 20.0f*log10f(pLevelData->peak0)) ); |
||||||
|
*/ |
||||||
|
} |
||||||
|
} // End loop()
|
After Width: | Height: | Size: 40 KiB |
@ -0,0 +1,253 @@ |
|||||||
|
// Following is 251 term Hilbert FIR filter
|
||||||
|
float32_t hilbert251A[]={ |
||||||
|
0.0000003255, |
||||||
|
0.0000000000, |
||||||
|
0.0000030702, |
||||||
|
0.0000000000, |
||||||
|
0.0000089286, |
||||||
|
0.0000000000, |
||||||
|
0.0000183061, |
||||||
|
0.0000000000, |
||||||
|
0.0000316287, |
||||||
|
0.0000000000, |
||||||
|
0.0000493436, |
||||||
|
0.0000000000, |
||||||
|
0.0000719193, |
||||||
|
0.0000000000, |
||||||
|
0.0000998451, |
||||||
|
0.0000000000, |
||||||
|
0.0001336320, |
||||||
|
0.0000000000, |
||||||
|
0.0001738120, |
||||||
|
0.0000000000, |
||||||
|
0.0002209393, |
||||||
|
0.0000000000, |
||||||
|
0.0002755899, |
||||||
|
0.0000000000, |
||||||
|
0.0003383625, |
||||||
|
0.0000000000, |
||||||
|
0.0004098790, |
||||||
|
0.0000000000, |
||||||
|
0.0004907853, |
||||||
|
0.0000000000, |
||||||
|
0.0005817525, |
||||||
|
0.0000000000, |
||||||
|
0.0006834782, |
||||||
|
0.0000000000, |
||||||
|
0.0007966881, |
||||||
|
0.0000000000, |
||||||
|
0.0009221383, |
||||||
|
0.0000000000, |
||||||
|
0.0010606178, |
||||||
|
0.0000000000, |
||||||
|
0.0012129515, |
||||||
|
0.0000000000, |
||||||
|
0.0013800041, |
||||||
|
0.0000000000, |
||||||
|
0.0015626848, |
||||||
|
0.0000000000, |
||||||
|
0.0017619529, |
||||||
|
0.0000000000, |
||||||
|
0.0019788241, |
||||||
|
0.0000000000, |
||||||
|
0.0022143787, |
||||||
|
0.0000000000, |
||||||
|
0.0024697715, |
||||||
|
0.0000000000, |
||||||
|
0.0027462425, |
||||||
|
0.0000000000, |
||||||
|
0.0030451312, |
||||||
|
0.0000000000, |
||||||
|
0.0033678928, |
||||||
|
0.0000000000, |
||||||
|
0.0037161183, |
||||||
|
0.0000000000, |
||||||
|
0.0040915578, |
||||||
|
0.0000000000, |
||||||
|
0.0044961498, |
||||||
|
0.0000000000, |
||||||
|
0.0049320558, |
||||||
|
0.0000000000, |
||||||
|
0.0054017033, |
||||||
|
0.0000000000, |
||||||
|
0.0059078375, |
||||||
|
0.0000000000, |
||||||
|
0.0064535860, |
||||||
|
0.0000000000, |
||||||
|
0.0070425380, |
||||||
|
0.0000000000, |
||||||
|
0.0076788436, |
||||||
|
0.0000000000, |
||||||
|
0.0083673390, |
||||||
|
0.0000000000, |
||||||
|
0.0091137048, |
||||||
|
0.0000000000, |
||||||
|
0.0099246683, |
||||||
|
0.0000000000, |
||||||
|
0.0108082660, |
||||||
|
0.0000000000, |
||||||
|
0.0117741868, |
||||||
|
0.0000000000, |
||||||
|
0.0128342256, |
||||||
|
0.0000000000, |
||||||
|
0.0140028938, |
||||||
|
0.0000000000, |
||||||
|
0.0152982506, |
||||||
|
0.0000000000, |
||||||
|
0.0167430570, |
||||||
|
0.0000000000, |
||||||
|
0.0183664064, |
||||||
|
0.0000000000, |
||||||
|
0.0202060801, |
||||||
|
0.0000000000, |
||||||
|
0.0223120327, |
||||||
|
0.0000000000, |
||||||
|
0.0247516963, |
||||||
|
0.0000000000, |
||||||
|
0.0276183140, |
||||||
|
0.0000000000, |
||||||
|
0.0310445375, |
||||||
|
0.0000000000, |
||||||
|
0.0352256211, |
||||||
|
0.0000000000, |
||||||
|
0.0404611696, |
||||||
|
0.0000000000, |
||||||
|
0.0472354231, |
||||||
|
0.0000000000, |
||||||
|
0.0563851215, |
||||||
|
0.0000000000, |
||||||
|
0.0694911881, |
||||||
|
0.0000000000, |
||||||
|
0.0899418673, |
||||||
|
0.0000000000, |
||||||
|
0.1265473875, |
||||||
|
0.0000000000, |
||||||
|
0.2116132716, |
||||||
|
0.0000000000, |
||||||
|
0.6358933477, |
||||||
|
0.0000000000, |
||||||
|
-0.6358933478, |
||||||
|
0.0000000000, |
||||||
|
-0.2116132717, |
||||||
|
0.0000000000, |
||||||
|
-0.1265473876, |
||||||
|
0.0000000000, |
||||||
|
-0.0899418674, |
||||||
|
0.0000000000, |
||||||
|
-0.0694911882, |
||||||
|
0.0000000000, |
||||||
|
-0.0563851216, |
||||||
|
0.0000000000, |
||||||
|
-0.0472354232, |
||||||
|
0.0000000000, |
||||||
|
-0.0404611697, |
||||||
|
0.0000000000, |
||||||
|
-0.0352256212, |
||||||
|
0.0000000000, |
||||||
|
-0.0310445376, |
||||||
|
0.0000000000, |
||||||
|
-0.0276183141, |
||||||
|
0.0000000000, |
||||||
|
-0.0247516964, |
||||||
|
0.0000000000, |
||||||
|
-0.0223120328, |
||||||
|
0.0000000000, |
||||||
|
-0.0202060802, |
||||||
|
0.0000000000, |
||||||
|
-0.0183664065, |
||||||
|
0.0000000000, |
||||||
|
-0.0167430571, |
||||||
|
0.0000000000, |
||||||
|
-0.0152982507, |
||||||
|
0.0000000000, |
||||||
|
-0.0140028939, |
||||||
|
0.0000000000, |
||||||
|
-0.0128342257, |
||||||
|
0.0000000000, |
||||||
|
-0.0117741869, |
||||||
|
0.0000000000, |
||||||
|
-0.0108082661, |
||||||
|
0.0000000000, |
||||||
|
-0.0099246684, |
||||||
|
0.0000000000, |
||||||
|
-0.0091137049, |
||||||
|
0.0000000000, |
||||||
|
-0.0083673391, |
||||||
|
0.0000000000, |
||||||
|
-0.0076788437, |
||||||
|
0.0000000000, |
||||||
|
-0.0070425381, |
||||||
|
0.0000000000, |
||||||
|
-0.0064535861, |
||||||
|
0.0000000000, |
||||||
|
-0.0059078376, |
||||||
|
0.0000000000, |
||||||
|
-0.0054017034, |
||||||
|
0.0000000000, |
||||||
|
-0.0049320559, |
||||||
|
0.0000000000, |
||||||
|
-0.0044961499, |
||||||
|
0.0000000000, |
||||||
|
-0.0040915579, |
||||||
|
0.0000000000, |
||||||
|
-0.0037161184, |
||||||
|
0.0000000000, |
||||||
|
-0.0033678929, |
||||||
|
0.0000000000, |
||||||
|
-0.0030451313, |
||||||
|
0.0000000000, |
||||||
|
-0.0027462426, |
||||||
|
0.0000000000, |
||||||
|
-0.0024697716, |
||||||
|
0.0000000000, |
||||||
|
-0.0022143788, |
||||||
|
0.0000000000, |
||||||
|
-0.0019788242, |
||||||
|
0.0000000000, |
||||||
|
-0.0017619530, |
||||||
|
0.0000000000, |
||||||
|
-0.0015626849, |
||||||
|
0.0000000000, |
||||||
|
-0.0013800042, |
||||||
|
0.0000000000, |
||||||
|
-0.0012129516, |
||||||
|
0.0000000000, |
||||||
|
-0.0010606179, |
||||||
|
0.0000000000, |
||||||
|
-0.0009221384, |
||||||
|
0.0000000000, |
||||||
|
-0.0007966882, |
||||||
|
0.0000000000, |
||||||
|
-0.0006834783, |
||||||
|
0.0000000000, |
||||||
|
-0.0005817526, |
||||||
|
0.0000000000, |
||||||
|
-0.0004907854, |
||||||
|
0.0000000000, |
||||||
|
-0.0004098791, |
||||||
|
0.0000000000, |
||||||
|
-0.0003383626, |
||||||
|
0.0000000000, |
||||||
|
-0.0002755900, |
||||||
|
0.0000000000, |
||||||
|
-0.0002209394, |
||||||
|
0.0000000000, |
||||||
|
-0.0001738121, |
||||||
|
0.0000000000, |
||||||
|
-0.0001336321, |
||||||
|
0.0000000000, |
||||||
|
-0.0000998452, |
||||||
|
0.0000000000, |
||||||
|
-0.0000719194, |
||||||
|
0.0000000000, |
||||||
|
-0.0000493437, |
||||||
|
0.0000000000, |
||||||
|
-0.0000316288, |
||||||
|
0.0000000000, |
||||||
|
-0.0000183062, |
||||||
|
0.0000000000, |
||||||
|
-0.0000089287, |
||||||
|
0.0000000000, |
||||||
|
-0.0000030703, |
||||||
|
0.0000000000, |
||||||
|
-0.0000003256}; |
Loading…
Reference in new issue