- •Омский государственный технический университет Пояснительная записка
- •Техническое задание
- •Студенту гр. В – 531 ОмГту Нагаеву Андрею Александровичу
- •Оглавление
- •Формат mp3-файла.
- •2.1 Выбор инструментальной среды разработки по
- •3.1 Разработка алгоритма основной программы
- •3.3 Модули id3v1, id3v2 Данные модули используются для работы с тэгами mp3-файла.
- •4.1. Подпрограмма mpeg frame header data
- •4.2. Подпрограмма GetFrameLength
- •4.3. Подпрограмма FindFrame
- •4.4. Подпрограмма ReadTag
- •4.5. Подпрограмма GetTagVersion
4.1. Подпрограмма mpeg frame header data
function TMPEGaudio.ReadFromFile(const FileName: string): Boolean;
var
SourceFile: file;
Data: array [1..MAX_MPEG_FRAME_LENGTH * 2] of Byte;
Transferred: Integer;
begin
Result := false;
{ At first search for tags, then search for a MPEG frame and VBR data }
if (FID3v2.ReadFromFile(FileName)) and (FID3v1.ReadFromFile(FileName)) then
try
{ Open file, read first block of data and search for a frame }
AssignFile(SourceFile, FileName);
FileMode := 0;
Reset(SourceFile, 1);
FFileLength := FileSize(SourceFile);
Seek(SourceFile, FID3v2.Size);
BlockRead(SourceFile, Data, SizeOf(Data), Transferred);
FFrame := FindFrame(Data, FVBR);
{ Try to search in the middle if no frame at the beginning found }
if (not FFrame.Found) and (Transferred = SizeOf(Data)) then
begin
Seek(SourceFile, (FFileLength - FID3v2.Size) div 2);
BlockRead(SourceFile, Data, SizeOf(Data), Transferred);
FFrame := FindFrame(Data, FVBR);
end;
{ Search for vendor ID at the end if CBR encoded }
if (FFrame.Found) and (not FVBR.Found) then
begin
if not FID3v1.Exists then Seek(SourceFile, FFileLength - SizeOf(Data))
else Seek(SourceFile, FFileLength - SizeOf(Data) - 128);
BlockRead(SourceFile, Data, SizeOf(Data), Transferred);
FVendorID := FindVendorID(Data, FFrame.Size * 5);
end;
CloseFile(SourceFile);
Result := true;
except
end;
4.2. Подпрограмма GetFrameLength
function GetFrameLength(const Frame: FrameData): Word;
var
Coefficient, BitRate, SampleRate, Padding: Word;
begin
{ Calculate MPEG frame length }
Coefficient := GetCoefficient(Frame);
BitRate := GetBitRate(Frame);
SampleRate := GetSampleRate(Frame);
Padding := GetPadding(Frame);
Result := Trunc(Coefficient * BitRate * 1000 / SampleRate) + Padding;
end;
4.3. Подпрограмма FindFrame
function FindFrame(const Data: array of Byte; var VBR: VBRData): FrameData;
var
HeaderData: array [1..4] of Byte;
Iterator: Integer;
begin
{ Search for valid frame }
FillChar(Result, SizeOf(Result), 0);
Move(Data, HeaderData, SizeOf(HeaderData));
for Iterator := 0 to SizeOf(Data) - MAX_MPEG_FRAME_LENGTH do
begin
{ Decode data if frame header found }
if IsFrameHeader(HeaderData) then
begin
DecodeHeader(HeaderData, Result);
{ Check for next frame and try to find VBR header }
if ValidFrameAt(Iterator + GetFrameLength(Result), Data) then
begin
Result.Found := true;
Result.Position := Iterator;
Result.Size := GetFrameLength(Result);
Result.Xing := IsXing(Iterator + SizeOf(HeaderData), Data);
VBR := FindVBR(Iterator + GetVBRDeviation(Result), Data);
break;
end;
end;
{ Prepare next data block }
HeaderData[1] := HeaderData[2];
HeaderData[2] := HeaderData[3];
HeaderData[3] := HeaderData[4];
HeaderData[4] := Data[Iterator + SizeOf(HeaderData)];
end;
end;