kopia lustrzana https://github.com/raspberrypi/pico-playground
Merge 9f05e1eb47
into 49a701a955
commit
f6a2cb5a7b
|
@ -17,6 +17,11 @@
|
||||||
// todo forget why this is using core 1 for sound: presumably not necessary
|
// todo forget why this is using core 1 for sound: presumably not necessary
|
||||||
// todo noop when muted
|
// todo noop when muted
|
||||||
|
|
||||||
|
// modification for USB-sound rate feedback and mute
|
||||||
|
#define USB_FEEDBACK 1 // USB-audio rate feedback using buffer status
|
||||||
|
#define MUTE_CMD 1 // mute command
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
CU_REGISTER_DEBUG_PINS(audio_timing)
|
CU_REGISTER_DEBUG_PINS(audio_timing)
|
||||||
|
|
||||||
// ---- select at most one ---
|
// ---- select at most one ---
|
||||||
|
@ -40,7 +45,12 @@ static char *descriptor_strings[] =
|
||||||
#undef AUDIO_SAMPLE_FREQ
|
#undef AUDIO_SAMPLE_FREQ
|
||||||
#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
|
#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
|
||||||
|
|
||||||
|
#if USB_FEEDBACK
|
||||||
|
// when USB-audio feedback applies, it receives upto 49 samples in each packet
|
||||||
|
#define AUDIO_MAX_PACKET_SIZE(freq) (uint8_t)(((freq + 1999) / 1000) * 4)
|
||||||
|
#else
|
||||||
#define AUDIO_MAX_PACKET_SIZE(freq) (uint8_t)(((freq + 999) / 1000) * 4)
|
#define AUDIO_MAX_PACKET_SIZE(freq) (uint8_t)(((freq + 999) / 1000) * 4)
|
||||||
|
#endif
|
||||||
#define FEATURE_MUTE_CONTROL 1u
|
#define FEATURE_MUTE_CONTROL 1u
|
||||||
#define FEATURE_VOLUME_CONTROL 2u
|
#define FEATURE_VOLUME_CONTROL 2u
|
||||||
|
|
||||||
|
@ -256,6 +266,22 @@ static struct {
|
||||||
|
|
||||||
static struct audio_buffer_pool *producer_pool;
|
static struct audio_buffer_pool *producer_pool;
|
||||||
|
|
||||||
|
#if USB_FEEDBACK
|
||||||
|
#define BUFFER_NUM 16 // number of buffer
|
||||||
|
|
||||||
|
//for USB-audio rate feedback, number of vacant buffers is used
|
||||||
|
static int countFreeBuffers(void) {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
audio_buffer_t *audio_buffer = producer_pool->free_list;
|
||||||
|
while(audio_buffer != NULL) {
|
||||||
|
audio_buffer = audio_buffer->next;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void _as_audio_packet(struct usb_endpoint *ep) {
|
static void _as_audio_packet(struct usb_endpoint *ep) {
|
||||||
assert(ep->current_transfer);
|
assert(ep->current_transfer);
|
||||||
struct usb_buffer *usb_buffer = usb_current_out_packet_buffer(ep);
|
struct usb_buffer *usb_buffer = usb_current_out_packet_buffer(ep);
|
||||||
|
@ -268,6 +294,11 @@ static void _as_audio_packet(struct usb_endpoint *ep) {
|
||||||
assert(audio_buffer->sample_count);
|
assert(audio_buffer->sample_count);
|
||||||
assert(audio_buffer->max_sample_count >= audio_buffer->sample_count);
|
assert(audio_buffer->max_sample_count >= audio_buffer->sample_count);
|
||||||
uint16_t vol_mul = audio_state.vol_mul;
|
uint16_t vol_mul = audio_state.vol_mul;
|
||||||
|
#if MUTE_CMD
|
||||||
|
if(audio_state.mute) {
|
||||||
|
vol_mul = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int16_t *out = (int16_t *) audio_buffer->buffer->bytes;
|
int16_t *out = (int16_t *) audio_buffer->buffer->bytes;
|
||||||
int16_t *in = (int16_t *) usb_buffer->data;
|
int16_t *in = (int16_t *) usb_buffer->data;
|
||||||
for (int i = 0; i < audio_buffer->sample_count * 2; i++) {
|
for (int i = 0; i < audio_buffer->sample_count * 2; i++) {
|
||||||
|
@ -288,8 +319,14 @@ static void _as_sync_packet(struct usb_endpoint *ep) {
|
||||||
assert(buffer->data_max >= 3);
|
assert(buffer->data_max >= 3);
|
||||||
buffer->data_len = 3;
|
buffer->data_len = 3;
|
||||||
|
|
||||||
|
#if USB_FEEDBACK
|
||||||
|
// calc rate adjustment value between -40 to 40
|
||||||
|
int feedbackvalue = (countFreeBuffers() - BUFFER_NUM / 2) * (2 * 40 / BUFFER_NUM);
|
||||||
|
uint feedback = ((audio_state.freq + feedbackvalue) << 14u) / 1000u;
|
||||||
|
#else
|
||||||
// todo lie thru our teeth for now
|
// todo lie thru our teeth for now
|
||||||
uint feedback = (audio_state.freq << 14u) / 1000u;
|
uint feedback = (audio_state.freq << 14u) / 1000u;
|
||||||
|
#endif
|
||||||
|
|
||||||
buffer->data[0] = feedback;
|
buffer->data[0] = feedback;
|
||||||
buffer->data[1] = feedback >> 8u;
|
buffer->data[1] = feedback >> 8u;
|
||||||
|
@ -613,7 +650,13 @@ int main(void) {
|
||||||
.sample_stride = 4
|
.sample_stride = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if USB_FEEDBACK
|
||||||
|
// when USB-audio feedback applies, it receives upto 49 samples in each packet
|
||||||
|
producer_pool = audio_new_producer_pool(&producer_format, BUFFER_NUM,
|
||||||
|
AUDIO_MAX_PACKET_SIZE(AUDIO_FREQ_MAX) / 4);
|
||||||
|
#else
|
||||||
producer_pool = audio_new_producer_pool(&producer_format, 8, 48); // todo correct size
|
producer_pool = audio_new_producer_pool(&producer_format, 8, 48); // todo correct size
|
||||||
|
#endif
|
||||||
bool __unused ok;
|
bool __unused ok;
|
||||||
struct audio_i2s_config config = {
|
struct audio_i2s_config config = {
|
||||||
.data_pin = PICO_AUDIO_I2S_DATA_PIN,
|
.data_pin = PICO_AUDIO_I2S_DATA_PIN,
|
||||||
|
@ -628,7 +671,14 @@ int main(void) {
|
||||||
panic("PicoAudio: Unable to open audio device.\n");
|
panic("PicoAudio: Unable to open audio device.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USB_FEEDBACK
|
||||||
|
// It is not clear what is meant by the number "96" but I fixed it as well as producer_pool.
|
||||||
|
// ok = audio_i2s_connect_extra(producer_pool, false, 2, 96, NULL);
|
||||||
|
ok = audio_i2s_connect_extra(producer_pool, false, 2,
|
||||||
|
AUDIO_MAX_PACKET_SIZE(AUDIO_FREQ_MAX) / 2, NULL);
|
||||||
|
#else
|
||||||
ok = audio_i2s_connect_extra(producer_pool, false, 2, 96, NULL);
|
ok = audio_i2s_connect_extra(producer_pool, false, 2, 96, NULL);
|
||||||
|
#endif
|
||||||
assert(ok);
|
assert(ok);
|
||||||
usb_sound_card_init();
|
usb_sound_card_init();
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue