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

Пока что у меня проблемы с записью данных в memo1. Можете посмотреть на код и сказать что сделать, что бы данные шли в своем порядке. А то ни как не могу сделать красиво и ровно. должно быть так:
Код:
RIFF
chunkSize 2194
WAVE
fmt 
subchunk1Size 16
audioFormat 1
numChannels 1
sampleRate 22050
byteRate 44100
blockAlign 2
bitsPerSample 16
data
subchunk2Size 2158
А оно все так:
Код:
RIFF
WAVE
fmt 
16
data
2158
audioFormat 0001
numChannels 1
sampleRate 22050
byteRate 44100
blockAlign 2
bitsPerSample 16
Так же отмечу, что не могу найти 2 значение chunkSize. Не вывести, не мне даже понять, в каком месте оно читается.

Код:
Код:
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;
  WAVE_FORMAT_PCM    = 1;
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;
type
  EWavError = class(Exception);
 
  TWaveFormat = packed record
    wFormatTag: Word;
    nChannels: Word;
    nSamplesPerSec: DWORD;
    nAvgBytesPerSec: DWORD;
    nBlockAlign: Word;
    wBitsPerSample: Word;
  end;

  TWavInfo = record
    WaveFormat: TWaveFormat;
    Samples: array of array of Word;
  end;

var
  Form1: TForm1;
  TxtFile : TextFile;
  i : integer;
  sample: Int64;
  SampleSize, chanel: Longword;
  NumSamples: Longword;
  s1: String;
  s2: integer;
  Ini:Tinifile;
  language:string;

implementation

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

uses math, Unit2;

procedure RaiseWavError(const Msg: string);
begin
  raise EWavError.Create(Msg);
end;
 
procedure ReadWavInfo(const FileName: string; var WavInfo: TWavInfo);
type
  TChunkName = packed array[0..3] of AnsiChar;
 
  TRiffChunk = packed record
    RiffSign: TChunkName;
    RiffSize: Longword;
    WaveSign: TChunkName;
  end;
 
  TChunk = packed record
    Name: TChunkName;
    Size: Longword;
  end;

var
  fs: TFileStream;
  RiffChunk: TRiffChunk;
  Chunk: TChunk;
  FmtPos, DataPos, NewPos: Int64;
  DataSize, NumSamples, BytsPerSample, I, J: Longword;
 
  procedure DecRiffSize(Size: Longword);
  begin
    if RiffChunk.RiffSize < Size then RaiseWavError('Wav-файл повреждён');
    Dec(RiffChunk.RiffSize, Size);

  end;

begin
  Finalize(WavInfo);
  FillChar(WavInfo, SizeOf(WavInfo), 0);
 
  fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
  try
    fs.ReadBuffer(RiffChunk, SizeOf(RiffChunk));
    if (RiffChunk.RiffSign <> 'RIFF') or (RiffChunk.WaveSign <> 'WAVE') then RaiseWavError('Это не wav-файл');

    DecRiffSize(SizeOf(RiffChunk.WaveSign));
    Form1.memo1.Lines.Add(RiffChunk.RiffSign);
    Form1.memo1.Lines.Add(RiffChunk.WaveSign);

    FmtPos := 0;
    DataPos := 0;
 
    while RiffChunk.RiffSize > 0 do
    begin
      fs.ReadBuffer(Chunk, SizeOf(Chunk));
      DecRiffSize(SizeOf(Chunk));
      DecRiffSize(Chunk.Size);
 
      if Chunk.Name = 'fmt ' then
      begin
        if FmtPos <> 0 then RaiseWavError('Встретилось несколько секций "fmt"');
        if Chunk.Size < SizeOf(WavInfo.WaveFormat) then RaiseWavError('Неверный размер секции "fmt"');
        FmtPos := fs.Position;
      end else
        if Chunk.Name = 'data' then
        begin
          if DataPos <> 0 then RaiseWavError('Встретилось несколько секций "data"');
          DataPos := fs.Position;
          DataSize := Chunk.Size;
        end;
 
      NewPos := fs.Position + Chunk.Size;
      fs.Position := NewPos;
      if fs.Position <> NewPos then RaiseWavError('Wav-файл повреждён');
    end;
 
    if FmtPos = 0 then RaiseWavError('Отсутствует секция "fmt"');
 
    if DataPos = 0 then RaiseWavError('Отсутствует секция "data"');
 
    fs.Position := FmtPos;
    fs.ReadBuffer(WavInfo.WaveFormat, SizeOf(WavInfo.WaveFormat));
 
    if WavInfo.WaveFormat.wFormatTag = WAVE_FORMAT_PCM then
    begin
      if WavInfo.WaveFormat.nChannels = 0 then RaiseWavError('Отсутствуют каналы');
      BytsPerSample := WavInfo.WaveFormat.wBitsPerSample div 8;
      if BytsPerSample = 0 then RaiseWavError('Неверная разрядность сэмплов');
      NumSamples := DataSize div (BytsPerSample * WavInfo.WaveFormat.nChannels);
 
      SetLength(WavInfo.Samples, NumSamples, WavInfo.WaveFormat.nChannels);
      fs.Position := DataPos;

      for I := 1 to NumSamples do
      begin
        for J := 1 to WavInfo.WaveFormat.nChannels do
        begin
          fs.ReadBuffer(WavInfo.Samples[I - 1, J - 1], BytsPerSample);
        end;
      end;
    end;

  finally
    fs.Free;
  end;
end;
Ответить с цитированием