Среда, 18.06.2025, 23:18
Приветствую Вас Гость | RSS
Меню сайта
fff
  • Индексация
  • Девочки
    Форма входа
    Категории раздела
    Теория алгоритмов [3]
    Теория алгоритмов
    Code Snippets [1]
    Code Snippets
    Все о PHP [20]
    Все о PHP
    Visual C++ [13]
    Visual C++
    WIN32 API [7]
    WIN32 API
    Delphi [72]
    Delphi
    ASP [2]
    ASP
    Java [67]
    Java
    VBScript [6]
    VBScript
    CGI [2]
    CGI
    VRML [2]
    VRML
    PERL [9]
    PERL
    HTML [4]
    HTML
    XML [10]
    XML
    Архив записей

    Статьи по Оптимизации

    ПРОГРАММИРОВАНИЕ! СОЗДАНИЕ САЙТОВ И ИХ ОПТИМИЗАЦИЯ

    Главная » Статьи » Программирование » Delphi

    Декомпилляция звукового файла формата Wave и получение звуковых данных
    Декомпилляция звукового файла формата Wave и получение звуковых данных
    Интересно, есть ли технология преобразования Wave-формата в обычный набор звуковых данных? К примеру, мне необходимо удалить заголовок и механизм (метод) сжатия, которые могут компилироваться и сохраняться вместе с Wave-файлами.
    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, : 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(,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(,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(,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'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 N0
    then LastDataBaseItem := LastDataBaseItem-1;
    end;
    end; {InitDataBase}

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

    ThisOne := 0;
    FindDataBaseName := -1;
    while ThisOne

    Категория: Delphi | Добавил: Merlin (07.12.2009)
    Просмотров: 423 | Рейтинг: 0.0/0
    Всего комментариев: 0
    Имя *:
    Email *:
    Код *: