Play sound every x seconds

Status
Not open for further replies.

gerry

Member
Hi,

I am completely new to the Teensy, but I only need to figure out one more thing.
For a project I connected the pui audio board to a Teensy 3.6 and I am able to play sounds (e.g. a sine wave) via DAC using the Audio Library.

However, what I actually need, is that the Teensy plays a sine wave for a second and after that it should be silent again for some seconds (say 15s). The timing is very important, but I cannot use an IntervalTimer, because interrupts might happen. I can also not use the void loop() {} because many other things need to happen at the same time. The sound needs to play independently from anything else.

Does anyone have an idea how to do that?
I thought of the IntervalTimer, which is a no-go.
Then I thought, maybe I can multiply a square or pulse and a sine wave - but I cannot get it to work the way I want it to.
There should be an easy for this, right?

Thanks in advance for any help! :)

Here is an example of what I have tried:

EDIT: I actually just connected one DAC, so I think then this is already not right (0 and 1, should be 0 and 0, but also does not work)
AudioConnection patchCord1(sine, 0, multiply1, 0);
AudioConnection patchCord2(square, 0, multiply1, 1);


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



// GUItool: begin automatically generated code
AudioSynthWaveform       sine;      //xy=390,155
AudioSynthWaveform       square; //xy=391,230
AudioEffectMultiply      multiply1;      //xy=624,211
AudioOutputAnalog        dac1;           //xy=834,204
AudioConnection          patchCord1(sine, 0, multiply1, 0);
AudioConnection          patchCord2(square, 0, multiply1, 1);
AudioConnection          patchCord3(multiply1, dac1);
AudioControlSGTL5000     sgtl5000_1;     //xy=635,407
// GUItool: end automatically generated code


#define RESOLUTION 12


void setup() {
   analogWriteResolution(RESOLUTION);
  // Start audio
  AudioMemory(20);
  float freq = 440.0;
  float angle = 90.0;

  AudioMemory(15);
  //AudioNoInterrupts();

  sine.begin(WAVEFORM_SINE);
  sine.frequency(freq);
  sine.amplitude(1.0);
  sine.phase(0);

  square.begin(WAVEFORM_SQUARE);
  square.frequency(0.5);
  square.amplitude(1.0);
  square.phase(angle);

  //AudioInterrupts();

  // End audio
  
  //sine1.amplitude(0.05);
  //sine1.frequency(8000);
}

void loop() {
}
 
Last edited:
Interrupts do happen, that's the point with IntervalTimers, not sure why they cannot be used.
The interval trigger every x seconds and sends a NoteOn to an envelop, or sets a mixer amplitude.

Another option is to write an AudioTimedGate object, all audio objects are clocked by the update calls occuring regularily.
Let the gate count number of updates to pass audio data and number of updates to block audio data. Perhaps some smoothing is needed when starting and stopping sounds.
 
To use both DACs on the T3.6 you need to use AudioOutputAnalogStereo
Code:
AudioOutputAnalogStereo    dacs;
and then in the connections reference port 0 (left) and port 1 (right)
Code:
AudioConnection          patchCord3L(multiply1, 0, dacs, 0);
AudioConnection          patchCord3R(multiply1, 0, dacs, 1);

Pete
 
Thanks, but the point is actually that I only use one DAC, not two.
So I tried to let the teensy multiply a square wave and a sine wave, such that I get a sine wave that turns on/off. So then the multiplied signal should be send to one DAC. Still, not able to get 1 second of sine wave and then 10 seconds of silence.
 
Sorry, I misread your EDIT comment.

The output of the square waveform does not alternate between zero and one. It is +1 or -1. All that does to your signal is periodically invert it.
One way to handle this is to use AudioEffectWaveshaper to change -1 to zero. Here's a snippetty bit:
Code:
AudioSynthWaveform       sine;      //xy=390,155
AudioSynthWaveform       square; //xy=391,230
AudioEffectMultiply      multiply1;      //xy=624,211
AudioEffectWaveshaper    ws;
.
.
AudioConnection          patchws(square,ws);
AudioConnection          patchCord1(sine, 0, multiply1, 0);
AudioConnection          patchCord2(ws, 0, multiply1, 1);
.
.
float ws_array[2] = {0,1};
.
.
  ws.shape(ws_array,sizeof(ws_array)/sizeof(float));

You can use square.pulsewidth(amount) to change the duty cycle of the wave so that you get something other than 50%.
[EDIT] OOOppsss. Nope, it looks like you can't use pulsewidth to change the duty cycle of a squarewave.

Pete
 
Aha. Change square.begin(WAVEFORM_SQUARE); to square.begin(WAVEFORM_PULSE); which also generates +1 and -1 and therefore needs shaping. But then you can use pulseWidth to get whatever duty cycle is appropriate.

Pete
 
Last edited:
Status
Not open for further replies.
Back
Top