怎样分割Wave文件

debussy 2003-09-10 10:37:53
如何按照指定的时间段分割一个标准的PCM格式的Wave文件
...全文
169 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Haofei 2003-11-21
  • 打赏
  • 举报
回复
楼主,你这个贴子太久了,总还没结题,我做了一个程帮你赶紧结题算了:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TWaveHeader = record
rId : longint; //固定标记 值为"RIFF"
rLen : longint; //随后的字节数 值为(wSampleLength +36)
wId : longint; //固定标记 值为"WAVE"
fId : longint; //ckID 值为"fmt "
fLen : longint; //nChunkSize Wave文件块的大小 16
wFormatTag : word; //音频数据的编码方式 此值常为1 表示PCM方式
nChannels : word; //声道数
nSamplesPerSec : longint; //每秒采样频率
nAvgBytesPerSec : longint; //每秒字节数
nBlockAlign : word; //一次输出的字节数 值为采样位数*声道数/8
wBitsPerSample : word; //采样位数 一般16位和8位
dId : longint; //固定标记 值为"data"
wSampleLength : longint; //采样数据长度 值为文件大小-文件头大小(44)
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
fs, fd : TFileStream ;
m,s,ms, Temp : Integer ;
dm,ds,dms : Integer ;
WaveHeader, WaveHeader2 : TWaveHeader ;
begin
// Wave文件的分割
//从00:10:250处分割
dm:=0; ds := 10; dms := 250;

fs := TFileStream.Create('d:\a.wav',fmOpenRead);

//读出原文件的文件头
fs.Read(WaveHeader,Sizeof(WaveHeader));

//计算原文件的长度 按分:秒:毫秒计
ms := (WaveHeader.wSampleLength mod WaveHeader.nAvgBytesPerSec)*1000 div WaveHeader.wSampleLength;
s := (WaveHeader.wSampleLength div WaveHeader.nAvgBytesPerSec) mod 60;
m := (WaveHeader.wSampleLength div WaveHeader.nAvgBytesPerSec) div 60;

//此处比较分割点是否在原文件长度之内,此处略

//计算机新文件b的长度
Temp := WaveHeader.wBitsPerSample*WaveHeader.nChannels div 8;//每个采样字节数
WaveHeader2 := WaveHeader ;
WaveHeader2.wSampleLength := WaveHeader2.nAvgBytesPerSec*(dS + dM*60)+
WaveHeader2.nAvgBytesPerSec * dms div 1000;
WaveHeader2.wSampleLength := WaveHeader2.wSampleLength div Temp * Temp;//保证采样数据的完整性
WaveHeader2.rLen := WaveHeader2.wSampleLength + 36;

//写入新文件 b
fd := TFileStream.Create('d:\b.wav',fmCreate);
fd.write(WaveHeader2,Sizeof(WaveHeader2));
fd.CopyFrom(fs,WaveHeader2.wSampleLength);
fd.Free;

//计算新文件C的长度
WaveHeader2.wSampleLength := WaveHeader.wSampleLength-WaveHeader2.wSampleLength;
WaveHeader2.rLen := WaveHeader2.wSampleLength + 36 ;

//将余下的写入文件C
fd := TFileStream.Create('d:\c.wav',fmCreate);
fd.Write(WaveHeader2,Sizeof(WaveHeader2));
fd.CopyFrom(fs,WaveHeader2.wSampleLength);
fd.Free;

fs.Free;

end;

end.

在D7上通过。
cmain83 2003-09-15
  • 打赏
  • 举报
回复
我写过一个这样的程序.
用的是 API
源码已传到了网上.

http://www.codestudy.net/codesource/list.asp?id=120

不过其中的界面用了LMD控包.

其中录音放音都做了十分详细的注释.

TWaveUnit目录下的三个PAS文件是录放音的文件:

TCMWaveType.pas :录放音公用过程、函数、数据结构
TPlayWaveUnit.pas :放音类
TRecordWaveUnit.pas :录音类

并且还可以显示波形、快慢速播放、复制、粘帖音频数据等很多操作。
可以直接复制上述的三个文件进行改进和程序设计
Cipherliu 2003-09-14
  • 打赏
  • 举报
回复
WAVE文件的格式最简单的,按PCM编码直接存下来的,Haofei(昊飞)说得很清楚了.
前年我也专门写了一些这样的程序
可以向你推荐一本书,<Windows程序设计>,(老外写的那套最经典的),上面有一章写得很清楚,当时我就是看的那本书,别的书上还真没见过
tanqth 2003-09-12
  • 打赏
  • 举报
回复
Haofei 2003-09-11
  • 打赏
  • 举报
回复
上一贴有点问题,应该为:如果要在时间X(以秒为单位)分割,只要取出第(44+nAvgBytesPerSec*X)个字节只后的所有字节,并加上一文件头即可!
不要再除8 了!
Haofei 2003-09-11
  • 打赏
  • 举报
回复
Wave文件的结构很简单,一个44字节的文件头加上各个采样数据,文件头的结构为:
TWaveHeader = record //定义一个Wav文件头格式
rId : longint;
rLen : longint;
wId : longint;
fId : longint;
fLen : longint;
wFormatTag : word;
nChannels : word; //声道数
nSamplesPerSec : longint; //每秒采样频率
nAvgBytesPerSec : longint; //每秒字节数
nBlockAlign : word;
wBitsPerSample : word; //采样位一般16位和8位
dId : longint;
wSampleLength : longint;
end;

如果要在时间X(以秒为单位)分割,只要取出第(44+nAvgBytesPerSec*X/8)个字节只后的所有字节,并加上一文件头即可!
tellyes 2003-09-11
  • 打赏
  • 举报
回复
我有一个源程序,如果需要,可以留下EMAIL。
hongqi162 2003-09-11
  • 打赏
  • 举报
回复
不懂!学习!!!
蓝色光芒 2003-09-10
  • 打赏
  • 举报
回复
不懂Wave协议,只有UP的份。
hansome 2003-09-10
  • 打赏
  • 举报
回复
惭愧,UP

1,185

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