Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: set period=1024 for sample-accurate capture timing

ALSA defaults (period=32768 = 682ms) caused massive timing drift.
Period=1024 gives ~21ms latency. The EIO root causes (HDMI open,
6-period playback, boot mixer) are all fixed so this should work now.

Removed first-chunk skip hack — with 21ms periods the direct write
path is precise enough.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+11 -8
+11 -8
fedac/native/src/audio.c
··· 1034 1034 return NULL; 1035 1035 } 1036 1036 1037 - // Configure — NO period/buffer setting (ALSA defaults work on this HDA) 1038 1037 snd_pcm_hw_params_t *hw; 1039 1038 snd_pcm_hw_params_alloca(&hw); 1040 1039 snd_pcm_hw_params_any(cap, hw); ··· 1049 1048 1050 1049 unsigned int rate = 48000; 1051 1050 snd_pcm_hw_params_set_rate_near(cap, hw, &rate, NULL); 1051 + 1052 + // Set period=1024 (~21ms) for low-latency capture. This previously 1053 + // caused EIO but the root causes were: HDMI audio open (exhausting 1054 + // HDA streams), 6-period playback buffer, and capture mixer in 1055 + // audio_init. All three are now fixed. 1056 + snd_pcm_uframes_t period_frames = 1024; 1057 + snd_pcm_hw_params_set_period_size_near(cap, hw, &period_frames, NULL); 1058 + snd_pcm_uframes_t buffer_frames = 8192; 1059 + snd_pcm_hw_params_set_buffer_size_near(cap, hw, &buffer_frames); 1052 1060 1053 1061 if (snd_pcm_hw_params(cap, hw) < 0) { 1054 1062 snprintf(audio->mic_last_error, sizeof(audio->mic_last_error), ··· 1110 1118 continue; 1111 1119 } 1112 1120 1113 - // Skip first chunk after recording starts — it contains stale 1114 - // pre-buffered audio from before the user pressed rec. 1115 - int is_first_rec_chunk = (audio->recording && audio->sample_write_pos == 0); 1116 - 1117 1121 float peak = 0.0f; 1118 1122 // Simple compressor: track envelope, apply gain reduction 1119 1123 static float env = 0.0f; // envelope follower ··· 1155 1159 audio->mic_ring[audio->mic_ring_pos % audio->sample_max_len] = sample; 1156 1160 audio->mic_ring_pos++; 1157 1161 1158 - // Direct-write when recording (skip first stale chunk) 1159 - if (audio->recording && !is_first_rec_chunk && 1160 - audio->sample_write_pos < audio->sample_max_len) { 1162 + // Direct-write when recording 1163 + if (audio->recording && audio->sample_write_pos < audio->sample_max_len) { 1161 1164 audio->sample_buf[audio->sample_write_pos++] = sample; 1162 1165 } 1163 1166 }