如何按照指定的时间段分割一个标准的PCM格式的Wave文件

解决方案 »

  1.   

    我有一个源程序,如果需要,可以留下EMAIL。
      

  2.   

    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)个字节只后的所有字节,并加上一文件头即可!
      

  3.   

    上一贴有点问题,应该为:如果要在时间X(以秒为单位)分割,只要取出第(44+nAvgBytesPerSec*X)个字节只后的所有字节,并加上一文件头即可!
    不要再除8 了!
      

  4.   

    WAVE文件的格式最简单的,按PCM编码直接存下来的,Haofei(昊飞)说得很清楚了.
    前年我也专门写了一些这样的程序
    可以向你推荐一本书,<Windows程序设计>,(老外写的那套最经典的),上面有一章写得很清楚,当时我就是看的那本书,别的书上还真没见过
      

  5.   

    我写过一个这样的程序.
    用的是 API
    源码已传到了网上.http://www.codestudy.net/codesource/list.asp?id=120不过其中的界面用了LMD控包.其中录音放音都做了十分详细的注释.TWaveUnit目录下的三个PAS文件是录放音的文件:TCMWaveType.pas     :录放音公用过程、函数、数据结构
    TPlayWaveUnit.pas   :放音类
    TRecordWaveUnit.pas :录音类并且还可以显示波形、快慢速播放、复制、粘帖音频数据等很多操作。
    可以直接复制上述的三个文件进行改进和程序设计
      

  6.   

    楼主,你这个贴子太久了,总还没结题,我做了一个程帮你赶紧结题算了:
    unit Unit1;interfaceuses
      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上通过。