WAV格式和FLAC都是无损吗?有什么区别 您所在的位置:网站首页 wav和flac格式哪个好 WAV格式和FLAC都是无损吗?有什么区别

WAV格式和FLAC都是无损吗?有什么区别

2023-04-23 16:28| 来源: 网络整理| 查看: 265

WAV格式和FLAC格式都是无损,常见的无损格式有ape,wav,flac三种。

WAV格式和FLAC格式区别如下:

1、解析区别。FLAC与WAV都是无损压缩,也就是说音频以FLAC编码压缩后不会丢失任何信息,将FLAC文件还原为WAV文件后,与压缩前的WAV文件内容相同。WAV 格式容量过大,因而使用起来很不方便。

2、文件大小。WAV是最接近无损的音乐格式,所以文件大小相对也比较大。大多数情况下,一个WAV音频文件经压缩后得到的APE文件,一般会比压缩为FLAC文件稍微小一些。

3、容错能力。WAV文件的容错性差,而FLAC文件因为每帧数据之间无关联。因此当FLAC文件在传播过程中受损,导致某帧数据损坏缺失的话,只会损失该帧的音频信息唤悄,不会影响到前后的数据。这是FLAC的优势,但也因此FLAC的压缩率略低。

扩展资料:

WAV 格式容量过大,因而使用起来很不方便。因此,一般情况下我们把它压缩为MP3或 WMA 格式。压缩方法有无损压缩,有损压缩,以及混成压缩。MPEG, JPEG就属于混成压缩,如果把压缩的数据还原回去,数据其实是不一样的。

如果把 MP3, OGG格式从压缩的状态还原回去的话,就会产生损失。然而, APE和FLAC格式即使还原,也能毫无损失地保留原有音质。所以, APE和FLAC可以无损失高音质地压缩和还原。在完全保持音质的前提下,APE的压缩容量有了适当的减小。

在特殊情况下,可以将FLAC文件视为一个光盘镜像,并加载到虚拟光驱上,这可以通过Nero将FLAC文和指渣件刻录到映像文件然后通过虚拟光驱加载来实现,也可以通过WinMount软件可以直接把Flac文件挂载到一个虚拟光驱。但是因为操作繁琐,所以除非在必要情逗档况下,一般我们都是通过播放软件直接播放的。

参考资料:百度百科_flac

百度百科_WAV

百度百科_无损音频

大小上:wavflacape

WAV格式文件所占容量(B) = (取样频率 X量化位数X 声道) X 时间 / 8 (字节= 8bit) 每一分钟WAV格式的音频文件的大小为10MB,其大小不随音量大小及清晰度的变化而变化。WAV是最接近无损的音乐格式,所以文件大小相对也比较大。

FLAC是无损压缩,也就是说音频以FLAC编码压缩后不会丢失任何信息,将FLAC文件还原为WAV文件后,与压缩前的WAV文件内容相同。这种压缩与ZIP的方式类似顷亮,但FLAC的压缩比率大于ZIP和RAR,因为FLAC是专门针对PCM音频的特点设计的压缩方式。

相较同类文件格式FLAC,APE有查错能力但不提供纠错功能,以保证文件的无损和纯正;其另一个特色是压缩率约为55%,比FLAC高,体积大概为原CD的一半,便于存储。

扩展资料:

作为数字音乐文件格式的标准,WAV格式体积过大,一个3分左右的音乐文件30-50MB,使用起来很不方便。因此,一般情况下我们把它压缩为MP3等体积更小的缺乎昌格式。

常见的音频压缩方法有:无损压缩,有损压缩。其中,有损压缩是以破坏源文件数据方式(直接删除人耳听力范围之外的数字信息、甚至是删除部分人耳听力范围之内的信息,只保留基本声音)来换取小体积文件的,如常见的MP2、MP3、ogg、m4a、wma等等格式;

这种破坏是永久性的、不可逆的。稍加比较,你就能听出(如MP3)低于120K码率的文件和320K码率文件音质的天壤之别。但对于320K码率的音乐,由于其删除的只是人耳听力范围之外的信息,一般是难以与CD分辨的。

尽管如此,如果用高级音响设备放大播放的话,声音与CD还是有差的,毕竟是删除了数据的。无损压缩,顾名思义,就是只改变源文件数据记录方式,使其体积变小,它对元数据不作任何不可逆性地破坏。伏扒

目前常见的无损压缩数字音乐格式有:APE、FLAC等。

function [y,Fs,bits,opt_ck] = wavread(file,ext)

nargchk(1,2,nargin)

if nargin2, 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-ckfound

[opt_ck,msg] = read_wavefmt(fid,ck,opt_ck)

error(msg)

case 'data'

% data-ckfound:

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-ckfound:

[opt_ck,msg] = read_factck(fid, ck, opt_ck)

error(msg)

case 'disp'

% Optional disp-ckfound:

[opt_ck,msg] = read_dispck(fid, ck, opt_ck)

error(msg)

case 'list'

% Optional list-ckfound:

[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+1end

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 nargin2, ftype = ''end

[ck,msg] = read_ckinfo(fid)

if ~isempty(msg), returnend

% Was a required chunk type specified?

if ~isempty(ftype) ~strcmpi(ck.ID,ftype),

msg = ['' ftype '-ckdid 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-ckheader

msg = ''

err_msg = 'Error reading list-ckchunk.'

if total_bytes nbytes,

msg = err_msg

return

end

% Read standard list-ckdata:

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 = 'Product'

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+1end

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+1end

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-ckheader

msg = ''

err_msg = 'Error reading disp-ckchunk.'

if total_bytes nbytes,

msg = err_msg

return

end

% Read standard disp-ckdata:

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,[840])

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+1end

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-ckheader

msg = ''

err_msg = 'Error reading fact-ckchunk.'

if total_bytes nbytes,

msg = err_msg

return

end

% Read standard fact-ckdata:

opt_ck.fact = char(fread(fid,total_bytes,'uchar')')

% Skip over any unprocessed data:

if rem(total_bytes,2), total_bytes=total_bytes+1end

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-fmtsubchunk.

% 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-formatheader

msg = ''

err_msg = 'Error reading wave-fmtchunk.'

if total_bytes nbytes,

msg = err_msg

return

end

% Read standard wave-formatdata:

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+1end

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-specificinfo

% ---------------------------------------------

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-formatheader

msg = ''

err_msg = 'Error reading PCM wave-fmtchunk.'

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+1end

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-ckand wave-formatstructures 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-datachunk.

% Assumes fid points to the wave-data chunk

% Requires data-ckand wave-formatstructures 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.'returnend

% 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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://outofmemory.cn/tougao/8184343.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有