Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Мультимедиа
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 22.09.2012, 17:18
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию Сэмплы, асимметрия и эксцесс

Здравствуйте! Столкнулся с проблемой. Надо вычислить асимметрию и эксцесс по сэмплам wav файла. Я точно не знаю правильно ли оно считается, потому что возникли непонятки с сэмплами и Max Amplitude. Я вывожу все сэмплы в txt файл и вижу, например следующее:
Код:
65529 {Я считаю, это не настоящие значение}
9 {А вот такое - нормальное}
65525
15 {Ну и такое - нормальное}
65510
78 {И такое}
50
65514
13
65521
65528
65504
65506
В общем понятно. Из-за этого постоянно Max Amplitude = 65535. И так с любым файлом. Этого же не может быть, верно? Так вот что здесь не так, помогите! Следовательно и формулы не правильно вычисляют.
Вот код этого всего дела.
P.S Выводы в memo сделал просто для наглядности.
Код:
      Sample := 0;
      Sl:=tStringlist.Create;
      for I := 1 to NumSamples do
      begin
        for J := 1 to WavInfo.WaveFormat.nChannels do
        begin
          fs.ReadBuffer(Sample, BytsPerSample);
         case BytsPerSample of
            1: Sample := Int64(Sample);
            2: Sample := Int64(Sample);
          end;
      WavInfo.Samples[J - 1, I - 1] := Sample;
      if Abs(Sample) > WavInfo.MaxAmplitude then WavInfo.MaxAmplitude := Abs(Sample);

         sl.Add(IntToStr(Sample));

        end;
      end;
      sl.SaveToFile('Samples.txt');
         SL.Free;
    WavInfo.NumSamples := LongInt(NumSamples);
    end;

    for Sample := 1 to NumSamples do
      begin
        s:=s+Sample;
      end;
    Xch:=S/NumSamples;

    S2:=0;
    for Sample := 1 to NumSamples do
    begin
    S2:=s2+Sqr(Sample-Xch);
    end;
    M1:=Sqrt((s2/NumSamples)*(s2/NumSamples)*(s2/NumSamples));
      {Form1.Memo3.Lines.Add('S2(1): '+FloatToStr(s2));  }
    S2:=0;
    for Sample := 1 to NumSamples do
    begin
    S2:=s2+(Sample-Xch)*(Sample-Xch)*(Sample-Xch);
    end;
    M2:=(s2/NumSamples);
      {Form1.Memo3.Lines.Add('S2(2): '+FloatToStr(s2)); }
    S2:=0;
    for Sample := 1 to NumSamples do
    begin
    S2:=s2+sqr(Sample-Xch);
    end;
    M3:=Sqr(s2/NumSamples);
      {Form1.Memo3.Lines.Add('S2(3): '+FloatToStr(s2)); }
    S2:=0;
    for Sample := 1 to NumSamples do
    begin
    S2:=s2+sqr(Sqr(Sample-Xch));
    end;
    M4:=(s2/NumSamples);
      {Form1.Memo3.Lines.Add('S2(4): '+FloatToStr(s2));  }
    A:=M2/m1;
    E:=m4/m3;

    Form1.Memo3.Lines.Add('S: '+intToStr(s));
    Form1.Memo3.Lines.Add('Xch: '+FloatToStr(Xch));
    Form1.Memo3.Lines.Add('M1: '+FloatToStr(m1));
    Form1.Memo3.Lines.Add('M2: '+FloatToStr(m2));
    Form1.Memo3.Lines.Add('M3: '+FloatToStr(m3));
    Form1.Memo3.Lines.Add('M4: '+FloatToStr(m4));
     Form1.Memo3.Lines.Add('Asymmetry: '+FloatToStr(A));
     Form1.Memo3.Lines.Add('Excess: '+FloatToStr(E));
    Form1.Memo3.Lines.Add('MaxAmplitude: ' + IntToStr(WavInfo.MaxAmplitude));

Последний раз редактировалось Dmitry_DM, 22.09.2012 в 17:25.
Ответить с цитированием
  #2  
Старый 22.09.2012, 21:34
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Ну помогите мне, пожалуйста! Мне срочно надо, чтобы двигаться дальше.
Ответить с цитированием
  #3  
Старый 23.09.2012, 20:38
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Здравствуйте! Столкнулся с проблемой. Надо вычислить асимметрию и эксцесс по сэмплам wav файла. Я точно не знаю правильно ли оно считается, потому что возникли непонятки с сэмплами и Max Amplitude. Я вывожу все сэмплы в txt файл и вижу, например следующее:
Код:
65529 {Я считаю, это не настоящие значение}
9 {А вот такое - нормальное}
65525
15 {Ну и такое - нормальное}
65510
78 {И такое}
50
65514
13
65521
65528
65504
65506
Это просто отрицательные числа. Например 65529 это на самом деле -7 (минус семь), 65525 это -11 и т.д.
Цитата:
Сообщение от Dmitry_DM
Код:
          fs.ReadBuffer(Sample, BytsPerSample);
         case BytsPerSample of
            1: Sample := Int64(Sample);
            2: Sample := Int64(Sample);
          end;
Откуда здесь взялось Int64? У меня в коде такого не было. В этом месте и возникает проблема. Верни так как было в моём коде и всё будет нормально работать.
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
Dmitry_DM (23.09.2012)
  #4  
Старый 23.09.2012, 21:36
robt robt вне форума
Активный
 
Регистрация: 17.02.2011
Сообщения: 298
Репутация: -1806
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Надо вычислить асимметрию и эксцесс
это что за хрень
Ответить с цитированием
  #5  
Старый 23.09.2012, 21:49
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от robt
это что за хрень
Проще говоря: в моем случае асимметрия - это отклонение от нормального распределения по оси X, а эксцесс - это отклонение от нормального распределения по оси Y. В результате вычисления асимметрия должна близиться к 0, а эксцесс - к 3.
Ответить с цитированием
  #6  
Старый 23.09.2012, 21:58
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от poli-smen
Это просто отрицательные числа. Например 65529 это на самом деле -7 (минус семь), 65525 это -11 и т.д.
Откуда здесь взялось Int64? У меня в коде такого не было. В этом месте и возникает проблема. Верни так как было в моём коде и всё будет нормально работать.
Так было?
Код:
         
case BytsPerSample of
            1: Sample := ShortInt(Sample);
            2: Sample := SmallInt(Sample);
end;
Да, было так. Но у меня выводится странные строки в txt файл. Они во внимание программы не берутся, так как макс амплитуда корректно показывает. А эти строки такого типа:
4294966664
4294967086
4294967113
Как их убрать?
И еще одно: в txt файле с выведенными всеми сэмплами, нету сэмпла, равному MaxAmplitude. Хотя раньше (С Int64) такое число находилось. Неувязка получается..
А еще я заметил, что если в файле число байт для предоставления одного отчета: 4, а не 2, то сэмплов в txt файле в 2 раза больше, чем указано в NumSamples. Еще одна неувязка..

Последний раз редактировалось Dmitry_DM, 23.09.2012 в 22:25.
Ответить с цитированием
  #7  
Старый 23.09.2012, 23:11
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Так было?
Код:
         
case BytsPerSample of
            1: Sample := ShortInt(Sample);
            2: Sample := SmallInt(Sample);
end;
Да, было так. Но у меня выводится странные строки в txt файл. Они во внимание программы не берутся, так как макс амплитуда корректно показывает. А эти строки такого типа:
4294966664
4294967086
4294967113
Как их убрать?.
А переменная Sample каким типом объявлена?
Ответить с цитированием
  #8  
Старый 24.09.2012, 11:42
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от poli-smen
А переменная Sample каким типом объявлена?
Тип Longword
Я попробовал повысить его до LongInt. Теперь все нормально (с величиной чисел). Вот только я не знаю:числа у меня вывелись <0 и >0. Это логично. Но по-моему не логично то, что на графике столбик-сэмпл выше оси OX соответствует отрицательному числу в txt файле. Как бы наоборот получается...
P.S Всегда MaxAmplitude положительное, это из-за:
Код:
if Abs(Sample) > WavInfo.MaxAmplitude then WavInfo.MaxAmplitude := Abs(Sample);
Но всегда эта MaxAmplitude в TXT файле отрицательна.
И еще все же мне непонятно так должно быть или нет: когда в wav BlockAling 4, а не 2, то сэмплов выводиться ровно в 2 раза больше.

Последний раз редактировалось Dmitry_DM, 24.09.2012 в 11:56.
Ответить с цитированием
  #9  
Старый 24.09.2012, 13:57
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Тип Longword
Я попробовал повысить его до LongInt. Теперь все нормально (с величиной чисел).
Сейчас посмотрел свои исходники - там действительно переменная Sample объявлена как Longword, но ошибок не возникает из-за того, что я эту переменную использую только как минибуфер для чтения/записи. Если же с этой переменной нужно производить вычисления, то её нужно объявлять как LongInt.
Цитата:
Сообщение от Dmitry_DM
Вот только я не знаю:числа у меня вывелись <0 и >0. Это логично. Но по-моему не логично то, что на графике столбик-сэмпл выше оси OX соответствует отрицательному числу в txt файле. Как бы наоборот получается...
В Windows'е принято, что координата 0,0 находится в левом верхнем углу и ордината (т.е. координата OY) увеличивается по направлению вниз, а в математике ордината увеличивается по направлению вверх. "Как бы наоборот получается..."
Чтобы перевернуть ординату в правильное положение нужно просто вычесть её из высоты (или из другой константы).

Цитата:
Сообщение от Dmitry_DM
P.S Всегда MaxAmplitude положительное, это из-за:
Код:
if Abs(Sample) > WavInfo.MaxAmplitude then WavInfo.MaxAmplitude := Abs(Sample);
Но всегда эта MaxAmplitude в TXT файле отрицательна.
MaxAmplitude всегда положительна, так как это абсолютная величина и не имеет смысла делать её отрицательной. А вот само значение максимальной амплитуды не обязательно будет только отрицательным - это как уж повезёт с wav-файлом.
Цитата:
Сообщение от Dmitry_DM
И еще все же мне непонятно так должно быть или нет: когда в wav BlockAling 4, а не 2, то сэмплов выводиться ровно в 2 раза больше.
А зачем вручную менять BlockAling? Там в процедуре WriteWav ей присваивается автоматически нужное значение.
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
Dmitry_DM (24.09.2012)
  #10  
Старый 24.09.2012, 14:01
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от poli-smen
Чтобы перевернуть ординату в правильное положение нужно просто вычесть её из высоты (или из другой константы).
Можно по-подробнее?
Цитата:
Сообщение от poli-smen
А зачем вручную менять BlockAling? Там в процедуре WriteWav ей присваивается автоматически нужное значение.
Я то понимаю, я хочу, что бы не выводилось в 2 раза больше сэмплов только из-за того, что BlockAling = 4.
Или это так надо, исходя из того, что используется 2 канала?

Последний раз редактировалось Dmitry_DM, 24.09.2012 в 14:17.
Ответить с цитированием
  #11  
Старый 24.09.2012, 14:58
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Можно по-подробнее?
Код:
    for i := X1 to X2 do
    begin
      X := Trunc(KX * (i - X1));
      Y := aHeight - Trunc(KY * FWavInfo.Samples[Chanel, i] + DY);
         //^^^^^^^^^ - ВОТ ЭТО ДОБАВИТЬ
      if DrawWaveForm then
      begin
        if i = X1 then Can.MoveTo(X, Y) else Can.LineTo(X, Y);
      end else
      begin
        Can.Rectangle(X, DY, Trunc(KX * (i - X1 + 1)), Y);
      end;
    end;

Цитата:
Сообщение от Dmitry_DM
Я то понимаю, я хочу, что бы не выводилось в 2 раза больше сэмплов только из-за того, что BlockAling = 4.
BlockAlign вычисляется так:
Код:
Header.BlockAlign := Header.NumChannels * BytsPerSample;
Если звук двухканальный и двубайтный (т.е. 16-ти-битный), то как раз и получится 4 байта на сэмпл. А как можно вместить двухканальный двухбайтный сэмпл в 2 байта?
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
Dmitry_DM (24.09.2012)
  #12  
