Bonjour à tous,
I'm using a T4 as an audio USB device plugged into a Mac. Planning to send audio BFSK data to a host (eventually, cellphones), I explored the awesome™ Teensy Audio library and played with AudioPlayQueue.
Curiously, the length of the produced beeps recorded on the mac doesn't match the length coded into the T4 sketch... Am I missing something? I know some handshake is done between host and devices, but I thought isochronous transfers where stable once negotiated (although without any error correction).
Here's the test sketch, it should produce 5011 samples of a 440 Hz tone, repeatedly:
And for a 100 seconds interval I recorded the T4 USB audio stream on macOS 12.7.6 and measured all the 329 beeps duration and no beep had the desired length of 5011:
But (funnily ?) the mean is exactly 5011 samples... I confirmed my automated length measurements by checking some beep lengths manually in Audacity. The discrepancy between the 5011 desired duration and those observed is not that serious (20 samples too short and 109 too long) but it produces superfluous discontinuities in the signal... I would like to start and finish beeps on a null value. Any suggestion?
The recording and length values computation is done with this python script:
I'm using a T4 as an audio USB device plugged into a Mac. Planning to send audio BFSK data to a host (eventually, cellphones), I explored the awesome™ Teensy Audio library and played with AudioPlayQueue.
Curiously, the length of the produced beeps recorded on the mac doesn't match the length coded into the T4 sketch... Am I missing something? I know some handshake is done between host and devices, but I thought isochronous transfers where stable once negotiated (although without any error correction).
Here's the test sketch, it should produce 5011 samples of a 440 Hz tone, repeatedly:
C++:
#include <Audio.h>
AudioPlayQueue queue1;
AudioOutputUSB usb1;
AudioConnection patchCord1(queue1, 0, usb1, 0);
AudioConnection patchCord2(queue1, 0, usb1, 1);
void setup() {
AudioMemory(10);
queue1.setBehaviour(AudioPlayQueue::ORIGINAL); // blocking when full
queue1.setMaxBuffers(4);
}
void queueBeep() {
float phas = 0.f;
for (int i = 0; i < 5011; i++) { // should be exactly 50 whole cycles at 440 Hz
int16_t sample = (int16_t)(sin(phas) * 8000.);
phas += 440. / AUDIO_SAMPLE_RATE_EXACT * TWO_PI;
if (phas > TWO_PI)
phas -= TWO_PI;
queue1.play(sample);
}
}
void loop() {
queueBeep();
delay(200);
}
And for a 100 seconds interval I recorded the T4 USB audio stream on macOS 12.7.6 and measured all the 329 beeps duration and no beep had the desired length of 5011:
Code:
[4992 4992 5120 4992 4991 4991 4992 4992 4991 5120 4992 4992 4992 4992
4992 5120 4991 4992 4992 4992 4992 4992 5119 4992 4992 4992 4992 4992
4992 5120 4992 4992 4992 4991 4992 4991 5120 4992 4992 4992 4991 4992
5120 4992 4992 4992 4992 4992 4991 5120 4992 4991 4992 4992 4992 4992
5120 4992 4990 4992 4992 4992 4992 5120 4992 4992 4992 4992 4991 5119
4992 4991 4992 4992 4992 4992 5120 4992 4992 4992 4991 4991 4992 5120
4991 4992 4992 4991 4992 4992 5120 4992 4992 4992 4990 4992 5120 4992
4992 4992 4992 4992 4992 5120 4992 4991 4992 4992 4992 4992 5120 4992
4992 4992 4992 4992 4991 5120 4992 4992 4992 4991 4992 5120 4992 4992
4992 4991 4992 4992 5120 4992 4992 4992 4990 4992 4992 5119 4992 4992
4992 4991 4992 5120 4990 4992 4992 4991 4992 4992 5120 4992 4991 4992
4992 4992 4992 5119 4992 4992 4991 4992 4992 4991 5120 4992 4992 4991
4992 4992 5118 4992 4992 4992 4992 4992 4992 5120 4992 4992 4991 4991
4992 4991 5120 4992 4992 4992 4991 4992 4991 5120 4992 4991 4992 4992
4992 5120 4992 4991 4992 4992 4992 4992 5120 4992 4990 4992 4992 4992
4992 5120 4992 4991 4992 4992 4991 4991 5120 4992 4992 4992 4992 4992
5120 4992 4992 4992 4991 4991 4992 5120 4992 4992 4992 4991 4992 4992
5120 4992 4992 4992 4992 4992 4992 5120 4992 4992 4992 4992 4992 5120
4992 4991 4992 4992 4991 4992 5120 4992 4992 4992 4992 4992 4991 5120
4992 4992 4992 4991 4992 5120 4991 4992 4992 4991 4992 4992 5120 4991
4992 4992 4990 4992 4992 5120 4992 4992 4992 4991 4992 4992 5119 4992
4992 4992 4992 4992 5120 4992 4991 4992 4991 4992 4992 5119 4992 4992
4992 4992 4992 4991 5120 4992 4992 4991 4992 4992 4992 5120 4992 4992
4992 4992 4992 5120 4992 4992 4991], mean duration: 5010.8 samples
But (funnily ?) the mean is exactly 5011 samples... I confirmed my automated length measurements by checking some beep lengths manually in Audacity. The discrepancy between the 5011 desired duration and those observed is not that serious (20 samples too short and 109 too long) but it produces superfluous discontinuities in the signal... I would like to start and finish beeps on a null value. Any suggestion?
The recording and length values computation is done with this python script:
Python:
import sounddevice as sd, numpy as np
from skimage.morphology import closing
from skimage.measure import regionprops_table, label
# using image analysis tools for 1-D audio? Yes.
fs = 44100
duration = 100 # seconds
# defaut audio input is Teensy USB Audio
audioData = sd.rec(int(duration * fs), samplerate=fs, channels=1, dtype='int16')
sd.wait() # block until recording is finished
oneBitAmplitude = np.abs(audioData)>1 # from sinus to 1 bit square wave
oneBitAmplitudeClosed = closing(oneBitAmplitude.T[0], np.ones(5)) # removing gaps
synthImage = np.array([oneBitAmplitudeClosed,oneBitAmplitudeClosed]) # going 2-D for using regionprops_table ()
props = regionprops_table(label(synthImage), properties=('centroid', 'bbox'))
# use found bounding boxes coords to compute widths (ie lengths). Remove ends, frequently truncated
lengths = (props['bbox-3'] - props['bbox-1'])[1:-1]
print('%s, mean duration: %.1f samples'%(lengths, lengths.mean()))
Last edited: