Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
kelaynak2
Üye
Mesajlar: 135 Kayıt: 30 Haz 2003 02:18
Mesaj
gönderen kelaynak2 » 25 Haz 2006 12:36
Bir *.wav dosyanın header bilgilerini alarak dosyayla ilgili bilgileri editlere yazmak istiyorum.
*.wav dosyanın header bilgileri
http://ccrma.stanford.edu/courses/422/p ... aveFormat/ adresinde var.
Şimdiye kadar yazdığım kod:
Kod: Tümünü seç
procedure TForm1.BitBtn1Click(Sender: TObject);
var
NumRead: Integer;
Buf: array[0..2048] of byte;//2049 bayt yer ayır.
F: file; //binary aç, TextFile ise text aç.
filename:string;
oldMode: Word;
i:integer;
kar:char;
str:string;
begin
if opendialog1.Execute then begin
filename:=opendialog1.FileName;
AssignFile(F, FileName);
oldMode := FileMode;
FileMode := fmOpenRead or fmShareDenyWrite;//0; { read-only access }
Reset(F, 1);
FileMode := oldMode;
try
BlockRead(F, Buf, SizeOf(Buf), NumRead); //file,buf,okunacak bayt,okunan bayt.
edit1.Text:='';
for i:=0 to 3 do begin
kar:=char(buf[i]);
edit1.Text:=edit1.Text+kar;
end;
CHUNKidi aldım.Chunksize'yi nasıl alacağım.Galiba pointer falan kullanmak gerekiyor.Saygılar.
rsimsek
Admin
Mesajlar: 4482 Kayıt: 10 Haz 2003 01:48
Konum: İstanbul
Mesaj
gönderen rsimsek » 25 Haz 2006 01:14
Başlıkta okuduğun değerlerin ascii karakterlerini alman değerlerini vermeyeceğinden HexToDec gibi bir fonksiyonla çevirmen gerekecek. Forumda makaleler bölümünde daha önce verilen çevirme fonksiyonu ile aşağıdaki gibi bir yapı kullanabilirsin.
Kod: Tümünü seç
procedure TForm1.Button1Click(Sender: TObject);
function hex2dec(hex: string): longint;
function digt(ch: char): byte;
const
hexdigts: string[16] = '0123456789abcdef';
var
i: byte;
n: byte;
begin
n := 0;
for i := 1 to length(hexdigts) do
if ch = hexdigts[i] then
n := i - 1;
digt := n;
end;
const
hexset: set of char = ['0'..'9', 'a'..'f'];
var
j: longint;
error: boolean;
dec: longint;
begin
dec := 0;
error := false;
for j := 1 to length(hex) do
begin
if not (upcase(hex[j]) in hexset) then
error := true;
dec := dec + digt(upcase(hex[j])) shl ((length(hex) - j) * 4);
{ 16^n = 2^(n * 4) }
{ n shl ((length(hex) - j) * 4) = n * 16^(length(hex) - j) }
end;
if error then
hex2dec := 0
else
hex2dec := dec;
end;
var
NumRead: Integer;
Buf: array[0..2048] of byte; //2049 bayt yer ayır.
F: file; //binary aç, TextFile ise text aç.
filename: string;
oldMode: Word;
i: integer;
kar: char;
str: string;
begin
if opendialog1.Execute then
filename := opendialog1.FileName;
AssignFile(F, FileName);
oldMode := FileMode;
FileMode := fmOpenRead or fmShareDenyWrite; //0; { read-only access }
Reset(F, 1);
FileMode := oldMode;
try
BlockRead(F, Buf, SizeOf(Buf), NumRead); //file,buf,okunacak bayt,okunan bayt.
edit1.Text := '';
for i := 4 to 7 do //
begin
str := IntToStr(buf[i]); //char(buf[i]);
edit1.Text := edit1.Text + str;
end;
edit1.Text := IntToStr(hex2dec(edit1.Text));
except
end;
end;
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
ulu coder
Üye
Mesajlar: 838 Kayıt: 01 Nis 2006 06:46
Konum: Ankara
Mesaj
gönderen ulu coder » 25 Haz 2006 01:24
Kod: Tümünü seç
Var
i :Integer;
boyut :Word;
begin
boyut := 0;
For i := 4 to 7 do
boyut := boyut+buf[i]*Power(256,i-4);
//256 tabanından dönüştürme gibi düşünebilirsiniz
Edit1.Text := Edit1.Text+inttostr(boyut);
end;
Kolay gelsin.
kelaynak2
Üye
Mesajlar: 135 Kayıt: 30 Haz 2003 02:18
Mesaj
gönderen kelaynak2 » 25 Haz 2006 01:43
@rsimsek
*.wav dosyasını Ultra edit ile açtığımda
52 49 46 46 EA 6B 00 00 rakamları var.
R I F F
ilk dör bayt="RIFF" sonraki dört bayt Dword değerinde
yani 00006BEAh=27626
Windows gezgininden baktığımda *.wav dosyasının uzunluğu 27634.Çünkü Chunkid her zaman wav dosyanın uzunluğunda 8 bayt eksik oluyor.
Benim Programla bulmak istediğim 27626 Chunkid değeri.
Verdiğiniz kodda çok uzun sayılar çıkıyor.
@ulu coder
Kod: Tümünü seç
boyut := boyut+buf[i]*Power(256,i-4);
satırı incompatible type Word and extended hatası veriyor.
lütfen yardım.saygılar.
ulu coder
Üye
Mesajlar: 838 Kayıt: 01 Nis 2006 06:46
Konum: Ankara
Mesaj
gönderen ulu coder » 25 Haz 2006 02:09
Kod: Tümünü seç
boyut := boyut+buf[i]*Trunc(Power(256,i-4));
Power'ın sonucu float da olabiliyormuş.
Bu yüzden önce tamsayıya çevirmek gerekiyormuş...
Opt2000
Üye
Mesajlar: 216 Kayıt: 09 Tem 2003 10:04
Mesaj
gönderen Opt2000 » 25 Haz 2006 02:25
Selam,
İstediğin bilgileri aşağıdaki gibi okuyabilirsin.
Kod: Tümünü seç
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TDataInfo = record
SubChunkID2:Integer;
SubChunkSize:Integer;
Data:Pointer;
end;
type
TChunkFormatInfo = record
SubChunkID:Integer;
SubChunkSize:Integer;
AudioFormat:WORD;
NumOfChannels:WORD;
SampleRate:Integer;
ByteRate:Integer;
BlockAlign:WORD;
end;
type
TRIFFInfo = record
ChunkID:array[0..3]of Char;
ChunkSize:Integer;
Format:Integer;
end;
type
TWave = record
RIFFInfo : TRIFFInfo;
FormatInfo : TChunkFormatInfo;
DataInfo : TDataInfo;
end;
type
TForm1 = class(TForm)
btn1: TButton;
dlgOpen: TOpenDialog;
mmo1: TMemo;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
WaveFile:TFileStream;
WaveInfo:TWave;
begin
if dlgOpen.Execute then
begin
WaveFile:=TFileStream.Create(dlgOpen.FileName, fmOpenRead);
waveFile.Read(WaveInfo, SizeOf(WaveInfo) - SizeOf(WaveInfo.DataInfo.Data));
WaveFile.Free;
mmo1.Clear;
mmo1.Lines.Add('ChunkID : ' + (WaveInfo.RIFFInfo.ChunkID));
mmo1.Lines.Add('ChunkSize : ' + IntToStr(WaveInfo.RIFFInfo.ChunkSize));
mmo1.Lines.Add('Format : ' + IntToStr(WaveInfo.RIFFInfo.Format));
mmo1.Lines.Add('');
mmo1.Lines.Add('SubChunk1ID : ' + IntToStr(WaveInfo.FormatInfo.SubChunkID));
mmo1.Lines.Add('SubChunk1Size : ' + IntToStr(WaveInfo.FormatInfo.SubChunkSize));
mmo1.Lines.Add('AudioFormat : ' + IntToStr(WaveInfo.FormatInfo.AudioFormat));
mmo1.Lines.Add('NumOfChannels : ' + IntToStr(WaveInfo.FormatInfo.NumOfChannels));
mmo1.Lines.Add('SampleRate : ' + IntToStr(WaveInfo.FormatInfo.SampleRate));
mmo1.Lines.Add('ByteRate : ' + IntToStr(WaveInfo.FormatInfo.ByteRate));
mmo1.Lines.Add('BlockAlign : ' + IntToStr(WaveInfo.FormatInfo.BlockAlign));
mmo1.Lines.Add('');
mmo1.Lines.Add('SubChunk2ID : ' + IntToStr(WaveInfo.DataInfo.SubChunkID2));
mmo1.Lines.Add('SubChunk2Size : ' + IntToStr(WaveInfo.DataInfo.SubChunkSize));
end;
end;
end.
Kolay gelsin,
Bahadır Alkaç
kelaynak2
Üye
Mesajlar: 135 Kayıt: 30 Haz 2003 02:18
Mesaj
gönderen kelaynak2 » 25 Haz 2006 03:38
Bahadır bey kodunuz gerçekten işe yarıyor
Yalnız:
Format : WAVE
SubChunk1ID : fmt
SubChunk2ID : data
kelimelerini içerdiğinden aşağıdaki şekilde kodu değiştirdim.Yardımlarınız için teşekkürler.Saygılar.
Kod: Tümünü seç
procedure TForm1.Button2Click(Sender: TObject);
type
TDataInfo = record
SubChunkID2:array[0..3]of Char;//data
SubChunkSize:Integer;
Data:Pointer;
end;
type
TChunkFormatInfo = record
SubChunkID:array[0..2]of Char;// fmt
SubChunkSize:Integer;
AudioFormat:WORD;
NumOfChannels:WORD;
SampleRate:Integer;
ByteRate:Integer;
BlockAlign:WORD;
end;
type
TRIFFInfo = record
ChunkID:array[0..3]of Char;
ChunkSize:Integer;
Format:array[0..3]of Char; //WAVE
end;
type
TWave = record
RIFFInfo : TRIFFInfo;
FormatInfo : TChunkFormatInfo;
DataInfo : TDataInfo;
end;
var
WaveFile:TFileStream;
WaveInfo:TWave;
begin
if opendialog1.Execute then
begin
WaveFile:=TFileStream.Create(Opendialog1.FileName, fmOpenRead);
waveFile.Read(WaveInfo, SizeOf(WaveInfo) - SizeOf(WaveInfo.DataInfo.Data));
WaveFile.Free;
mmo1.Clear;
mmo1.Lines.Add('ChunkID : ' + (WaveInfo.RIFFInfo.ChunkID));
mmo1.Lines.Add('ChunkSize : ' + IntToStr(WaveInfo.RIFFInfo.ChunkSize));
mmo1.Lines.Add('Format : ' + WaveInfo.RIFFInfo.Format);
mmo1.Lines.Add('');
mmo1.Lines.Add('SubChunk1ID : ' + WaveInfo.FormatInfo.SubChunkID);
mmo1.Lines.Add('SubChunk1Size : ' + IntToStr(WaveInfo.FormatInfo.SubChunkSize));
mmo1.Lines.Add('AudioFormat : ' + IntToStr(WaveInfo.FormatInfo.AudioFormat));
mmo1.Lines.Add('NumOfChannels : ' + IntToStr(WaveInfo.FormatInfo.NumOfChannels));
mmo1.Lines.Add('SampleRate : ' + IntToStr(WaveInfo.FormatInfo.SampleRate));
mmo1.Lines.Add('ByteRate : ' + IntToStr(WaveInfo.FormatInfo.ByteRate));
mmo1.Lines.Add('BlockAlign : ' + IntToStr(WaveInfo.FormatInfo.BlockAlign));
mmo1.Lines.Add('');
mmo1.Lines.Add('SubChunk2ID : ' + WaveInfo.DataInfo.SubChunkID2);
mmo1.Lines.Add('SubChunk2Size : ' + IntToStr(WaveInfo.DataInfo.SubChunkSize));
end;
end;
kelaynak2
Üye
Mesajlar: 135 Kayıt: 30 Haz 2003 02:18
Mesaj
gönderen kelaynak2 » 27 Haz 2006 12:55
Bahadır bey tekrar merhaba
Verdiğiniz kod 16 bit wav dosyalarda işe yarıyor.Fakat 24 bit veya 32 bit olursa Chunk2id ve chunk2size yi bulamıyor.Bunun sebebi ise Chunkid1size uzunluğu değişken.Yukarıda verdiğim linki kontrol ederseniz chunk1size satırından itibaren (bu satır hesaba katılmıyor.) chunkid1size boyutu kadar ekleme yaptıktan sonra Chunk2id'e yani "data" yazan bölüme erişmek mümkün.Bir dinamik arrayla aradaki farkı kapatmayı düşündüm.Fakat Setlength(..satırına gelince Exception hatası veriyor.Recordlar dinamik array kabul etmiyormu? Kod aşağıdaki gibi.Lütfen bir el at.Selamlar.
Kod: Tümünü seç
type
TDataInfo = record
fark:array of byte;//Chnuk1size kadar dinamik array oluştur.
SubChunkID2:array[0..3]of Char;//data
SubChunkSize:Dword;
Data:Pointer;
end;
type
TChunkFormatInfo = record
SubChunkID:array[0..2]of Char;// fmt
SubChunkSize:dword;
AudioFormat:WORD;
NumOfChannels:WORD;
SampleRate:Dword;
ByteRate:Dword;
BlockAlign:WORD;
end;
type
TRIFFInfo = record
ChunkID:array[0..3]of Char;
ChunkSize:Dword;
Format:array[0..3]of Char; //WAVE
end;
type
TWave = record
RIFFInfo : TRIFFInfo;
FormatInfo : TChunkFormatInfo;
DataInfo :TDataInfo;
end;
var
WaveFile:TFileStream;
WaveInfo:TWave;
begin
if opendialog1.Execute then
begin
WaveFile:=TFileStream.Create(Opendialog1.FileName, fmOpenRead);
waveFile.Read(WaveInfo, SizeOf(WaveInfo) - SizeOf(WaveInfo.DataInfo.Data));
WaveFile.Free;
mmo1.Clear;
mmo1.Lines.Add('ChunkID : ' + (WaveInfo.RIFFInfo.ChunkID));
mmo1.Lines.Add('ChunkSize : ' + IntToStr(WaveInfo.RIFFInfo.ChunkSize));
mmo1.Lines.Add('Format : ' + WaveInfo.RIFFInfo.Format);
mmo1.Lines.Add('');
mmo1.Lines.Add('SubChunk1ID : ' + WaveInfo.FormatInfo.SubChunkID);
mmo1.Lines.Add('SubChunk1Size : ' + IntToStr(WaveInfo.FormatInfo.SubChunkSize));
mmo1.Lines.Add('AudioFormat : ' + IntToStr(WaveInfo.FormatInfo.AudioFormat));
mmo1.Lines.Add('NumOfChannels : ' + IntToStr(WaveInfo.FormatInfo.NumOfChannels));
mmo1.Lines.Add('SampleRate : ' + IntToStr(WaveInfo.FormatInfo.SampleRate));
mmo1.Lines.Add('ByteRate : ' + IntToStr(WaveInfo.FormatInfo.ByteRate));
mmo1.Lines.Add('BlockAlign : ' + IntToStr(WaveInfo.FormatInfo.BlockAlign));
SetLength(WaveInfo.DataInfo.fark,WaveInfo.FormatInfo.SubChunkSize);
mmo1.Lines.Add('');
mmo1.Lines.Add('SubChunk2ID : ' + WaveInfo.DataInfo.SubChunkID2);
mmo1.Lines.Add('SubChunk2Size : ' + IntToStr(WaveInfo.DataInfo.SubChunkSize));
end;
end;
Opt2000
Üye
Mesajlar: 216 Kayıt: 09 Tem 2003 10:04
Mesaj
gönderen Opt2000 » 27 Haz 2006 02:07
Merhaba,
Aslında record'u hazırlarken parça parça hazırlamamın en büyük sebebi buydu
Linkteki açıklamalarda şöyle bir satır var.
34 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.
2 ExtraParamSize if PCM, then doesn't exist
X ExtraParams space for extra parameters
İşte sizin dikkat etmeniz gereken nokta burası.
Öncelikle size gönderdiğim koddaki gibi tek parçada okumayın, onun yerine şu şekilde okuma yaptırın.
Kod: Tümünü seç
waveFile.Read(WaveInfo.RIFFInfo, SizeOf(WaveInfo.RIFFInfo));
waveFile.Read(WaveInfo.FormatInfo, SizeOf(WaveInfo.FormatInfo));
Bundan sonra AudioFormat bilgisine göre ne kadar ekstra veri okuyacağınızı bilebilirsiniz. Gerekli açıklama aşağıdaki linkte var
http://www.sonicspot.com/guide/wavefiles.html
Bu linkte AudioFormat, Compression Code olarak adlandırılmış.
Eğer problem yaşayacak olursanız yardımcı olurum.
Kolay gelsin,
Bahadır Alkaç
kelaynak2
Üye
Mesajlar: 135 Kayıt: 30 Haz 2003 02:18
Mesaj
gönderen kelaynak2 » 30 Haz 2006 01:36
Bahadır bey, aşağıdaki kodda doğru sonucu buldum.Compression codeyi dikkate almadım.Amacım frekanslardan osilaskop görüntüsüne aktarıp, ses tanımayla ilgili bir program yapmaktı.Benim için PCM yeterli.Umduğum kadar kolay bir program olmadığın anladım.Selamlar.
Kod: Tümünü seç
procedure TForm1.Button1Click(Sender: TObject);
var
MS: TMemoryStream;
RiffCount: integer;
RiffId: array[0..3] of char;
WaveId:array[0..3] of char;// string;// = 'WAVE';
FmtId: array[0..3] of char;//string;// = 'fmt ';
chunk1size:integer;
audioformat:word;
NumChannels:word;
SampleRate:Dword; // = 11025; // 8000, 11025, 22050, or 44100
ByteRate :dword;
BlockAlign:word;
BitsPerSample:word;
chunk2id:array[0..3] of char;//data
Subchunk2Size:dword;
begin
MS := TMemoryStream.Create;
if opendialog1.Execute then begin
ms.LoadFromFile(opendialog1.FileName);
ms.Position :=0;
ms.Read(Riffid,4);
edit1.Text:=riffid;
ms.Read(riffcount,SizeOf(DWORD));
edit2.Text:=inttostr(riffcount);
ms.Read(WaveId, Length(WaveId)); // 'WAVE'
edit3.Text:=waveid;
ms.read(FmtId, Length(FmtId)); // 'fmt '
edit4.Text:=Fmtid;
ms.read(chunk1size, SizeOf(DWORD));
edit5.Text:=inttostr(chunk1size);
ms.Read(audioformat,sizeof(word));
edit6.Text:=inttostr(audioformat);
ms.Read(NumChannels,sizeof(word));
edit7.Text:=inttostr(NumChannels);
ms.Read(SampleRate,sizeof(dword));
edit8.Text:=inttostr(samplerate);
ms.Read(ByteRate,sizeof(dword));
edit9.Text:=inttostr(ByteRate);
ms.Read(BlockAlign,sizeof(word));
edit10.Text:=inttostr(BlockAlign);
ms.Read(BitsPerSample,sizeof(word));
edit11.Text:=inttostr(BitsPerSample);
ms.Position:=16+chunk1size+4;
ms.Read(chunk2id,4); //data
edit12.Text:=chunk2id;
ms.Read(Subchunk2Size,sizeof(dword));
edit13.text:=inttostr(Subchunk2Size);
end;
MS.Free;
end;