Старый 24.09.2012, 15:15
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Цитата:
Сообщение от poli-smen
Код:
    for i := X1 to X2 do
    begin
      X := Trunc(KX * (i - X1));
      Y := aHeight - Trunc(KY * FWavInfo.Samples[Chanel, i] + DY);
         //^^^^^^^^^ - ВОТ ЭТО ДОБАВИТЬ
      if DrawWaveForm then
      begin
        if i = X1 then Can.MoveTo(X, Y) else Can.LineTo(X, Y);
      end else
      begin
        Can.Rectangle(X, DY, Trunc(KX * (i - X1 + 1)), Y);
      end;
    end;

BlockAlign вычисляется так:
Код:
Header.BlockAlign := Header.NumChannels * BytsPerSample;
Если звук двухканальный и двубайтный (т.е. 16-ти-битный), то как раз и получится 4 байта на сэмпл. А как можно вместить двухканальный двухбайтный сэмпл в 2 байта?
Все понятно. Спасибо большое за помощь!!!
Ответить с цитированием
  #13  
Старый 25.09.2012, 16:24
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Здравствуйте! Столкнулся с проблемой. Надо вычислить асимметрию и эксцесс по сэмплам wav файла. Я точно не знаю правильно ли оно считается, потому что возникли непонятки с сэмплами и Max Amplitude.
Очень сильно сомневаюсь, что этот код действительно вычисляет "асимметрию и эксцесс по сэмплам wav файла". Почему? Потому-что единственное что участвует в вычислениях это NumSamples (количество сэмплов), а сами сэмплы нигде не участвуют.

Ну ладно. Теперь комментарии по коду:
Цитата:
Сообщение от Dmitry_DM
Код:
for Sample := 1 to NumSamples do
  begin
    s:=s+Sample;
  end;
Во-первых где инициализация переменной s?
Во-вторых зачем в цикле складывать числа от 1 до NumSamples если для этого есть формула суммы арифметической прогрессии: , благодаря которой этот кусок кода превращается в такой:
Код:
s := s + (NumSamples + 1) * NumSamples div 2;

А следующие 4 цикла можно объединить в один:
Код:
  M1 := 0;
  M2 := 0;
  M4 := 0;
  for Sample := 1 to NumSamples do
  begin
    S2 := Sample - Xch;
    M3 := Sqr(S2);

    M1 := M1 + M3;
    M2 := M2 + M3 * S2;
    M4 := M4 + Sqr(M3);
  end;

  S2 := M1 / NumSamples;
  M1 := S2 * S2 * S2;
  M2 := M2 / NumSamples;
  M3 := Sqr(S2); 
  M4 := M4 / NumSamples; 
Этот код я проверил - выдаёт тот же результат, что и твой
Например при NumSamples:=12345 и твой и мой код выводят:
Цитата:
S: 76205685
Xch: 6173
M1: 45258630618,8337
M2: 0
M3: 161287934139948
M4: 290318278911923
Asymmetry: 0
Excess: 1,79999998425187
Ответить с цитированием
  #14  
Старый 25.09.2012, 21:28
Dmitry_DM Dmitry_DM вне форума
Активный
 
Регистрация: 07.08.2012
Сообщения: 258
Версия Delphi: Delphi 7
Репутация: 11
По умолчанию

Ну почему же Sample не участвует в вычислениях? Ведь именно это число самое главное, к тому же подтверждением этих сэмплов есть вывод их в txt. Они там благополучно присутствуют.
На счет инициализации s: Что, просто поставить в начале всего процесса S:=0; ? И еще: почему мы заменяем
Код:
s:=s+Sample;
на это?
Код:
s := s + (NumSamples + 1) * NumSamples div 2;

Если по формуле надо к S прибавлять X[i]. В моем случае это Sample.
На счет объединения я согласен, так лучше.
И все же меня обеспокоило, что вы думаете, что Sample не участвуют в вычислениях. А ведь должны...
Кстати я попробовал на своем файле ваш и мой коды и результаты отличаются. Вот мой код:
Код:
S: 2128579200
Xch: 5340,24566473988
M1: 1,14695763333214E16
M2: 1,50001740981296E16
M3: 2,58660334456677E21
M4: 4,71908198619544E21
Asymmetry: 1,30782285781133
Excess: 1,82443202824585
MaxAmplitude: 24927
BytsPerSample: 2
NumSamples: 398592
Вот ваш код:
Код:
S: 2128579200
Xch: 5340,24566473988
M1: 1,31551181265887E32
M2: 1,50001740981296E16
M3: 2,58660334456677E21
M4: 4,71908198619544E21
Asymmetry: 1,14025385053835E-16
Excess: 1,82443202824585
MaxAmplitude: 24927
BytsPerSample: 2
NumSamples: 398592
А еще если заменить мою строчку этой
Код:
s := s + (NumSamples + 1) * NumSamples div 2;

