BilgiTeknoloji.net    
b i l g i   t e k n o l o j i   y a z ı l ı m

Ana Sayfa

Marjinal XML Access Pratik Uygulamalar Projeler Ekonometri Dilimiz Editörden Çetrefil İletişim
 

Wav Dosyalarını Birleştirin

 
Bu makalede Wav dosyaları hakkında bazı bilgileri ve Delphi hakkında ilginç ipuçlarını bulacaksınız.
 

FILE FORMAT COLLECTION

Böyle işler için önce www.wotsit.org adresine uğrayın. Bu sitenin, ailenizin "The Programmers File Format Collection"cusu gibi bir vazifesi var. Bu sitede Wav dışında yüzlerce dosya türünün de formatı yer alıyor.

Birçok dosya gibi Wav dosyalarının yapısı da basit sayılır. Gerçi sıkıştırılmış dosyalar biraz zor olabilir. Bu makalenin konusu dosyaların tamamını birleştirmek olduğuna göre işimiz kolay.

Ondan önce konunun daha kolay anlaşılması için Outlook Express'e ait olan DBX dosyalarının yapısından biraz bahsedeyim.

İlk 4 karakter dosyanın Outlook Express'e ait olduğunu anlamak için yerleştiriliyor. Sonrasında ise OE'nin kullandığı bayraklara ait baytlar var. Mesaj bilgileri için de önce bloğun büyüklüğünün ne kadar olduğu, sonra bloğun kendisi yazılıyor.

Bir mesaja ait okundu/okunmadı, bayraklı/bayraksız gibi bilgiler dosyada birer bayt yer kaplıyorlar.

Wav dosyalarında da önce ses bloğunun uzunluğu, sonra ses bloğu yerleştirilir. Ses bloğunun içi ise birçok ayrı bloktan oluşur ama bizim kullanacağımız wav dosyaları aynı yapıda olacağı için bu blokları alıp birleştirmek sorun çıkarmayacaktır.


WAVLAR NASIL BİRLEŞİYOR

Wav dosyalarında ilk 44 bayttan sonrası ses bloğudur. İlk baytlar dosyanın belli öznitelik ve uzunluk bilgilerini taşıyor.

Bu durumda benzer öznitelikli wav dosyalarının ses bloklarını peşpeşe dizdikten sonra ilk 44 bayttaki gerekli yerlere uzunluk bilgilerini yazmak yeterli.

Fazla uğraşmamak için hile yapıp sonuç dosyasının başına dosyalardan birini yerleştiriyorum. Sonra diğer dosyaları sırayla okuyup gerekli blokları arkaya doğru yerleştiriyorum. Tüm birleştirme işlemlerinden sonra oluşan yeni ses bloğunun uzunluğunu dosyanın başına yazmak gerekiyor.

Sonuç dosyasının 5-8. baytlarına [ DosyaUzunluğu - 8 ] ve 41-44. baytlarına [ DosyaUzunluğu - 44 ] yazmak yeterli.

Bu işlemlerin aynı kalite seviyesindeki Wav dosyaları için geçerli olduğunu hatırlatmalıyım.

{
MYVOICE: MergeWavs
Serkan Sahinoglu
http://bilgiteknoloji.net
1999 Istanbul / Turkiye
}


library myvoice;

uses
  SysUtils,
  Classes,
  Dialogs;


{
EXTERNALS:
procedure MergeWavs(FromFiles,ToFile:string; Owerrite:boolean=True);

INTERNALS:
function GetBinaryValue(ix:cardinal):string;

}

{DLL KULLANMA ORNEGI:
implementation
  procedure MergeWavs(FromFiles,ToFile:string; Owerrite:boolean=True);
      far; external 'myvoice.dll'
}




{$R *.RES}


function GetBinaryValue(ix:cardinal):string;
var
  intl: cardinal;
  ch: array[1..4] of char absolute intl;
begin
  intl:=ix;
  result:=ch;
end;


procedure MergeWavs(FromFiles,ToFile:string; Owerrite:boolean=True);
// FromFiles'te dosya isimleri arasinda virgul olacak.
// #13, #10 ya da #1310 kullanilabilir. Noktali virgul olmaz.
// Isimlerde kenarlarda bosluklar oldugunda bunlar kirpiliyor.
// Yeni sesler hedef dosyanin sonuna eklenecekse son parametre False olmali.
var
  f:file;
  s:string;
  yeni:boolean;
  filesizex:integer;
  liste:TStringList;
  i:integer;

  procedure BlockToBlock(FromFileName:string; startx,lenx:integer);
  var
    FromF: file;
    NumRead, NumWritten: Integer;
    Buf: array[1..2048] of Char;
    TotalWritten:Integer;

  begin

    if FromFileName='' then Exit;

    if not FileExists(FromFileName) then
    begin
      ShowMessage('Dosya bulunamadi.' + #13 + FromFileName);
      Exit;
    end;

    AssignFile(FromF, FromFileName);
    Reset(FromF, 1);
    TotalWritten:=0;
    if startx > 1 then Seek(FromF,startx-1);
    repeat
      BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
      if lenx>0 then
         if TotalWritten+numread>lenx then numread:=Lenx-TotalWritten;
      BlockWrite(f, Buf, NumRead, NumWritten);
      inc(TotalWritten,NumWritten);
    until (NumRead = 0) or (NumWritten <> NumRead);

    CloseFile(FromF);

  end;

begin

  //Ana dosyayi hazirla. Yoksa olustur.
  AssignFile(f, ToFile);

  if ( Owerrite or (not FileExists(ToFile)) ) then
  begin
    ReWrite(f,1);
    Yeni:=True;
  end
  else begin
    Reset(f, 1);
    Seek(f,filesize(f));
    Yeni:=False;
  end;

  //Liste hazirlaniyor.
 
liste:=TStringList.create;
  liste.CommaText:=FromFiles;

  //Eger dosya yeni ise ilk wav dosyasinin tamamini almali.
  //Digerlerini bunun sonuna ekleyecek.
 
for i:=0 to liste.Count-1 do
      if ((Yeni) and (i=0))
      then BlockToBlock(Trim(liste[i]),0,0)
      else BlockToBlock(Trim(liste[i]),45,0);

  //FileSize ogrenmek icin.
 
CloseFile(f);
  AssignFile(f, ToFile);
  Reset(f,1);
  FileSizex:= FileSize(f);

  //5-8 baytlarina Uzunluk-8 yaz.
 
s:=GetBinaryValue(filesizex-8);
  Seek(f,4);
  BlockWrite(f, s[1],length(s));

  //41-44 baytlarina Uzunluk-44 yaz.
 
s:=GetBinaryValue(filesizex-44);
  Seek(f,40);
  BlockWrite(f, s[1],length(s));

  CloseFile(f);

end;


exports
  MergeWavs;


begin
end.


Ctrl+F9 ile projeyi derleyip DLL dosyası oluşturabilirsiniz.


Serkan ŞAHİNOĞLU


http://BilgiTeknoloji.net