Skip to content

isRecording() 等待,存在“假完成”的竞态窗口,导致机器音/金属音 #222

@MOVING2014

Description

@MOVING2014

if (M5.Mic.record(pcm_buffer, CHUNK_SIZE, SAMPLE_RATE)) {
while (M5.Mic.isRecording()) {
vTaskDelay(1);
}
// 这里开始使用 pcm_buffer
}

但 M5Unified 的 isRecording() 不是 pcm_buffer 已经填满的完成标志,它依赖 _is_recording 这个 flag,而这个 flag 在 mic_task 中有明确的“空窗期”:
当 mic_task 发现两个 _rec_info 都没活时,会做:
self->_is_recording = false;
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);(睡眠等通知)
当你调用 record() 时,_rec_raw() 只是把 _rec_info[...] = info; 然后 xTaskNotifyGive(mic_task),立刻返回:
Mic_Class.cpp
Lines 761-779
while (_rec_info[_rec_flip].length) { xSemaphoreTake(_task_semaphore, 1); }
_rec_info[_rec_flip] = info;
xTaskNotifyGive(this->_task_handle);
return true;
while (_rec_info[_rec_flip].length) { xSemaphoreTake(_task_semaphore, 1); }_rec_info[_rec_flip] = info;xTaskNotifyGive(this->_task_handle);return true;
竞态点就在这里:你 record() 返回后立刻去读 isRecording(),但此时 mic_task 可能还没来得及被调度运行、还没把 _is_recording 置回 true,于是:

isRecording() 会因为 _is_recording == false 直接返回 0
你这边 while(isRecording()) 立刻退出
然后你开始处理 pcm_buffer —— 但它可能是上一次的残留数据或正在被后台写入的半截数据
这种“读到半帧/脏帧”的听感,非常像机器音/金属音,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions