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

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;




求高手与熟手指点下啊。如果哪位有代码请帮下俺啊。在线等,很急。
...全文
327 6 打赏 收藏 举报
写回复
用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
  • 打赏
  • 举报
回复
这个组件可以实现吗????
内容概要:本文针对基于输入并联输出串联(IPOS)结构的双三相LLC谐振变换器,系统研究其在宽增益工况下的谐振参数优化方法与启动过程中冲击电流的抑制策略。通过Simulink平台构建系统仿真模型,结合变频控制与电压电流双闭环调控策略,深入分析变换器在全范围软开关条件下的工作边界、模式切换动态响应及多模式运行稳定性。研究提出优化谐振腔参数设计以扩展电压增益范围,并引入降频软启动、星形耦合自均流等机制有效抑制上电瞬间的电流冲击,提升系统启动可靠性与运行效率。同时探讨了变频调压、多模式切换控制及交错并联带来的均流优势,为高增益、大功率密度DC-DC变换器的设计提供了完整的建模、控制与优化解决方案; 适合人群:具备电力电子与电力系统基础知识,从事新能源变换器、高频开关电源、电动汽车充电系统、航空航天电源等相关领域研究的研究生、科研人员及工程技术人员; 使用场景及目标:①为高电压增益、高效率、高功率密度DC-DC变换器的谐振参数设计与控制策略制定提供理论依据与仿真验证手段;②指导LLC谐振变换器在新能源并网、车载充电机、直流微网等应用场景中的工程实现与性能优化;③支撑高水平学术论文(如IEEE期刊)的复现、科研项目关键技术攻关及系统级仿真平台搭建; 阅读建议:建议结合Simulink仿真实例,细致理解谐振参数设计准则、软开关实现条件、冲击电流形成机理及其抑制方法的有效性验证过程,重点关注模式切换过程中的动态响应特性与闭环控制参数整定规律,宜配合相关文献进行对比分析以深化对系统稳定性和控制策略优越性的认知。

1,184

社区成员

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

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