Struktur File WAV
Format file wav merupakan bagian dari spesifikasi RIFF milik Microsoft yang digunakan untuk penyimpanan file-file multimedia. File wav dimulai dengan bagian header dan diikuti oleh rentetan data chunk. File wav terdiri dari 3 bagian, yaitu main chunk, format chunk, dan data chunk.
Sinyal suara yang direpresentasikan file wav dalam bentuk discrete, berupa deret bilangan yang merepresentasikan amplitudo dalam domain waktu. Pada bagian file header terdapat informasi tentang file wav tersebut, diantaranya menyatakan nilai sample rate, jumlah channel, dan bit per sample. Dari keterangan pada file header tersebut dapat diketahui berapa sampel yang dicuplik dari sinyal analog tiap detik. Struktur WAV dapat dilihat pada Gambar di bawah ini :
- Bagian Main Chunk
- ChunkID : berisi kata “RIFF” dalam format ASCII.
- ChunkSize : berisi informasi ukuran chunk.
- Format : berisi kata “WAVE”.
- Bagian Format Chunk
- SubChunk1ID : berisi kata “fmt”.
- SubChunk1Size : berisi informasi ukuran subchunk1
- c. AudioFormat : informasi jenis kompresi data chunk. Misalnya bernilai 1 untuk kompresi PCM.
- NumChannels : banyaknya channel. Misal: Mono=1, Stereo=2.
- SampleRate : sample rate dari file wav, misal 8000 untuk 8000Hz, 44100 untuk 44100 Hz.
- ByteRate : banyaknya byte tiap detik. ByteRate = SampleRate x NumChannels x BitsPerSample / 8.
- BitsPerSample : ukuran bits untuk tiap sampel.Misal: 8 bit = 8
- Bagian Data Chunk
- SubChunk2ID : berisi kata “data”.
- SubChunk2Size : berisi informasi ukuran subchunk2. SubChunk2Size = NumSamples x NumChannels x BitsPerSample / 8. NumSamples = (DataByte / NumChannels) / BitsPerSample.
- Data : Data suara aktual dalam byte, merepresentasi-kan amplitudo tiap sampel dari sinyal.
Proses Pembacaan File WAV di Delphi 7:
Pada dasarnya bahasa pemrograman delphi sudah mempunyai kelas untuk dapat membaca suatu file yang berekstensi *.wav. Membuat struktur data dan variabel global untuk digunakan pada prosedur pembacaan file wav. Berikut ini merupakan source code program pembacaan file wav pada bahasa pemrograman delphi 7 :
- Written By Adhitya A P (0510960002)
- Student of Computer Science in Brawijaya University
- Indonesia}
- unit Unit1;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, TeEngine, Series, ExtCtrls, TeeProcs, Chart;
- type
- TWaveHeader = packed record
- { harus bernilai 'RIFF' }
- Marker_RIFF: array [0..3] of char;
- ChunkSize: cardinal;
- { harus bernilai 'WAVE' }
- Marker_WAVE: array [0..3] of char;
- { harus bernilai 'fmt ' }
- Marker_fmt: array [0..3] of char;
- SubChunkSize: cardinal;
- {
- Audio Format see mmsystem.pas
- 1 : WAVE_FORMAT_PCM
- }
- FormatTag: word;
- { nChannels : 1 jika mono, 2 jika stereo }
- NumChannels: word;
- SampleRate: longint;
- BytesPerSecond: longint;
- BytesPerSample: word;
- BitsPerSample: word;
- { Harus bernilai 'data' }
- Marker_data: array [0..3] of char;
- { Jumlah seluruh sampel dalam byte }
- DataBytes: longint;
- end;
- TChannel = record
- {
- tiap sample dinyatakan sebagai signed integer
- berukuran 16-bit (2 byte).
- tipe data ini pada delphi adalah smallint
- yang memiliki nilai dalam jangkauan -32767..32768
- }
- Data : array of smallint;
- end;
- type
- TForm1 = class(TForm)
- Memo1: TMemo;
- Button1: TButton;
- Button2: TButton;
- Chart1: TChart;
- Series1: TFastLineSeries;
- Chart2: TChart;
- Series2: TFastLineSeries;
- procedure Button1Click(Sender: TObject);
- procedure Button2Click(Sender: TObject);
- private
- { Private declarations }
- wavehdr : TWaveHeader;
- wavedata : array [0..1] of TChannel;
- numsamples : integer;
- public
- { Public declarations }
- procedure GetInfoWav(filename : string);
- end;
- var
- Form1: TForm1;
- nFrame : Integer;
- implementation
- {$R *.dfm}
- procedure TForm1.GetInfoWav(filename : string);
- var
- tmpstr : string;
- i : integer;
- Stream : TFileStream;
- begin
- Stream := TFileStream.Create(filename, fmOpenRead);
- FillChar(wavehdr, sizeof(wavehdr), 0);
- Stream.Read(wavehdr, sizeof(wavehdr));
- { Log Header data }
- with memo1.Lines do begin
- Add('Bagian Main Chunk');
- Add('Header size : '+inttostr(sizeof(wavehdr)));
- tmpstr := wavehdr.Marker_RIFF;
- Add('Chunk ID : '+tmpstr+''' ');
- Add('Chunk size : '+inttostr(wavehdr.ChunkSize));
- tmpstr := wavehdr.Marker_WAVE;
- Add('Format : '+tmpstr+''' ');
- tmpstr := wavehdr.Marker_fmt;
- Add('');
- Add('Bagian Format Chunk');
- Add('SubChunk ID : '+tmpstr+''' ');
- Add('SubChunk size : '+inttostr(wavehdr.SubChunkSize));
- Add('Audio Format : '+inttostr(wavehdr.FormatTag));
- Add('Num Channels : '+inttostr(wavehdr.NumChannels));
- Add('Sample rate : '+inttostr(wavehdr.SampleRate));
- Add('Bytes rate : '+inttostr(wavehdr.BytesPerSecond));
- Add('Bits per sample : '+inttostr(wavehdr.BitsPerSample));
- numsamples := (wavehdr.DataBytes div wavehdr.NumChannels) div wavehdr.BytesPerSample;
- tmpstr := wavehdr.Marker_data;
- Add('');
- Add('Bagian Data Chunk');
- Add('SubChunk2 ID : '+tmpstr+''' ');
- Add('SubChunk2 Size : '+IntToStr(Round(wavehdr.NumChannels*numsamples*wavehdr.BytesPerSample/8)));
- Add('Data Length : '+inttostr(wavehdr.DataBytes));
- end;
- { Log data amplitudo }
- case wavehdr.NumChannels of
- 1:begin
- SetLength(wavedata[0].Data, numsamples);
- Stream.Read(wavedata[0].Data[0], numsamples);
- end;
- 2:begin
- SetLength(wavedata[0].Data, numsamples);
- SetLength(wavedata[1].Data, numsamples);
- for i := 0 to high(wavedata[0].Data) do begin
- Stream.Read(wavedata[0].Data[i], 2);
- Stream.Read(wavedata[1].Data[i], 2);
- //Memo1.Lines.Add('Nilai ke-'+IntToStr(i+1)+' = \tLeft : '+IntToStr(round(wavedata[0].Data[i]))+' Right : '+IntToStr(round(wavedata[1].Data[i])));
- end;
- end;
- end;
- Memo1.Lines.Add('Nilai Amplitudo : ');
- for i := 0 to high(wavedata[0].Data)do
- Memo1.Lines.Add('Nilai ke-'+IntToStr(i+1)+' = \tLeft : '+IntToStr(round(wavedata[0].Data[i]))+' Right : '+IntToStr(round(wavedata[1].Data[i])));
- end;
- Memo1.Lines.Add('');
- { inisialisasi ulang }
- Stream.Free;
- end;
- //tombol proses pembacaan
- procedure TForm1.Button1Click(Sender: TObject);
- var i: Integer;
- begin
- Memo1.Clear;
- GetInfoWav('arif10.wav');
- //pembuatan grafik
- Series1.Clear;
- for i:=0 to high(wavedata[0].Data) do
- Series1.AddXY(i, round(wavedata[0].Data[i]), '', clTeeColor);
- Series2.Clear;
- for i:=0 to high(wavedata[0].Data) do
- Series2.AddXY(i, round(wavedata[1].Data[i]), '', clTeeColor);
- end;
- //tombol bersihkan layar
- procedure TForm1.Button2Click(Sender: TObject);
- begin
- Memo1.Clear;
- Series1.Clear;
- Series2.Clear;
- end;
- end.
Hasil tampilan program :
Download source code lengkapnya disini
No comments:
Post a Comment