录音时,显示即时播形图,求助

nowordwind 2006-11-06 09:44:22
我想在录音的时候,同时显示出对应的波形数据,我用的是waveinstart系列函数,但是最终生成的wave文件中,并没有声音,用千千静听播放时,全是杂音,而且千千静听显示的波形很怪。我用的是如下方法生成wave文件头的。
procedure TRecorder.WriteHead;
var
fmtSize: Integer;
fileSize: DWORD;

wf : file of TWavHeader;
wh : TWavHeader;
begin
wh.rId := $46464952;
wh.rLen := 36 + m_SumData;
wh.wId := $45564157;
wh.fId := $20746d66;
wh.fLen := 16;
wh.wFormatTag := 1;
wh.nChannels := m_WaveFormat.nChannels;
wh.nSamplesPerSec := m_WaveFormat.nSamplesPerSec;
wh.nAvgBytesPerSec := m_WaveFormat.nAvgBytesPerSec;
wh.nBlockAlign := m_WaveFormat.nBlockAlign;
wh.wBitsPerSample := m_WaveFormat.wBitsPerSample;
wh.dId := $61746164;
wh.wSampleLength := m_SumData;

FileStream.Write(wh, SizeOf(wh));
end;

其他代码即如下:




constructor TRecorder.Create(wBitsPerSample, wChannels: Word;
dwSampleRate: Cardinal; nBufferLength: Integer);
var
i: Integer;
begin
m_bRecording := FALSE;
m_bDeviceOpen := FALSE;
m_PcmFormat.wBitsPerSample := wBitsPerSample;
m_PcmFormat.wChannels := wChannels;
m_PcmFormat.dwSampleRate := dwSampleRate;
m_dwBufferSize := (nBufferLength * (m_PcmFormat.wChannels) * (m_PcmFormat.wBitsPerSample) div 8);
fnProcessBuffer := nil;
m_lpWaveHdr := nil;
m_SumData := 0;
m_hEvent := 0;
m_hThread := 0;
for i:= 0 to MAXNUMOFBUFFER - 1 do
begin
m_hWaveInHdr[i] := 0;
m_hInBuffer[i] := 0;
end;
end;

constructor TRecorder.Create(nBufferLength: Integer);
var
i: Integer;
begin
m_bRecording := False;
m_bDeviceOpen := False;
m_PcmFormat.wBitsPerSample := 16;
m_PcmFormat.wChannels := 2;
m_PcmFormat.dwSampleRate := 11025;
m_dwBufferSize := (nBufferLength * m_PcmFormat.wChannels * m_PcmFormat.wBitsPerSample div 8);
fnProcessBuffer := nil;
m_lpWaveHdr := nil;

m_hEvent := 0;
m_hThread := 0;
for i:= 0 to MAXNUMOFBUFFER - 1 do
begin
m_hWaveInHdr[i] := 0;
m_hInBuffer[i] := 0;
end;
end;

constructor TRecorder.Create(pcm: TPCMFormat; nBufferLength: Integer);
var
i: Integer;
begin
m_bRecording := FALSE;
m_bDeviceOpen := FALSE;
m_PcmFormat.wBitsPerSample := pcm.wBitsPerSample;
m_PcmFormat.wChannels := pcm.wChannels;
m_PcmFormat.dwSampleRate := pcm.dwSampleRate;
m_dwBufferSize := (nBufferLength * m_PcmFormat.wChannels * m_PcmFormat.wBitsPerSample div 8);
fnProcessBuffer := nil;
m_lpWaveHdr := nil;

m_hEvent := 0;
m_hThread := 0;
for i:= 0 to MAXNUMOFBUFFER - 1 do
begin
m_hWaveInHdr[i] := 0;
m_hInBuffer[i] := 0;
end;

end;


function TRecorder.GetPosition: Int64;
var
mmtime: TMMTime;
begin
if m_hWaveIn <> 0 then
begin
mmtime.wType := TIME_SAMPLES;
if waveInGetPosition(m_hWaveIn, @mmTime, SizeOf(mmTime)) <> MMSYSERR_NOERROR then
Result := -1
else
Result := mmTime.sample;
end;
Result := -1;
end;

function TRecorder.IsDeviceOpen: Boolean;
begin
Result := m_bDeviceOpen;
end;

function TRecorder.IsFormatSupported(wfEX: tWAVEFORMATEX;
nDev: Cardinal): Boolean;
var
mm: MMRESULT;
begin
mm := waveInOpen(nil, nDev, @wfEx, 0, 0, WAVE_FORMAT_QUERY);
if mm = MMSYSERR_NOERROR then
Result := True
else
Result := False;
end;

function TRecorder.IsRecording: Boolean;
begin
Result := m_bRecording;
end;

procedure TRecorder.Open(dwCallBack, dwCallbackType: Cardinal;
wMCIDeviceID: MCIDEVICEID);
var
i: Integer;
begin
if not m_bDeviceOpen then
begin
if dwCallBack = 0 then
dwCallBack := DWord(@waveinProc);

for i:= 0 to MAXNUMOFBUFFER - 1 do
begin
m_hWaveInHdr[i] := GlobalAlloc(GHND or GMEM_SHARE, SizeOf(TWaveHdr));
m_lpWaveInHdr[i] := pWaveHdr(GlobalLock(m_hWaveInHdr[i]));
m_hInBuffer[i] := GlobalAlloc(GHND or GMEM_SHARE , m_dwBufferSize);
m_lpInBuffer[i] := PBYTE(GlobalLock(m_hInBuffer[i]));
m_lpWaveInHdr[i]^.lpData := PChar(m_lpInBuffer[i]);
m_lpWaveInHdr[i]^.dwBufferLength := m_dwBufferSize;
m_lpWaveInHdr[i]^.dwBytesRecorded := 0;
m_lpWaveInHdr[i]^.dwUser := Cardinal(Pointer(Self));
m_lpWaveInHdr[i]^.dwFlags := 0;
m_lpWaveInHdr[i]^.dwLoops := 1;
m_lpWaveInHdr[i]^.lpNext := nil;
m_lpWaveInHdr[i]^.reserved := 0;
end;

m_WaveFormat.wFormatTag := WAVE_FORMAT_PCM;
m_WaveFormat.nChannels := m_PcmFormat.wChannels;
m_WaveFormat.wBitsPerSample := m_PcmFormat.wBitsPerSample;
m_WaveFormat.nSamplesPerSec := m_PcmFormat.dwSampleRate;
m_WaveFormat.nBlockAlign := m_WaveFormat.nChannels * m_WaveFormat.wBitsPerSample div 8;
m_WaveFormat.nAvgBytesPerSec := m_WaveFormat.nBlockAlign * m_WaveFormat.nSamplesPerSec;
m_waveClass.lpData := Self;

if not ((waveInOpen(PHWAVEIN(@m_waveClass), wMCIDeviceID, PWaveFormatEx(@m_WaveFormat),
dwCallBack, 0, dwCallbackType) <> 0) or
(m_waveClass.hWave = 0)
) then
begin
m_waveClass.lpData := Self;
m_hWaveIn := HWAVEIN(m_waveClass.hWave);
m_hEvent := CreateEvent(nil, False, False, nil);
m_bDeviceOpen := True;
end;
end;
end;

function TRecorder.Pause: Boolean;
begin
Result := False;
if m_hWaveIn <> 0 then
begin
if waveInStop(m_hWaveIn) = MMSYSERR_NOERROR then
begin
m_bRecording := False;
Result := True;
end;
end;
end;

procedure TRecorder.ProcessNextBuffer(pwh: PWaveHdr);
begin
if @fnProcessBuffer <> nil then
fnProcessBuffer(m_lpData,pwh);
m_SumData := m_SumData + 2048 -1;
waveInUnprepareHeader(m_hWaveIn, pwh, sizeof(WAVEHDR));
waveInPrepareHeader (m_hWaveIn, pwh, sizeof(WAVEHDR));
waveInAddBuffer(m_hWaveIn, pwh, sizeof(WAVEHDR));
end;

procedure TRecorder.SetBufferFunction(lpData: Pointer;
fnProcess: ProcessBuffer);
begin
m_lpData := lpData;
fnProcessBuffer := fnProcess;
end;

procedure TRecorder.SetFormat(lpPcmFormat: pPCMFormat);
begin
if m_bDeviceOpen = False then
begin
m_PcmFormat.wBitsPerSample := lpPcmFormat^.wBitsPerSample;
m_PcmFormat.wChannels := lpPcmFormat^.wChannels;
m_PcmFormat.dwSampleRate := lpPcmFormat^.dwSampleRate;
end;
end;

procedure TRecorder.SetFormat(wBitsPerSample, wChannels: Word;
dwSampleRate: Cardinal);
begin
if m_bDeviceOpen = False then
begin
m_PcmFormat.wBitsPerSample := wBitsPerSample;
m_PcmFormat.wChannels := wChannels;
m_PcmFormat.dwSampleRate := dwSampleRate;
end;
end;

procedure TRecorder.Start;
var
i: Integer;
ThreadId: DWORD;
begin
if not m_bDeviceOpen then
Exit
else
begin
for i:= 0 to MAXNUMOFBUFFER - 1 do
begin
if waveInPrepareHeader(m_hWaveIn, m_lpWaveInHdr[i], SizeOf(TWaveHdr)) <> MMSYSERR_NOERROR then
Exit;
if waveInAddBuffer(m_hWaveIn, m_lpWaveInHdr[i], SizeOf(TWaveHdr)) <> MMSYSERR_NOERROR then
Exit;
end;
FileStream := TFileStream.Create('c:\wave.wav', fmCreate or fmOpenReadWrite );
WriteHead;
//begin sampling
m_bRecording := True;
m_hThread := CreateThread(nil, 0, @RecorderThreadFunc, Self, 0, ThreadId);
waveInStart(m_hWaveIn);
if m_hThread <> 0 then
begin
SetPriorityClass(m_hThread, REALTIME_PRIORITY_CLASS);
SetThreadPriority(m_hThread, THREAD_PRIORITY_HIGHEST);
end;
end;
end;

procedure TRecorder.Stop;
begin
if (m_bDeviceOpen = False) or (m_bRecording = False) then
Exit;
if (waveInStop(m_hWaveIn)) <> MMSYSERR_NOERROR then
Exit
else
m_bRecording := False;
end;




求高手与熟手指点下啊。如果哪位有代码请帮下俺啊。在线等,很急。
...全文
256 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
billwillman 2006-11-16
  • 打赏
  • 举报
回复
直接使用DirectX,对应数据话矩形,就可以搞定
nowordwind 2006-11-15
  • 打赏
  • 举报
回复
数据已实现出来了,请问哪位老大有显示波形图的函数啊。急啊
ly_liuyang 2006-11-06
  • 打赏
  • 举报
回复
用Wave Audio组件的TAudioRecorder(开源的)
就都不用自己写代码,呵呵~
  • 打赏
  • 举报
回复
好像没多少人有这么多工夫来检查这么多的代码。自己调试吧。哪出的问题,针对它查资料。
nowordwind 2006-11-06
  • 打赏
  • 举报
回复
剩下的代码:
procedure TRecorder.Close;
var
i: Integer;
begin
FileStream.Position := 0; //重定位
WriteHead;
if m_bRecording then
Stop;
if m_hThread <> 0 then
CloseHandle(m_hThread);
if m_bDeviceOpen then
waveInClose(m_hWaveIn);

for i:= 0 to MAXNUMOFBUFFER-1 do
begin
if (m_hWaveInHdr[i] <> 0 ) then
begin
if GlobalUnlock(m_hWaveInHdr[i]) then
GlobalFree(m_hWaveInHdr[i]);
if GlobalUnlock(m_hInBuffer[i]) then
GlobalFree(m_hInBuffer[i]);
m_hWaveInHdr[i] := 0;
m_hInBuffer[i] := 0;
end;
end;

m_bDeviceOpen := False;
m_bRecording := False;
m_hThread := 0;
end;

function TRecorder.Continue: Boolean;
begin
Result := False;
if m_hWaveIn <> 0 then
begin
if waveInStart(m_hWaveIn) = MMSYSERR_NOERROR then
begin
m_bRecording := False;
Result := True;
end;
end;
end;
nowordwind 2006-11-06
  • 打赏
  • 举报
回复
这个组件可以实现吗????
机场内通系统的设计方案 1. 内通系统技术规格与要求 1.1系统概述 1) 这个机场内通系统按照功能划分应分为以下子系统,内部调度指挥系统,内话系统和旅 客求助系统。 2) 内部调度指挥系统主要提供提供机场客货运营各生产保障单位内部通话联络、相互通讯 、指挥调度等用途。系统充分保证生产运营一线内部调度信息联络顺畅、通讯迅捷、调 度有序,从而提高工作效率,提高机场服务水平。 3) 内话系统主要提供航站楼相关业务柜台、柜台与各航空公司现场办公室、机场营运部门 之间的联络功能。 4) 旅客求助系统既在机场的各个公共场所设置求助终端和在机场设立一个旅客求助呼叫中 心,每个需要帮助的旅客可在任意一个求助终端处得到呼叫中心统一高质量的语音服务 。 5) 内通系统主要由内通服务器或主机、用户操作终端机(包括:数字台式广播终端机、数 字台式普通用户终端机、数字壁挂式用户终端机和噪音消除终端等)及其各种专用通讯 接口和相关软硬件设备组成。本期终端容量按xxx门配置。单个系统终极容量不小于500 0门,可多系统无限扩容。 1.2 系统总体技术和功能要求 1) 应采用国内外先进的成熟的符合航站楼工作特点和国际标准及中国国家相关标准的系统 。内通设备需采用最新技术生产的全数字程控交换机,通话迅速敏捷,话音清晰不失真 ,运行稳定可靠。具有适合不同环境多种系列化通信终端,充分保证生产运营一线相互 联络和指挥调度的需要。 2) 内通系统建立一套独立的内部调度通讯交换网,星型结构,供航站楼内各业务部门之间 指挥调度、相互通讯及其他用途(如本地广播)使用。 3) *系统应采用适合机场应用的专业内通系统,不能使用基于程控交换机的电话系统。 4) *系统应采用全数字内通设备,即设备所有控制和音频信号都要是数字化传输和处理。 5) *内通系统具有高通话质量,整个系统的音频带宽不小于7KHz,所有终端设备在免提状态 下应具有开放式全双工通话功能。 6) *系统具有故障监测能力,对于系统的所有部件或装置都能够进行自动诊断监测,发现故 障、报警、及登记并可以提供打印报告(配备PC、打印机)。对于公共功能部件,故 障定位到板卡和功能模块;对于外围接口部件,故障定位到端口。 7) *终端/话站应具有麦克风- 扬声器音频检测功能,即话站扬声器定会发出一个音频检测信号, 该信号应为带数字编码的音频,话站麦克风会拾取到该信号并解码,以随保证话站各 部件工作正常。 8) *终端和主机以及主机和主机之间除了用双绞线联网以外,还可以使用通用的计算机网络 来连接。重要的设备之间应可采用冗余的连接方式。 9) *通过计算机网络传送的语音信号应采用专用编码如IoIP协议,不能采用公开的编码协议 如VoIP等以防止窃听和篡改。 10) *系统具有灵活的通讯方式,具有多方会议、全呼和组呼及其应答、呼叫转移、呼叫代答 、遇忙回叫、遇忙在线等待、遇忙强插与强拆、调度终端不示忙、自动呼叫分配(ACD) 、主操作呼叫队列和多路话音等特殊功能,以实现电话会议、发布命令、广播通知、寻 呼找人、紧急呼叫等特殊服务。并可通过编程设置,其操作简便,话音清晰。 11) 具有多路实录音功能,对各重要业务部门的通话,实录音记录,以便随重放通讯 实况。可靠性高,复原度高、保密性好、不可删改,查询方便。 12) *具有多种不同接口功能,可以同其他通讯电子设备兼容。接口方式应具有干接点,RS2 32/422和TCP/IP三种方式; 13) 系统总的性能要求:技术先进、可靠性高、高话务量、高忙呼叫处理能力、设备平均 无故障间长、通讯快捷、音质好、模块化、接口种类多、功能齐全、便于维护。 1.3内部通讯系统接口要求 1.3.1内通系统与集成系统的接口功能 1)通过内部调度通讯系统与集成系统的接口,内部调度通讯系统接口工作站实将其前 端用户终端机的发来的登机广播和最后登机广播以及开闸、关闸等控制信息,传递给集 成系统中央数据库后,发布到广播系统和航显系统,自动触发登机广播和登机显示通知 。 2)组成与结构 l 接口种类 发布信息接口可支持TCP/IP协议等 l 服务器方 集成系统服务器及AODB l 客户机方 内部通讯系统接口工作站及接口软件 1.3.2内通系统与钟系统的接口功能 内通主机应能支持SNTP钟同步协议,通过TCP/IP方式与机场钟系统取得间同步。 1.3.3内通系统与现有交换机及电话虚拟公网系统的接口 内通系统通过用户环路或中继接口建立与现有交换机及电话虚拟公用通信网接口xx个, 作为内通用户与现有交换机及电话虚拟公网用户的备用手段,根据编程设定,不同权限 的用户可以拨打内话、本地、国内长途或国际长途电话。 1.3.4 内通系统与录音系统的接口 通过内部通讯系统与录音系统的接口,可以在内通用户

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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