⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umpegaformat.pas

📁 MP3播放器
💻 PAS
字号:
unit uMPEGAFormat;

interface

uses Classes;

const BufSize = 128;
  MPEG_VER_ERROR = 0;
  MPEG_VER_1 = 1;
  MPEG_VER_2 = 2;
  MPEG_VER_2_5 = 3;

  MPEG_LAYER_ERROR = 0;
  MPEG_LAYER_I = 1;
  MPEG_LAYER_II = 2;
  MPEG_LAYER_III = 3;

  MPEG_BITRATE_ERROR = -1;
  MPEG_SAMPLINGRATE_ERROR = -1;

  MPEG_CHANNEL_STEREO = 0;
  MPEG_CHANNEL_JOINTSTEREO = 1;
  MPEG_CHANNEL_DUAL = 2;
  MPEG_CHANNEL_SINGLE = 3;
  MaxGapBeforeMpeg = 10240;
  //位率索引表
  MpegKBitRate : array [1 .. 3, 1 .. 3, 0 .. 15] of Integer = ( (//MPEG 1
    (0,32,64, 96,128,160,192,224,256,288,320,352,
     384,416,448,MPEG_BITRATE_ERROR), //Layer I
    (0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,
     256,320,384,MPEG_BITRATE_ERROR), //Layer II
    (0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,
     224,256,320,MPEG_BITRATE_ERROR)  //Layer III
     ), (//MPEG 2
    (0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,
     192,224,256,MPEG_BITRATE_ERROR), //Layer I)
    (0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
     128,144,160,MPEG_BITRATE_ERROR), //Layer II
    (0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
     128,144,160,MPEG_BITRATE_ERROR)  //Layer III
     ),
    (//MPEG 2.5
    (0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,
     192,224,256,MPEG_BITRATE_ERROR), //Layer I)
    (0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
     128,144,160,MPEG_BITRATE_ERROR), //Layer II
    (0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
     128,144,160,MPEG_BITRATE_ERROR)  //Layer III
    ));
    // 采样频率索引表
    MpegSamplingRate : array [1 .. 3, 0 .. 3] of integer = ( (44100, 48000, 32000, MPEG_SAMPLINGRATE_ERROR),     (22050, 24000, 16000, MPEG_SAMPLINGRATE_ERROR),    (32000, 16000,  8000, MPEG_SAMPLINGRATE_ERROR));
    MpegEmphasisStr : array [0 .. 3] of string = (
    'None', '50/15 ms', '', 'CCIT J.17');
type  //MPEG Audio Frame Header的类
  TMPEGAFormat = class
  private
    FHdrbuf: array[0..3] of Byte;
    Buf: array[0..BufSize-1] of Byte;
    function Locatehdr: Boolean;
    function GetHdrInfo: Boolean;
    function GetFrameLen: Integer;
  public
    Version: Integer;                // 版本
    KBitRate: Integer;               // 位率 (kbps)
    SamplingRate: Integer;           // 采样频率 (HZ)
    FrameLen: Integer;               // 帧长度
    Frames: Integer;                 // 帧数
    Len: Integer;                    // 播放时间(单位毫秒)
    Layer: Integer;                  // 压缩层次
    PaddingLen: Integer;             // 填料长度
    Padding: Boolean;                // 是否有填料
    ChannelMode: Integer;            // 声道模式
    ChannelModeExt: Integer;         // 声道扩展模式
    ChannelModeExtStr: string;       // 声道扩展模式对应字符串
    Copyright: Boolean;              // 版权
    Original: Boolean;
    EmphasisStr: string;
  // 主函数,从流中获取MPEG info
  function GetinfoFromStream(Stream: TStream): Boolean;
end;

implementation

function TMPEGAFormat.GetinfoFromStream(Stream: TStream): Boolean;
var
  Pos, Count, Size: Integer;
begin
  Pos := 0; Size := Stream.Size;
  Result := False;
  // 每次读取128字节,找MPEG的帧头
  while (Pos < MaxGapBeforeMpeg) and (Pos < Size) do
  begin
    if Size - Pos > BufSize then
      Count:=BufSize else Count := Size - Pos;
      Stream.ReadBuffer(Buf, Count);
     // 通过帧头,获取基本信息
     if Locatehdr and GetHdrInfo then
     begin
         Frames := (Size - pos) div FrameLen;
         // 计算帧数
         Len:= Round((Size - Pos)*8/KBitRate);
         // 计算播放时间
         Result := True;
         Exit;
     end;
     Inc(Pos, Count);
  end;
end;

function TMPEGAFormat.Locatehdr: Boolean;
var
  I: Integer;
begin
  I := 0;  Result := False;
  while (I < BufSize - 4) do
  begin
    if (Buf[I] = 255) and (Buf[I+1] and $E0 = $E0) then
    // 利用帧同步,找帧头32位
    begin
      Move(Buf[I], Fhdrbuf, 4);
      Result := True;
      Exit;
    end;
    Inc(I);
  end;
end;
// 计算帧长度
function TMPEGAFormat.GetFrameLen: Integer;
{  384 samples/frame for Layer I
  1152 samples/frame for Layer II and Layer III
  8 bits Mpeg 1, 16 bits Mpeg 2 & 2.5}
var
  BitRate: Integer;
begin
  BitRate := KBitRate * 1000;
  if SamplingRate > 0 then
    if Version = MPEG_VER_1 then
      if Layer = MPEG_LAYER_I then
        Result := Trunc ((48 * BitRate) / SamplingRate) + PaddingLen
      else Result := Trunc ((144 * BitRate) / SamplingRate) + PaddingLen
    else
      if Layer = MPEG_LAYER_I then
        Result := Trunc ((24 * BitRate) / SamplingRate) + PaddingLen
      else Result := Trunc ((72 * BitRate) / SamplingRate) + PaddingLen
  else
  Result := 0;
end;

function TMPEGAFormat.GetHdrInfo: Boolean;
begin
  //获取版本
  case (FHdrBuf [1] shr 3) and 3 of
    0: Version := MPEG_VER_2_5;
    2: Version := MPEG_VER_2;
    3: Version := MPEG_VER_1;
  else Version := MPEG_VER_ERROR;
  end;
  // 压缩层次
  Layer := (4 - (FHdrBuf[1] shr 1) and 3) and 3;
  // 位率
  if (Version <> MPEG_VER_ERROR) and (Layer <> MPEG_LAYER_ERROR) then
    KBitRate := MpegKBitRate [Version, Layer, (FHdrBuf [2] shr 4) and $F]
  else KBitRate := MPEG_BITRATE_ERROR;
  // 采样频率 (HZ)
  if Version <> MPEG_VER_ERROR then
    SamplingRate := MpegSamplingRate [Version, (FHdrBuf [2] shr 2) and 3]
  else SamplingRate := MPEG_SAMPLINGRATE_ERROR;
   // 填料的长度
   Padding := ((FHdrBuf [2] shr 1) and 1) = 1;
   if Padding  then
     if Layer = MPEG_LAYER_I  then Paddinglen := 4  else Paddinglen := 1;
   // 帧长度
   FrameLen := GetFrameLen;
   // 声道模式
   ChannelMode := (FHdrBuf [3] shr 6) and 3;
   // 声道扩展模式
   ChannelModeExt:=(FHdrBuf [3] shr 4) and 3;
   // 版权
   Copyright:=((fHdrBuf [3] shr 3) and 1) = 1;
   //
   Original := ((FHdrBuf [3] shr 2) and 1) = 1;
   EmphasisStr := MpegEmphasisStr[fHdrBuf [3] and 3];
   if (Version <> MPEG_VER_ERROR)  and (Layer <> MPEG_LAYER_ERROR)
    and (KBitRate <> MPEG_BITRATE_ERROR) and (SamplingRate <> MPEG_SAMPLINGRATE_ERROR) then
   Result := True else Result := False;
end;
end.


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -