Понедельник, 29 Апр 2024, 13:36
Uchi.ucoz.ru
Меню сайта
Форма входа

Категории раздела
Высшая математика [11]
Экономическая социология [95]
Основы Менеджмента [64]
Бухгалтерский учёт [157]
Философия [163]
Мировая Экономика [603]
Бизнес планирование [29]
Финансирование и кредитование инвест [105]
Ценообразование [46]
Гражданское право [196]
Права Человека [173]
Основы Маркетинга [207]
Основы энергосбережения [55]
Информатика [0]
Экология и устойчивое развитие [0]
Физика для студентов [0]
Основы права [0]
Политология [0]
Не стандартные примеры на Delphi [169]
Примеры на Delphi7 [108]
Алгоритмы [94]
API [110]
Pascal [152]
Базы Данных [6]
Новости
Чего не хватает сайту?
500
Статистика
Зарегистрировано на сайте:
Всего: 51635


Онлайн всего: 4
Гостей: 4
Пользователей: 0
Яндекс.Метрика
Рейтинг@Mail.ru

Каталог статей


Главная » Статьи » Студентам » Алгоритмы

Декомпилляция звукового файла формата Wave и получение звуковых данных
Интересно, есть ли технология преобразования Wave-формата в
обычный набор звуковых данных? К примеру, мне необходимо удалить заголовок и
механизм (метод) сжатия, которые могут компилироваться и сохраняться вместе с
Wave-файлами.
У меня есть программа под D1/D2, которая читает WAV-файлы и вытаскивает
исходные данные, но она не может их восстанавить, используя зашитый алгоритм
сжатия.

unit
LinearSystem;

interface

{==============
Тип, описывающий формат WAV ==================}
type WAVHeader
= record

nChannels : Word;
nBitsPerSample : LongInt;
nSamplesPerSec : LongInt;
nAvgBytesPerSec : LongInt;
RIFFSize : LongInt;
fmtSize : LongInt;
formatTag : Word;
nBlockAlign : LongInt;
DataSize : LongInt;
end;
{============== Поток
данных сэмпла ========================}
const MaxN = 300; { максимальное значение величины
сэмпла }
type SampleIndex = 0 ..
MaxN+3;
type DataStream = array[
SampleIndex ] of Real;

var N :
SampleIndex;

{============== Переменные сопровождения
======================}
type Observation = record

Name : String[40]; {Имя данного сопровождения}
yyy : DataStream; {Массив указателей
на данные}
WAV : WAVHeader; {Спецификация WAV
для сопровождения}
Last : SampleIndex; {Последний
доступный индекс yyy}
MinO, MaxO : Real; {Диапазон значений
yyy}
end;
var K0R, K1R, K2R, K3R :
Observation;

K0B, K1B, K2B, K3B : Observation;
{================== Переменные имени файла
===================}
var StandardDatabase : String[
80 ];

BaseFileName : String[ 80
];
StandardOutput : String[ 80
];
StandardInput : String[ 80
];
{=============== Объявления процедур
==================}
procedure ReadWAVFile (var Ki, Kj :
Observation);
procedure WriteWAVFile (var Ki, Kj :
Observation);
procedure ScaleData (var Kk :
Observation);
procedure InitAllSignals;
procedure
InitLinearSystem;

implementation
{$R
*.DFM}
uses VarGraph, SysUtils;

{================== Стандартный формат WAV-файла
===================}
const MaxDataSize : LongInt = (MaxN+1)*2*2;
const MaxRIFFSize : LongInt = (MaxN+1)*2*2+36;
const StandardWAV : WAVHeader = (

nChannels : Word(2);
nBitsPerSample : LongInt(16);
nSamplesPerSec : LongInt(8000);
nAvgBytesPerSec : LongInt(32000);
RIFFSize : LongInt((MaxN+1)*2*2+36);
fmtSize : LongInt(16);
formatTag : Word(1);
nBlockAlign : LongInt(4);
DataSize : LongInt((MaxN+1)*2*2)
);

{==================
Сканирование переменных сопровождения ===================}

