日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC++ 保存数据为音频文件(WAV)学习

發布時間:2025/4/14 c/c++ 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++ 保存数据为音频文件(WAV)学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? 根據到目前我的認識,凡是保存為某種格式的文件的程序,都是用C++做的。下面來學習一下保存為wav文件;

1. 音頻簡介

經常見到這樣的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等.
44100HZ 16bit stereo: 每秒鐘有 44100 次采樣, 采樣數據用 16 位(2字節)記錄, 雙聲道(立體聲);
22050HZ 8bit ?mono: 每秒鐘有 22050 次采樣, 采樣數據用 8 位(1字節)記錄, 單聲道;

采樣率是指:聲音信號在“模→數”轉換過程中單位時間內采樣的次數。采樣值是指每一次采樣周期內聲音模擬信號的積分值。

對于單聲道聲音文件,采樣數據為八位的短整數(short int 00H-FFH);

而對于雙聲道立體聲聲音文件,每次采樣數據為一個16位的整數(int),高八位(左聲道)和低八位(右聲道)分別代表兩個聲道。

人對頻率的識別范圍是 20HZ - 20000HZ, 如果每秒鐘能對聲音做 20000 個采樣, 回放時就足可以滿足人耳的需求. 所以 22050 的采樣頻率是常用的, 44100已是CD音質, 超過48000的采樣對人耳已經沒有意義。這和電影的每秒 24 幀圖片的道理差不多。

2 wav 文件格式

WAV文件遵循RIFF規則,其內容以區塊(chunk)為最小單位進行存儲。
WAV文件一般由3個區塊組成:RIFF chunk、Format chunk和Data chunk。另外,文件中還可能包含一些可選的區塊,如:Fact chunk、Cue points chunk、Playlist chunk、Associated data list chunk等。

3 VC++保存數據為音頻文件

首先要定義波形數據格式,

typedef struct{WORD ?wFormatTag;?
?? ? ?WORD nChannels;?
?? ? ?DWORD nSamplesPerSec;?
?? ? ?DWORD nAvgBytesPerSec;
?? ? ?WORD ?nBlockAlign;?
?? ? ?WORD wBitsPerSample;?
?? ? ?WORD ?cbSize; } WAVEFORMATEX;

wFormatTag:波形數據的格式,定義在MMREG.H文件中
nChannels:波形數據的通道數:單聲道或立體聲
nSamplesPerSec:采樣率,對于PCM格式的波形數據,采樣率有8.0 kHz,11.025kHz,22.05 kHz,44.1 kHz等
nAvgBytesPerSec:數據率,對于PCM格式的波形數據,數據率等于采樣率乘以每樣點字節數
nBlockAlign:每個樣點字節數
wBitsPerSample:采樣精度,對于PCM格式的波形數據,采樣精度為8或16
cbSize:附加格式信息的數據塊大小

然后要定義設備頭結構
WAVEHDR定義了指向波形數據緩沖區的設備頭。

typedef struct { LPSTR lpData;?
?? ?DWORD dwBufferLength;?
?? ?DWORD dwBytesRecorded;?
?? ?DWORD dwUser;?
?? ?DWORD dwFlags;?
?? ?DWORD dwLoops;?
?? ?struct wavehdr_tag * lpNext;?
?? ?DWORD reserved; } WAVEHDR;?

lpData:波形數據的緩沖區地址
dwBufferLength:波形數據的緩沖區地址的長度
dwBytesRecorded:當設備用于錄音時,標志已經錄入的數據長度
dwUser:用戶數據
dwFlags:波形數據的緩沖區的屬性
dwLoops:播放循環的次數,僅用于播放控制中
lpNext和reserved均為保留值

定義這些結構體是為了保存數據用的;

基本保存代碼如下;
CFile m_file;
CFileException fileException;
CString m_csFileName= "F:\\audio.wav";//保存路徑
m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException);
DWORD m_WaveHeaderSize = 38;
DWORD m_WaveFormatSize = 18;
m_file.SeekToBegin();
m_file.Write("RIFF",4);
unsigned int Sec=(sizeof pSaveBuffer + m_WaveHeaderSize);
m_file.Write(&Sec,sizeof(Sec));
m_file.Write("WAVE",4);
m_file.Write("fmt ",4);
m_file.Write(&m_WaveFormatSize,sizeof(m_WaveFormatSize));
m_file.Write(&waveform.wFormatTag,sizeof(waveform.wFormatTag));
m_file.Write(&waveform.nChannels,sizeof(waveform.nChannels));
m_file.Write(&waveform.nSamplesPerSec,sizeof(waveform.nSamplesPerSec));
m_file.Write(&waveform.nAvgBytesPerSec,sizeof(waveform.nAvgBytesPerSec));
m_file.Write(&waveform.nBlockAlign,sizeof(waveform.nBlockAlign));
m_file.Write(&waveform.wBitsPerSample,sizeof(waveform.wBitsPerSample));
m_file.Write(&waveform.cbSize,sizeof(waveform.cbSize));
m_file.Write("data",4);
m_file.Write(&dwDataLength,sizeof(dwDataLength));
m_file.Write(pSaveBuffer,dwDataLength);
m_file.Seek(dwDataLength,CFile::begin);
m_file.Close();

總結

以上是生活随笔為你收集整理的VC++ 保存数据为音频文件(WAV)学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。