Цитата:
Сообщение от Dmitry_DM
poli-smen, я все сделал и у меня все работает, как я хотел. Но в то время пока я занимался медиаплеером и графиками, (по чистой случайности заметил), перестала работать ЗАПИСЬ нового wav. Причину я, скорее всего, вычислил. Это идентификатор NumSamples. Он стал находится в
Код:
TWavInfo = record
WaveFormat: TWaveFormat;
NumSamples: Integer;
MaxAmplitude: Integer;
Samples: packed array of array of Smallint;
end;
Я так понял это нужно для построения графика. Но перестала работать запись, просто кнопка не работает.
Я заметил в процедуре чтения эту новую строчку:
Код:
WavInfo.NumSamples := LongInt(NumSamples);
|
Это просто преобразование типов (так как локальная переменная NumSamples является беззнаковым целым, а поле WavInfo.NumSamples целое со знаком), но в процедуре чтения не только это изменилось.
Самое главное изменение это то, что в массиве Samples поменялись местами размерности. Это изменение связано с особенностью реализации динамических массивов в Delphi, а именно то что:
Код:
SetLength(Samples, 10000000, 2); // такая команда съест значительно больше памяти
SetLength(Samples, 2, 10000000); // чем такая
А так как у звукового файла количество каналов невелико (обычно 1 или 2), а сэмплов наоборот может быть довольно значительное количество, то имело смысл сделать первой размерностью именно номер канала, а не сэмпла, как было до этого. Из-за этого изменения теперь нельзя получить количество сэмплов таким образом:
Код:
NumSamples := Length(WavInfo.Samples);
Вместо этого в структуру TWavInfo было добавлено новое поле NumSamples, которое теперь и нужно читать, чтобы узнать количество сэмплов:
Код:
NumSamples := WavInfo.NumSamples;
Ну и конечно, в связи с изменением порядка размерностей в массиве Samples теперь к его элементам нужно обращаться "наоборот":
Код:
// Т.е. вместо:
fs.WriteBuffer(WavInfo.Samples[I - 1, J - 1], BytsPerSample);
// нужно писать так:
fs.WriteBuffer(WavInfo.Samples[J - 1, I - 1], BytsPerSample);
Кроме того, в структуру TWavInfo добавлено поле MaxAmplitude в которое процедура чтения записывает максимальное значение амплитуды звука (это значение потом используется для нормального масштабирования при прорисовке), ну и у массива Samples поменялся тип его элементов: вместо беззнакового (Word) теперь используется знаковый (Smallint) двухбайтовый тип, так как сэмплы в действительности и являются числами со знаком (по крайней мере в формате PCM это именно так).
Цитата:
Сообщение от Dmitry_DM
Код записи:
Код:
procedure WriteWav(const FileName: string; const WavInfo: TWavInfo);
...
var
Header: THeader;
NumSamples, BytsPerSample, I, J: Longword;
fs: TFileStream;
begin
NumSamples := LongInt(NumSamples); //это я изменил, думал поможет, нет!
...
|
Нет, эта команда тут лишена смысла.
В программе рисования звуковой волны процедура сохранения была не нужна, поэтому её я не переделывал (и не использовал), но теперь у тебя есть вся информация для её переделки.