錄音時,顯示即時播形圖,求助

來源:互聯網
上載者:User
錄音時,顯示即時播形圖,求助 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiMultimedia/html/delphi_20061106094422173.html
我想在錄音的時候,同時顯示出對應的波形資料,我用的是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;  
   
   
   
   
  求高手與熟手指點下啊。如果哪位有代碼請幫下俺啊。線上等,很急。  
 

剩下的代碼:  
  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;

好像沒多少人有這麼多工夫來檢查這麼多的代碼。自己調試吧。哪出的問題,針對它查資料。

用Wave   Audio組件的TAudioRecorder(開源的)  
  就都不用自己寫代碼,呵呵~

這個組件可以實現嗎????  
 

資料已實現出來了,請問哪位老大有顯示波形圖的函數啊。急啊

直接使用DirectX,對應資料話矩形,就可以搞定

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.