8 bit Frequency Shift Keying Teensy 3.6

Status
Not open for further replies.

drewski

New member
Hey ya'll

So I'm running into some problems I haven't been able to figure out. I am generating 8 sine waves, each sine representing a bit in a char. I'll change the amplitudes of each sine waveform, hold it for 5 ms, and then encode the next char. I also synth a DC waveform, this waveform's amplitude toggles between .6 and -.6 between chars. Right now I am just outputting the audio from a Teensy 3.6 via USB to my Mac. I can record the audio with Audacity. Later, when I'm happy with the signals I'll switch over to the Teensy Audio Shield.

I actually have this working... sort of. Their are some quirky things going on. For example; the DC waveform is only supposed to be on the L-channel, however is shows up on L&R. If i don't have an AudioOutputI2S object declared, there is no audio output through USB?? Adding other variables to measure the delay in micros() between encoding chars completely changes the audio signal.

Here are my instantiations of the audio objects. The AudioOutoutI2S is declared, but never used. Nothing will output through USB if its not there.

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioSynthWaveformSine   mySin[7];          
AudioSynthWaveformDc     square_clk;          
AudioMixer4              mixer1;        
AudioMixer4              mixer2;         
AudioMixer4              mixer3;
AudioOutputI2S           i2s2_output;          
AudioOutputUSB           usb1;

AudioConnection          patchCord1(mySin[0], 0, mixer1, 0);
AudioConnection          patchCord2(mySin[1], 0, mixer1, 1);
AudioConnection          patchCord3(mySin[2], 0, mixer1, 2);
AudioConnection          patchCord4(mySin[3], 0, mixer1, 3);
AudioConnection          patchCord5(mySin[4], 0, mixer2, 0);
AudioConnection          patchCord6(mySin[5], 0, mixer2, 1);
AudioConnection          patchCord7(mySin[6], 0, mixer2, 2);
AudioConnection          patchCord8(mySin[7], 0, mixer2, 3);
AudioConnection          patchCord9(mixer1, 0, mixer3, 0);
AudioConnection          patchCord10(mixer2, 0, mixer3, 1);
AudioConnection          patchCord11(square_clk, 0, usb1, 0);
AudioConnection          patchCord12(mixer3, 0, usb1, 1);

Screen Shot 2017-02-05 at 3.50.39 PM.png

Set things up

Code:
//unsigned long delay_u = 0;
//unsigned long time_u = 0;
char c[] = "hello world 123";
int count = 0;
int clk = 1;
int my_freq[] = {8E3, 9E3, 10E3, 11E3, 12E3, 13E3, 14E3, 15E3};

void setup() {

  AudioMemory(50);

  // Assign a freq and amp to each sin.
  AudioNoInterrupts();
  for(int i=0; i<8; i++){
    mySin[i].frequency(my_freq[i]);
    mySin[i].amplitude(0);
  }
  AudioInterrupts();

  delay(1000);
}

The unsigned long delay and time are used to measure the delay between chars, I have them commented because they were screwing things up. "hello world" is just repeated over and again, there is a 5 char delay between each repeat.

The Loop

Code:
void loop() {

  //time_u = micros();

  int len = sizeof(c);
  if(count < len+5){
    count++;
  }else {
    count = 0;
  }

  if( count < len ){
    char key = c[count];
    AudioNoInterrupts();

    // Toggle Clock
    if(clk == 1){
      clk = 0;
      square_clk.amplitude(-.6);
    } else {
      clk = 1;
      square_clk.amplitude(.6);
    }
    // Toggle Sins
    for (int i = 0; i<8; i++){
      if(bitRead(key, 7-i) == 1){
        mySin[i].amplitude(.6);
      } else {
        mySin[i].amplitude(0);
      } // end else if
    } // end for bit read
    
    AudioInterrupts();
  }
  
  
  if(count >= len){
    // No Data  
    AudioNoInterrupts();
    if(clk == 1){
      clk = 0;
      square_clk.amplitude(-.6);
    } else {
      clk = 1;
      square_clk.amplitude(.6);
    }
    for(int i=0;i<8;i++){
      mySin[i].amplitude(0);
    } //end for
    AudioInterrupts();
  }
    


  //delay_u = micros() - time_u;
  //delayMicroseconds(5E3-dealy_u)
  delay(5);
  
} // end loop

The waveform

Screen Shot 2017-02-05 at 3.34.30 PM.jpg

So you can see the clock is on both R&L channels and the duration of the clock isn't as good as I would like it to be. However, the clk period is consistent with the period of the data. So I can still decode it. :eek:

Subtracting out the delay between encoding each char doesn't work either. It did't fix the clk period and for whatever reason it added the clk and sin waveforms...

Any good ideas? I'm out lol. I realize I am doing something the library wasn't made to do.

Thanks for the help! I love these boards!

FYI the purpose of this is to encode data into the audio channels of recording devices.
 
Thanks, you are absolutely right about that. So now my MSB is working. I guess I could have been changing things in memory I shouldn't have been?

Same problems remain. Not a game changer if I can't them fixed, its just a bit annoying.

DC wave form is still on both channels, and AudioOutputI2S still needs to be declared in order to work.

Screen Shot 2017-02-05 at 5.05.53 PM.jpg

Frequency spectrum of 'e'. Looks good.

Screen Shot 2017-02-05 at 5.06.49 PM.jpg

Printing out what bit in a char is assigned to a sine waveform.

Screen Shot 2017-02-05 at 5.09.27 PM.png

Thanks
 
The fact that the i2s output has to be included even if you are only using USB is a known "bug", or "feature" of the audio library. USB won't work on its own - you need some other output like DAC or I2S to actually trigger the audio library updates.
I am wondering why you are generating the clock in your sketch, instead of just including a synth object of type WAVEFORM and setting its type to WAVEFORM SQUARE? You then set its freq and amplitude, and it will give a steady clock. If you need to gate the clock on and off between characters, for example, you can just set its amplitude to zero for that time. The synth waveform object will generate a steady square wave of 50% duty cycle.You can also use the phase setting to start the waveform at a specific time if you need this feature.
I don't know why your DC waveform object, which is definitely only wired to one channel from the looks of your code, is showing up in both channels. I've used audio lib USB output, but only for a mono signal, and wouldn't have noticed something like this, if it is indeed. a bug in the library ( which I doubt).
Brian
 
Status
Not open for further replies.
Back
Top