如何通过声卡和麦克风录音我想通过声卡和麦克风录音,把系统mp3播放出来的声音和我用麦克录的声音采集到一起,谢谢

解决方案 »

  1.   

    http://dev.yesky.com/246/2032246.shtml
      

  2.   

    下载一个COOLEDIT,挺简单的录音软件,一看就会
      

  3.   

    在开始工作之前,要先介绍DirectSound录音用到的三个非常重要的对象:  ·IDirectSoundCapture8 ,设备对象,根据你录音的设备创建的设备对象,利用该对象可以获取设备的属性。   ·IDirectSoundCaptureBuffer8,缓冲区对象,该对象由设备对象创建,主要用来操作音频数据  ·IDirectSoundNotify8 ,事件通知对象,该对象用来通知应用程序从缓冲区中将数据取走,写入文件保存起来。  利用DirectSound录音的主要思路,就是先根据选择的录音设备创建设备对象,然后通过设备对象创建辅助缓冲区对象,开始录音的时候,设备将数据写入缓冲区,应用程序主动的从缓冲区将数据读出来写文件即可,就实现了录音功能。这里简单介绍一下dsound的通知功能,应用程序会创建一个通知对象,然后将通知对象邦定,然后设定通知位置(position),什么是通知位置呢,比如缓冲区的大小为4000字节,如果你想当数据达到缓冲区一半的时候能得到通知开始copy数据,那么此时你就可以将通知位置设定为2000,通知位置可以任意的设定,当缓冲区的数据达到你设定的位置时,就会通知应用程序将缓冲区的数据copy到文件中,缓冲区是循环利用的,当缓冲区填充满了以后,就会从头开始充填数据,所以,缓冲区就是一边读,一边写的过程。  下面我讲一下录音的主要步骤,可以使大家的思路更清晰一些  1、枚举录音的设备  2、根据选择的设备创建设备对象  3、利用设备对象创建缓冲区对象  4、设置通知机制  5、创建工作线程,用来将缓冲区的数据写入文件。
      

  4.   

    可采用DirectX开发包,或者用Windows自带的MCI或wavForm都可以实现。
    Help->Widows SDK里头有这方面说明。
      

  5.   

    来源自 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;