то вообще будет так:
Код:
S: -1789100032
Xch: -4488,54977520873
M1: 1,6427827395735E32
M2: 1,65569732810786E16
M3: 2,99953145624851E21
M4: 5,33904181819595E21
Asymmetry: 1,00786140992552E-16
Excess: 1,77995860222565
MaxAmplitude: 24927
BytsPerSample: 2
NumSamples: 398592
И как будет правильно я не знаю, что вы посоветуете?

Последний раз редактировалось Dmitry_DM, 25.09.2012 в 21:41.
Ответить с цитированием
  #15  
Старый 26.09.2012, 03:00
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Dmitry_DM
Ну почему же Sample не участвует в вычислениях?
Где я писал что Sample не участвует в вычислениях? Я писал что в вычислениях не участвуют сэмплы из wav-файла.
Цитата:
Сообщение от Dmitry_DM
Ведь именно это число самое главное, к тому же подтверждением этих сэмплов есть вывод их в txt. Они там благополучно присутствуют.
Я и не писал что в выводе в файл они не участвуют. Но после вывода в файл идут вычисления, и вот в вычислениях они уже не участвуют.
Цитата:
Сообщение от Dmitry_DM
На счет инициализации s: Что, просто поставить в начале всего процесса S:=0; ?
Можно в начале процесса, но лучше сразу перед подсчётом суммы, т.е. так как это сделано для переменной S2.
Цитата:
Сообщение от Dmitry_DM
И еще: почему мы заменяем
Код:
s:=s+Sample;
на это?
Код:
s := s + (NumSamples + 1) * NumSamples div 2;
Нет, нет. Я не писал что нужно заменить одну строчку на другую. Заменять нужно весь цикл на ту строчку. Т.е. заменить это:
Код:
for Sample := 1 to NumSamples do
  begin
    s:=s+Sample;
  end;
на это:
Код:
s := s + (NumSamples + 1) * NumSamples div 2;
И если переменная S должна быть проинициализирована нулём, то строчку S:=0; в твоём случае нужно поставить сразу перед циклом, а в моём случае упростить заменяющую строчку на такую:
Код:
s := (NumSamples + 1) * NumSamples div 2;
Цитата:
Сообщение от Dmitry_DM
Кстати я попробовал на своем файле ваш и мой коды и результаты отличаются.
Да, я там забыл квадратный корень из M1. В программе во время теста исправил, а при отправке на форум исправить забыл
Смотри во вложении тестовый пример. Там левая кнопка выводит в левый Memo результат работы твоего кода, а правая кнопка выводит в правый Memo результат работы моего кода. Результаты не должны отличаться. Для вычислений открывать wav-файл не нужно, достаточно ввести в поле ввода значение NumSamples (количество сэмплов), которые ты можешь получить открыв wav-файл в своей программе, ну и заодно убедиться, что результаты работы в твоей программе и в этом тестовом примере не отличаются и не зависят от самого wav-файла.
И ещё обрати внимание, что у тебя там происходит переполнение: если сложить все числа от 1 до 398592 (т.е. 1+2+3+...+398591+398592), то должно получиться огромное число 79437990528, а у тебя показывает всего лишь:
Цитата:
Сообщение от Dmitry_DM
Код:
S: 2128579200
...
Явное переполнение (18 раз). Это всё потому что максимальное число которое можно записать в переменную типа LongWord равно 4294967295. Чтобы не было переполнения нужно использовать более вместительные типы Int64 или Extended.
Цитата:
Сообщение от Dmitry_DM
И как будет правильно я не знаю, что вы посоветуете?
Ну, по моему, это и так понятно - нужно чтобы в вычислении участвовали также и сэмплы из wav-файла, а не только NumSamples.
Вложения
Тип файла: 7z CalcNumSamples.7z (1.9 Кбайт, 4 просмотров)
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
Dmitry_DM (26.09.2012)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:53.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter