소스 검색

Actually transmit usb audio to PC

main
PaulStoffregen 8 년 전
부모
커밋
7fc6f36003
1개의 변경된 파일70개의 추가작업 그리고 29개의 파일을 삭제
  1. +70
    -29
      teensy3/usb_audio.cpp

+ 70
- 29
teensy3/usb_audio.cpp 파일 보기

@@ -223,6 +223,15 @@ void AudioOutputUSB::begin(void)
right_1st = NULL;
}

static void copy_from_buffers(uint32_t *dst, int16_t *left, int16_t *right, unsigned int len)
{
// TODO: optimize...
while (len > 0) {
*dst++ = (*right++ << 16) | (*left++ & 0xFFFF);
len--;
}
}

void AudioOutputUSB::update(void)
{
audio_block_t *left, *right;
@@ -251,7 +260,19 @@ void AudioOutputUSB::update(void)
right = left;
}
__disable_irq();
if (left_1st == NULL) {
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) {
left_1st = left;
right_1st = right;
offset_1st = 0;
@@ -270,16 +291,11 @@ void AudioOutputUSB::update(void)
right_2nd = right;
offset_1st = 0; // TODO: discard part of this data?
outgoing_count = AUDIO_BLOCK_SAMPLES*2;
serial_print("*");
//serial_print("*");
release(discard1);
release(discard2);
}
__enable_irq();
if (!transmitting) {
serial_print("b");
usb_tx_isochronous(AUDIO_TX_ENDPOINT, usb_audio_transmit_buffer, 176);
transmitting = 1;
}
}


@@ -289,30 +305,55 @@ void AudioOutputUSB::update(void)
// no data to transmit
unsigned int usb_audio_transmit_callback(void)
{
serial_print(".");
AudioOutputUSB::transmitting = 0;
return 0;
}


















static uint32_t count=5;
uint32_t avail, num, target, offset, len=0;
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
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;
}


#endif // F_CPU

Loading…
취소
저장