waveForm输入(mmeapi)可以提前添加多少个缓冲区?

huangapple go评论90阅读模式
英文:

How many buffers can be added in advance for waveForm input (mmeapi)?

问题

我正在为Windows编写音频流应用程序,使用MMEAPI和waveIn*函数。上次接触这个API是20多年前,所以我不太记得语义了。
我所做的是设置一个waveInProc回调函数,然后调用waveInOpen函数,然后分配录制缓冲区,并为每个缓冲区填充WAVEHDR结构。然后,我应该对每个WAVEHDR调用waveInPrepareHeaderwaveInAddBuffer,调用这一对函数的次数与我分配的缓冲区数量相同,对吗?然后当然要调用waveInStart
我的问题是,Windows 10只允许我一次添加一个缓冲区。比如说,我有两个缓冲区。我添加第0个,它说OK,我添加第1个,它返回33(错误“仍在播放”),即使我还没有调用waveInStart。只有在前一个缓冲区填满录音后,它才允许我添加下一个缓冲区。即使我先运行waveInStart,然后再添加缓冲区,它仍然只允许我一次添加一个,直到前一个完成。
录音本身似乎是正常工作的,我只是担心如果我被迫一次只使用一个底层缓冲区,会导致音频流中出现间隙。

我不记得在Windows 2000/XP中出现这种MMEAPI行为。我有什么遗漏吗?

更新。
如您所请求的代码
https://github.com/UrsusArctos/mickey

英文:

I'm writing audio streaming app for Windows using MMEAPI and waveIn* functions. Last time I touched that API 20+ years ago so I can't quite remember the semantics.
So what I do is setup a waveInProc callback, then call waveInOpen then allocate recording buffers and fill WAVEHDR structure for each of them. I'm then supposed to call waveInPrepareHeader and waveInAddBuffer on each WAVEHDR, calling that pair of funcs same number of times as the number of buffers I allocated, right? And then waveInStart, of course.
My problem is that Windows 10 only lets me add ONE buffer at a time. Say, I have two. I add 0th, it says OK, I add 1st and it returns 33 (error "still playing") even though I didn't call waveInStart yet. It lets me add next buffer only after the previous one is filled with recordings. And even if I run waveInStart first and add buffers after that it still only lets me add only one until previous is done.
The recording itself seems to work though, I'm just worrying about gaps in audio stream if I'm forced to use only one underlying buffer at a time.

I don't remember that MMEAPI behavior being the case with Windows 2000/XP. Am I missing something?

UPD.
Code as requested
https://github.com/UrsusArctos/mickey

答案1

得分: 1

我实际上在我的代码中发现了一个错误。这是一个严重但很难发现的错误,特别是在一个不适合WinAPI编程的语言中。我打算删除这个代码库,但如果有人对发生的情况感兴趣,这里是相关的代码片段。

func (wmic *TWinMicrophone) queueRecBuffer(index uint8) {
    wmic.initWaveHDR(index)
    ret0, ret1, ret2 := wmic.callProc(waveInPrepareHeader,
        uintptr(wmic.hWaveIn),
        uintptr(unsafe.Pointer(&wmic.waveHDR[wmic.recBufIndex])),
        uintptr(unsafe.Sizeof(wmic.waveHDR[wmic.recBufIndex])))

    if ret0 == 0 {
        ret10, ret11, ret12 := wmic.callProc(waveInAddBuffer,
            uintptr(wmic.hWaveIn),
            uintptr(unsafe.Pointer(&wmic.waveHDR[wmic.recBufIndex])),
            uintptr(unsafe.Sizeof(wmic.waveHDR[wmic.recBufIndex])))

可以看到,waveHDR 结构体的索引使用了 wmic.recBufIndex 而不是函数参数 index。我感到很愚蠢。但现在错误已经消失了。感谢大家的努力和关注。

英文:

I actually found a mistake in my code. Serious but hard to spot mistake, especially in a language not suitable for WinAPI programming.
I'm going to delete the repository but in case anyone is interested what happened, here's the relevant snippet.

func (wmic *TWinMicrophone) queueRecBuffer(index uint8) {
	wmic.initWaveHDR(index)
	ret0, ret1, ret2 := wmic.callProc(waveInPrepareHeader,
		uintptr(wmic.hWaveIn),
		uintptr(unsafe.Pointer(&wmic.waveHDR[wmic.recBufIndex])),
		uintptr(unsafe.Sizeof(wmic.waveHDR[wmic.recBufIndex])))
	if ret0 == 0 {
		ret10, ret11, ret12 := wmic.callProc(waveInAddBuffer,
			uintptr(wmic.hWaveIn),
			uintptr(unsafe.Pointer(&wmic.waveHDR[wmic.recBufIndex])),
			uintptr(unsafe.Sizeof(wmic.waveHDR[wmic.recBufIndex])))

See the waveHDR structures are being indexed with wmic.recBufIndex instead of index function parameter.
I feel stupid.
But now the error is gone.
Thank you all for your efforts and attention.

huangapple
  • 本文由 发表于 2023年3月29日 03:31:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75870361.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定