Browse Source

Implement usb audio asychronous feedback loop

teensy4-core
PaulStoffregen 8 years ago
parent
commit
4199a5dee7
2 changed files with 27 additions and 10 deletions
  1. +26
    -9
      teensy3/usb_audio.cpp
  2. +1
    -1
      teensy3/usb_audio.h

+ 26
- 9
teensy3/usb_audio.cpp View File

audio_block_t * AudioInputUSB::ready_left; audio_block_t * AudioInputUSB::ready_left;
audio_block_t * AudioInputUSB::ready_right; audio_block_t * AudioInputUSB::ready_right;
uint16_t AudioInputUSB::incoming_count; uint16_t AudioInputUSB::incoming_count;
//uint16_t AudioInputUSB::underflow_flag;
uint8_t AudioInputUSB::receive_flag;


#define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4))) #define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4)))
uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR; uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR;
uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR; uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR;
uint32_t usb_audio_sync_feedback DMABUFATTR; uint32_t usb_audio_sync_feedback DMABUFATTR;


static uint32_t feedback_accumulator = 722534 << 8;

void AudioInputUSB::begin(void) void AudioInputUSB::begin(void)
{ {
incoming_count = 0; incoming_count = 0;
incoming_right = NULL; incoming_right = NULL;
ready_left = NULL; ready_left = NULL;
ready_right = NULL; ready_right = NULL;
receive_flag = 0;
// update_responsibility = update_setup(); // update_responsibility = update_setup();
// TODO: update responsibility is tough, partly because the USB // TODO: update responsibility is tough, partly because the USB
// interrupts aren't sychronous to the audio library block size, // interrupts aren't sychronous to the audio library block size,
// but also because the PC may stop transmitting data, which // but also because the PC may stop transmitting data, which
// means we no longer get receive callbacks from usb_dev. // means we no longer get receive callbacks from usb_dev.
update_responsibility = false; update_responsibility = false;
usb_audio_sync_feedback = 722824;
usb_audio_sync_feedback = 723700; // too fast?
//usb_audio_sync_feedback = 722824;
//usb_audio_sync_feedback = 723700; // too fast?
usb_audio_sync_feedback = 722534; // too slow usb_audio_sync_feedback = 722534; // too slow
} }


audio_block_t *left, *right; audio_block_t *left, *right;
const uint32_t *data; const uint32_t *data;


AudioInputUSB::receive_flag = 1;
len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right
data = (const uint32_t *)usb_audio_receive_buffer; data = (const uint32_t *)usb_audio_receive_buffer;


if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) { if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) {
// buffer overrun, PC sending too fast // buffer overrun, PC sending too fast
AudioInputUSB::incoming_count = count + avail; AudioInputUSB::incoming_count = count + avail;
if (len > 0) {
serial_print("!");
serial_phex(len);
}
//if (len > 0) {
//serial_print("!");
//serial_phex(len);
//}
return; return;
} }
send: send:
ready_left = NULL; ready_left = NULL;
right = ready_right; right = ready_right;
ready_right = NULL; ready_right = NULL;
// TODO: use incoming_count for USB isochronous feedback
uint16_t c = incoming_count; uint16_t c = incoming_count;
uint8_t f = receive_flag;
receive_flag = 0;
__enable_irq(); __enable_irq();
if (f) {
int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c;
feedback_accumulator += diff;
// TODO: min/max sanity check for feedback_accumulator??
usb_audio_sync_feedback = (feedback_accumulator >> 8) + diff * 3;
//if (diff > 0) {
//serial_print(".");
//} else if (diff < 0) {
//serial_print("^");
//}
}
//serial_phex(c); //serial_phex(c);
//serial_print("."); //serial_print(".");
if (!left || !right) { if (!left || !right) {
serial_print("#"); // buffer underrun - PC sending too slow
//serial_print("#"); // buffer underrun - PC sending too slow
if (f) feedback_accumulator += 10 << 8;
} }
if (left) { if (left) {
transmit(left, 0); transmit(left, 0);

+ 1
- 1
teensy3/usb_audio.h View File

static audio_block_t *ready_left; static audio_block_t *ready_left;
static audio_block_t *ready_right; static audio_block_t *ready_right;
static uint16_t incoming_count; static uint16_t incoming_count;
//static uint16_t underflow_flag;
static uint8_t receive_flag;
}; };


#endif // __cplusplus #endif // __cplusplus

Loading…
Cancel
Save