procedure ScaleData(var Kk : Observation);
var I :
SampleIndex;
begin

{Инициализация переменных
сканирования}
Kk.MaxO := Kk.yyy[0];
Kk.MinO := Kk.yyy[0];

{Сканирование для получения максимального и
минимального значения}
for I := 1 to Kk.Last
do
begin
if Kk.MaxO < Kk.yyy[I] then Kk.MaxO :=
Kk.yyy[I];
if Kk.MinO > Kk.yyy[I] then Kk.MinO :=
Kk.yyy[I];
end;end; { ScaleData
}

procedure ScaleAllData;
begin

ScaleData(K0R);
ScaleData(K0B);
ScaleData(K1R);
ScaleData(K1B);
ScaleData(K2R);
ScaleData(K2B);
ScaleData(K3R);
ScaleData(K3B);end; {ScaleAllData}

{================== Считывание/запись WAV-данных
===================}

VAR InFile, OutFile : file of
Byte;

type Tag = (F0, T1, M1);
type FudgeNum =
record

case X:Tag of
F0 : (chrs : array[0..3] of Byte);
T1 : (lint : LongInt);
M1 : (up,dn: Integer);
end;var ChunkSize :
FudgeNum;

procedure
WriteChunkName(Name:String);
var i : Integer;

MM : Byte;begin

for i := 1 to 4 do
begin
MM := ord(Name[i]);
write(OutFile,MM);
end;end; {WriteChunkName}

procedure
WriteChunkSize(LL:Longint);
var I : integer;
begin

ChunkSize.x:=T1;
ChunkSize.lint:=LL;
ChunkSize.x:=F0;
for I := 0 to 3 do
Write(OutFile,ChunkSize.chrs[I]);end;

procedure
WriteChunkWord(WW:Word);
var I : integer;
begin

ChunkSize.x:=T1;
ChunkSize.up:=WW;
ChunkSize.x:=M1;
for I := 0 to 1 do Write(OutFile,ChunkSize.chrs[I]);end;
{WriteChunkWord}

procedure
WriteOneDataBlock(var Ki, Kj : Observation);
var I :
Integer;
begin

ChunkSize.x:=M1;
with Ki.WAV do
begin
case nChannels of
1:if nBitsPerSample=16
then begin {1..2 Помещаем в буфер
одноканальный 16-битный сэмпл}
ChunkSize.up := trunc(Ki.yyy[N]+0.5);
if N<MaxN then ChunkSize.dn :=
trunc(Ki.yyy[N+1]+0.5);
N := N+2;
end
else begin {1..4 Помещаем в буфер
одноканальный 8-битный сэмпл}
for I:=0 to 3 do ChunkSize.chrs[I]
:= trunc(Ki.yyy[N+I]+0.5);
N := N+4;
end;
2:if nBitsPerSample=16
then begin {2 Двухканальный 16-битный
сэмпл}
ChunkSize.dn := trunc(Ki.yyy[N]+0.5);
ChunkSize.up := trunc(Kj.yyy[N]+0.5);
N := N+1;
end
else begin {4 Двухканальный 8-битный
сэмпл}
ChunkSize.chrs[1] :=
trunc(Ki.yyy[N]+0.5);
ChunkSize.chrs[3] := trunc(Ki.yyy[N+1]+0.5);
ChunkSize.chrs[0] :=
trunc(Kj.yyy[N]+0.5);
ChunkSize.chrs[2] := trunc(Kj.yyy[N+1]+0.5);
N := N+2;
end;
end; {with WAV do begin..}
end; {четырехбайтовая переменная
"ChunkSize" теперь заполнена}

ChunkSize.x:=T1;
WriteChunkSize(ChunkSize.lint);{помещаем 4
байта данных}end; {WriteOneDataBlock}

procedure
WriteWAVFile(var Ki, Kj : Observation);
var MM :
Byte;

I : Integer;
OK : Boolean;begin

{Приготовления для записи файла
данных}
AssignFile(OutFile, StandardOutput); { Файл,
выбранный в диалоговом окне }
ReWrite( OutFile );
With Ki.WAV do
begin DataSize := nChannels*(nBitsPerSample div 8)*(Ki.Last+1);
RIFFSize := DataSize+36;
fmtSize := 16;
end;

{Записываем ChunkName "RIFF"}
WriteChunkName('RIFF');

{Записываем ChunkSize}
WriteChunkSize(Ki.WAV.RIFFSize);

{Записываем ChunkName "WAVE"}
WriteChunkName('WAVE');

{Записываем tag "fmt_"}
WriteChunkName('fmt ');

{Записываем ChunkSize}
Ki.WAV.fmtSize := 16; {должно быть 16-18}
WriteChunkSize(Ki.WAV.fmtSize);

{Записываем formatTag,
nChannels}
WriteChunkWord(Ki.WAV.formatTag);
WriteChunkWord(Ki.WAV.nChannels);

{Записываем nSamplesPerSec}
WriteChunkSize(Ki.WAV.nSamplesPerSec);

{Записываем nAvgBytesPerSec}
WriteChunkSize(Ki.WAV.nAvgBytesPerSec);

{Записываем nBlockAlign,
nBitsPerSample}
WriteChunkWord(Ki.WAV.nBlockAlign);
WriteChunkWord(Ki.WAV.nBitsPerSample);

{Записываем метку блока данных
"data"}
WriteChunkName('data');

{Записываем DataSize}
WriteChunkSize(Ki.WAV.DataSize);

N:=0; {первая
запись-позиция}
while N<=Ki.Last do WriteOneDataBlock(Ki,Kj);
{помещаем 4 байта и увеличиваем счетчик N}

{Освобождаем буфер файла}
CloseFile( OutFile );end; {WriteWAVFile}

procedure
InitSpecs;
begin
end; { InitSpecs
}

procedure InitSignals(var Kk :
Observation);
var J : Integer;
begin

for J := 0 to MaxN do
Kk.yyy[J] := 0.0;
Kk.MinO := 0.0;
Kk.MaxO := 0.0;
Kk.Last := MaxN;end; {InitSignals}

procedure InitAllSignals;
begin
InitSignals(K0R);
InitSignals(K0B);
InitSignals(K1R);
InitSignals(K1B);
InitSignals(K2R);
InitSignals(K2B);
InitSignals(K3R);
InitSignals(K3B);end; {InitAllSignals}

var ChunkName :
string[4];

procedure
ReadChunkName;
var I : integer;

MM : Byte;begin

ChunkName[0]:=chr(4);
for I := 1 to 4 do
begin
Read(InFile,MM);
ChunkName[I]:=chr(MM);
end;end; {ReadChunkName}

procedure
ReadChunkSize;
var I : integer;

MM : Byte;begin

ChunkSize.x := F0;
ChunkSize.lint := 0;
for I := 0 to 3 do
begin
Read(InFile,MM);
ChunkSize.chrs[I]:=MM;
end;
ChunkSize.x := T1;end; {ReadChunkSize}

procedure
ReadOneDataBlock(var Ki,Kj:Observation);
var I :
Integer;
begin

if N<=MaxN then
begin
ReadChunkSize; {получаем 4 байта
данных}
ChunkSize.x:=M1;
with Ki.WAV do
case nChannels of
1:if nBitsPerSample=16
then begin {1..2 Помещаем в буфер
одноканальный 16-битный сэмпл}
Ki.yyy[N] :=1.0*ChunkSize.up;
if N<MaxN then Ki.yyy[N+1]:=1.0*ChunkSize.dn;
N := N+2;
end
else begin {1..4 Помещаем в буфер
одноканальный 8-битный сэмпл}
for I:=0 to 3 do Ki.yyy[N+I]:=1.0*ChunkSize.chrs[I];
N := N+4;
end;
2:if nBitsPerSample=16
then begin {2 Двухканальный 16-битный
сэмпл}
Ki.yyy[N]:=1.0*ChunkSize.dn;
Kj.yyy[N]:=1.0*ChunkSize.up;
N := N+1;
end
else begin {4 Двухканальный 8-битный
сэмпл}
Ki.yyy[N] :=1.0*ChunkSize.chrs[1];
Ki.yyy[N+1]:=1.0*ChunkSize.chrs[3];
Kj.yyy[N] :=1.0*ChunkSize.chrs[0];
Kj.yyy[N+1]:=1.0*ChunkSize.chrs[2];
N := N+2;
end;
end;
if N<=MaxN then begin {LastN := N;}
Ki.Last := N;
if Ki.WAV.nChannels=2 then
Kj.Last := N;
end
else begin {LastN :=
MaxN;}
Ki.Last := MaxN;
if Ki.WAV.nChannels=2 then
Kj.Last := MaxN;

