Allow audio underrun (#1)

* Allow audio underrun

* HDMI audio

* Allow audio underrun

* Allow audio underrun
pull/94/head
fruit-bat 2024-03-25 22:24:07 +00:00 zatwierdzone przez GitHub
rodzic dd7ba281ee
commit 21869f0460
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
8 zmienionych plików z 56 dodań i 45 usunięć

Wyświetl plik

@ -21,5 +21,7 @@ target_link_libraries(colour_terminal_audio
libdvi
)
# pico_enable_stdio_uart(colour_terminal_audio 1)
# create map/bin/hex file etc.
pico_add_extra_outputs(colour_terminal_audio)

Wyświetl plik

@ -86,23 +86,22 @@ audio_sample_t audio_buffer[AUDIO_BUFFER_SIZE];
struct repeating_timer audio_timer;
bool audio_timer_callback(struct repeating_timer *t) {
int size = get_write_size(&dvi0.audio_ring, false);
audio_sample_t *audio_ptr = get_write_pointer(&dvi0.audio_ring);
audio_sample_t sample;
static uint sample_count = 0;
for (int cnt = 0; cnt < size; cnt++) {
sample.channels[0] = commodore_argentina[sample_count % commodore_argentina_len] << 8;
sample.channels[1] = commodore_argentina[(sample_count+1024) % commodore_argentina_len] << 8;
*audio_ptr++ = sample;
sample_count = sample_count + 1;
}
increase_write_pointer(&dvi0.audio_ring, size);
return true;
while(true) {
int size = get_write_size(&dvi0.audio_ring, false);
if (size == 0) return true;
audio_sample_t *audio_ptr = get_write_pointer(&dvi0.audio_ring);
audio_sample_t sample;
static uint sample_count = 0;
for (int cnt = 0; cnt < size; cnt++) {
sample.channels[0] = commodore_argentina[sample_count % commodore_argentina_len] << 8;
sample.channels[1] = commodore_argentina[(sample_count+1024) % commodore_argentina_len] << 8;
*audio_ptr++ = sample;
sample_count = sample_count + 1;
}
increase_write_pointer(&dvi0.audio_ring, size);
}
}
// Pixel format RGB222
static inline void set_colour(uint x, uint y, uint8_t fg, uint8_t bg) {
if (x >= CHAR_COLS || y >= CHAR_ROWS)
@ -146,6 +145,8 @@ int __not_in_flash("main") main() {
// Run system at TMDS bit clock
set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true);
// setup_default_uart();
dvi0.timing = &DVI_TIMING;
dvi0.ser_cfg = DVI_DEFAULT_SERIAL_CONFIG;
dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());
@ -166,6 +167,8 @@ int __not_in_flash("main") main() {
dvi_set_audio_freq(&dvi0, 44100, 28000, 6272);
add_repeating_timer_ms(-2, audio_timer_callback, NULL, &audio_timer);
printf("starting...\n");
multicore_launch_core1(core1_main);
while (1)

Wyświetl plik

@ -26,14 +26,14 @@
struct dvi_inst dvi0;
uint16_t framebuf[FRAME_WIDTH * FRAME_HEIGHT];
void core1_main() {
void __not_in_flash_func(core1_main)() {
dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
dvi_start(&dvi0);
dvi_scanbuf_main_16bpp(&dvi0);
__builtin_unreachable();
}
void core1_scanline_callback() {
void __not_in_flash_func(core1_scanline_callback)() {
// Discard any scanline pointers passed back
uint16_t *bufptr;
while (queue_try_remove_u32(&dvi0.q_colour_free, &bufptr))
@ -45,7 +45,7 @@ void core1_scanline_callback() {
scanline = (scanline + 1) % FRAME_HEIGHT;
}
int main() {
int __not_in_flash_func(main)() {
vreg_set_voltage(VREG_VSEL);
sleep_ms(10);
#ifdef RUN_FROM_CRYSTAL

Wyświetl plik

@ -73,7 +73,7 @@ struct semaphore dvi_start_sem;
#define CHAR_ROWS (FRAME_HEIGHT / FONT_CHAR_HEIGHT)
char charbuf[CHAR_ROWS * CHAR_COLS];
static inline void prepare_scanline(const char *chars, uint y) {
static inline void __not_in_flash_func(prepare_scanline)(const char *chars, uint y) {
static uint8_t scanbuf[FRAME_WIDTH / 8];
// First blit font into 1bpp scanline buffer, then encode scanbuf into tmdsbuf
for (uint i = 0; i < CHAR_COLS; ++i) {
@ -86,13 +86,13 @@ static inline void prepare_scanline(const char *chars, uint y) {
queue_add_blocking(&dvi0.q_tmds_valid, &tmdsbuf);
}
void core1_scanline_callback() {
void __not_in_flash_func(core1_scanline_callback)() {
static uint y = 1;
prepare_scanline(charbuf, y);
y = (y + 1) % FRAME_HEIGHT;
}
void __not_in_flash("main") core1_main() {
void __not_in_flash_func(core1_main)() {
dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
sem_acquire_blocking(&dvi_start_sem);
dvi_start(&dvi0);
@ -104,7 +104,7 @@ void __not_in_flash("main") core1_main() {
__builtin_unreachable();
}
int __not_in_flash("main") main() {
int __not_in_flash_func(main)() {
vreg_set_voltage(VREG_VSEL);
sleep_ms(10);
#ifdef RUN_FROM_CRYSTAL

Wyświetl plik

@ -61,16 +61,16 @@ static const struct dvi_serialiser_cfg micromod_cfg = {
};
// Pico DVI Sock (small hat on the bottom) which solders to the end of a Pico
// static const struct dvi_serialiser_cfg pico_sock_cfg = {
// .pio = DVI_DEFAULT_PIO_INST,
// .sm_tmds = {0, 1, 2},
// .pins_tmds = {12, 18, 16},
// .pins_clk = 14,
// .invert_diffpairs = false
// };
static const struct dvi_serialiser_cfg pico_sock_cfg = {
.pio = DVI_DEFAULT_PIO_INST,
.sm_tmds = {0, 1, 2},
.pins_tmds = {12, 18, 16},
.pins_clk = 14,
.invert_diffpairs = false
};
// pico-RGB2HDMI
static const struct dvi_serialiser_cfg pico_sock_cfg = {
static const struct dvi_serialiser_cfg pico_rgb2hdmi_cfg = {
.pio = pio0,
.sm_tmds = {0, 1, 2},
.pins_tmds = {5, 7, 9},

Wyświetl plik

@ -206,7 +206,7 @@ void __not_in_flash_func(set_null)(void *data, int size) {
}
}
int __not_in_flash_func(set_audio_sample)(data_packet_t *data_packet, const audio_sample_t *p, int n, int frameCt) {
int __not_in_flash_func(set_audio_sample)(data_packet_t *data_packet, audio_ring_t *audio_ring, const int n, int frameCt) {
const int layout = 0;
const int samplePresent = (1 << n) - 1;
const int B = (frameCt < n) ? (1 << frameCt) : 0;
@ -214,24 +214,34 @@ int __not_in_flash_func(set_audio_sample)(data_packet_t *data_packet, const aud
data_packet->header[1] = (layout << 4) | samplePresent;
data_packet->header[2] = B << 4;
compute_header_parity(data_packet);
const int read_size = get_read_size(audio_ring, true);
for (int i = 0; i < n; ++i)
{
uint8_t *d = data_packet->subpacket[i];
const int16_t l = (*p).channels[0];
const int16_t r = (*p).channels[1];
int16_t l, r;
if (i < read_size) {
audio_sample_t *audio_sample_ptr = get_read_pointer(audio_ring);
l = (*audio_sample_ptr).channels[0];
r = (*audio_sample_ptr).channels[1];
increase_read_pointer(audio_ring, 1);
}
else {
l = (int16_t)0;
r = (int16_t)0;
}
const uint8_t vuc = 1; // valid
uint8_t *d = data_packet->subpacket[i];
d[0] = 0;
d[1] = l;
d[2] = l >> 8;
d[3] = 0;
d[4] = r;
d[5] = r >> 8;
++p;
bool pl = compute8_3(d[1], d[2], vuc);
bool pr = compute8_3(d[4], d[5], vuc);
d[6] = (vuc << 0) | (pl << 3) | (vuc << 4) | (pr << 7);
compute_subpacket_parity(data_packet, i);
d[7] = encode_BCH_7(d);
// channel status (is it relevant?)
// After testing, seems better to ignore

Wyświetl plik

@ -85,7 +85,7 @@ void compute_info_frame_checkSum(data_packet_t *data_packet);
void encode_header(const data_packet_t *data_packet, uint32_t *dst, int hv, bool firstPacket);
void encode_subpacket(const data_packet_t *data_packet, uint32_t *dst1, uint32_t *dst2);
void set_null(void *data, int size);
int set_audio_sample(data_packet_t *data_packet, const audio_sample_t *p, int n, int frameCt);
int set_audio_sample(data_packet_t *data_packet, audio_ring_t *audio_ring, const int n, int frameCt);
void set_audio_clock_regeneration(data_packet_t *data_packet, int CTS, int N);
void set_audio_info_frame(data_packet_t *data_packet, int freq);
void set_AVI_info_frame(data_packet_t *data_packet, scan_info s, pixel_format y, colorimetry c, picture_aspect_ratio m,

Wyświetl plik

@ -412,16 +412,12 @@ bool __dvi_func(dvi_update_data_packet_)(struct dvi_inst *inst, data_packet_t *p
return true;
}
}
int sample_pos_24 = inst->audio_sample_pos >> 24;
int read_size = get_read_size(&inst->audio_ring, false);
int n = MIN(4, MIN(sample_pos_24, read_size));
inst->audio_sample_pos -= (n << 24);
const int sample_pos_24 = inst->audio_sample_pos >> 24;
const int n = MIN(4, sample_pos_24);
if (n)
{
audio_sample_t *audio_sample_ptr = get_read_pointer(&inst->audio_ring);
inst->audio_frame_count = set_audio_sample(packet, audio_sample_ptr, n, inst->audio_frame_count);
increase_read_pointer(&inst->audio_ring, n);
inst->audio_sample_pos -= (n << 24);
inst->audio_frame_count = set_audio_sample(packet, &inst->audio_ring, n, inst->audio_frame_count);
return true;
}