Показать сообщение отдельно
  #72  
Старый 14.08.2012, 17:09
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от poli-smen
Этот код не дублирует первый канал, а выдаёт то что содержится в wav-файле и если там идут одинаковые значения для левого и правого канала, то что же должно выводиться?
Да, правда. Попробовал гигантский wav и там правда есть расходимость в каналах. 2 вопроса снято! Остался 3: все же как теперь записать значения? И не записывать вручную это
Код:
NumSamples := 1079;
и это
Код:
Sample := 1111;
. Что бы они сами заполнялись, как вы сказали, используя массив. Это для меня непосильная задача. Вот наверняка почти весь исходный код:
Код:
unit Unit1;

interface               

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus, sSkinManager, ImgList, Inifiles, ComCtrls,
  sTabControl, acHeaderControl, sGauge, sPageControl, sMemo, sButton;

Const
  noError            = 0;
  ReadError          = 1;
  HeaderError        = 2;
  DataError          = 3;
  FileCorrupt        = 4;
  IncorectFileFormat = 5;

type
  TForm1 = class(TForm)

    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    N7: TMenuItem;
    N8: TMenuItem;
    N9: TMenuItem;
    N10: TMenuItem;
    N11: TMenuItem;
    N12: TMenuItem;
    sSkinManager1: TsSkinManager;
    ImageList1: TImageList;
    SaveDialog2: TSaveDialog;
    TabSheet1: TsTabSheet;
    TabSheet2: TsTabSheet;
    Memo1: TsMemo;
    Memo2: TsMemo;
    Button1: TsButton;
    Button2: TsButton;
    Button3: TsButton;
    Button4: TsButton;
    Button5: TsButton;
    Button6: TsButton;
    OpenDialog2: TOpenDialog;
    PageControl1: TsPageControl;

    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure N5Click(Sender: TObject);
    procedure N6Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure N8Click(Sender: TObject);
    procedure N9Click(Sender: TObject);
    procedure N10Click(Sender: TObject);
    procedure N11Click(Sender: TObject);
    procedure N12Click(Sender: TObject);
    { Private declarations }
  public
    { Public declarations }
end;
  TWaveHeaderChank = record
    wFormatTag     : Smallint;
    wChannels      : WORD;
    wSamplesPerSec : Cardinal;
    wAvgBytesPerSec: Cardinal;
    wBlockAlign    : WORD;
    wBitsPerSample : WORD;
    wcbSize        : WORD;

  end;

  TWaveResult = record
    ERROR          : WORD;
    wAvgBytesPerSec: Cardinal;
    wBitsPerSample : WORD;
    wChannels      : WORD;
    Data           : TMemoryStream;
  end;

var
  Form1: TForm1;
  TxtFile : TextFile;
  i : integer;
  sample: Int64;
  SampleSize, chanel, n: Integer;
  s: String;
  s1: String;
  Ini:Tinifile;
  language:string;
  Handled: Boolean;
implementation

{$R *.dfm}
{$R WindowsXP.res}

uses math, Unit2;

Function ReadWave(FileName : AnsiString) : TWaveResult;
var
  f             : TFileStream;
  wFileSize     : Cardinal;
  wChankSize    : Cardinal;
  ID            : array[0..3] of Char;
  Header        : TWaveHeaderChank;

Begin
  FillChar(Result, SizeOf(Result), 0);

  Try
    f := TFileStream.Create(FileName, fmOpenRead);
    f.Seek(0, soFromBeginning);
    f.ReadBuffer(ID[0], 4);
  If String(ID) <> 'RIFF'
    then
      Begin
        Result.ERROR := IncorectFileFormat;
        f.Free;
        exit;
      end;
  Form1.memo1.Lines.Add(String(ID));

     f.ReadBuffer(wFileSize, 4);
                                        
      Form1.memo1.Lines.Add('' + intToStr(wFileSize));

    if f.size <> (wFileSize + 8)
    then
      Begin
        Result.ERROR := FileCorrupt;
        f.Free;
        exit;
      end;

    f.ReadBuffer(ID[0], 4);

      Form1.memo1.Lines.Add(String(ID));

    if String(ID) <> 'WAVE'
    then
      Begin
        Result.ERROR := IncorectFileFormat;
        f.Free;
        exit;
      end;

    wChankSize := 0;
    repeat
      f.Seek(wChankSize, soFromCurrent);
      f.ReadBuffer(ID[0], 4);

        Form1.memo1.Lines.Add(String(ID));
      f.ReadBuffer(wChankSize, 4);

      if wChankSize > High(integer)
      then
        Begin
          Result.ERROR := DataError;
          f.Free;
          exit;
        end;

        Form1.memo1.Lines.Add('' + intToStr(wChankSize));
    until  (String(ID)='fmt ') or (String(ID)='data');

    if String(ID)='data'
    then
      Begin
        Result.ERROR := HeaderError;
        f.Free;
        exit;
      end;

    f.ReadBuffer(Header, Min(wChankSize, SizeOf(TWaveHeaderChank)));
      Form1.memo1.Lines.Add(''   + intToStr(Header.wFormatTag));
      Form1.memo1.Lines.Add(''   + intToStr(Header.wChannels));
      Form1.memo1.Lines.Add(''   + intToStr(Header.wSamplesPerSec));
      Form1.memo1.Lines.Add(''   + intToStr(Header.wAvgBytesPerSec));
      Form1.memo1.Lines.Add(''   + intToStr(Header.wBlockAlign));
      Form1.memo1.Lines.Add(''   + intToStr(Header.wBitsPerSample));

    if wChankSize > SizeOf(TWaveHeaderChank)
    then
      f.Seek(wChankSize - SizeOf(TWaveHeaderChank), soFromCurrent);

    if wChankSize >= SizeOf(TWaveHeaderChank)
    then

        Form1.memo1.Lines.Add(''        + intToStr(Header.wcbSize));

    wChankSize := 0;
    repeat
      f.Seek(wChankSize, soFromCurrent);
      f.ReadBuffer(ID[0], 4);

        Form1.memo1.Lines.Add(String(ID));
      f.ReadBuffer(wChankSize, 4);
        Form1.memo1.Lines.Add(''    + intToStr(wChankSize));
    until  String(ID)='data';

