yorgyetson
Member
Hello,
I'm a little confused on how sine.phase() works.
I am trying to generate two sine waves, one for the left channel, and one for the right.
The sine waves have identical frequencies, but the right channel needs to variably be 90 or 270 degrees out of phase.
I am able to create the sine waves, and in setup() I can set sine.phase(90) on the right channel and get the correct output.
But when I try to change the phase in the loop() I run into issues:
In order to get to a 270 degree offset between the two do I need to use:
sine.phase(180)
or
sine.phase(270)
and to go back to a 90 degree offset, do I use:
sine.phase(180)
or
sine.phase(90)
I believe that the phase is persistent on the sine object, since it continues to be out of phase if I don't attempt to change it. So I think I should be able to just move it 180 degrees each time. But the documentation says that sine.phase() "Jumps to a specific point within it's cycle" which makes me think I need to use 90/270 as my values.
Either way my experimentation has not been fruitful. I also noticed a fair amount of popping when the phase changes, which I'm not sure how to avoid when making such a dramatic phase shift.
Am I missing something obvious here? Am I going about this the wrong way?
I did find this on stackoverflow, but I'm not sure if its possible/necessary to implement using the existing sine functions:
https://stackoverflow.com/questions...e-pops-from-concatented-sound-data-in-pyaudio
The code below waits for a serial value like "a1000;" or "a-1000;" then changes the direction/phase based on the value being positive/negative and the frequency based on the absolute value of the integer. It works perfectly in one direction, but not the other.
P.S. I got the startChar concept from the VideoDisplay.ino in the Octows2811 Library and I love it, but I'm just using abc as placeholders for now while I work out the phase stuff first.
I'm a little confused on how sine.phase() works.
I am trying to generate two sine waves, one for the left channel, and one for the right.
The sine waves have identical frequencies, but the right channel needs to variably be 90 or 270 degrees out of phase.
I am able to create the sine waves, and in setup() I can set sine.phase(90) on the right channel and get the correct output.
But when I try to change the phase in the loop() I run into issues:
In order to get to a 270 degree offset between the two do I need to use:
sine.phase(180)
or
sine.phase(270)
and to go back to a 90 degree offset, do I use:
sine.phase(180)
or
sine.phase(90)
I believe that the phase is persistent on the sine object, since it continues to be out of phase if I don't attempt to change it. So I think I should be able to just move it 180 degrees each time. But the documentation says that sine.phase() "Jumps to a specific point within it's cycle" which makes me think I need to use 90/270 as my values.
Either way my experimentation has not been fruitful. I also noticed a fair amount of popping when the phase changes, which I'm not sure how to avoid when making such a dramatic phase shift.
Am I missing something obvious here? Am I going about this the wrong way?
I did find this on stackoverflow, but I'm not sure if its possible/necessary to implement using the existing sine functions:
https://stackoverflow.com/questions...e-pops-from-concatented-sound-data-in-pyaudio
StackOverflow.com said:A better method of stitching the waveforms together is to keep track of the phase from one tone and use that as the starting phase for the next.
The code below waits for a serial value like "a1000;" or "a-1000;" then changes the direction/phase based on the value being positive/negative and the frequency based on the absolute value of the integer. It works perfectly in one direction, but not the other.
Code:
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <SerialFlash.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioSynthWaveformSine sine1; //xy=718,208
AudioSynthWaveformSine sine2; //xy=718,208
AudioOutputUSB usb1; //xy=1313,236
AudioOutputI2S i2s2; //xy=1318,168
AudioConnection patchCord1(sine1, 0, i2s2, 0);
AudioConnection patchCord2(sine2, 0, i2s2, 1);
AudioConnection patchCord3(sine1, 0, usb1, 0);
AudioConnection patchCord4(sine2, 0, usb1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=743,433
// GUItool: end automatically generated code
int currentDirection;
int newDirection;
void setup() {
AudioMemory(18);
Serial.begin(115200);
Serial1.begin(115200);
//while (!Serial) ; // wait for Arduino Serial Monitor
delay(200);
sine1.frequency(0);
sine2.frequency(0);
sgtl5000_1.enable();
sgtl5000_1.volume(0.45);
sine2.phase(90);
currentDirection=0;
newDirection=0;
}
char buffer[16];
void loop() {
int incomingByte;
// If no serial keep doing what its doing
while(!Serial1.available());
int startChar = Serial1.read();
if (startChar == 'a'){
int size = Serial1.readBytesUntil(';', buffer, 16);
String myString = String(buffer);
Serial.println("timecode input detected");
int value = myString.toInt();
if (value > 100 || value < -100){
Serial.println("value");
Serial.println(value);
if (value < 0) {
newDirection = 1;
if (currentDirection != newDirection ){
sine2.phase(180);
}
currentDirection = newDirection;
usbMIDI.sendControlChange(48, 1, 2);
sine1.frequency(-value);
sine2.frequency(-value);
} else if (value > 0) {
newDirection = 0;
if (currentDirection != newDirection ){
sine2.phase(180);
}
currentDirection = newDirection;
usbMIDI.sendControlChange(48, 127, 2);
sine1.frequency(value);
sine2.frequency(value);
}
currentDirection = newDirection;
delay(1);
} else {
sine1.frequency(0);
sine2.frequency(0);
}
} else if (startChar == 'b'){
Serial.println("device type 2 input detected");
int size = Serial1.readBytesUntil(';', buffer, 16);
String myString = String(buffer);
Serial.println(myString);
} else if (startChar == 'c'){
Serial.println("device type 3 input detected");
int size = Serial1.readBytesUntil(';', buffer, 16);
String myString = String(buffer);
Serial.println(myString);
} else {
Serial.println("nope");
}
}
P.S. I got the startChar concept from the VideoDisplay.ino in the Octows2811 Library and I love it, but I'm just using abc as placeholders for now while I work out the phase stuff first.
Last edited: