请教关于实时录音/放音的问题

gandw 2001-05-06 07:51:00
我现在用VC和RTP协议做个IP电话的软件,就是一台电脑通过话筒录音,另一台收到声音数据之后播放.前几天在网上弄到个录音的源程序,是边录音边把数据写到wave文件,然后播放wave文件,用的是MCI.但我对这方面不熟悉,请教一下高手这样做可以实时传输数据吗?我想要做到实时当然最好是用流文件,但另一台电脑收到数据之后怎么以WAVE格式播放这些数据我不是太清楚,请各位指教一下我该怎么做,或者哪儿有这方面的书或源代码?
...全文
215 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
niki 2001-05-16
  • 打赏
  • 举报
回复
没有源代码,用的是IIS的codec.
blueboy_2000 2001-05-16
  • 打赏
  • 举报
回复
to niki,
有没有mp3的编码程序?
gandw 2001-05-15
  • 打赏
  • 举报
回复
to niki,
你的回信我已经收到了,你能不能给我具体讲讲每个函数的用途?万分感谢。
niki 2001-05-15
  • 打赏
  • 举报
回复
应该对各种格式都行吧。
试过gsm,g.723,lernout & hauspie, mp3, truespeech, a_law, u_law,..
niki 2001-05-15
  • 打赏
  • 举报
回复
check your mailbox.
gandw 2001-05-15
  • 打赏
  • 举报
回复
to niki,
你的信我已经收到,不过我想要的是CWaveIn和CWaveOut的说明文档,因为里面的几个函数我看不大懂。所以得麻烦你再mail一次,谢谢了.
gandw 2001-05-15
  • 打赏
  • 举报
回复
to niki,
你的信我已经收到,不过我想要的是CWaveIn和CWaveOut的说明文档,因为里面的几个函数我看不大懂。所以得麻烦你再mail一次,谢谢了.
niki 2001-05-15
  • 打赏
  • 举报
回复
please check your mailbox.
niki 2001-05-14
  • 打赏
  • 举报
回复
http://www.csdn.net/expert/topic/120/120134.shtm中我已经告诉了你mailbox。

thanks.
gandw 2001-05-14
  • 打赏
  • 举报
回复
to michaelh
我去看了看,上面好像没有介绍什么东西啊。
gandw 2001-05-14
  • 打赏
  • 举报
回复
To blueboy_2000:
能不能把你的整个project的源代码给我看看(gandw@263.net)?我看你好像用的不是MFC,你的程序只有函数,偶水平有限,看不出整个程序是怎么调用的,呵呵,谢了.我现在毕业设计做这个,然后在这儿卡住了,月底就要交差,急啊.
blueboy_2000 2001-05-14
  • 打赏
  • 举报
回复
to:gandw, 有兴趣的话可以看看下面的代码,不是用MCI
to:niki, 你们用的是什么压缩算法啊

头文件

#ifndef WAVE_PLAY_H
#define WAVE_PLAY_H

#include <mmsystem.h>

#define BUFF_LEN (20000)
#define NUM_CATCH 2

void WaveOutInitFormat(
WORD nCh, // number of channels (mono, stereo)
DWORD nSampleRate, // sample rate
WORD BitsPerSample);

BOOL OpenOutput();
BOOL PlayFile(const char * pPlayBuff);
BOOL PlayMemo(char * pPlayBuff, DWORD len);
BOOL WaveOutRestart(void);
BOOL WaveOutPause(void);
BOOL WaveOutClose(void);



void WaveInInitFormat(
WORD nCh, // number of channels (mono, stereo)
DWORD nSampleRate, // sample rate
WORD BitsPerSample);
BOOL OpenMic();
BOOL AddBuffer(char * pBuff, int len);
BOOL WaveInClose(void);

BOOL OpenAux();
BOOL CloseAux();

#endif


cpp文件

#include "stdafx.h"
#include "wave.h"

WAVEOUTCAPS g_WaveOutDevCaps;
HWAVEOUT g_WaveOut = 0;
WAVEHDR g_WaveOutHeader;
WAVEFORMATEX g_WaveOutFormat;
HANDLE g_WaveOutEvent = NULL;


WAVEINCAPS g_WaveInDevCaps;
HWAVEIN g_WaveIn = 0;
WAVEHDR g_WaveInHeader;
WAVEFORMATEX g_WaveInFormat;
HANDLE g_WaveInEvent = NULL;
char g_waveinBuff[2][BUFF_LEN];
bool g_bSelect = 0;
bool g_bIsClose = FALSE;

extern int SendTo(const char * ipstr, unsigned short port,
const char * buf, int len);
extern HWND g_hEdit;

///////////////////////////////////////////////////////////////////
//wavout+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

BOOL OpenOutput()
{
MMRESULT result;

if(g_WaveOut)
return 0;

result=waveOutGetNumDevs();
if (result == 0)
{
return 0;
}

// test for Mic available
result=waveOutGetDevCaps(0, &g_WaveOutDevCaps,
sizeof(WAVEOUTCAPS));
if ( result!= MMSYSERR_NOERROR)
{
return 0;
}

// init format
WaveOutInitFormat(1/* mono*/,8000 /* khz */,16 /* bits */);

// Open Output
result = waveOutOpen(&g_WaveOut, 0,
&g_WaveOutFormat, (DWORD)g_WaveOutEvent,
NULL ,CALLBACK_EVENT );
if (result != MMSYSERR_NOERROR)
{
return 0;
}

return 1;
}

BOOL PlayMemo(char * pPlayBuff, DWORD len)
{
MMRESULT result;

if(!g_WaveOut)
return 0;

result = waveOutReset(g_WaveOut);
if(result != MMSYSERR_NOERROR)
return 0;

waveOutUnprepareHeader(g_WaveOut, &g_WaveOutHeader,
sizeof(WAVEHDR) );
// prepare header

g_WaveOutHeader.lpData = pPlayBuff;
g_WaveOutHeader.dwBufferLength = len;
g_WaveOutHeader.dwFlags = 0;

result = waveOutPrepareHeader( g_WaveOut, &g_WaveOutHeader,
sizeof(WAVEHDR) );
if ( (result!= MMSYSERR_NOERROR) ||
( g_WaveOutHeader.dwFlags != WHDR_PREPARED) )
{
return 0;
}

result = waveOutWrite( g_WaveOut, &g_WaveOutHeader,
sizeof(WAVEHDR) );
if (result!= MMSYSERR_NOERROR)
{
return 0;
}

return 1;
}

void WaveOutInitFormat(WORD nCh, //number of channels (mono, stereo)
DWORD nSampleRate, // sample rate
WORD BitsPerSample)
{
g_WaveOutFormat.wFormatTag = WAVE_FORMAT_PCM;
g_WaveOutFormat.nChannels = nCh;
g_WaveOutFormat.nSamplesPerSec = nSampleRate;
g_WaveOutFormat.nAvgBytesPerSec = nSampleRate * nCh *
BitsPerSample/8;
g_WaveOutFormat.nBlockAlign = g_WaveOutFormat.nChannels *
BitsPerSample/8;
g_WaveOutFormat.wBitsPerSample = BitsPerSample;
g_WaveOutFormat.cbSize = 0;
}

BOOL WaveOutRestart(void)
{
MMRESULT result = waveOutRestart(g_WaveOut);
if(result != MMSYSERR_NOERROR)
return 0;
else
return 1;
}

BOOL WaveOutPause(void)
{
MMRESULT result = waveOutPause(g_WaveOut);
if(result != MMSYSERR_NOERROR)
return 0;
else
return 1;
}