//Попытка считать Сэмплы
if Header.wFormatTag<>1 then
    begin
      Form1.Memo1.Lines.Add('ОШИБКА! Я умею читать wav-файлы только в формате PCM, а этот файл в формате 0x'+IntToHex(Header.wFormatTag, 4));
    end;
    SampleSize:=(Header.wBitsPerSample+7) div 8;
    if SampleSize>SizeOf(sample) then
    begin
      Form1.Memo1.Lines.Add('ОШИБКА! Слишком большой размер сэмпла ('+IntToStr(SampleSize)+' байт)');
      Exit;
    end;
    if Header.wChannels=0 then
    begin
      Form1.Memo1.Lines.Add('ОШИБКА! Нет каналов');
      Exit;
    end;
    Form1.Memo1.WordWrap:=False;
    Form1.Memo1.ScrollBars:=ssBoth;
    sample:=0;
    i:=0;
    while wChankSize>=(SampleSize*Header.wChannels) do
    begin
      if Header.wBlockAlign>0 then
      begin
        n:=f.Position mod Header.wBlockAlign;
        if n>0 then
begin
  n:=Header.wBlockAlign-n;
  f.Seek(n, soFromCurrent);
  Dec(wChankSize, n);
  if wChankSize<(SampleSize*Header.wChannels) then Break;
end;
      end;

      Inc(i);
s1:='';
for chanel := 1 to Header.wChannels do
begin
  f.ReadBuffer(sample, SampleSize);
  Dec(wChankSize, SampleSize);

  s1:=s1+IntToHex(sample, SampleSize*2);
end;
Form1.Memo1.Lines.Add(s1);
    end;
        exit;
f.Free;
Except
    Result.ERROR := ReadError;
  end;
end;
procedure  TForm1.Button1Click(Sender: TObject);
var
  r : TWaveResult;
begin
  if opendialog1.Execute
  then
    r := ReadWave(opendialog1.FileName);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if SaveDialog1.Execute then
Form1.Memo1.Lines.SaveToFile(Form1.SaveDialog1.FileName + '.txt');
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
if OpenDialog2.Execute then
Form1.Memo2.Lines.LoadFromFile(Form1.OpenDialog2.FileName + '');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
Memo1.Clear;
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
Memo2.Clear;
end;



procedure WriteWav(const FileName: String);
type
  TMassiv = array of array of Integer;
  TChunkID = packed array [0..3] of Char;
  THeader = packed record
    ChunkID       : TChunkID;
    ChunkSize     : Longword;
    Format        : TChunkID;
    Subchunk1ID   : TChunkID;
    Subchunk1Size : Longword;
    AudioFormat   : Word;
    NumChannels   : Word;
    SampleRate    : Longword;
    ByteRate      : Longword;
    BlockAlign    : Word;
    BitsPerSample : Word;
    Subchunk2ID   : TChunkID;
    Subchunk2Size : Longword;
  end;
var
  Header: THeader;
  NumSamples, BytsPerSample, Sample, I, J: Longword;
  fs: TFileStream;
  Massiv: TMassiv;
begin
  NumSamples := 1079; {Massiv[I, J];}
  BytsPerSample := 2;

  Header.ChunkID       := 'RIFF';
  Header.ChunkSize     := StrToInt(Form1.Memo2.Lines[1]);
  Header.Format        := 'WAVE';
  Header.Subchunk1ID   := 'fmt ';
  Header.Subchunk1Size := StrToInt(Form1.Memo2.Lines[4]);
  Header.AudioFormat   := $0001;
  Header.NumChannels   := StrToInt(Form1.Memo2.Lines[6]);
  Header.SampleRate    := StrToInt(Form1.Memo2.Lines[7]);
  Header.ByteRate      := StrToInt(Form1.Memo2.Lines[8]);
  Header.BlockAlign    := StrToInt(Form1.Memo2.Lines[9]);
  Header.BitsPerSample := StrToInt(Form1.Memo2.Lines[10]);
  Header.Subchunk2ID   := 'data';
  Header.Subchunk2Size := StrToInt(Form1.Memo2.Lines[12]);
  fs := TFileStream.Create('New File.wav',fmCreate);
  try
    fs.WriteBuffer(Header, SizeOf(Header));
      for I := 1 to NumSamples do
    begin
      for J := 1 to Header.NumChannels do
      begin
        Sample := 1111;
        fs.WriteBuffer(Sample, BytsPerSample);
      end;
    end;
  finally
    fs.Free;
  end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
  if SaveDialog2.Execute then
  begin
    WriteWav(SaveDialog2.FileName);
  end;
  end;
end.
Полный код:
Вложения
Тип файла: txt ИК.txt (9.0 Кбайт, 4 просмотров)
Ответить с цитированием