Форум: "Media";
Текущий архив: 2008.02.24;
Скачать: [xml.tar.bz2];
ВнизЗаголовок wav файла Найти похожие ветки
← →
Дмитрий (Гомель) (2007-03-20 09:08) [0]Итак, здравствуйте, друзья-программисты. Задача такова. Я имею несколько wav файлов одинакового формата PCM, 44100HZ, 16 bit... Собираю их в один файловый поток, предварительно убирая заголовки каждого (фрагмент кода взял из инета - каюсь), прописываю заголовок для полученного файла. Открываю для воспроизведения. И что? Winamp выдает "Invalid Fyle Type" Forge вообще может подвиснуть. Я так понимаю, что с заголовком что-то не так. Код будет через 6 часов выложен. Ваши мнения и поддержка? Кстати, уже благодарен господину Карапетяну за изложение струтуры wav файла. Но где-то собака порылась.
← →
toboom © (2007-03-20 16:29) [1]Судя по выдаваемому сообщению дело именно в заголовке.
В него, наск. я помню, нужно добавлять и длину результирующего файла.
Может ещё какая беда. Но думаю, что именно в заголовке.
← →
TRUNK © (2007-03-20 21:11) [2]> [0] Дмитрий (Гомель) (20.03.07 09:08)
>Код будет через 6 часов выложен
А где он будет выложен?
> [1] toboom © (20.03.07 16:29)
>нужно добавлять и длину результирующего файла
Как таковая, длина файла в заголовке отсутствует. Вместо неё там есть два значения, взаимосвязанных с ней:
1) размер RIFF, меньше или равен FileSize-8;
2) размер звуковых данных, меньше или равен FileSize-44.
← →
Дмитрий (Гомель) (2007-03-21 08:08) [3]Полностью согласен с предыдущими ответами. Однако, склеивая два файла в один, я получаю при проигрывании все равно первый. Файл в размерах как на два, а играет один. Даю фрагмент кода, но сразу оговариваюсь, что "да, я в самом начале в поток прописываю заголовок, но учитываю длину двух файлов, например длина одного 1431344, другого 2855845, то в итоге просто записал сумму, при остальных одинаковых параметрах, может где еще собака порылась". Вот код...:
....
type
TWaveHeader = record
idRiff: array[0..3] of char;
RiffLen: longint;
idWave: array[0..3] of char;
idFmt: array[0..3] of char;
{InfoLen: longint;}
WaveType: smallint;
Ch: smallint;
Freq: longint;
BytesPerSec: longint;
align: smallint;
Bits: smallint;
idData:array[0..3] of char;
end;
{
TDataHeader = record
idData: array[0..3] of char;
DataLen: longint;
end;}
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.DFM}
function GetWaveHeader(FileName: TFileStream): TWaveHeader;
const
riff = "RIFF";
wave = "WAVE";
var
w: TWaveHeader;
begin
FileName.Read(w, Sizeof(w));
if w.idRiff <> riff then
begin
Showmessage("This is not a RIFF File");
exit;
end;
if w.idWave <> wave then
begin
Showmessage("This is not a valid wave file");
exit;
end;
Result := w;
end;
procedure RenderBlocks(Den:integer);
const Modes: array[Boolean] of Word = (fmCreate, fmOpenReadWrite);
const
riff = "RIFF";
wave = "WAVE";
var
i,ix,k,p:integer;
long,long1:longint;
FName,FBlock,F: TFileStream;
DataSize : DWord;
Name,NameBlock,NameBlock1,ListFiles:String;
w,zw: TWaveHeader;
Begin {1}
FBlock := TFileStream.Create(NameBlock, Modes[FileExists(NameBlock)]);
try {4}
FBlock.Seek(0, soFromEnd);
FName:=TFileStream.Create(Name,fmOpenRead);
FName.Seek(0,soFromBeginning);
w := GetWaveHeader(FName);
long:=long+w.RiffLen;
w.RiffLen:=0;
w.RiffLen:=long;{вот здесь и пишу сумму, может надо еще что-то суммировать?}
Fname.Position:=SizeOf(w);
FBlock.Write(w,SizeOf(w));
FBlock.CopyFrom(FName,FName.Size-SizeOf(w));
FName.Free;
{!!}
end; {6}
ix:=ix+1;
end; {5}
finally
w.RiffLen:=0;
w.RiffLen:=long;
FBlock.Free;
{F.Free; }
end; {4}
end; {3}
end;{2}
end;{1}
← →
Дмитрий (Гомель) (2007-03-21 08:50) [4]Ну вот. Ваше мнение? Может еще какой-то параметр нужно изменять. Например, InfoLen...?
← →
wicked © (2007-03-21 16:10) [5]код весь не читал - лениво вглядываться в плохо отформатированный текст...
но после вот этого маразма
> TWaveHeader = record
> idRiff: array[0..3] of char;
> RiffLen: longint;
> idWave: array[0..3] of char;
> idFmt: array[0..3] of char;
> {InfoLen: longint;}
> WaveType: smallint;
> Ch: smallint;
> Freq: longint;
> BytesPerSec: longint;
> align: smallint;
> Bits: smallint;
> idData:array[0..3] of char;
> end;
есть мнение - источник, это выдавший, не имеет права на доверие - это НЕ ЗАГОЛОВОК wav.... это несколько заголовков, склеенных в кучу, причем между ними могут быть еще данные
поэтому, я бы не советовал пользоваться примерами из того же источника - они заведомо неправильные
см. также сюда - http://delphimaster.net/view/8-1173158554/
← →
Дмитрий (Гомель) (2007-03-22 07:56) [6]А теперь ответ для особо "ленивых". Эта запись представляет собой структуру заголовка wav-файла. Причем эта вся вещь теперь работает. Я разобрался. Остальным советую читать доки. Опять же опираюсь на статьи господина Карапетяна, который внятно и доступно изложил все понятия. Весь листинг программы приведу чуть позже. Исправил баги, и склеиваю файлы вместе не два и не три, а то и больше. Причем это я сделал без API. И этим горжусь. Всем удачи... Ждите продолжения.
← →
wicked © (2007-03-22 12:19) [7]> Дмитрий (Гомель) (22.03.07 07:56) [6]
удачи и попутного ветра.... :)
← →
Дмитрий (Гомель) (2007-03-23 08:40) [8]Ну вот в принципе для всех желающих и выкладыдываю код. он был применен для конкретной задачи. но тот, кому это будет нужно, разберется. В принципе смысл следующий - грид представляет собой календарь, в каждой ячейке которого находится несколько файлов (т.е. их названий). При отслеживании н-ого количества файлов в ячейке программа собирает их в один. Ну вот. Рецензии принимаются. Программа работает.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, Calendar;
type
TForm2 = class(TForm)
Calendar1: TCalendar;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
procedure Button2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TWaveHeader = record
idRiff: array[0..3] of char;
RiffLen: longint;
idWave: array[0..3] of char;
idFmt: array[0..3] of char;
InfoLen: longint;
WaveType: smallint;
Ch: smallint;
Freq: longint;
BytesPerSec: longint;
align: smallint;
Bits: smallint;
idData:array[0..3] of char;
idDatalen:longint;
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.DFM}
function GetWaveHeader(FileName: TFileStream): TWaveHeader;
const
riff = "RIFF";
wave = "WAVE";
var
w: TWaveHeader;
begin
FileName.Read(w, Sizeof(w));
if w.idRiff <> riff then
begin
Showmessage("This is not a RIFF File");
exit;
end;
if w.idWave <> wave then
begin
Showmessage("This is not a valid wave file");
exit;
end;
Result := w;
end;
procedure RenderBlocks(Den:integer);
const Modes: array[Boolean] of Word = (fmCreate, fmOpenReadWrite);
const
riff = "RIFF";
wave = "WAVE";
var
i,ix:integer;
long,L:longint;
FName,FBlock,F: TFileStream;
Name,NameBlock,ListFiles:String;
w: TWaveHeader;
Begin {1}
Form1.Gauge1.MinValue:=0;
{Form1.ProgressBar1.Min:=0;}
Form1.Gauge1.MaxValue:=Form1.ListBox3.Items.Count;
Form1.Gauge1.Progress:=0;
{Form1.ProgressBar1.Max:=Form1.ListBox3.Items.Count;
Form1.ProgressBar1.Position:=0;}
for i:=1 to Form1.ListBox3.Items.Count do
begin {2}
if Form1.StringGrid1.Cells[Den,i]<>""
then
begin {3}
{Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+1;}
Form1.Gauge1.Progress:=Form1.Gauge1.Progress+ i;
{Создаем файлстрим на определенное время блока}
NameBlock:="";
NameBlock:="("+IntToStr(Den)+"."+IntToStr(Form1.ComboBox2.Items.IndexOf(Form1.ComboBox2.Text)+1)+") "+Form1.StringGrid1.Cells[0,i]+".wav";
FBlock := TFileStream.Create(NameBlock, Modes[FileExists(NameBlock)]);
F:=TFileStream.Create("temp.tmp", fmCreate);
try {4}
FBlock.Seek(0, soFromEnd);
F.Seek(0, soFromEnd);
{Закончили создание файлстрима на определенное время блока}
ix:=0;
ListFiles:="";
ListFiles:=Form1.StringGrid1.Cells[Den,i];
long:=0;
L:=0;
while ix<=Length(ListFiles) do
begin {5}
if ListFiles[ix]="#"
then
begin {6}
Name:=TecDir+"\"+copy(ListFiles,1,ix-1)+".wav";
Delete(ListFiles,1,ix);
ix:=0;
{!!}
FName:=TFileStream.Create(Name,fmOpenRead);
FName.Seek(0,soFromBeginning);
w := GetWaveHeader(FName);
long:=long+w.RiffLen;
L:=L+w.idDataLen;
Fname.Position:=SizeOf(w);
F.CopyFrom(FName,w.idDataLen);
FName.Free;
{!!}
end; {6}
ix:=ix+1;
end; {5}
finally
F.Free;
w.RiffLen:=0;
w.idDataLen:=0;
w.RiffLen:=long;
w.idDataLen:=L;
FBlock.Seek(0,soFromBeginning);
FBlock.Write(w,SizeOf(w));
F:=TFileStream.Create("temp.tmp", fmOpenRead);
FBlock.copyfrom(F,F.Size);
FBlock.Free;
F.Free;
DeleteFile("temp.tmp")
end; {4}
end; {3}
end;{2}
Form1.Gauge1.Progress:=Form1.Gauge1.MaxValue;
{Form1.ProgressBar1.Position:=Form1.ProgressBar1.Max;
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Min;}
end;{1}
procedure TForm2.Button2Click(Sender: TObject);
begin
Form2.Close;
end;
procedure TForm2.FormShow(Sender: TObject);
begin
Button1.SetFocus;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
d:integer;
begin
d:=0;
d:=Calendar1.Day;
Form2.Hide;
Form2.Close;
RenderBlocks(D);
end;
end.
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2008.02.24;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.041 c