10121|22

69

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

录音与播放,边录边放问题(附代码和思路)急! [复制链接]

各位好,这个问题弄了几天了,网上搜以好多资料,道理基本明白,可就是程序实现起来老不行,我现在是可以实现单独录音和单独播放,但想边录边放就不行了,现在就是想开两buffer,一个录一个往缓冲区写,写到一定程度,比如40ms就开始播放,播放也用两buffer,一个放一个从缓冲区取数据,就这思路,可不知道为怎么就是不行,请各位说说或者帮忙实现一下,有现成的程序请发xyj8303@yahoo.com.cn谢谢!
下面是我录音和播放的代码:
void CRecordHWndDlg::OnRecStart()
{
        // TODO: Add your control notification handler code here
        //allocate buffer memory
        pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE);
        pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE);
        if (!pBuffer1 || !pBuffer2) {
                if (pBuffer1) free(pBuffer1);
                if (pBuffer2) free(pBuffer2);
                MessageBeep(MB_ICONEXCLAMATION);
                AfxMessageBox("Memory erro!");
                return ;
        }
       
        //open waveform audo for input
       
        waveform.wFormatTag=WAVE_FORMAT_PCM;
        waveform.nChannels=1;
        waveform.nSamplesPerSec=11025;
        waveform.nAvgBytesPerSec=11025;
        waveform.nBlockAlign=1;
        waveform.wBitsPerSample=8;
        waveform.cbSize=0;

       
        if (waveInOpen(&hWaveIn,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {
                free(pBuffer1);
                free(pBuffer2);
                MessageBeep(MB_ICONEXCLAMATION);
                AfxMessageBox("Audio can not be open!");
        }
        pWaveHdr1->lpData=(LPTSTR)pBuffer1;
        pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE;
        pWaveHdr1->dwBytesRecorded=0;
        pWaveHdr1->dwUser=0;
        pWaveHdr1->dwFlags=0;
        pWaveHdr1->dwLoops=1;
        pWaveHdr1->lpNext=NULL;
        pWaveHdr1->reserved=0;
       
        waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
       
        pWaveHdr2->lpData=(LPTSTR)pBuffer2;
        pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE;
        pWaveHdr2->dwBytesRecorded=0;
        pWaveHdr2->dwUser=0;
        pWaveHdr2->dwFlags=0;
        pWaveHdr2->dwLoops=1;
        pWaveHdr2->lpNext=NULL;
        pWaveHdr2->reserved=0;
       
        waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));
       
        //////////////////////////////////////////////////////////////////////////
        pSaveBuffer = (PBYTE)realloc (pSaveBuffer, 1) ;
        // Add the buffers
       
        waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
        waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
       
        // Begin sampling
       
        bRecording = TRUE ;
        bEnding = FALSE ;
        dwDataLength = 0 ;
        waveInStart (hWaveIn) ;               
}
void CRecordHWndDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam)
{
        // TODO: Add your message handler code here and/or call default
        // Reallocate save buffer memory
       
        //////////////////////////////////////////////////////////////////////////
       
        pNewBuffer = (PBYTE)realloc (pSaveBuffer, dwDataLength +
                ((PWAVEHDR) lParam)->dwBytesRecorded) ;
       
        if (pNewBuffer == NULL)
        {
                waveInClose (hWaveIn) ;
                MessageBeep (MB_ICONEXCLAMATION) ;
                AfxMessageBox("erro memory");
                return ;
        }
       
        pSaveBuffer = pNewBuffer ;
        //////////////////////////////////////////////////////////////////////////
       
        CopyMemory (pSaveBuffer + dwDataLength, ((PWAVEHDR) lParam)->lpData,
                ((PWAVEHDR) lParam)->dwBytesRecorded) ;
       
        dwDataLength += ((PWAVEHDR) lParam)->dwBytesRecorded ;
       
        if (bEnding)
        {
                waveInClose (hWaveIn) ;
                return ;
        }       
        // Send out a new buffer
       
        waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;
        TRACE("done input data\n");
        return ;       
}
void CRecordHWndDlg::OnPlayStart()
{
       
        // TODO: Add your control notification handler code here
        if (bPlaying) {
                waveOutReset(hWaveOut);
        }

        //open waveform audio for output
        waveform.wFormatTag                =        WAVE_FORMAT_PCM;
        waveform.nChannels                =        1;
        waveform.nSamplesPerSec        =11025;
        waveform.nAvgBytesPerSec=11025;
        waveform.nBlockAlign        =1;
        waveform.wBitsPerSample        =8;
        waveform.cbSize                        =0;
       
       
        if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {
                MessageBeep(MB_ICONEXCLAMATION);
                AfxMessageBox("Audio output erro");
        }       
        return ;       
}
void CRecordHWndDlg::OnMM_WOM_OPEN(UINT wParam, LONG lParam){
        TRACE("open MM_WOM_OPEN\n");
        // Set up header
       
        pWaveHdr1->lpData          = waveBufferRecord[k];//(LPTSTR)pSaveBuffer ;
        pWaveHdr1->dwBufferLength  = INP_BUFFER_SIZE;//dwDataLength ;
        pWaveHdr1->dwBytesRecorded = 0 ;
        pWaveHdr1->dwUser          = 0 ;
        pWaveHdr1->dwFlags         = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
        pWaveHdr1->dwLoops         = dwRepetitions ;
        pWaveHdr1->lpNext          = NULL ;
        pWaveHdr1->reserved        = 0 ;
       
        // Prepare and write
       
        waveOutPrepareHeader (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
        waveOutWrite (hWaveOut, pWaveHdr1, sizeof (WAVEHDR)) ;
}

最新回复

mark  详情 回复 发表于 2010-1-12 22:34
点赞 关注

回复
举报

79

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
没人说一下吗,自己顶一下
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
PC上的DIRECTX下有没对应的例子程序?你找找看看,看能不能对你有帮助!
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

4
 
谢谢楼上的,我现在能录和播放,但不是同时进行,我要的效果是录完延迟40ms后自动播放,现在的问题就是不懂得怎么操作缓冲区,这事情很急啊,这两天要搞定,希望各位大哥帮忙!有demo或者源码更好,可多给分,谢谢!
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

5
 
怎么没人说一下,希望各位给看看
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

6
 
也想知道怎么回事。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

7
 
100分,谁给个可用的边录边播放的程度,邮箱xyj8303@yahoo.com.cn,收到给分,谢谢
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

8
 
怎么没人给说一下,难道这里不是讨论VC++的?
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

9
 
引用 7 楼 xyj0663 的回复:
怎么没人给说一下,难道这里不是讨论VC++的?


是啊,这个不是讨论这个的,并且,今天很少人进来这里,估计工作忙。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

10
 
那去哪讨论?其实我以前也是做底层的,现在有项目才做应用,才有那么多的问题啊
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

11
 
可能是你的声音驱动不支持全双工。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

12
 
还有这回事,你的意思是声卡本身不支持是不是?单独录和放都没问题
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 11 楼 xyj0663 的回复:
还有这回事,你的意思是声卡本身不支持是不是?单独录和放都没问题


也许声卡支持,但驱动没有做
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

14
 
给你发几个例子吧
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

15
 
谢谢楼上的
声卡这个应该是支持全双工的,应该不是这个问题,感觉很可能是进程的问题,是否应该开两个进程?我现在是先录,但一点播放就死掉了,还有MM_WOM_OPEN这个是在什么时候触发的,我调用waveOutOpen后怎么感觉有时不会进到这里来
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

16
 
看看HDA AC97规范,感觉一般的驱动程序不支持双向流同时进行,需要对其进行设置。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

17
 
我是在PC上写的程序,声卡驱动应该支持的
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

18
 
楼主,估计你得看一下驱动先,看支不支持全双工
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

19
 
加一些通信机制进行限制呢?在录线程跟播放线程间加一些通信协调的机制看看。比如用关键区,事件什么的来协调两个线程间的工作!
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

20
 
我觉得主要是线程之间要同步!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表