Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
15-1201140506
O.O
2008-01-24 05:08
2008.02.24
Перевод числа в строку на разных языках


2-1201512491
@!!ex
2008-01-28 12:28
2008.02.24
Запрет SWAP a для приложения


3-1191993601
Kolan
2007-10-10 09:20
2008.02.24
Почему в QueryAnalyzer е скрипт работает, а у меня нет?


15-1201091326
Bober_crazy
2008-01-23 15:28
2008.02.24
Ошибка 530 Authentication failed, sorry


15-1201017444
sauron
2008-01-22 18:57
2008.02.24
BIOS?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский