波形捕捉:(9)写入到WAV文件

简介: 写入到WAV文件         WAV文件为资源交换文件格式(RIFF),包括若干数量的命名块,其中包含头信息(如声音采样格式)或数据(如样本本身)。Win 32 API提供了打开关闭FIFF文件、查找块等函数。

写入到WAV文件

 

      WAV文件为资源交换文件格式(RIFF),包括若干数量的命名块,其中包含头信息(如声音采样格式)或数据(如样本本身)。Win 32 API提供了打开关闭FIFF文件、查找块等函数。这些函数的名字都以“mmio”开头。

      DirectSound API 不包括写入WAV文件的方法。但是 DXUTsound.cpp 文件实现了一个 CWaveFile 类,这个类具有以下管理捕捉文件的方法:
      ·Open 方法。打开一个文件并且写入头部块。
      ·Write 方法。将数据从缓冲区写入到数据块中并且提高写指针。
      ·Close 方法。将数据块的大小写入到头部并且关闭文件。

      写入到一个WAV文件的第一步是调用 CWaveFile::Open 方法。这样会创建一个文件并且写WAV格式块。参数为文件名,一个指向初始化后的WAVEFORMATEX 结构体的指针和 WAVEFILE_WRITE 标志。这个方法返回一个 HRESULT。

下面的代码为写入打开了一个WAV文件:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
    CWaveFile   g_pWaveFile;
    WAVEFORMATEX  wfxInput;
     
    ZeroMemory( 
&wfxInput, sizeof(wfxInput));
    wfxInput.wFormatTag 
= WAVE_FORMAT_PCM;
    wfxInput.nSamplesPerSec 
= 22050
    wfxInput.wBitsPerSample 
=  8
    wfxInput.nChannels 
= 1;
    wfxInput.nBlockAlign 
= 
        wfxInput.nChannels 
* (wfxInput.wBitsPerSample / 8);
    wfxInput.nAvgBytesPerSec 
= 
        wfxInput.nBlockAlign 
* wfxInput.nSamplesPerSec;
     
    g_pWaveFile 
= new CWaveFile;
    
if (FAILED(g_pWaveFile->Open("mywave.wav"&wfxInput,
        WAVEFILE_WRITE)))
    {
      g_pWaveFile
->Close();
    }


      应用程序现在可以开始从捕捉缓冲区复制数据到这个文件了。

      下面的示例函数将在每次读指针到达通知位置时被调用。在这个函数内,将使用如下全局变量:
      ·g_pDSBCapture 是一个指向缓冲区中的 IDirectSoundCaptureBuffer8 接口的指针。
      ·g_dwNextCaptureOffset 跟踪缓冲区中下一个将要被复制到文件的数据块的偏移量。
      ·g_dwCaptureBufferSize 表示缓冲区大小,被用在计算"环绕"。

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
    HRESULT RecordCapturedData() 
    {
      HRESULT hr;
      VOID
* pbCaptureData  = NULL;
      DWORD dwCaptureLength;
      VOID
* pbCaptureData2 = NULL;
      DWORD dwCaptureLength2;
      VOID
* pbPlayData   = NULL;
      UINT  dwDataWrote;
      DWORD dwReadPos;
      LONG lLockSize;
     
      
if (NULL == g_pDSBCapture)
          
return S_FALSE;
      
if (NULL == g_pWaveFile)
          
return S_FALSE;
     
      
if (FAILED (hr = g_pDSBCapture->GetCurrentPosition( 
        NULL, 
&dwReadPos)))
          
return hr;
     
      
// Lock everything between the private cursor 
      
// and the read cursor, allowing for wraparound.
     
      lLockSize 
= dwReadPos - g_dwNextCaptureOffset;
      
if( lLockSize < 0 ) lLockSize += g_dwCaptureBufferSize;
     
      
if( lLockSize == 0 ) return S_FALSE;
     
      
if (FAILED(hr = g_pDSBCapture->Lock( 
            g_dwNextCaptureOffset, lLockSize, 
            
&pbCaptureData, &dwCaptureLength, 
            
&pbCaptureData2, &dwCaptureLength2, 0L)))
        
return hr;
     
      
// Write the data. This is done in two steps
      
// to account for wraparound.
    
      
if (FAILED( hr = g_pWaveFile->Write( dwCaptureLength, 
          (BYTE
*)pbCaptureData, &dwDataWrote)))
        
return hr; 
     
      
if (pbCaptureData2 != NULL)
      {
        
if (FAILED(hr = g_pWaveFile->Write( 
            dwCaptureLength2, (BYTE
*)pbCaptureData2, 
            
&dwDataWrote)))
          
return hr; 
      }
     
      
// Unlock the capture buffer.
     
     g_pDSBCapture
->Unlock( pbCaptureData, dwCaptureLength, 
        pbCaptureData2, dwCaptureLength2  );
      
      
// Move the capture offset forward.
     
      g_dwNextCaptureOffset 
+= dwCaptureLength; 
      g_dwNextCaptureOffset 
%= g_dwCaptureBufferSize; 
      g_dwNextCaptureOffset 
+= dwCaptureLength2; 
      g_dwNextCaptureOffset 
%= g_dwCaptureBufferSize; 
     
      
return S_OK;
    }

When capturing 
is finished, the application closes the WAV file.

    g_pWaveFile
->Close();


查看其它:
      导 言
      1.枚举“捕捉设备”
      2.创建“捕捉设备对象”
      3.“捕捉设备”性能
      4.创建一个“捕捉缓冲区”
      5.“捕捉缓冲区”信息
      6.“捕捉缓冲区”通知
      7. “捕捉缓冲区”特效
      8.使用“捕捉缓冲区”
      9.写入到WAV文件 

 
目录
打赏
0
0
0
0
214
分享
相关文章
基于DCT和扩频的音频水印嵌入提取算法matlab仿真
本文介绍了结合DCT和扩频技术的音频水印算法,用于在不降低音质的情况下嵌入版权信息。在matlab2022a中实现,算法利用DCT进行频域处理,通过扩频增强水印的隐蔽性和抗攻击性。核心程序展示了水印的嵌入与提取过程,包括DCT变换、水印扩频及反变换步骤。该方法有效且专业,未来研究将侧重于提高实用性和安全性。
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
118 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
3月前
|
ThreeJs的音频和位置音频
这篇文章详细介绍了在Three.js中如何使用Audio和PositionalAudio来实现普通音频和位置相关的音频效果,包括音频加载、音量控制以及如何根据位置变化调整音频的播放。
43 1
|
8月前
|
基于DSP的音频信号降噪技术
基于DSP的音频信号降噪技术
329 4
通过扩频和DCT变换算法将图像水印嵌入到音频信号中并提取水印matlab仿真
通过扩频和DCT变换算法将图像水印嵌入到音频信号中并提取水印matlab仿真
228 0
通过扩频和DCT变换算法将图像水印嵌入到音频信号中并提取水印matlab仿真
m基于matlab的PCM-FM码同步和GMSK的调制和解调方法,包括多符号检测MSD和Turbo编解码
m基于matlab的PCM-FM码同步和GMSK的调制和解调方法,包括多符号检测MSD和Turbo编解码
200 0
m基于matlab的PCM-FM码同步和GMSK的调制和解调方法,包括多符号检测MSD和Turbo编解码
从视频到音频:使用VIT进行音频分类
在本文中,我们将利用ViT - Vision Transformer的是一个Pytorch实现在音频分类数据集GTZAN数据集-音乐类型分类上训练它。
290 0
从视频到音频:使用VIT进行音频分类
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等