BOOL WaveOutClose(void)
{
MMRESULT result = waveOutReset(g_WaveOut);
if(result != MMSYSERR_NOERROR)
return 0;

result = waveOutClose(g_WaveOut);
if(result != MMSYSERR_NOERROR)
{
return 0;
}

g_WaveOut = 0;
return 1;
}
//wavout----------------------------------------------------------

///////////////////////////////////////////////////////////////////
//wavin++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

DWORD WINAPI WaveInProc(LPVOID lpParameter)
{
UINT result;
MMTIME mmtime;
char str[30];

g_bIsClose = FALSE;
while(!g_bIsClose)
{
result = WaitForSingleObject(g_WaveInEvent,INFINITE);
if(result == WAIT_OBJECT_0)
{
mmtime.wType = TIME_BYTES;
waveInGetPosition(g_WaveIn, &mmtime, sizeof(MMTIME));
if(mmtime.wType == TIME_BYTES &&
mmtime.u.cb >= BUFF_LEN-2)
{

GetWindowText(g_hEdit, str, 20);
SendTo(str, 2000,
g_waveinBuff[g_bSelect], BUFF_LEN);
g_bSelect = !g_bSelect;
AddBuffer(g_waveinBuff[g_bSelect], BUFF_LEN);
}
}
else
return 0; //
}
CloseHandle (g_WaveInEvent);
return 1;
}

BOOL OpenMic()
{
MMRESULT result;
DWORD thrid;

if(g_WaveIn)
return 0;

g_WaveInEvent = CreateEvent(NULL, FALSE, FALSE,
"WaveInThreadEvent");
if(!g_WaveInEvent)
return 0;

if(!::CreateThread(NULL, 0, WaveInProc,
g_WaveInEvent, 0, &thrid))
return 0;

result=waveInGetNumDevs();
if (result == 0)
return 0;

// test for Mic available
result=waveInGetDevCaps (0, &g_WaveInDevCaps,
sizeof(WAVEINCAPS));
if ( result!= MMSYSERR_NOERROR)
{
return 0;
}

// init format
WaveInInitFormat(1/* mono*/,8000 /* khz */,16 /* bits */);


// Open Input
result = waveInOpen(&g_WaveIn, 0, &g_WaveInFormat,
(DWORD)g_WaveInEvent, NULL, CALLBACK_EVENT);
if ( result!= MMSYSERR_NOERROR)
{
return 0;
}

return 1;
}

void WaveInInitFormat(WORD nCh, // number of channels (mono, stereo)
DWORD nSampleRate, // sample rate
WORD BitsPerSample)
{
g_WaveInFormat.wFormatTag = WAVE_FORMAT_PCM;
g_WaveInFormat.nChannels = nCh;
g_WaveInFormat.nSamplesPerSec = nSampleRate;
g_WaveInFormat.nAvgBytesPerSec = nSampleRate * nCh *
BitsPerSample/8;
g_WaveInFormat.nBlockAlign = g_WaveInFormat.nChannels *
BitsPerSample/8;
g_WaveInFormat.wBitsPerSample = BitsPerSample;
g_WaveInFormat.cbSize = 0;
}

BOOL AddBuffer(char * pBuff, int len)
{
MMRESULT result;

if(!g_WaveIn)
return 0;

if(waveInStop(g_WaveIn) != MMSYSERR_NOERROR)
return 0;

if(waveInReset(g_WaveIn) != MMSYSERR_NOERROR)
return 0;

waveInUnprepareHeader(g_WaveIn, &g_WaveInHeader, sizeof(WAVEHDR));

// prepare header
g_WaveInHeader.lpData = pBuff;
g_WaveInHeader.dwBufferLength = len;
g_WaveInHeader.dwFlags = 0;

result = waveInPrepareHeader(g_WaveIn, &g_WaveInHeader,
sizeof(WAVEHDR));
if ((result!= MMSYSERR_NOERROR) ||
(g_WaveInHeader.dwFlags != WHDR_PREPARED))
{
return 0;
}

result = waveInAddBuffer( g_WaveIn, &g_WaveInHeader,
sizeof(WAVEHDR) );
if (result!= MMSYSERR_NOERROR)
{
return 0;
}

// all is correct now we can start the process
result = waveInStart( g_WaveIn );
if (result!= MMSYSERR_NOERROR)
{
return 0;
}

return 1;
}

