Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 18.05.2008, 23:26
PvP PvP вне форума
Прохожий
 
Регистрация: 18.05.2008
Сообщения: 2
Репутация: 10
Сообщение Слияние Wav

Здравствуйте, мне нужно слить два файла wav в один, я написал вот этот код:

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    Panel2: TPanel;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


  TWaveHeader = record
Marker1:        Array[0..3] of Char;
BytesFollowing: LongInt;
Marker2:        Array[0..3] of Char;
Marker3:        Array[0..3] of Char;
Fixed1:         LongInt;
FormatTag:      Word;
Channels:       Word;
SampleRate:     LongInt;
BytesPerSecond: LongInt;
BytesPerSample: Word;
BitsPerSample:  Word;
Marker4:        Array[0..3] of Char;
DataBytes:      LongInt;
end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
fl: file of TWaveHeader;
fl3: file of TWaveHeader;
WaveHeader: TWaveHeader;
WaveHeader2: TWaveHeader;
WaveHeader3: TWaveHeader;
header:integer;
header2:integer;
header3:integer;
Buffer: pbyte;
I:longint;
c: longint;
v:longint;
begin
v:=0;

assignfile(fl, 'C:\bp.wav');  //Получаем заголовок файла
reset(fl);
read(fl, WaveHeader);
closefile(fl);

assignfile(fl, 'C:\SuJ.wav');  //Получаем заголовок файла
reset(fl);
read(fl, WaveHeader3);
closefile(fl);

GetMem(Buffer, WaveHeader.DataBytes);//Резервируем буфер для одной записи

header:=FileOPen('C:\SuJ.wav', fmOpenRead);
header3:=FileOPen('C:\bp.wav', fmOpenRead);
header2:=FileCreate('C:\magawave.wav', fmOpenWrite);

//Перекачиваем параметры

WaveHeader2.Marker1 := WaveHeader.Marker1 ;
WaveHeader2.BytesFollowing:=WaveHeader.BytesFollowing+WaveHeader3.BytesFollowing;
WaveHeader2.Marker2 := WaveHeader.Marker2;
WaveHeader2.Marker3 := WaveHeader.Marker3;
WaveHeader2.Fixed1 := WaveHeader.Fixed1;
WaveHeader2.FormatTag := WaveHeader.FormatTag;
WaveHeader2.SampleRate := WaveHeader.SampleRate;
WaveHeader2.Channels := WaveHeader.Channels;
WaveHeader2.BytesPerSecond := WaveHeader.BytesPerSecond;
WaveHeader2.BytesPerSample:=WaveHeader.BytesPerSample;
WaveHeader2.BitsPerSample := WaveHeader.BitsPerSample+WaveHeader3.BitsPerSample;
WaveHeader2.Marker4 := WaveHeader.Marker4;
WaveHeader2.DataBytes := WaveHeader.DataBytes;



v:=filewrite(header2, WaveHeader2, sizeof(WaveHeader2));

//Считываем первый файл
v:=fileseek(header, sizeOf(WaveHeader), 0);
//showmessage(inttostr(v));

c:=round(WaveHeader.BytesFollowing/WaveHeader.DataBytes);
//if c < WaveHeader.BytesFollowing/WaveHeader.DataBytes then c:=c+1;
I:=0;
while i<c do
begin
v:=fileread(header, Buffer^, WaveHeader.DataBytes);
//showmessage(inttostr(i));
v:=filewrite(header2, Buffer^, WaveHeader2.DataBytes);
i:=i+1;
end;


//Считываем второой файл

v:=fileseek(header3, sizeOf(WaveHeader3), 0);

c:=round(WaveHeader3.BytesFollowing/WaveHeader3.DataBytes);
//if c < WaveHeader3.BytesFollowing/WaveHeader3.DataBytes then c:=c+1;
I:=0;
while not(i=c) do
begin
v:=fileread(header3, Buffer^, WaveHeader3.DataBytes);
//showmessage(inttostr(v));
v:=filewrite(header2, Buffer^, WaveHeader2.DataBytes);
//showmessage(inttostr(v));
i:=i+1;
end;

fileclose(header);
fileclose(header3);
fileclose(header2);

end;

function GetFileInfo(Fn:string):string;
var
fl: file of TWaveHeader;
WaveHeader: TWaveHeader;
begin

assignfile(fl, Fn);  //Получаем заголовок файла
reset(fl);
read(fl, WaveHeader);
closefile(fl);

GetFileInfo:='Метка №1: '+WaveHeader.Marker1+chr(13)+'Количество байт в файле: '+inttostr(WaveHeader.BytesFollowing)+chr(13)+'Метка №2: '+WaveHeader.Marker2+chr(13)+'Метка №3:'+WaveHeader.Marker3+chr(13)+'Байт в секунду: '+inttostr(WaveHeader.BytesPerSecond)+chr(13)+'Фиксированный: '+inttostr(WaveHeader.Fixed1)+chr(13)+'Тэг формата: '+inttostr(WaveHeader.FormatTag)+chr(13)+'Частота: '+inttostr(WaveHeader.SampleRate)+chr(13)+'Количество каналов: '+inttostr(WaveHeader.Channels)+chr(13)+'Байт в сэмпле: '+inttostr(WaveHeader.BytesPerSample)+chr(13)+'Бит в сэмпле: '+inttostr(WaveHeader.BitsPerSample)+chr(13)+'Метка №4: '+WaveHeader.Marker4+chr(13)+'Байт в блоке: '+inttostr(WaveHeader.DataBytes);

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
label1.Caption:=GetFileInfo('C:\bp.wav');
label2.Caption:=GetFileInfo('C:\SuJ.wav');
end;

end.

Но к сожалению при воспроизведении созданного файла, проигрывается только Первая часть файла. С чем это может быть связано?
Ответить с цитированием
  #2  
Старый 19.05.2008, 03:22
Аватар для zip000
zip000 zip000 вне форума
Начинающий
 
Регистрация: 24.07.2007
Сообщения: 194
Репутация: 25
По умолчанию

Первое что бросается в глаза
Код:
WaveHeader2.DataBytes := WaveHeader.DataBytes;
Вы ж в конечный файл записываете размер данных первого файла. Надо что-то в этом духе
Код:
WaveHeader2.DataBytes := WaveHeader.DataBytes + WaveHeader3.DataBytes;
__________________
Не профи, но и не чайник . D6 - лучше не придумали. Пока.
Ответить с цитированием
  #3  
Старый 19.05.2008, 12:51
PvP PvP вне форума
Прохожий
 
Регистрация: 18.05.2008
Сообщения: 2
Репутация: 10
По умолчанию

Дело в том, что WaveHeader.DataBytes это размер блока данных, он стандартен для всех wav, а за размер отвечает вот это поле WaveHeader.BytesFollowing
Ответить с цитированием
  #4  
Старый 19.05.2008, 17:05
Аватар для zip000
zip000 zip000 вне форума
Начинающий
 
Регистрация: 24.07.2007
Сообщения: 194
Репутация: 25
По умолчанию

PvP, вы немного напутали с форматом файла, дело в том, что ваше последнее поле DataBytes как раз и есть размер данных wav файла. А вот второе поле BytesFollowing это размер всего файла (или что-то другое, точно не помню уже). Попробуйте сделать как я написал. А вот за размер блока данных отвечает поле Block Align, которого у вас нет, точнее есть, но почему-то называется BytesPerSample.

UPD Вот посидел чуток, все работает. Обработку ошибок сами сделаете.
Код:
type
  TWaveHeader = record
    Marker1        : array [0..3] of Char;
    BytesFollowing : LongInt;
    Marker2        : Array[0..3] of Char;
    Marker3        : Array[0..3] of Char;
    Fixed1         : LongInt;
    FormatTag      : Word;
    Channels       : Word;
    SampleRate     : LongInt;
    BytesPerSecond : LongInt;
    BlockAlign     : Word;
    BitsPerSample  : Word;
    Marker4        : Array[0..3] of Char;
    DataBytes      : LongInt;
  end;

procedure JoinWAVEFiles(FileIn1, FileIn2, FileOut : String);
var
  f1, f2, fo : TFileStream;
  h1, h2, ho : TWaveHeader;
begin
  f1 := TFileStream.Create(FileIn1, fmOpenRead);
  f2 := TFileStream.Create(FileIn2, fmOpenRead);
  f1.Read(h1, SizeOf(h1));
  f2.Read(h2, SizeOf(h2));
  if (h1.Channels = h2.Channels) and
     (h1.SampleRate = h2.SampleRate) and
     (h1.BitsPerSample = h2.BitsPerSample) then begin
    ho := h1;
    ho.BytesFollowing := h1.BytesFollowing + h2.DataBytes;
    ho.DataBytes := h1.DataBytes + h2.DataBytes;
    fo := TFileStream.Create(FileOut, fmCreate);
    fo.Write(ho, SizeOf(ho));
 {  f1.Position := SizeOf(h1);
    f2.Position := SizeOf(h2); } как-то не обратил внимания, что эти строки можно убрать.
    fo.CopyFrom(f1, h1.DataBytes);
    fo.CopyFrom(f2, h2.DataBytes);
    fo.Free;
  end;
  f1.Free;
  f2.Free;
end;
__________________
Не профи, но и не чайник . D6 - лучше не придумали. Пока.

Последний раз редактировалось zip000, 19.05.2008 в 21:24.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:17.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter