|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#61
|
||||
|
||||
Цитата:
|
#62
|
||||
|
||||
Цитата:
Строка вида '1234' может быть преобразована в число 1234, но строка вида 'wave' естественно ни в какое число не может быть преобразована. Цитата:
|
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
Dmitry_DM (14.08.2012)
|
#63
|
|||
|
|||
Цитата:
Код:
Header.ChunkID := 'RIFF'; Header.ChunkSize := StrToInt(Form1.Memo2.Lines[2]); Header.Format := 'WAVE'; Header.Subchunk1ID := 'fmt '; Header.Subchunk1Size := StrToInt(Form1.Memo2.Lines[5]); Header.AudioFormat := $0001; Header.NumChannels := StrToInt(Form1.Memo2.Lines[7]); Header.SampleRate := StrToInt(Form1.Memo2.Lines[8]); Header.ByteRate := StrToInt(Form1.Memo2.Lines[9]); Header.BlockAlign := StrToInt(Form1.Memo2.Lines[10]); Header.BitsPerSample := StrToInt(Form1.Memo2.Lines[11]); Header.Subchunk2ID := 'data'; Header.Subchunk2Size := StrToInt(Form1.Memo2.Lines[12]); Процедура записи: Код:
procedure TForm1.Button4Click(Sender: TObject); begin if SaveDialog2.Execute then begin WriteWav(SaveDialog2.FileName); end; |
#64
|
||||
|
||||
Цитата:
Вы же конечно знаете, что нумерация строк в Memo начинается с нуля? Нумерация с нуля в компьютерной технике вообще нормальное явление. |
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
Dmitry_DM (14.08.2012)
|
#65
|
|||
|
|||
Цитата:
|
#66
|
|||
|
|||
Теперь во всем деле есть только 3 проблемы. И все! На этом проект пока приостанавливается. Но все же есть 3 проблемы: первая - это почему при считывании самих сэмплов идет, к примеру так: FFFA 000A FFEE, а должно быть FAFF 0A00 EEFF. В проф. HEX эдиторе так. Можно это как то поменять местами 2 символа при выводе? Вот код:
Код:
if Header.wFormatTag<>1 then begin Form1.Memo1.Lines.Add('ОШИБКА! Я умею читать wav-файлы только в формате PCM, а этот файл в формате 0x'+IntToHex(Header.wFormatTag, 4)); end; SampleSize:=(Header.wBitsPerSample+7) div 8; if SampleSize>SizeOf(sample) then begin Form1.Memo1.Lines.Add('ОШИБКА! Слишком большой размер сэмпла ('+IntToStr(SampleSize)+' байт)'); Exit; end; if Header.wChannels=0 then begin Form1.Memo1.Lines.Add('ОШИБКА! Нет каналов'); Exit; end; Form1.Memo1.WordWrap:=False; Form1.Memo1.ScrollBars:=ssBoth; sample:=0; i:=0; while wChankSize>=(SampleSize*Header.wChannels) do begin if Header.wBlockAlign>0 then begin n:=f.Position mod Header.wBlockAlign; if n>0 then begin n:=Header.wBlockAlign-n; f.Seek(n, soFromCurrent); Dec(wChankSize, n); if wChankSize<(SampleSize*Header.wChannels) then Break; end; end; Inc(i); s1:=''; s:=''+IntToStr(i); for chanel := 1 to Header.wChannels do begin f.ReadBuffer(sample, SampleSize); Dec(wChankSize, SampleSize); s:=s+' Chanel'+IntToStr(chanel)+' '+IntToHex(sample, SampleSize*2); s1:=IntToHex(sample, SampleSize*2); end; Form1.Memo1.Lines.Add(s1); end; exit; f.Free; Except Result.ERROR := ReadError; end; end; |
#67
|
||||
|
||||
Цитата:
Цитата:
|
#68
|
|||
|
|||
Цитата:
1 Канал1: 0000 Канал2: 0000 2 Канал1: 0002 Канал2: 0002 И т.д... Но потом я сделал так, чтобы выводилось только значение. 0002, например. В одноканальном проблем нет, так как там 0002 и все. Но так же выводит и для 2-х канального. А должно быть так 00020002. То есть 2 канала рядом. как так вывести? В правильном итоге, как на картинке, в не правильном, значение в одном канале. Последний раз редактировалось Dmitry_DM, 14.08.2012 в 16:25. |
#69
|
||||
|
||||
Цитата:
Код:
Inc(i); s1:=''; s:=''+IntToStr(i); for chanel := 1 to Header.wChannels do begin f.ReadBuffer(sample, SampleSize); Dec(wChankSize, SampleSize); s:=s+' Chanel'+IntToStr(chanel)+' '+IntToHex(sample, SampleSize*2); s1:=s1+IntToHex(sample, SampleSize*2);// <======= end; Form1.Memo1.Lines.Add(s1); |
#70
|
|||
|
|||
Цитата:
|
#71
|
||||
|
||||
Цитата:
|
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
Dmitry_DM (14.08.2012)
|
#72
|
|||
|
|||
Цитата:
Код:
NumSamples := 1079; Код:
Sample := 1111; Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Menus, sSkinManager, ImgList, Inifiles, ComCtrls, sTabControl, acHeaderControl, sGauge, sPageControl, sMemo, sButton; Const noError = 0; ReadError = 1; HeaderError = 2; DataError = 3; FileCorrupt = 4; IncorectFileFormat = 5; type TForm1 = class(TForm) OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; MainMenu1: TMainMenu; N1: TMenuItem; N2: TMenuItem; N3: TMenuItem; N4: TMenuItem; N5: TMenuItem; N6: TMenuItem; N7: TMenuItem; N8: TMenuItem; N9: TMenuItem; N10: TMenuItem; N11: TMenuItem; N12: TMenuItem; sSkinManager1: TsSkinManager; ImageList1: TImageList; SaveDialog2: TSaveDialog; TabSheet1: TsTabSheet; TabSheet2: TsTabSheet; Memo1: TsMemo; Memo2: TsMemo; Button1: TsButton; Button2: TsButton; Button3: TsButton; Button4: TsButton; Button5: TsButton; Button6: TsButton; OpenDialog2: TOpenDialog; PageControl1: TsPageControl; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure N2Click(Sender: TObject); procedure N3Click(Sender: TObject); procedure N5Click(Sender: TObject); procedure N6Click(Sender: TObject); procedure FormShow(Sender: TObject); procedure N8Click(Sender: TObject); procedure N9Click(Sender: TObject); procedure N10Click(Sender: TObject); procedure N11Click(Sender: TObject); procedure N12Click(Sender: TObject); { Private declarations } public { Public declarations } end; TWaveHeaderChank = record wFormatTag : Smallint; wChannels : WORD; wSamplesPerSec : Cardinal; wAvgBytesPerSec: Cardinal; wBlockAlign : WORD; wBitsPerSample : WORD; wcbSize : WORD; end; TWaveResult = record ERROR : WORD; wAvgBytesPerSec: Cardinal; wBitsPerSample : WORD; wChannels : WORD; Data : TMemoryStream; end; var Form1: TForm1; TxtFile : TextFile; i : integer; sample: Int64; SampleSize, chanel, n: Integer; s: String; s1: String; Ini:Tinifile; language:string; Handled: Boolean; implementation {$R *.dfm} {$R WindowsXP.res} uses math, Unit2; Function ReadWave(FileName : AnsiString) : TWaveResult; var f : TFileStream; wFileSize : Cardinal; wChankSize : Cardinal; ID : array[0..3] of Char; Header : TWaveHeaderChank; Begin FillChar(Result, SizeOf(Result), 0); Try f := TFileStream.Create(FileName, fmOpenRead); f.Seek(0, soFromBeginning); f.ReadBuffer(ID[0], 4); If String(ID) <> 'RIFF' then Begin Result.ERROR := IncorectFileFormat; f.Free; exit; end; Form1.memo1.Lines.Add(String(ID)); f.ReadBuffer(wFileSize, 4); Form1.memo1.Lines.Add('' + intToStr(wFileSize)); if f.size <> (wFileSize + 8) then Begin Result.ERROR := FileCorrupt; f.Free; exit; end; f.ReadBuffer(ID[0], 4); Form1.memo1.Lines.Add(String(ID)); if String(ID) <> 'WAVE' then Begin Result.ERROR := IncorectFileFormat; f.Free; exit; end; wChankSize := 0; repeat f.Seek(wChankSize, soFromCurrent); f.ReadBuffer(ID[0], 4); Form1.memo1.Lines.Add(String(ID)); f.ReadBuffer(wChankSize, 4); if wChankSize > High(integer) then Begin Result.ERROR := DataError; f.Free; exit; end; Form1.memo1.Lines.Add('' + intToStr(wChankSize)); until (String(ID)='fmt ') or (String(ID)='data'); if String(ID)='data' then Begin Result.ERROR := HeaderError; f.Free; exit; end; f.ReadBuffer(Header, Min(wChankSize, SizeOf(TWaveHeaderChank))); Form1.memo1.Lines.Add('' + intToStr(Header.wFormatTag)); Form1.memo1.Lines.Add('' + intToStr(Header.wChannels)); Form1.memo1.Lines.Add('' + intToStr(Header.wSamplesPerSec)); Form1.memo1.Lines.Add('' + intToStr(Header.wAvgBytesPerSec)); Form1.memo1.Lines.Add('' + intToStr(Header.wBlockAlign)); Form1.memo1.Lines.Add('' + intToStr(Header.wBitsPerSample)); if wChankSize > SizeOf(TWaveHeaderChank) then f.Seek(wChankSize - SizeOf(TWaveHeaderChank), soFromCurrent); if wChankSize >= SizeOf(TWaveHeaderChank) then Form1.memo1.Lines.Add('' + intToStr(Header.wcbSize)); wChankSize := 0; repeat f.Seek(wChankSize, soFromCurrent); f.ReadBuffer(ID[0], 4); Form1.memo1.Lines.Add(String(ID)); f.ReadBuffer(wChankSize, 4); Form1.memo1.Lines.Add('' + intToStr(wChankSize)); until String(ID)='data'; //Попытка считать Сэмплы if Header.wFormatTag<>1 then begin Form1.Memo1.Lines.Add('ОШИБКА! Я умею читать wav-файлы только в формате PCM, а этот файл в формате 0x'+IntToHex(Header.wFormatTag, 4)); end; SampleSize:=(Header.wBitsPerSample+7) div 8; if SampleSize>SizeOf(sample) then begin Form1.Memo1.Lines.Add('ОШИБКА! Слишком большой размер сэмпла ('+IntToStr(SampleSize)+' байт)'); Exit; end; if Header.wChannels=0 then begin Form1.Memo1.Lines.Add('ОШИБКА! Нет каналов'); Exit; end; Form1.Memo1.WordWrap:=False; Form1.Memo1.ScrollBars:=ssBoth; sample:=0; i:=0; while wChankSize>=(SampleSize*Header.wChannels) do begin if Header.wBlockAlign>0 then begin n:=f.Position mod Header.wBlockAlign; if n>0 then begin n:=Header.wBlockAlign-n; f.Seek(n, soFromCurrent); Dec(wChankSize, n); if wChankSize<(SampleSize*Header.wChannels) then Break; end; end; Inc(i); s1:=''; for chanel := 1 to Header.wChannels do begin f.ReadBuffer(sample, SampleSize); Dec(wChankSize, SampleSize); s1:=s1+IntToHex(sample, SampleSize*2); end; Form1.Memo1.Lines.Add(s1); end; exit; f.Free; Except Result.ERROR := ReadError; end; end; procedure TForm1.Button1Click(Sender: TObject); var r : TWaveResult; begin if opendialog1.Execute then r := ReadWave(opendialog1.FileName); end; procedure TForm1.Button2Click(Sender: TObject); begin if SaveDialog1.Execute then Form1.Memo1.Lines.SaveToFile(Form1.SaveDialog1.FileName + '.txt'); end; procedure TForm1.Button5Click(Sender: TObject); begin if OpenDialog2.Execute then Form1.Memo2.Lines.LoadFromFile(Form1.OpenDialog2.FileName + ''); end; procedure TForm1.Button3Click(Sender: TObject); begin Memo1.Clear; end; procedure TForm1.Button6Click(Sender: TObject); begin Memo2.Clear; end; procedure WriteWav(const FileName: String); type TMassiv = array of array of Integer; TChunkID = packed array [0..3] of Char; THeader = packed record ChunkID : TChunkID; ChunkSize : Longword; Format : TChunkID; Subchunk1ID : TChunkID; Subchunk1Size : Longword; AudioFormat : Word; NumChannels : Word; SampleRate : Longword; ByteRate : Longword; BlockAlign : Word; BitsPerSample : Word; Subchunk2ID : TChunkID; Subchunk2Size : Longword; end; var Header: THeader; NumSamples, BytsPerSample, Sample, I, J: Longword; fs: TFileStream; Massiv: TMassiv; begin NumSamples := 1079; {Massiv[I, J];} BytsPerSample := 2; Header.ChunkID := 'RIFF'; Header.ChunkSize := StrToInt(Form1.Memo2.Lines[1]); Header.Format := 'WAVE'; Header.Subchunk1ID := 'fmt '; Header.Subchunk1Size := StrToInt(Form1.Memo2.Lines[4]); Header.AudioFormat := $0001; Header.NumChannels := StrToInt(Form1.Memo2.Lines[6]); Header.SampleRate := StrToInt(Form1.Memo2.Lines[7]); Header.ByteRate := StrToInt(Form1.Memo2.Lines[8]); Header.BlockAlign := StrToInt(Form1.Memo2.Lines[9]); Header.BitsPerSample := StrToInt(Form1.Memo2.Lines[10]); Header.Subchunk2ID := 'data'; Header.Subchunk2Size := StrToInt(Form1.Memo2.Lines[12]); fs := TFileStream.Create('New File.wav',fmCreate); try fs.WriteBuffer(Header, SizeOf(Header)); for I := 1 to NumSamples do begin for J := 1 to Header.NumChannels do begin Sample := 1111; fs.WriteBuffer(Sample, BytsPerSample); end; end; finally fs.Free; end; end; procedure TForm1.Button4Click(Sender: TObject); begin if SaveDialog2.Execute then begin WriteWav(SaveDialog2.FileName); end; end; end. |
#73
|
||||
|
||||
Цитата:
У вас функция ReadWave для возвращения результата уже использует структуру такого вида: Код:
type TWaveResult = record ERROR : WORD; wAvgBytesPerSec: Cardinal; wBitsPerSample : WORD; wChannels : WORD; Data : TMemoryStream; end; |
#74
|
|||
|
|||
Цитата:
|
#75
|
||||
|
||||
Цитата:
Дополнять нужно теми параметрами, которые можно прочитать из wav-файла в функции ReadWave, и которые нужно потом передать в процедуру WriteWav. |