packetloss69
New member
Hi PJRC forum. I hope some of the info listed below will help anyone else trying to get the SuperAudioBoard going under Windows.
Being dumb, it took me quite a while to get this far..
Issues had:
1. Sine generator not providing accurate frequency.
2. Distorted Audio
Sample sketch based on Whollender github example.
Creates a 1KHz sine wave on analogue output as well as sending to PC via USB.
Sine output was ok on output, but with mid-cycle cuts and distortion. Seemed like a timing issue.
I used a Teensy 3.2 @ 96MHz
Teensyduino 1.8.5
To get i2s to play nice on 48KHz i had to modify
File: output_i2s.cpp
This provided a clock of exactly 48KHz for i2s
Sine wave frequency was now 1kHz exactly on analogue outputs.
Windows sound did not enjoy the 1KHz sine input.
Input was 48KHz sampled, but delivered via 44.1KHz
This caused mid-cycle distotion as well as a frequency offset etc.
Did not sound right at all.
Had to modify the following to get windows to use it as a 48KHz recording / playback source.
usb_desc.c
Had to replace both occurrences of
usb_audio.cpp
usb_desc.h
usb_dev.c
Had to uninstall windows Teensy audio driver and re-install to get access to 48KHz version for some reason.
Testing Analog input > usb next.
Being dumb, it took me quite a while to get this far..
Issues had:
1. Sine generator not providing accurate frequency.
2. Distorted Audio
Sample sketch based on Whollender github example.
Creates a 1KHz sine wave on analogue output as well as sending to PC via USB.
Code:
// Example Sketch using the SuperAudioBoard with the Teensy Audio library
// RF William Hollender (2015)
// This file is public domain
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
// GUItool: begin automatically generated code
AudioInputUSB usb1; //xy=236,101
AudioOutputUSB usb2; // To PC
AudioSynthWaveformSine sine1; //xy=185.09091186523438,194.09091186523438
AudioOutputI2Sslave i2s1; //xy=376.0909118652344,219.09091186523438
AudioConnection patchCord1(sine1, 0, i2s1, 0);
AudioConnection patchCord2(sine1, 0, i2s1, 1);
AudioConnection patchCord3(sine1, 0, usb2, 0);
AudioConnection patchCord4(sine1, 0, usb2, 1);
AudioControlCS4272 AudioBoard;
// GUItool: end automatically generated code
#define CS4272_ADDR 0x10
// This is the actual sample rate with the SuperAudioBoard
#define ACTUAL_SAMPLE_RATE 48000
void setup() {
// put your setup code here, to run once:
AudioMemory(20);
AudioBoard.enable();
// AudioBoard.enableDither();
// Register 0x1 DAC Digital Interface Format (Bits 2:0)
// Usinge I2S, up to 24-bit data
Wire.beginTransmission(CS4272_ADDR);
Wire.write(1); // Write to Register 0x1 as on page 38
Wire.write(B00101001); // See datasheet Page 38 Table 8.1
Wire.endTransmission();
// Want to set a frequency of 1kHz, but need to account for the difference
// between the sample rate assumed by the library object (AUDIO_SAMPLE_RATE_EXACT)
// and the actual sample rate.
sine1.frequency(1000 * AUDIO_SAMPLE_RATE_EXACT / ACTUAL_SAMPLE_RATE);
//sine1.frequency(1000);
sine1.amplitude(0.7);
}
void loop() {
// put your main code here, to run repeatedly:
// Read back audioboard settings
/*
Serial.print("New Loop: ");
Serial.print(AUDIO_SAMPLE_RATE_EXACT);
Serial.println(millis());
for(unsigned int i = 1; i < 9; i++)
{
Wire.beginTransmission(CS4272_ADDR);
Wire.write(i);
int ii = Wire.endTransmission();
if(ii != 0)
{
Serial.println("Error in end transmission:");
Serial.println(ii);
break;
}
if(Wire.requestFrom(CS4272_ADDR,1) < 1)
{
Serial.println("Error in request from");
break;
}
Serial.print(i);
Serial.print(" ");
Serial.println(Wire.read());
}
delay(5000); */
}
Sine output was ok on output, but with mid-cycle cuts and distortion. Seemed like a timing issue.
I used a Teensy 3.2 @ 96MHz
Teensyduino 1.8.5
To get i2s to play nice on 48KHz i had to modify
File: output_i2s.cpp
Code:
#if F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000
// PLL is at 96 MHz in these modes
-- #define MCLK_MULT 2
-- # define MCLK_DIV 17
++ #define MCLK_MULT 16
++ #define MCLK_DIV 125
This provided a clock of exactly 48KHz for i2s
Sine wave frequency was now 1kHz exactly on analogue outputs.
Windows sound did not enjoy the 1KHz sine input.
Input was 48KHz sampled, but delivered via 44.1KHz
This caused mid-cycle distotion as well as a frequency offset etc.
Did not sound right at all.
Had to modify the following to get windows to use it as a 48KHz recording / playback source.
usb_desc.c
Had to replace both occurrences of
Code:
--LSB(44100), MSB(44100), 0,
++LSB(48000), MSB(48000), 0,
usb_audio.cpp
Code:
// Called from the USB interrupt when ready to transmit another
// isochronous packet. If we place data into the transmit buffer,
// the return is the number of bytes. Otherwise, return 0 means
// no data to transmit
unsigned int usb_audio_transmit_callback(void)
{
static uint32_t count=5;
uint32_t avail, num, target = 48, offset, len=0;
audio_block_t *left, *right;
/*
if (++count < 9) { // TODO: dynamic adjust to match USB rate
target = 44;
} else {
count = 0;
target = 45;
} */
while (len < target) {
num = target - len;
left = AudioOutputUSB::left_1st;
if (left == NULL) {
// buffer underrun - PC is consuming too quickly
memset(usb_audio_transmit_buffer + len, 0, num * 4);
//serial_print("%");
break;
}
right = AudioOutputUSB::right_1st;
offset = AudioOutputUSB::offset_1st;
avail = AUDIO_BLOCK_SAMPLES - offset;
if (num > avail) num = avail;
copy_from_buffers((uint32_t *)usb_audio_transmit_buffer + len,
left->data + offset, right->data + offset, num);
len += num;
offset += num;
if (offset >= AUDIO_BLOCK_SAMPLES) {
AudioStream::release(left);
AudioStream::release(right);
AudioOutputUSB::left_1st = AudioOutputUSB::left_2nd;
AudioOutputUSB::left_2nd = NULL;
AudioOutputUSB::right_1st = AudioOutputUSB::right_2nd;
AudioOutputUSB::right_2nd = NULL;
AudioOutputUSB::offset_1st = 0;
} else {
AudioOutputUSB::offset_1st = offset;
}
}
return target * 4;
}
usb_desc.h
Code:
-- #define AUDIO_TX_SIZE 180 // 44.1 KHz
-- #define AUDIO_RX_SIZE 180 // 44.1 KHz
++ #define AUDIO_TX_SIZE 192 // 48 KHz
++ #define AUDIO_RX_SIZE 192 // 48 KHz
usb_dev.c
Code:
case 0x81A2: // GET_CUR (wValue=0, wIndex=interface, wLength=len)
if (setup.wLength >= 3) {
//reply_buffer[0] = 44100 & 255;
//reply_buffer[1] = 44100 >> 8;
reply_buffer[0] = 48000 & 255;
reply_buffer[1] = 48000 >> 8;
reply_buffer[2] = 0;
datalen = 3;
data = reply_buffer;
} else {
endpoint0_stall();
return;
}
break;
#endif
Had to uninstall windows Teensy audio driver and re-install to get access to 48KHz version for some reason.
Testing Analog input > usb next.
Last edited: