如何通过声卡和麦克风录音 如何通过声卡和麦克风录音我想通过声卡和麦克风录音,把系统mp3播放出来的声音和我用麦克录的声音采集到一起,谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://dev.yesky.com/246/2032246.shtml 下载一个COOLEDIT,挺简单的录音软件,一看就会 在开始工作之前,要先介绍DirectSound录音用到的三个非常重要的对象: ·IDirectSoundCapture8 ,设备对象,根据你录音的设备创建的设备对象,利用该对象可以获取设备的属性。 ·IDirectSoundCaptureBuffer8,缓冲区对象,该对象由设备对象创建,主要用来操作音频数据 ·IDirectSoundNotify8 ,事件通知对象,该对象用来通知应用程序从缓冲区中将数据取走,写入文件保存起来。 利用DirectSound录音的主要思路,就是先根据选择的录音设备创建设备对象,然后通过设备对象创建辅助缓冲区对象,开始录音的时候,设备将数据写入缓冲区,应用程序主动的从缓冲区将数据读出来写文件即可,就实现了录音功能。这里简单介绍一下dsound的通知功能,应用程序会创建一个通知对象,然后将通知对象邦定,然后设定通知位置(position),什么是通知位置呢,比如缓冲区的大小为4000字节,如果你想当数据达到缓冲区一半的时候能得到通知开始copy数据,那么此时你就可以将通知位置设定为2000,通知位置可以任意的设定,当缓冲区的数据达到你设定的位置时,就会通知应用程序将缓冲区的数据copy到文件中,缓冲区是循环利用的,当缓冲区填充满了以后,就会从头开始充填数据,所以,缓冲区就是一边读,一边写的过程。 下面我讲一下录音的主要步骤,可以使大家的思路更清晰一些 1、枚举录音的设备 2、根据选择的设备创建设备对象 3、利用设备对象创建缓冲区对象 4、设置通知机制 5、创建工作线程,用来将缓冲区的数据写入文件。 可采用DirectX开发包,或者用Windows自带的MCI或wavForm都可以实现。Help->Widows SDK里头有这方面说明。 来源自 Delphi 猛料:// 全局变量 var BufferFinished : boolean; // indicates current record buffer is full . UserStopRecord: boolean; Recording: boolean; WaveInHandle: HWaveIn; CurrentUsingBuffer: integer; WaveInHeader1: TWaveHdr; WaveInHeader2: TWaveHdr; RecordBufferSize: integer; TotalRecordedSize: DWORD; //进行录音 procedure TDlgRecord.BtnStartClick(Sender: TObject); var TempInt, TempCode: integer; TempFileName: string; MMR: MMResult; MyWaveFormat: TWaveFormatEx; begin PrgsBarSpace.Position := 0; Recording := false; OldDiskFree := DiskFree (RecordDrive); with RecordWaveFormat do begin if RdoBtnMono.Checked = true then Channels := 1 else Channels := 2; if RdoBtn8Bit.Checked = true then BitsPerSample := 8 else BitsPerSample := 16; Val (EditFrequency.Text, TempInt, TempCode); if TempCode <> 0 then begin Application.MessageBox ('无效数值', '错误', MB_Ok); exit; end else if TempInt > 48000 then begin Application.MessageBox('不能大于48000赫兹', '错误', MB_Ok); exit; end else begin SamplesPerSecond := TempInt; end; BytesPerSecond := SamplesPerSecond * Channels * BitsPerSample div 8; BlockAlign := BitsPerSample * Channels div 8 ; end; TempFileName := TempFileNameGenerator (Self.TempPath, 'WM_', 'TMP', 5); AssignFile (RecordFile, TempFileName); Rewrite (RecordFile, 1); if IOResult <> 0 then begin Application.Messagebox ('无法创建暂时文件,请检查临时目录设定。', '严重错误', MB_OK); exit; end; RecordFileName := TempFileName; RecordSuccess := false; // 由于文件名已经改变,所以在这里修改该变量。 // Preparation jobs here SttTextElapsedTime.Caption := '00:00:00'; ElapsedHours := 0; ElapsedMinutes := 0; ElapsedSeconds := 0; CurrentUsingBuffer := 1; TotalRecordedSize := 0; BufferFinished := false; UserStopRecord := false; RecordBufferSize := RecordWaveFormat.BytesPerSecond * 2; // for 2 se conds Buffer1 := nil; Buffer2 := nil; try GetMem (Buffer1, RecordBufferSize); except Application.MessageBox ('内存不足,分配第一缓冲区失败。', '错误', MB_OK); end; try GetMem (Buffer2, RecordBufferSize); except Application.MessageBox ('内存不足,分配第二缓冲区失败。', '错误', MB_OK); end; if (Buffer1 = nil) or (Buffer2 = nil) then begin CloseFile (RecordFile); exit; end; MyWaveFormat.wFormatTag := WAVE_FORMAT_PCM; MyWaveFormat.nChannels := RecordWaveFormat.Channels; MyWaveFormat.nSamplesPerSec := RecordWaveFormat.SamplesPerSecond; MyWaveFormat.nAvgBytesPerSec := RecordWaveFormat.BytesPerSecond; MyWaveFormat.nBlockAlign := RecordWaveFormat.BlockAlign; MyWaveFormat.wBitsPerSample := RecordWaveFormat.BitsPerSample; MyWaveFormat.cbSize := 0; MMR := waveInOpen (Addr (waveInHandle), SelectedDevice, Addr (MyWaveFormat), DWORD (Addr (WaveInCallBack)), 0, CALLBACK_FUNCTION); if MMR <> MMSYSERR_NOERROR then begin FreeMem (Buffer1); FreeMem (Buffer2); RecordBufferSize := 0; CloseFile (RecordFile); Application.MessageBox ('无法打开输入设备,请检查设定。', '错误', MB_OK); exit; end; waveInHeader1.lpData := Buffer1; waveInHeader1.dwBufferLength := RecordBufferSize; waveInHeader1.dwBytesRecorded := 0; waveInHeader1.dwUser := 0; // 32 bits of user data waveInHeader1.dwFlags := 0; waveInHeader1.dwLoops := 0; waveInHeader1.lpNext := nil; // reserved; must be zero waveInHeader1.reserved := 0; // reserved; must be zero MMR := waveInPrepareHeader (waveInHandle, Addr (waveInHeader1), sizeof (waveInHeader1)); if MMR <> MMSYSERR_NOERROR then begin FreeMem (Buffer1); FreeMem (Buffer2); RecordBufferSize := 0; CloseFile (RecordFile); Application.MessageBox ('第一录音缓冲区准备出错。', '错误', MB_OK) ; exit; end; waveInHeader2.lpData := Buffer2; waveInHeader2.dwBufferLength := RecordBufferSize; waveInHeader2.dwBytesRecorded := 0; waveInHeader2.dwUser := 0; // 32 bits of user data waveInHeader2.dwFlags := 0; waveInHeader2.dwLoops := 0; waveInHeader2.lpNext := nil; // reserved; must be zero waveInHeader2.reserved := 0; // reserved; must be zero MMR := waveInPrepareHeader (waveInHandle, Addr (waveInHeader2), sizeof (waveInHeader2)); if MMR <> MMSYSERR_NOERROR then begin waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof( waveInHeader1)); FreeMem (Buffer1); FreeMem (Buffer2); RecordBufferSize := 0; CloseFile (RecordFile); Application.MessageBox ('第二录音缓冲区准备出错。', '错误', MB_OK) ; exit; end; MMR := waveInAddBuffer (WaveInHandle, Addr (waveInHeader1), sizeof ( waveInHeader1)); if MMR <> MMSYSERR_NOERROR then begin waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof( waveInHeader1)); waveInUnprepareHeader (waveInHandle, Addr (waveInHeader2), sizeof( waveInHeader2)); FreeMem (Buffer1); FreeMem (Buffer2); RecordBufferSize := 0; CloseFile (RecordFile); Application.MessageBox ('添加第一缓冲区出错。', '错误', MB_OK); exit; end; MMR := waveInAddBuffer (WaveInHandle, Addr (waveInHeader2), sizeof ( waveInHeader2)); if MMR <> MMSYSERR_NOERROR then begin waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof( waveInHeader1)); waveInUnprepareHeader (waveInHandle, Addr (waveInHeader2), sizeof( waveInHeader2)); FreeMem (Buffer1); FreeMem (Buffer2); RecordBufferSize := 0; CloseFile (RecordFile); Application.MessageBox ('添加第二缓冲区出错。', '错误', MB_OK); exit; end; TimerRecording.Enabled := true; // Record has begun. Recording := true; MMR := waveInStart (waveInHandle); if MMR <> MMSYSERR_NOERROR then begin waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof( waveInHeader1)); waveInUnprepareHeader (waveInHandle, Addr (waveInHeader2), sizeof( waveInHeader2)); FreeMem (Buffer1); FreeMem (Buffer2); RecordBufferSize := 0; CloseFile (RecordFile); Recording := false; TimerRecording.Enabled := false; Application.MessageBox ('未能开始录音。', '错误', MB_OK); exit; end; // 应该在这里开始创建线程. // 需要传递参数: RecordFile, Buffer1, Buffer2, with TMediaRecordThread.Create (Addr(RecordFile), Buffer1, Buffer2) do OnTerminate := ThreadRecordStop; // disable/enable controls BtnCancel.Enabled := false; BtnStart.Enabled := false; GrpBoxChannel.Enabled := false; LBFrequency.Enabled := false; EditFrequency.Enabled := false; LstBoxFrequency.Enabled := false; GrpBoxSample.Enabled := false; BtnStop.Enabled := true; end; 变量内存分配的问题? 请问如何通过语句更改SQL账号登录方式? 大家来讨论一下pascal的几种字符串的 数据结构 Delphi第一款真正的原生DirectUI 界面库 各位前辈,在生成的EXE 图标(icon)时,怎样更改设成自己想要的logo? D7中怎样才能做到不打包就可以在没安装delphi的机器上运行delphi的.exe文件 关于数据拷贝问题。 就是隐藏不了qq的登陆窗口,有哪位高手请赐教,在下感激不进 Delphi 中如何取得打印机名及端口? 怎么样求某一字段前部分相同的最大值??? 软件的同步自动升级问题 delphi 怎么连接EDB格式的数据库,怎么访问数据库数据?
Help->Widows SDK里头有这方面说明。
var
BufferFinished : boolean; // indicates current record buffer is full
.
UserStopRecord: boolean;
Recording: boolean; WaveInHandle: HWaveIn; CurrentUsingBuffer: integer;
WaveInHeader1: TWaveHdr;
WaveInHeader2: TWaveHdr; RecordBufferSize: integer;
TotalRecordedSize: DWORD;
//进行录音
procedure TDlgRecord.BtnStartClick(Sender: TObject);
var
TempInt, TempCode: integer;
TempFileName: string; MMR: MMResult;
MyWaveFormat: TWaveFormatEx; begin
PrgsBarSpace.Position := 0;
Recording := false;
OldDiskFree := DiskFree (RecordDrive);
with RecordWaveFormat do
begin
if RdoBtnMono.Checked = true then
Channels := 1
else
Channels := 2;
if RdoBtn8Bit.Checked = true then
BitsPerSample := 8
else
BitsPerSample := 16;
Val (EditFrequency.Text, TempInt, TempCode);
if TempCode <> 0 then
begin
Application.MessageBox ('无效数值', '错误', MB_Ok);
exit;
end
else if TempInt > 48000 then
begin
Application.MessageBox('不能大于48000赫兹', '错误', MB_Ok);
exit;
end
else
begin
SamplesPerSecond := TempInt;
end;
BytesPerSecond := SamplesPerSecond * Channels * BitsPerSample div
8;
BlockAlign := BitsPerSample * Channels div 8 ;
end; TempFileName := TempFileNameGenerator (Self.TempPath, 'WM_', 'TMP',
5); AssignFile (RecordFile, TempFileName);
Rewrite (RecordFile, 1);
if IOResult <> 0 then
begin
Application.Messagebox ('无法创建暂时文件,请检查临时目录设定。',
'严重错误', MB_OK);
exit;
end; RecordFileName := TempFileName;
RecordSuccess := false; // 由于文件名已经改变,所以在这里修改该变量。
// Preparation jobs here
SttTextElapsedTime.Caption := '00:00:00';
ElapsedHours := 0;
ElapsedMinutes := 0;
ElapsedSeconds := 0;
CurrentUsingBuffer := 1;
TotalRecordedSize := 0;
BufferFinished := false;
UserStopRecord := false;
RecordBufferSize := RecordWaveFormat.BytesPerSecond * 2; // for 2 se
conds
Buffer1 := nil;
Buffer2 := nil; try
GetMem (Buffer1, RecordBufferSize);
except
Application.MessageBox ('内存不足,分配第一缓冲区失败。', '错误',
MB_OK);
end; try
GetMem (Buffer2, RecordBufferSize);
except
Application.MessageBox ('内存不足,分配第二缓冲区失败。', '错误',
MB_OK);
end; if (Buffer1 = nil) or (Buffer2 = nil) then
begin
CloseFile (RecordFile);
exit;
end; MyWaveFormat.wFormatTag := WAVE_FORMAT_PCM;
MyWaveFormat.nChannels := RecordWaveFormat.Channels;
MyWaveFormat.nSamplesPerSec := RecordWaveFormat.SamplesPerSecond;
MyWaveFormat.nAvgBytesPerSec := RecordWaveFormat.BytesPerSecond;
MyWaveFormat.nBlockAlign := RecordWaveFormat.BlockAlign;
MyWaveFormat.wBitsPerSample := RecordWaveFormat.BitsPerSample;
MyWaveFormat.cbSize := 0; MMR := waveInOpen (Addr (waveInHandle),
SelectedDevice,
Addr (MyWaveFormat),
DWORD (Addr (WaveInCallBack)),
0,
CALLBACK_FUNCTION);
if MMR <> MMSYSERR_NOERROR then
begin
FreeMem (Buffer1); FreeMem (Buffer2);
RecordBufferSize := 0;
CloseFile (RecordFile);
Application.MessageBox ('无法打开输入设备,请检查设定。', '错误',
MB_OK);
exit;
end; waveInHeader1.lpData := Buffer1;
waveInHeader1.dwBufferLength := RecordBufferSize;
waveInHeader1.dwBytesRecorded := 0;
waveInHeader1.dwUser := 0; // 32 bits of user data
waveInHeader1.dwFlags := 0;
waveInHeader1.dwLoops := 0;
waveInHeader1.lpNext := nil; // reserved; must be zero
waveInHeader1.reserved := 0; // reserved; must be zero
MMR := waveInPrepareHeader (waveInHandle, Addr (waveInHeader1),
sizeof (waveInHeader1));
if MMR <> MMSYSERR_NOERROR then
begin
FreeMem (Buffer1); FreeMem (Buffer2);
RecordBufferSize := 0;
CloseFile (RecordFile);
Application.MessageBox ('第一录音缓冲区准备出错。', '错误', MB_OK)
;
exit;
end; waveInHeader2.lpData := Buffer2;
waveInHeader2.dwBufferLength := RecordBufferSize;
waveInHeader2.dwBytesRecorded := 0;
waveInHeader2.dwUser := 0; // 32 bits of user data
waveInHeader2.dwFlags := 0;
waveInHeader2.dwLoops := 0;
waveInHeader2.lpNext := nil; // reserved; must be zero
waveInHeader2.reserved := 0; // reserved; must be zero MMR := waveInPrepareHeader (waveInHandle, Addr (waveInHeader2),
sizeof (waveInHeader2));
if MMR <> MMSYSERR_NOERROR then
begin
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof(
waveInHeader1));
FreeMem (Buffer1); FreeMem (Buffer2);
RecordBufferSize := 0;
CloseFile (RecordFile);
Application.MessageBox ('第二录音缓冲区准备出错。', '错误', MB_OK)
;
exit;
end; MMR := waveInAddBuffer (WaveInHandle, Addr (waveInHeader1), sizeof (
waveInHeader1));
if MMR <> MMSYSERR_NOERROR then
begin
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof(
waveInHeader1));
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader2), sizeof(
waveInHeader2));
FreeMem (Buffer1); FreeMem (Buffer2);
RecordBufferSize := 0;
CloseFile (RecordFile);
Application.MessageBox ('添加第一缓冲区出错。', '错误', MB_OK);
exit;
end; MMR := waveInAddBuffer (WaveInHandle, Addr (waveInHeader2), sizeof (
waveInHeader2));
if MMR <> MMSYSERR_NOERROR then
begin
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof(
waveInHeader1));
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader2), sizeof(
waveInHeader2));
FreeMem (Buffer1); FreeMem (Buffer2);
RecordBufferSize := 0;
CloseFile (RecordFile);
Application.MessageBox ('添加第二缓冲区出错。', '错误', MB_OK);
exit;
end;
TimerRecording.Enabled := true;
// Record has begun.
Recording := true; MMR := waveInStart (waveInHandle);
if MMR <> MMSYSERR_NOERROR then
begin
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader1), sizeof(
waveInHeader1));
waveInUnprepareHeader (waveInHandle, Addr (waveInHeader2), sizeof(
waveInHeader2));
FreeMem (Buffer1); FreeMem (Buffer2);
RecordBufferSize := 0;
CloseFile (RecordFile);
Recording := false;
TimerRecording.Enabled := false;
Application.MessageBox ('未能开始录音。', '错误', MB_OK);
exit;
end; // 应该在这里开始创建线程.
// 需要传递参数: RecordFile, Buffer1, Buffer2,
with TMediaRecordThread.Create (Addr(RecordFile), Buffer1, Buffer2)
do
OnTerminate := ThreadRecordStop; // disable/enable controls
BtnCancel.Enabled := false;
BtnStart.Enabled := false;
GrpBoxChannel.Enabled := false;
LBFrequency.Enabled := false;
EditFrequency.Enabled := false;
LstBoxFrequency.Enabled := false;
GrpBoxSample.Enabled := false; BtnStop.Enabled := true; end;