|
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
|