lm68140318 发表于 2023-8-3 18:10:26

MM_WIM_DATA 消息



afx_msg LRESULT CcsyinDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam) //当音频输入设备采集到一定量的音频数据时触发
{
        /*
        wParam = (WPARAM) hInputDev   接收数据的波形音频输入设备的句柄
        lParam = (LONG) lpwvhdr       指向 WAVEHDR 结构的指针,该结构标识包含数据的缓冲区
        */
       
        pNewBuffer = (PBYTE)realloc(pSaveBuffer, dwDataLength + ((PWAVEHDR)lParam)->dwBytesRecorded);
        /*
        ((PWAVEHDR)lParam)->dwBytesRecorded   缓冲区中已有的音频数据
        dwDataLength   是缓冲区大小
       
        */



        if (pNewBuffer == NULL)
        {
                waveInClose(hWaveIn);
                MessageBeep(MB_ICONEXCLAMATION);
                AfxMessageBox(_T("erro memory"));
                return TRUE;
        }

        pSaveBuffer = pNewBuffer;
        CopyMemory(pSaveBuffer + dwDataLength, ((PWAVEHDR)lParam)->lpData,((PWAVEHDR)lParam)->dwBytesRecorded);
        dwDataLength += ((PWAVEHDR)lParam)->dwBytesRecorded;

        if (bEnding)
        {
                waveInClose(hWaveIn);
                return TRUE;
        }

        waveInAddBuffer(hWaveIn, (PWAVEHDR)lParam, sizeof(WAVEHDR));
       
       
        return 0;
}



我的问题:要从麦克风的缓冲区读取数据
pNewBuffer = (PBYTE)realloc(pSaveBuffer, dwDataLength + ((PWAVEHDR)lParam)->dwBytesRecorded);
        /*
        ((PWAVEHDR)lParam)->dwBytesRecorded   缓冲区中已有的音频数据字节数
        dwDataLength   是缓冲区大小
       
        */

上面这条指令(PWAVEHDR)lParam)->dwBytesRecorded就是缓冲区中已有的音频数据字节数,为何还要加上dwDataLength缓冲区大小呢 ?

isdkz 发表于 2023-8-3 18:10:40

在这段代码中, (PWAVEHDR)lParam)->dwBytesRecorded表示缓冲区中已经录制的音频数据的字节数。而dwDataLength是你在代码中维护的当前缓冲区大小。这里将已录制的音频数据字节数与缓冲区大小相加,是为了确定需要重新分配内存的大小。

具体来说,代码中使用了realloc函数来重新分配存储音频数据的缓冲区的内存大小。 pSaveBuffer是一个指向之前分配的缓冲区的指针。通过将已录制的音频数据字节数与当前缓冲区大小相加,你确保新分配的内存能够容纳已录制的数据以及之前已经存在的数据。

这是因为在音频数据流中,每次处理完缓冲区中的数据后,你需要将新录制的数据追加到之前已经录制的数据之后,以便完整地保存整个音频流。所以你需要确保重新分配的内存大小足够大,以容纳已有的数据和新录制的数据。

总结起来,这段代码中的(PWAVEHDR)lParam)->dwBytesRecorded + dwDataLength部分计算了当前缓冲区中总共的数据大小,以便在需要时重新分配足够大小的内存来存储所有数据。

Mike_python小 发表于 2023-8-3 18:10:41

在这段代码中,pSaveBuffer 是一个指向已保存音频数据的缓冲区的指针,dwDataLength 表示缓冲区的大小。而 ((PWAVEHDR)lParam)->dwBytesRecorded 则表示缓冲区中已有的音频数据的字节数。

在这行代码 pNewBuffer = (PBYTE)realloc(pSaveBuffer, dwDataLength + ((PWAVEHDR)lParam)->dwBytesRecorded); 中,realloc 函数用于重新分配内存块的大小。新的缓冲区大小是原始缓冲区大小 dwDataLength 加上当前接收到的音频数据的字节数 ((PWAVEHDR)lParam)->dwBytesRecorded。

目的是为了扩展缓冲区大小,以便容纳更多的音频数据。因为每次接收到新的音频数据时,需要将其复制到缓冲区末尾,所以需要确保缓冲区足够大以容纳新的数据。通过将原始缓冲区的大小和新接收的音频数据的字节数相加,可以得到新的缓冲区大小。

希望这个回答对你有帮助!如果还有其他问题,请随时提问。

学习编程中的Ben 发表于 2023-8-3 18:10:42

根据代码中的注释,可以推断出 dwDataLength 是缓冲区的大小,而 (PWAVEHDR)lParam)->dwBytesRecorded 是缓冲区中已经录制的音频数据的字节数。

在这条指令 pNewBuffer = (PBYTE)realloc(pSaveBuffer, dwDataLength + ((PWAVEHDR)lParam)->dwBytesRecorded); 中,realloc 函数用于重新分配内存空间,并返回指向新分配内存的指针。这里的目的是将缓冲区的大小扩展到 dwDataLength + ((PWAVEHDR)lParam)->dwBytesRecorded 字节。

假设之前已经有一部分音频数据存储在 pSaveBuffer 中,通过 realloc 函数的调用,将原有的 pSaveBuffer 扩展到新的大小,以容纳更多的音频数据。这样做是为了确保缓冲区能够存储足够的音频数据,并避免数据溢出或丢失。

也就是说,pSaveBuffer 是用来存储音频数据的缓冲区,通过不断地扩展它的大小,确保能够容纳各个时刻的音频数据。

希望以上解释能够解决你的疑惑。如果还有其他问题,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!{:10_254:}{:10_254:}{:10_254:}

lm68140318 发表于 2023-8-3 18:22:58

isdkz 发表于 2023-8-3 18:10
在这段代码中, (PWAVEHDR)lParam)->dwBytesRecorded表示缓冲区中已经录制的音频数据的字节数。而dwDat ...

每次发出MM_WIM_DATA消息后,是不是自动清空缓冲区,再重新接受音频数据   ??

isdkz 发表于 2023-8-3 18:26:20

lm68140318 发表于 2023-8-3 18:22
每次发出MM_WIM_DATA消息后,是不是自动清空缓冲区,再重新接受音频数据   ??

不完全是。MM_WIM_DATA消息是在音频输入设备完成缓冲区的数据采集后发送的。发送此消息后,缓冲区中的数据不会自动清空,而是需要你在代码中显式地处理。

在你的代码中,你使用了waveInAddBuffer函数来重新将缓冲区添加到音频输入设备的队列中。这意味着,一旦数据被处理(在这种情况下,是被复制到pSaveBuffer),这个缓冲区就可以被音频输入设备重新使用,以便采集更多的音频数据。


所以,虽然缓冲区在发送MM_WIM_DATA消息后不会自动清空,但是你的代码确实在处理完数据后清空了缓冲区,以便它可以被重新使用。这是通过将缓冲区重新添加到音频输入设备的队列中来实现的。
页: [1]
查看完整版本: MM_WIM_DATA 消息