|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool AudioOutputUSB::update_responsibility; |
|
|
bool AudioOutputUSB::update_responsibility; |
|
|
bool AudioOutputUSB::transmitting; |
|
|
|
|
|
audio_block_t * AudioOutputUSB::left_1st; |
|
|
audio_block_t * AudioOutputUSB::left_1st; |
|
|
audio_block_t * AudioOutputUSB::left_2nd; |
|
|
audio_block_t * AudioOutputUSB::left_2nd; |
|
|
audio_block_t * AudioOutputUSB::right_1st; |
|
|
audio_block_t * AudioOutputUSB::right_1st; |
|
|
audio_block_t * AudioOutputUSB::right_2nd; |
|
|
audio_block_t * AudioOutputUSB::right_2nd; |
|
|
uint16_t AudioOutputUSB::offset_1st; |
|
|
uint16_t AudioOutputUSB::offset_1st; |
|
|
uint16_t AudioOutputUSB::outgoing_count; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR; |
|
|
uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR; |
|
|
|
|
|
|
|
|
void AudioOutputUSB::begin(void) |
|
|
void AudioOutputUSB::begin(void) |
|
|
{ |
|
|
{ |
|
|
update_responsibility = false; |
|
|
update_responsibility = false; |
|
|
transmitting = false; |
|
|
|
|
|
left_1st = NULL; |
|
|
left_1st = NULL; |
|
|
right_1st = NULL; |
|
|
right_1st = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (usb_audio_transmit_setting == 0) { |
|
|
if (usb_audio_transmit_setting == 0) { |
|
|
if (left) release(left); |
|
|
if (left) release(left); |
|
|
if (right) release(right); |
|
|
if (right) release(right); |
|
|
if (outgoing_count) { |
|
|
|
|
|
if (left_1st) release(left_1st); |
|
|
|
|
|
if (left_2nd) release(left_2nd); |
|
|
|
|
|
if (right_1st) release(right_1st); |
|
|
|
|
|
if (right_2nd) release(right_2nd); |
|
|
|
|
|
outgoing_count = 0; |
|
|
|
|
|
offset_1st = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (left_1st) release(left_1st); |
|
|
|
|
|
if (left_2nd) release(left_2nd); |
|
|
|
|
|
if (right_1st) release(right_1st); |
|
|
|
|
|
if (right_2nd) release(right_2nd); |
|
|
|
|
|
offset_1st = 0; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
if (left == NULL) { |
|
|
if (left == NULL) { |
|
|
|
|
|
|
|
|
right = left; |
|
|
right = left; |
|
|
} |
|
|
} |
|
|
__disable_irq(); |
|
|
__disable_irq(); |
|
|
if (!transmitting) { |
|
|
|
|
|
copy_from_buffers((uint32_t *)usb_audio_transmit_buffer, |
|
|
|
|
|
left->data, right->data, 44); |
|
|
|
|
|
left_1st = left; |
|
|
|
|
|
right_1st = right; |
|
|
|
|
|
left_2nd = NULL; |
|
|
|
|
|
right_2nd = NULL; |
|
|
|
|
|
offset_1st = 44; |
|
|
|
|
|
outgoing_count = AUDIO_BLOCK_SAMPLES - 44; |
|
|
|
|
|
usb_tx_isochronous(AUDIO_TX_ENDPOINT, usb_audio_transmit_buffer, 176); |
|
|
|
|
|
transmitting = 1; |
|
|
|
|
|
//serial_print("t"); |
|
|
|
|
|
} else if (left_1st == NULL) { |
|
|
|
|
|
|
|
|
if (left_1st == NULL) { |
|
|
left_1st = left; |
|
|
left_1st = left; |
|
|
right_1st = right; |
|
|
right_1st = right; |
|
|
offset_1st = 0; |
|
|
offset_1st = 0; |
|
|
outgoing_count = AUDIO_BLOCK_SAMPLES; |
|
|
|
|
|
} else if (left_2nd == NULL) { |
|
|
} else if (left_2nd == NULL) { |
|
|
left_2nd = left; |
|
|
left_2nd = left; |
|
|
right_2nd = right; |
|
|
right_2nd = right; |
|
|
outgoing_count += AUDIO_BLOCK_SAMPLES; |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// buffer overrun - PC is consuming too slowly |
|
|
// buffer overrun - PC is consuming too slowly |
|
|
audio_block_t *discard1 = left_1st; |
|
|
audio_block_t *discard1 = left_1st; |
|
|
|
|
|
|
|
|
right_1st = right_2nd; |
|
|
right_1st = right_2nd; |
|
|
right_2nd = right; |
|
|
right_2nd = right; |
|
|
offset_1st = 0; // TODO: discard part of this data? |
|
|
offset_1st = 0; // TODO: discard part of this data? |
|
|
outgoing_count = AUDIO_BLOCK_SAMPLES*2; |
|
|
|
|
|
//serial_print("*"); |
|
|
//serial_print("*"); |
|
|
release(discard1); |
|
|
release(discard1); |
|
|
release(discard2); |
|
|
release(discard2); |
|
|
|
|
|
|
|
|
uint32_t avail, num, target, offset, len=0; |
|
|
uint32_t avail, num, target, offset, len=0; |
|
|
audio_block_t *left, *right; |
|
|
audio_block_t *left, *right; |
|
|
|
|
|
|
|
|
if (usb_audio_transmit_setting == 0) { |
|
|
|
|
|
AudioOutputUSB::transmitting = 0; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
//serial_print("."); |
|
|
|
|
|
|
|
|
|
|
|
if (++count < 9) { // TODO: dynamic adjust to match USB rate |
|
|
if (++count < 9) { // TODO: dynamic adjust to match USB rate |
|
|
target = 44; |
|
|
target = 44; |
|
|
} else { |
|
|
} else { |