end;end;end; {ReadOneDataBlock}

procedure
ReadWAVFile(var Ki, Kj :Observation);
var MM : Byte;

I : Integer;
OK : Boolean;
NoDataYet : Boolean;
DataYet : Boolean;
nDataBytes : LongInt;begin

if FileExists(StandardInput)
then
with Ki.WAV do
begin { Вызов диалога открытия файла
}
OK := True; {если не изменится где-нибудь
ниже}
{Приготовления для чтения файла
данных}
AssignFile(InFile, StandardInput); { Файл,
выбранный в диалоговом окне }
Reset( InFile );

{Считываем ChunkName "RIFF"}
ReadChunkName;
if ChunkName<>'RIFF'
then OK := False;

{Считываем ChunkSize}
ReadChunkSize;
RIFFSize := ChunkSize.lint; {должно быть
18,678}

{Считываем ChunkName "WAVE"}
ReadChunkName;
if ChunkName<>'WAVE'
then OK := False;

{Считываем ChunkName "fmt_"}
ReadChunkName;
if ChunkName<>'fmt '
then OK := False;

{Считываем ChunkSize}
ReadChunkSize;
fmtSize := ChunkSize.lint; {должно быть
18}

{Считываем formatTag, nChannels}
ReadChunkSize;
ChunkSize.x := M1;
formatTag := ChunkSize.up;
nChannels := ChunkSize.dn;

{Считываем nSamplesPerSec}
ReadChunkSize;
nSamplesPerSec := ChunkSize.lint;

{Считываем nAvgBytesPerSec}
ReadChunkSize;
nAvgBytesPerSec := ChunkSize.lint;

{Считываем nBlockAlign}
ChunkSize.x := F0;
ChunkSize.lint := 0;
for I := 0 to 3 do
begin Read(InFile,MM);
ChunkSize.chrs[I]:=MM;
end;
ChunkSize.x := M1;
nBlockAlign := ChunkSize.up;

{Считываем nBitsPerSample}
nBitsPerSample := ChunkSize.dn;
for I := 17 to fmtSize
do Read(InFile,MM);

NoDataYet := True;
while NoDataYet do
begin
{Считываем метку блока данных
"data"}
ReadChunkName;

{Считываем DataSize}
ReadChunkSize;
DataSize := ChunkSize.lint;

if ChunkName<>'data'
then
begin
for I := 1 to DataSize
do {пропуск данных, не относящихся к набору звуковых
данных}
Read(InFile,MM);
end
else NoDataYet := False;
end;

nDataBytes := DataSize;
{Наконец, начинаем считывать данные для байтов
nDataBytes}
if nDataBytes>0 then
DataYet := True;
N:=0; {чтение с первой
позиции}
while DataYet do
begin
ReadOneDataBlock(Ki,Kj); {получаем 4
байта}
nDataBytes := nDataBytes-4;
if nDataBytes<=4 then
DataYet := False;
end;

ScaleData(Ki);
if Ki.WAV.nChannels=2
then begin Kj.WAV := Ki.WAV;
ScaleData(Kj);
end;
{Освобождаем буфер файла}
CloseFile( InFile );
end
else begin
InitSpecs;{файл не существует}
InitSignals(Ki);{обнуляем массив
"Ki"}
InitSignals(Kj);{обнуляем массив
"Kj"}
end;end; { ReadWAVFile
}

{================= Операции с
набором данных ====================}

const
MaxNumberOfDataBaseItems = 360;
type
SignalDirectoryIndex = 0 ..
MaxNumberOfDataBaseItems;

VAR DataBaseFile : file of
Observation;

LastDataBaseItem : LongInt; {Номер текущего
элемента набора данных}
ItemNameS : array[SignalDirectoryIndex] of
String[40];
procedure
GetDatabaseItem( Kk : Observation; N : LongInt );
begin

if N<=LastDataBaseItem
then begin
Seek(DataBaseFile, N);
Read(DataBaseFile, Kk);
end
else InitSignals(Kk);end; {GetDatabaseItem}
procedure PutDatabaseItem( Kk
: Observation; N : LongInt );
begin

if N<MaxNumberOfDataBaseItems
then
if N<=LastDataBaseItem
then begin
Seek(DataBaseFile, N);
Write(DataBaseFile, Kk);
LastDataBaseItem := LastDataBaseItem+1;
end
else while LastDataBaseItem<=N do
begin
Seek(DataBaseFile, LastDataBaseItem);
Write(DataBaseFile, Kk);
LastDataBaseItem := LastDataBaseItem+1;
end
else ReportError(1); {Попытка чтения MaxNumberOfDataBaseItems}end;
{PutDatabaseItem}

procedure
InitDataBase;
begin

LastDataBaseItem := 0;
if FileExists(StandardDataBase)
then
begin
Assign(DataBaseFile,StandardDataBase);
Reset(DataBaseFile);
while not EOF(DataBaseFile) do
begin
GetDataBaseItem(K0R, LastDataBaseItem);
ItemNameS[LastDataBaseItem] := K0R.Name;
LastDataBaseItem := LastDataBaseItem+1;
end;
if EOF(DataBaseFile)
then if LastDataBaseItem>0
then LastDataBaseItem := LastDataBaseItem-1;
end;end; {InitDataBase}

function FindDataBaseName(
Nstg : String ):LongInt;
var ThisOne :
LongInt;
begin

ThisOne := 0;
FindDataBaseName := -1;
while ThisOne<LastDataBaseItem do
begin
if Nstg=ItemNameS[ThisOne]
then begin
FindDataBaseName := ThisOne;
Exit;
end;
ThisOne := ThisOne+1;
end;end; {FindDataBaseName}

{======================= Инициализация модуля
========================}
procedure
InitLinearSystem;
begin

BaseFileName := '\PROGRA~1\SIGNAL~1\';
StandardOutput := BaseFileName + 'K0.wav';
StandardInput := BaseFileName + 'K0.wav';

StandardDataBase := BaseFileName + 'Radar.sdb';

InitAllSignals;
InitDataBase;
ReadWAVFile(K0R,K0B);
ScaleAllData;end; {InitLinearSystem}

begin {инициализируемый модулем код}

InitLinearSystem;end. {Unit
LinearSystem}
Категория: Алгоритмы | Добавил: Lerka (21 Ноя 2012)
Просмотров: 476 | Рейтинг: 1.0/ 8 Оштрафовать | Жаловаться на материал
Похожие материалы
Всего комментариев: 0

Для блога (HTML)


Для форума (BB-Code)


Прямая ссылка

Профиль
Понедельник
29 Апр 2024
13:36


Вы из группы: Гости
Вы уже дней на сайте
У вас: непрочитанных сообщений
Добавить статью
Прочитать сообщения
Регистрация
Вход
Улучшенный поиск
Поиск по сайту Поиск по всему интернету
Наши партнеры
Интересное
Популярное статьи
Портфолио ученика начальной школы
УХОД ЗА ВОЛОСАМИ ОЧЕНЬ ПРОСТ — ХОЧУ Я ЭТИМ ПОДЕЛИТ...
Диктанты 2 класс
Детство Л.Н. Толстого
Библиографический обзор литературы о музыке
Авторская программа элективного курса "Практи...
Контрольная работа по теме «Углеводороды»
Поиск
Главная страница
Используются технологии uCoz