Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.02.24;
Скачать: CL | DM;

Вниз

Заголовок 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 вся ветка

Текущий архив: 2008.02.24;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.019 c
2-1201628983
iwik
2008-01-29 20:49
2008.02.24
Передать данные в dll


11-1184171451
MTsv DN
2007-07-11 20:30
2008.02.24
Новости http://www.kolnmck.ru/


15-1200748755
Putnik
2008-01-19 16:19
2008.02.24
Статьи по работе с указателями


2-1201887760
Igora
2008-02-01 20:42
2008.02.24
Помогите кто знает, как сделать


15-1201008015
Vendict
2008-01-22 16:20
2008.02.24
Аудит в Windows