導航:首頁 > 文件教程 > c怎麼判讀讀取的文件格式是否是wav

c怎麼判讀讀取的文件格式是否是wav

發布時間:2025-08-14 12:45:49

㈠ 誰做過這種.wav文件的讀取程序vc++或者matlab,c

function [y,Fs,bits,opt_ck] = wavread(file,ext)
nargchk(1,2,nargin);
if nargin<2, ext=[]; end % Default - read all samples
exts = numel(ext); % length of extent info
if ~strncmpi(ext,'size',exts) && (exts > 2),
error('Index range must be specified as a scalar or 2-element vector.');
end
if ~ischar(ext) && exts==1,
if ext==0,
ext='size'; % synonym for size
else
ext=[1 ext]; % Prepend start sample index
end
end

[fid,msg] = open_wav(file);
error(msg);

try

[riffck,msg] = find_cktype(fid,'RIFF');

if ~isempty(msg),
error('Not a WAVE file.');
end

msg = check_rifftype(fid,'WAVE');
error(msg);

end_of_file = 0;
opt_ck = [];

while(~end_of_file),
[ck,msg] = find_cktype(fid);
error(msg);

switch lower(ck.ID)

case 'end of file'
end_of_file = 1;

case 'fmt'
% <fmt-ck> found
[opt_ck,msg] = read_wavefmt(fid,ck,opt_ck);
error(msg);

case 'data'
% <data-ck> found:
if ~isfield(opt_ck,'fmt'),
error('Corrupt WAV file: found audio data before format information.');
end

if strncmpi(ext,'size',exts) || ...
(~isempty(ext) && all(ext==0)),
% Caller doesn't want data - just data size:
[samples,msg] = read_wavedat(ck, opt_ck.fmt, -1);
error(msg);
y = [samples opt_ck.fmt.nChannels];

else
% Read <wave-data>:
[datack,msg] = read_wavedat(ck, opt_ck.fmt, ext);
error(msg);
y = datack.Data;

end

case 'fact'
% Optional <fact-ck> found:
[opt_ck,msg] = read_factck(fid, ck, opt_ck);
error(msg);

case 'disp'
% Optional <disp-ck> found:
[opt_ck,msg] = read_dispck(fid, ck, opt_ck);
error(msg);

case 'list'
% Optional <list-ck> found:
[opt_ck, msg] = read_listck(fid, ck, opt_ck);
error(msg);

otherwise
% Skip over data in unprocessed chunks:
if rem(ck.Size,2), ck.Size=ck.Size+1; end
if(fseek(fid,ck.Size,0)==-1),
error('Incorrect chunk size information in WAV file.');
end
end
end

catch
fclose(fid);
error(lasterr);
end

fclose(fid);

% Parse structure info for return to user:
Fs = opt_ck.fmt.nSamplesPerSec;
if opt_ck.fmt.wFormatTag == 1 || opt_ck.fmt.wFormatTag == 3,
% Type 3 floating point has no nBitsPerSample field, so use
% nBlockAlign to figure out number of bits
bits = (opt_ck.fmt.nBlockAlign / opt_ck.fmt.nChannels) * 8;
else
bits = []; % Unknown
end

% end of wavread()

% ------------------------------------------------------------------------
% Local functions:
% ------------------------------------------------------------------------

% ---------------------------------------------
% OPEN_WAV: Open a WAV file for reading
% ---------------------------------------------
function [fid,msg] = open_wav(file)
% Append .wav extension if it's missing:
[pat,nam,ext] = fileparts(file);
if isempty(ext),
file = [file '.wav'];
end
[fid,msg] = fopen(file,'rb','l'); % Little-endian
if fid == -1,
msg = 'Cannot open file.';
end
return

% ---------------------------------------------
% READ_CKINFO: Reads next RIFF chunk, but not the chunk data.
% If optional sflg is set to nonzero, reads SUBchunk info instead.
% Expects an open FID pointing to first byte of chunk header.
% Returns a new chunk structure.
% ---------------------------------------------
function [ck,msg] = read_ckinfo(fid)

msg = '';
ck.fid = fid;
ck.Data = [];
err_msg = 'Truncated chunk header found - possibly not a WAV file.';

[s,cnt] = fread(fid,4,'char');

