- •Омский государственный технический университет Пояснительная записка
- •Техническое задание
- •Студенту гр. В – 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.4. Подпрограмма ReadTag
function ReadTag(const FileName: string; var TagData: TagRecord): Boolean;
var
SourceFile: file;
begin
try
Result := true;
{ Set read-access and open file }
AssignFile(SourceFile, FileName);
FileMode := 0;
Reset(SourceFile, 1);
{ Read tag }
Seek(SourceFile, FileSize(SourceFile) - 128);
BlockRead(SourceFile, TagData, 128);
CloseFile(SourceFile);
except
{ Error }
Result := false;
end;
end;
4.5. Подпрограмма GetTagVersion
function GetTagVersion(const TagData: TagRecord): Byte;
begin
Result := TAG_VERSION_1_0;
{ Terms for ID3v1.1 }
if ((TagData.Comment[29] = #0) and (TagData.Comment[30] <> #0)) or
((TagData.Comment[29] = #32) and (TagData.Comment[30] <> #32)) then
Result := TAG_VERSION_1_1;
end;
Заключение
Рассмотренный алгоритм позволяет без заметных искажений mp3-файла записывать относительно большой объем данных, причем данные могут быть любого типа. При этом обнаружить эти данные довольно проблематично, а с использованием предварительного шифрования – практически невозможно.
Приложение.
Программа записи
procedure TMainForm.Button1Click(Sender: TObject);
var
q,NewMp3Byte,BufW:byte;
mp3Size,StartPos,LenFr,CountFr,i:integer;
TxtSize,Txtfile,Mp3File:integer;
CurPos:longword;
pomeha:real;
BufSt,BufMl,StepSt,StepMl,Mp3Byte,step:byte;
s,ext:string;
RealStep:integer;
begin
if Edit2.Text = '' then exit;
TxtFile:=FileOpen(Edit2.Text,fmOpenRead); //открыли txt
ext:=ExtractFileExt(Edit2.Text); //расширение
TxtSize := FileSeek(TxtFile,0,2); //размер txt
FileSeek(TxtFile,0,0); //на начало
if Edit1.Text = '' then exit;
Mp3File:=FileOpen(Edit1.Text,fmOpenReadWrite); //открыли mp3
mp3Size:=mainform.MPEGaudio.FileLength; //размер mp3
StartPos:=MainForm.MPEGaudio.Frame.Position; //позиция 1го фрейма
LenFr:=MainForm.MPEGaudio.Frame.Size; //длина фрейма
CountFr:=StrToint(MainForm.TotalFramesText.Text); //число фреймов
RealStep:=Round(1/(TxtSize / ((LenFr-6)*CountFr-128-50))-1);//шаг записи
if RealStep>255 then Step:=255
else Step:=RealStep div 4;
pomeha:=1/step*100; //искажение в процентах
if Round(pomeha)>25 then
showmessage('Рекомендуется выбрать файл-контейнер большего размера');
//--------------record step in mp3----------------------------------------------
Fileseek(Mp3File,20+StartPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,Step);
FileWrite(Mp3File,bb1,1); //пишем 87бит
Fileseek(Mp3File,40+StartPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,Step);
FileWrite(Mp3File,bb2,1); //пишем 65бит
Fileseek(Mp3File,60+StartPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,Step);
FileWrite(Mp3File,bb3,1); //пишем 43бит
Fileseek(Mp3File,80+StartPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,Step);
FileWrite(Mp3File,bb4,1); //пишем 21бит
//-------------record TxtSize in mp3-------------------------------------------
Fileseek(Mp3File,30+StartPos,0);
FileWrite(Mp3File,TxtSize,4);
//--------------record ext in mp3-------------------------------------------
Fileseek(Mp3File,40+StartPos,0);
FileWrite(Mp3File,ext,4);
//------------------------------------------------------------------------------
Fileseek(Mp3File,100+StartPos,0);
CurPos:=100+StartPos;
if MainForm.MPEGaudio.VBR.Found=true then exit; //проверка на VBR
q:=0;
Form1.Show;
Form1.Label2.Caption:=IntToStr(Round(pomeha))+ '%';
Form1.ProgressBar1.Max:=txtsize; //прогресс-бар
Form1.ProgressBar1.Min:=1;
for i:=1 to TxtSize do
begin //читаем 1байт txt
FileRead(Txtfile,BufW,1);
FileRead(Mp3File,Mp3Byte,1); //читаем 1байт mp3
MyRec4(Mp3Byte,BufW);
FileWrite(Mp3file,bb1,1); //пишем 78бит
CurPos:=CurPos+Step;
CurPos:=IsFrHead(CurPos,StartPos,LenFr); //не попали ли в FrameHeader;
Fileseek(Mp3File,CurPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,BufW);
FileWrite(Mp3file,bb2,1); //пишем 65бит
CurPos:=CurPos+Step;
CurPos:=IsFrHead(CurPos,StartPos,LenFr);
Fileseek(Mp3File,CurPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,BufW);
FileWrite(Mp3file,bb3,1); //пишем 43бит
CurPos:=CurPos+Step;
CurPos:=IsFrHead(CurPos,StartPos,LenFr);
Fileseek(Mp3File,CurPos,0);
FileRead(Mp3File,Mp3Byte,1);
MyRec4(Mp3Byte,BufW);
FileWrite(Mp3file,bb4,1); //пишем 21бит
Form1.ProgressBar1.StepBy(i div 2);
end;
FileClose(Mp3File);
FileClose(TxtFile);
end;
Блок-схема программы записи
TxtFile:=FileOpen(Edit2.Text,fmOpenRead); ext:=ExtractFileExt(Edit2.Text);
//расширение TxtSize
:= FileSeek(TxtFile,0,2); //размер
txt
FileSeek(TxtFile,0,0);
//на начало Mp3File:=FileOpen(Edit1.Text,fmOpenReadWrite);
//открыли mp3
mp3Size:=mainform.MPEGaudio.FileLength;
//размер mp3 StartPos:=MainForm.MPEGaudio.Frame.Position;
//позиция 1го
фрейма
LenFr:=MainForm.MPEGaudio.Frame.Size;
//длина фрейма
CountFr:=StrToint(MainForm.TotalFramesText.Text);
//число фреймов RealStep:=Round(1/(TxtSize
/ ((LenFr-6)*CountFr-128-50))-1);//шаг
записи
Fileseek(Mp3File,20+StartPos,0); FileRead(Mp3File,Mp3Byte,1); FileWrite(Mp3File,bb1,1);
Fileseek(Mp3File,40+StartPos,0); FileRead(Mp3File,Mp3Byte,1);
//пишем шаг
Fileseek(Mp3File,60+StartPos,0); FileRead(Mp3File,Mp3Byte,1); FileWrite(Mp3File,bb1,1);
Fileseek(Mp3File,80+StartPos,0); FileRead(Mp3File,Mp3Byte,1);
Подпрограмма определения
Байта для записи вMp3
FileClose(Mp3File); FileClose(TxtFile);
Да
FileRead(Txtfile,BufW,1);
FileRead(Mp3File,Mp3Byte,1) FileWrite(Mp3file,bb1,1);
//пишем 78бит CurPos:=CurPos+Step FileWrite(Mp3File,bb1,1);
Fileseek(Mp3File,80+StartPos,0); FileRead(Mp3File,Mp3Byte,1);
Повторяется 4 раза с шагом step
Каждый раз записывается
По 2 бита
Рис. 3.1. - Блок-схема программы записи