BOOL WaveInClose(void)
{
if(!g_WaveIn)
return 0;

g_bIsClose = FALSE;
SetEvent(g_WaveInEvent);

if(waveInStop(g_WaveIn) != MMSYSERR_NOERROR)
return 0;

if(waveInReset(g_WaveIn) != MMSYSERR_NOERROR)
return 0;

if(waveInClose(g_WaveIn) != MMSYSERR_NOERROR)
return 0;

Sleep(12);
g_WaveIn = 0;

return 1;
}

//wavin-----------------------------------------------------------


BOOL OpenAux()
{
if(!OpenOutput())
return FALSE;

if(!OpenMic())
return FALSE;

return TRUE;
}

BOOL CloseAux()
{
if(!WaveOutClose())
return 0;

if(!WaveInClose())
return 0;

return 1;
}
michaelh 2001-05-11
  • 打赏
  • 举报
回复
www.speakfreely.org
gandw 2001-05-09
  • 打赏
  • 举报
回复
To runbuff,
能不能给我具体讲一讲啊,我也很想这么做,因为为了保证实时,所以的数据都用的是UDP打包。但我在多媒体方面实在是不太清楚,无处下手。或者能不能给我点源码?万分感谢。
gandw 2001-05-09
  • 打赏
  • 举报
回复
niki,能不能把你的源码给我看看?(gandw@263.net)以前没有专门做过多媒体的东东,又找不到好书,看别人的源程序看的好累,RTP我有协议和源码(用C++写的),如果你的信箱足够大的话,告诉我你的信箱,我把资料发给你。我现在基本上没做什么东西,只做了RTP和RTCP的打包和接收,其他很多功能都还有待实现.
runbuff 2001-05-08
  • 打赏
  • 举报
回复
用WAVEY文件作中介,肯定实时性能不好。直接获取、传送、回放声卡数据不好么?
niki 2001-05-08
  • 打赏
  • 举报
回复
我们是用下面的方法实现的。(如果网络够快的话,不压缩也行喔)

waveform audio rec ----> compression ----> network
---->decompression ----> waveform audio play

另外,想知道你的rtp是如何实现的,性能如何,也许可以互换一下代码!
微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。微信小程序系统教程共有“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]——核心技术”、“微信小程序系统教程[阶段]客服消息+微信支付+九宝电商系统”。“微信小程序系统教程[阶段]全套课程”包含:1.微信小程序系统教程[阶段]_客服消息2.微信小程序系统教程[阶段]_微信支付3.微信小程序系统教程[阶段]_九宝电商系统学习“微信小程序系统教程[阶段]”要求有微信小程序的基础。建议先学习“微信小程序系统教程[初级阶段]”、“微信小程序系统教程[中级阶段]”,后在报名“微信小程序系统教程[阶段]”。阶段讲解的客服消息,是针对小程序的。后台程序用接近底层的技术,没有使用三方技术。这样降低同学们学习成本。微信支付,这部分课程很有难度,要求同学们认真听讲,有不会的技术问题可以请教老师。购买课程后请联系老师,提供单号,给你源程序。九宝电商系统是一套十分适和学习、项目的课程。既可以系统的学习微信小程序相关知识,还可以修改后上线。“微信小程序系统教程[中级阶段]——核心技术”重点讲解微信小程序事件、组件、API微信小程序系统教程[初级阶段],微信小程序0基础学起,讲解微信小程序开发的基础知识。购买课程的同学,可赠送就九宝老师编写的《微信小程序开发宝典》。购课请咨询qq2326321088

8,305

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