% Do not error-out if a few (<4) trailing chars are in file
% Just return quickly:
if (cnt~=4),
if feof(fid),
% End of the file (not an error)
ck.ID = 'end of file'; % unambiguous chunk ID (>4 chars)
ck.Size = 0;
else
msg = err_msg;
end
return
end

ck.ID = deblank(char(s'));

% Read chunk size (skip if subchunk):
[sz,cnt] = fread(fid,1,'uint32');
if cnt~=1,
msg = err_msg;
return
end
ck.Size = sz;
return

% ---------------------------------------------
% FIND_CKTYPE: Finds a chunk with appropriate type.
% Searches from current file position specified by fid.
% Leaves file positions to data of desired chunk.
% If optional sflg is set to nonzero, finds a SUBchunk instead.
% ---------------------------------------------
function [ck,msg] = find_cktype(fid,ftype)

msg = '';
if nargin<2, ftype = ''; end

[ck,msg] = read_ckinfo(fid);
if ~isempty(msg), return; end

% Was a required chunk type specified?
if ~isempty(ftype) & ~strcmpi(ck.ID,ftype),
msg = ['<' ftype '-ck> did not appear as expected'];
end
return

% ---------------------------------------------
% CHECK_RIFFTYPE: Finds the RIFF data type.
% Searches from current file position specified by fid.
% Leaves file positions to data of desired chunk.
% ---------------------------------------------
function msg = check_rifftype(fid,ftype)
msg = '';
[rifftype,cnt] = fread(fid,4,'char');
rifftype = char(rifftype)';

if cnt~=4,
msg = 'Not a WAVE file.';
elseif ~strcmpi(rifftype,ftype),
msg = ['File does not contain required ''' ftype ''' data chunk.'];
end

return

% ---------------------------------------------
% READ_LISTCK: Read the FLIST chunk:
% ---------------------------------------------
function [opt_ck,msg] = read_listck(fid,ck, orig_opt_ck)

opt_ck = orig_opt_ck;

orig_pos = ftell(fid);
total_bytes = ck.Size; % # bytes in subchunk
nbytes = 4; % # of required bytes in <list-ck> header
msg = '';
err_msg = 'Error reading <list-ck> chunk.';

if total_bytes < nbytes,
msg = err_msg;
return
end

% Read standard <list-ck> data:
listdata = char(fread(fid,total_bytes,'uchar')');

listtype = lower(listdata(1:4)); % Get LIST type
listdata = listdata(5:end); % Move past INFO

if strcmp(listtype,'info'),
% Information:
while(~isempty(listdata)),
id = listdata(1:4);
switch lower(id)
case 'iart'
name = 'Artist';
case 'icmt'
name = 'Comments';
case 'icrd'
name = 'Creation date';
case 'icop'
name = ['Copy' 'right'];
case 'ieng'
name = 'Engineer';
case 'inam'
name = 'Name';
case 'iprd'
name = 'Proct';
case 'isbj'
name = 'Subject';
case 'isft'
name = 'Software';
case 'isrc'
name = 'Source';
otherwise
name = id;
end

if ~isfield(opt_ck,'info'),
opt_ck.info = [];
end
len = listdata(5:8) * 2.^[0 8 16 24]';
txt = listdata(9:9+len-1);

% Fix up text: deblank, and replace CR/LR with LF
txt = deblank(txt);
idx=findstr(txt,char([13 10]));
txt(idx) = '';

% Store - don't include the "name" info
opt_ck.info.(lower(id)) = txt;

if rem(len,2), len=len+1; end
listdata = listdata(9+len:end);
end

else
if ~isfield(opt_ck,'list'),
opt_ck.list = [];
end
opt_ck.list.(listtype) = listdata;
end

% Skip over any unprocessed data:
if rem(total_bytes,2), total_bytes=total_bytes+1; end
rbytes = total_bytes - (ftell(fid) - orig_pos);
if rbytes~=0,
if (fseek(fid,rbytes,'cof')==-1),
msg = err_msg;
end
end
return

% ---------------------------------------------
% READ_DISPCK: Read the DISP chunk:
% ---------------------------------------------
function [opt_ck, msg] = read_dispck(fid,ck,orig_opt_ck)

opt_ck = orig_opt_ck;

orig_pos = ftell(fid);
total_bytes = ck.Size; % # bytes in subchunk
nbytes = 4; % # of required bytes in <disp-ck> header
msg = '';
err_msg = 'Error reading <disp-ck> chunk.';

if total_bytes < nbytes,
msg = err_msg;
return
end

% Read standard <disp-ck> data:
data = fread(fid,total_bytes,'uchar');

% Process data:

% First few entries are size info:
icon_data = data;
siz_info = reshape(icon_data(1:2*4),4,2)';
siz_info = siz_info*(2.^[0 8 16 24]');
is_icon = isequal(siz_info,[8;40]);

if ~is_icon,
% Not the icon:
opt_ck.disp.name = 'DisplayName';
txt = deblank(char(data(5:end)'));
opt_ck.disp.text = txt;
end

% Skip over any unprocessed data:
if rem(total_bytes,2), total_bytes=total_bytes+1; end
rbytes = total_bytes - (ftell(fid) - orig_pos);
if rbytes~=0,
if(fseek(fid,rbytes,'cof')==-1),
msg = err_msg;
end
end
return

% ---------------------------------------------
% READ_FACTCK: Read the FACT chunk:
% ---------------------------------------------
function [opt_ck,msg] = read_factck(fid,ck,orig_opt_ck)

opt_ck = orig_opt_ck;
orig_pos = ftell(fid);
total_bytes = ck.Size; % # bytes in subchunk
nbytes = 4; % # of required bytes in <fact-ck> header
msg = '';
err_msg = 'Error reading <fact-ck> chunk.';

if total_bytes < nbytes,
msg = err_msg;
return
end

% Read standard <fact-ck> data:
opt_ck.fact = char(fread(fid,total_bytes,'uchar')');

% Skip over any unprocessed data:
if rem(total_bytes,2), total_bytes=total_bytes+1; end
rbytes = total_bytes - (ftell(fid) - orig_pos);
if rbytes~=0,
if(fseek(fid,rbytes,'cof')==-1),
msg = err_msg;
end
end
return

% ---------------------------------------------
% READ_WAVEFMT: Read WAVE format chunk.
% Assumes fid points to the <wave-fmt> subchunk.
% Requires chunk structure to be passed, indicating
% the length of the chunk in case we don't recognize
% the format tag.
% ---------------------------------------------
function [opt_ck,msg] = read_wavefmt(fid,ck,orig_opt_ck)

opt_ck = orig_opt_ck;

orig_pos = ftell(fid);
total_bytes = ck.Size; % # bytes in subchunk
nbytes = 14; % # of required bytes in <wave-format> header
msg = '';
err_msg = 'Error reading <wave-fmt> chunk.';

if total_bytes < nbytes,
msg = err_msg;
return
end

% Read standard <wave-format> data:
opt_ck.fmt.wFormatTag = fread(fid,1,'uint16'); % Data encoding format
opt_ck.fmt.nChannels = fread(fid,1,'uint16'); % Number of channels
opt_ck.fmt.nSamplesPerSec = fread(fid,1,'uint32'); % Samples per second
opt_ck.fmt.nAvgBytesPerSec = fread(fid,1,'uint32'); % Avg transfer rate
opt_ck.fmt.nBlockAlign = fread(fid,1,'uint16'); % Block alignment

% Read format-specific info:
switch opt_ck.fmt.wFormatTag
case 1
% PCM Format:
[opt_ck.fmt, msg] = read_fmt_pcm(fid, ck, opt_ck.fmt);
end

% Skip over any unprocessed fmt-specific data:
if rem(total_bytes,2), total_bytes=total_bytes+1; end
rbytes = total_bytes - (ftell(fid) - orig_pos);
if rbytes~=0,
if(fseek(fid,rbytes,'cof')==-1),
msg = err_msg;
end
end

return

% ---------------------------------------------
% READ_FMT_PCM: Read <PCM-format-specific> info
% ---------------------------------------------
function [fmt,msg] = read_fmt_pcm(fid, ck, fmt)

% There had better be a bits/sample field:
total_bytes = ck.Size; % # bytes in subchunk
nbytes = 14; % # of bytes already read in <wave-format> header
msg = '';
err_msg = 'Error reading PCM <wave-fmt> chunk.';

if (total_bytes < nbytes+2),
msg = err_msg;
return
end

[bits,cnt] = fread(fid,1,'uint16');
nbytes=nbytes+2;
if (cnt~=1),
msg = err_msg;
return
end
fmt.nBitsPerSample=bits;

% Are there any additional fields present?
if (total_bytes > nbytes),
% See if the "cbSize" field is present. If so, grab the data:
if (total_bytes >= nbytes+2),
% we have the cbSize uint16 in the file:
[cbSize,cnt]=fread(fid,1,'uint16');
nbytes=nbytes+2;
if (cnt~=1),
msg = err_msg;
return
end
fmt.cbSize = cbSize;
end

% Simply skip any remaining stuff - we don't know what it is:
if rem(total_bytes,2), total_bytes=total_bytes+1; end
rbytes = total_bytes - nbytes;
if rbytes~=0,
if (fseek(fid,rbytes,'cof') == -1);
msg = err_msg;
end
end
end
return

% ---------------------------------------------
% READ_WAVEDAT: Read WAVE data chunk
% Assumes fid points to the wave-data chunk
% Requires <data-ck> and <wave-format> structures to be passed.
% Requires extraction range to be specified.
% Setting ext=[] forces ALL samples to be read. Otherwise,
% ext should be a 2-element vector specifying the first
% and last samples (per channel) to be extracted.
% Setting ext=-1 returns the number of samples per channel,
% skipping over the sample data.
% ---------------------------------------------
function [dat,msg] = read_wavedat(datack,wavefmt,ext)

% In case of unsupported data compression format:
dat = [];
fmt_msg = '';

switch wavefmt.wFormatTag
case 1
% PCM Format:
[dat,msg] = read_dat_pcm(datack,wavefmt,ext);
case 2
fmt_msg = 'Microsoft ADPCM';
case 3
% normalized floating-point
[dat,msg] = read_dat_pcm(datack,wavefmt,ext);
case 6
fmt_msg = 'CCITT a-law';
case 7
fmt_msg = 'CCITT mu-law';
case 17
fmt_msg = 'IMA ADPCM';
case 34
fmt_msg = 'DSP Group TrueSpeech TM';
case 49
fmt_msg = 'GSM 6.10';
case 50
fmt_msg = 'MSN Audio';
case 257
fmt_msg = 'IBM Mu-law';
case 258
fmt_msg = 'IBM A-law';
case 259
fmt_msg = 'IBM AVC Adaptive Differential';
otherwise
fmt_msg = ['Format #' num2str(wavefmt.wFormatTag)];
end
if ~isempty(fmt_msg),
msg = ['Data compression format (' fmt_msg ') is not supported.'];
end
return

% ---------------------------------------------
% READ_DAT_PCM: Read PCM format data from <wave-data> chunk.
% Assumes fid points to the wave-data chunk
% Requires <data-ck> and <wave-format> structures to be passed.
% Requires extraction range to be specified.
% Setting ext=[] forces ALL samples to be read. Otherwise,
% ext should be a 2-element vector specifying the first
% and last samples (per channel) to be extracted.
% Setting ext=-1 returns the number of samples per channel,
% skipping over the sample data.
% ---------------------------------------------
function [dat,msg] = read_dat_pcm(datack,wavefmt,ext)

dat = [];
msg = '';

% Determine # bytes/sample - format requires rounding
% to next integer number of bytes:
BytesPerSample = ceil(wavefmt.nBlockAlign / wavefmt.nChannels);
if (BytesPerSample == 1),
dtype='uchar'; % unsigned 8-bit
elseif (BytesPerSample == 2),
dtype='int16'; % signed 16-bit
elseif (BytesPerSample == 3)
dtype='bit24'; % signed 24-bit
elseif (BytesPerSample == 4),
% 32-bit 16.8 float (type 1 - 32-bit)
% 32-bit normalized floating point
dtype = 'float';
% 32-bit 24.0 float (type 1 - 24-bit)
if wavefmt.wFormatTag ~= 3 && wavefmt.nBitsPerSample == 24,
BytesPerSample = 3;
end
else
msg = 'Cannot read PCM file formats with more than 32 bits per sample.';
return
end

total_bytes = datack.Size; % # bytes in this chunk
total_samples = total_bytes / BytesPerSample;
SamplesPerChannel = total_samples / wavefmt.nChannels;
if ~isempty(ext) && isscalar(ext) && ext==-1
% Just return the samples per channel, and fseek past data:
dat = SamplesPerChannel;

% Add in a pad-byte, if required:
total_bytes = total_bytes + rem(datack.Size,2);

if(fseek(datack.fid,total_bytes,'cof')==-1),
msg = 'Error reading PCM file format.';
end

return
end

% Determine sample range to read:
if isempty(ext),
ext = [1 SamplesPerChannel]; % Return all samples
else
if numel(ext)~=2,
msg = 'Sample limit vector must have 2 elements.';
return
end
if ext(1)<1 || ext(2)>SamplesPerChannel,
msg = 'Sample limits out of range.';
return
end
if ext(1)>ext(2),
msg = 'Sample limits must be given in ascending order.';
return
end
end

bytes_remaining = total_bytes; % Preset byte counter

% Skip over leading samples:
if ext(1)>1,
% Skip over leading samples, if specified:
skipcnt = BytesPerSample * (ext(1)-1) * wavefmt.nChannels;
if(fseek(datack.fid, skipcnt,'cof') == -1),
msg = 'Error reading PCM file format.';
return
end
%
% Update count of bytes remaining:
bytes_remaining = bytes_remaining - skipcnt;
end

% Read desired data:
nSPCext = ext(2)-ext(1)+1; % # samples per channel in extraction range
dat = datack; % Copy input structure to output
% extSamples = wavefmt.nChannels*nSPCext;
dat.Data = fread(datack.fid, [wavefmt.nChannels nSPCext], dtype);
%
% Update count of bytes remaining:
skipcnt = BytesPerSample*nSPCext*wavefmt.nChannels;
bytes_remaining = bytes_remaining - skipcnt;

% if cnt~=extSamples, dat='Error reading file.'; return; end
% Skip over trailing samples:
if(fseek(datack.fid, BytesPerSample * ...
(SamplesPerChannel-ext(2))*wavefmt.nChannels, 'cof')==-1),
msg = 'Error reading PCM file format.';
return
end
% Update count of bytes remaining:
skipcnt = BytesPerSample*(SamplesPerChannel-ext(2))*wavefmt.nChannels;
bytes_remaining = bytes_remaining - skipcnt;

% Determine if a pad-byte is appended to data chunk,
% skipping over it if present:
if rem(datack.Size,2),
fseek(datack.fid, 1, 'cof');
end
% Rearrange data into a matrix with one channel per column:
dat.Data = dat.Data';
% Normalize data range: min will hit -1, max will not quite hit +1.
if BytesPerSample==1,
dat.Data = (dat.Data-128)/128; % [-1,1)
elseif BytesPerSample==2,
dat.Data = dat.Data/32768; % [-1,1)
elseif BytesPerSample==3,
dat.Data = dat.Data/(2^23); % [-1,1)
elseif BytesPerSample==4,
if wavefmt.wFormatTag ~= 3, % Type 3 32-bit is already normalized
dat.Data = dat.Data/32768; % [-1,1)
end
end

return

% end of wavread.m

㈡ 如何在C程序中調用音頻文件

一.在程序中直接播放聲音文件
在VC++ 中的多媒體動態連接庫中提供了一組與音頻設備有關的函數。利用這些函數可以方便地播放聲音。最簡單的播放聲音方法就是直接調用VC++中提供的聲音播放函數BOOL sndPlaySound ( LPCSTR lpszSound,UINT fuSound ); 或BOOL PlaySound( LPCSTR lpszSound, HMODULE hmod, DWORD fuSound );其中參數lpszSound是需要播放聲音的.W***文件的路徑和文件名, hmod在這里為NULL,fuSound是播放聲音的標志,詳細說明請參考VC++中的幫助。 例如播放C:soundmusic.wav可以用sndPlaySound ("c:\sound\music.wav",SND_ASYNC);或PlaySound("c:\sound\music.wav",NULL, SND_ASYNC|SND_NODEFAULT );如果沒有找到music.wav文件,第一種格式將播放系統默認的聲音,第二種格式不會播放系統默認的聲音。
二.將聲音文件加入到程序中
在VC++的程序設計中,可以利用各種標準的資源,如點陣圖,菜單,對話框等。同時VC++也允許用戶自定義資源,因此我們可以將聲音文件作為用戶自定義資源加入程序資源文件中,經過編譯連接生成EXE文件,實現無.W***文件的聲音播放。要實現作為資源的聲音文件的播放,首先要在資源管理器中加入待播放的聲音文件。
具體步驟入下:
1.獲得包含資源的模塊句柄:
HMODULE hmod=AfxGetResourceHandle();
2.檢索資源塊信息:
HRSRC hSndResource=FindResource(hmod,MAKEINTRESOURCE(IDR_W***E1),_T("W***E"));
3. 裝載資源數據並加鎖:
HGLOBAL hGlobalMem=LoadResource(hmod,hSndResource);
LPCTSTR lpMemSound=(LPCSTR)LockResource(hGlobalMem);
4.播放聲音文件:
sndPlaySound(lpMemSound,SND_MEMORY));
5.釋放資源句柄:
FreeResource(hGlobalMem);

㈢ 分析WAV音頻文件

音頻文件,特別是WAV格式文件,其核心由0和1的二進制數字構成。WAV文件作為微軟公司開發的一種聲音文件格式,遵循RIFF文件規范,廣泛應用於Windows平台及其應用程序。這類文件支持多種壓縮演算法與音頻格式,如MSADPCM、CCITT A LAW等。WAV文件的標准格式與CD一致,均採用44.1K的采樣頻率與16位量化數字,保證了與CD近乎相同的音質。

深入分析WAV文件結構,發現其遵循樹狀結構,每個塊由辨識碼、數據大小和數據本身組成。辨識碼通常為RIFF的ASCII碼,即52 49 46 46。隨後的四個位元組指示塊大小,餘下的數據則為文件內容。

在WAV格式中,除了文件頭部外,還包括兩個子塊:fmt和data。fmt塊用於描述文件信息,如采樣率、數據量、編碼格式和聲道數等。data塊則為真正播放聲音的數據部分。

fmt塊結構遵循RIFF模式,包含標識符「fmt」、塊大小和18個位元組的文件信息。fact子塊有時存在,用於存儲關於文件的重要信息,但並非所有標准WAV文件必備。data塊是真正包含聲音數據的區塊。

通過對比WAV文件結構,理解其組成與功能。在數據大小的計算中,注意到由於不同計算機的存儲方式差異(小端與大端),實際大小可能與預期有所不同。此外,WAVEFORMATEX結構在標准WAV文件中通常為16位元組,額外的兩個位元組可能出現在由特定軟體生成的文件中。

在C語言中,WAV文件的數據實際存儲於data子塊。根據文件的編碼格式wFormatTag,數據存儲方式各不相同。在多聲道文件中,樣本以交錯形式存儲,如8位量化時,每兩個樣本為一組,分別代表左聲道和右聲道。

具體而言,通過編程手段可從雙聲道WAV文件中提取單聲道樣本,只需每隔一個樣本選取一個值即可實現。

閱讀全文

與c怎麼判讀讀取的文件格式是否是wav相關的資料

熱點內容
網路中常用的傳輸介質 瀏覽:518
文件如何使用 瀏覽:322
同步推密碼找回 瀏覽:865
樂高怎麼才能用電腦編程序 瀏覽:65
本機qq文件為什麼找不到 瀏覽:264
安卓qq空間免升級 瀏覽:490
linux如何刪除模塊驅動程序 瀏覽:193
at89c51c程序 瀏覽:329
怎麼創建word大綱文件 瀏覽:622
裊裊朗誦文件生成器 瀏覽:626
1054件文件是多少gb 瀏覽:371
高州禁養區內能養豬多少頭的文件 瀏覽:927
win8ico文件 瀏覽:949
仁和數控怎麼編程 瀏覽:381
項目文件夾圖片 瀏覽:87
怎麼在東芝電視安裝app 瀏覽:954
plc顯示數字怎麼編程 瀏覽:439
如何辨別假網站 瀏覽:711
寬頻用別人的賬號密碼 瀏覽:556
新app如何佔有市場 瀏覽:42

友情鏈接