0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
1

Получение данных из аудиофайла

16.02.2014, 00:00. Показов 2813. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Необходим код программы, открывающей уже имеющийся аудиофайл и извлекающий данные из него по следующему принципу: 1)задаются временные границы (например 2:30 начало и 2:55 конец, то есть работаем с 15 секундами открытого аудиофайла)
2) задается шаг, с которым будем идти по выделенному временному интервалу (например наш интервал в 15 секунд мы разобьем на 30 интервалов с ШАГОМ 0,5 секунд)
3) вычисляются значения амплитуды аудиофайла начиная с нижней границы с заданным шагом до верхней границы
В итоге в программе должны храниться данные типа х1-у1, х2-у2 и тд, где х и у- амплитуда и отсчет времени, в который производилось измерение амплитуды. Вот такую вот своеобразнуй программу "оцифровки" я ищу. Находил до этого лишь программы по работе со звуком в реальном времени (данные снимались в режиме реального времени с аудиовхода звуковой карты), а хотелось бы поработать со звуком в офлайне.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.02.2014, 00:00
Ответы с готовыми решениями:

Получение метаданных аудиофайла в Qt5 без использования QMediaPlayer?
Здравствуйте. Получить метаданные проигрываемого в данный момент файла легко: player = new...

Линк данных Access-Excel, Получение данных с внешних источников
Описание задачи: Есть некая база в Аксесе, данные с которой выгружаются в ексель с помощью линка....

Получение данных с веб-страницы с закраской ячеек в определенный цвет в зависимости от ID данных
Помогите пожалуйста с написанием макроса, т.к. в VB особенно не разбираюсь. Макрос должен по...

Ввод данных, добавление данных, получение информации из файла по заданным критериям выборки
Все привет!!!Обращаюсь к вам за помощью...никак не получается решить задачку... Суть...

10
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
16.02.2014, 16:25  [ТС] 2
нашел в инете похожую программу, помогите, пожалуйста, разобраться в коде. Код ниже открывает wav-файл и строит его осциллограмму. Вопросы по коду: 1) зачем нужны переменные w1 и w2?
2) зачем при построении графика в цикле делить всю длину файла на 4?
3) как понять 5000/r.Data.Size*i? То есть зачем делить постоянное число на длину всего файла, умноженную на 1,2,3,4 ... до длины файла?
К посту прикреплена сама прога, если что.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TForm1.Button1Click(Sender: TObject);
var
  r : TWaveResult;
  i : integer;
  W1, W2 : SmallInt;
begin
  if opendialog1.Execute
  then
    r := ReadWave(opendialog1.FileName);
 
  r.Data.seek(0, soFromBeginning);
 
  Form1.Canvas.MoveTo(100, 200);
  for i := 1 to r.Data.Size div 4
  do
   Begin
      r.Data.readBuffer(W1, 2);
      r.Data.readBuffer(W2, 2);
      Form1.Canvas.LineTo(round(100+5000/r.Data.Size*i), round(200+W1/200));
 
   end;
end;
Вложения
Тип файла: rar Wav.rar (37.0 Кб, 20 просмотров)
0
Пишу на Delphi...иногда
1423 / 1278 / 286
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
16.02.2014, 16:32 3
Цитата Сообщение от Turgenev Посмотреть сообщение
зачем нужны переменные w1 и w2?
это буферы, в которые производится чтение данных (возможно, что два канала)
Цитата Сообщение от Turgenev Посмотреть сообщение
зачем при построении графика в цикле делить всю длину файла на 4?
каждый раз читают два буфера по 2 байта, итого 4 байта, чтобы не было повторений чтения - длину файла делят на 4
Цитата Сообщение от Turgenev Посмотреть сообщение
как понять 5000/r.Data.Size*i?
масштабный коэффициент, умножают на i для того, чтобы новый всплеск рисовался не на этом же месте, а сдвигался (в файле не 5000, а 2000)
1
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
16.02.2014, 18:39  [ТС] 4
За ответ- спасибо, почти понял))
Но я хочу модифицировать программу- увидеть оси и их размерности. Засунул результат программы в чарт:
Delphi
1
Series1.AddXY(i,w2,'',clgreen);
В программу подал тестовый сигнал, созданный при помощи Multi Oscillator Tone Generator 1.9, а именно синусоиду 1кГц с периодом 1с. Результат: синусоида длительностью 85+ чего-то. Это что-то, я так понял, байты и точное их число указывается ниже в мемо в строке chankSize. Проделав тоже самое с файлом песни длительностью 263 сек, получил кол-во байт 50568192. Вывод: у разных файлов свое кол-во байт в сек. Вопросы: 1) как узнать сколько байт в сек для разных файлов?
2) можно ли так вообще строить график, используя лишь w2 как абсциссу и i как ординату? Ведь когда строили через канвас использовали 2 буфера и все эти коэффициенты
3) в чем измеряется амплитуда на оси абсцисс?
0
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
16.02.2014, 18:45  [ТС] 5
вот скрин того, о чем я говорю
Миниатюры
Получение данных из аудиофайла  
0
Пишу на Delphi...иногда
1423 / 1278 / 286
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
16.02.2014, 18:47 6
Цитата Сообщение от Turgenev Посмотреть сообщение
как узнать сколько байт в сек для разных файлов?
Формат WAV-файлов
0
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
16.02.2014, 19:12  [ТС] 7
не не, про организацию wave файла я уже читал, вопрос как вывести именно BytesPerSecond?
Я пытался выводить так же, как выводится размер файла в программе(предварительно описав в структуре файла wBytesPerSecond: LongInt:

Delphi
1
2
   f.ReadBuffer(wBytesPerSecond, 4);  
    Form1.memo1.Lines.Add('bps ' + intToStr(wBytesPerSecond));
Вылетает исключение на строке
Delphi
1
r.Data.seek(0, soFromBeginning);
(описание при нажатии на кнопку открытия файла)
0
пофигист широкого профиля
4732 / 3167 / 858
Регистрация: 15.07.2013
Сообщений: 18,248
16.02.2014, 19:19 8
Цитата Сообщение от Turgenev Посмотреть сообщение
Вылетает исключение на строке
r.Data.seek(0, soFromBeginning);
Объект Data создать забыл.
0
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
16.02.2014, 20:15  [ТС] 9
Цитата Сообщение от northener Посмотреть сообщение
Объект Data создать забыл.
Не понимаю. Я вывожу значение wAvgBytesPerSec так же как и автор выводит значение wFileSize, почему вылезает [Hint] Unit1.pas(67): Variable 'RealFileSize' is declared but never used in 'ReadWave'?


Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, TeEngine, Series, ExtCtrls, TeeProcs, Chart;
 
Const
  noError            = 0;
  ReadError          = 1;
  HeaderError        = 2;
  DataError          = 3;
  FileCorrupt        = 4;
  IncorectFileFormat = 5;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    Chart1: TChart;
    Series1: TFastLineSeries;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  TWaveHeaderChank = record     //Заголвок (чанк) формата
    wFormatTag     : Smallint;
    wChannels      : WORD;
    wSamplesPerSec : Cardinal;
    wAvgBytesPerSec: Cardinal;
    wBlockAlign    : WORD;
    wBitsPerSample : WORD;
    wcbSize        : WORD;
 
  end;
 
  TWaveResult = record          //Минимальная структура
    ERROR          : WORD;      //Используеися для возвращения результата
    wAvgBytesPerSec: Cardinal;  //разбора Wav файла
    wBitsPerSample : WORD;
    wChannels      : WORD;
    Data           : TMemoryStream;
 
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
uses math;
 
Function ReadWave(FileName : AnsiString) : TWaveResult;
var
  f             : TFileStream;
  wFileSize     : Cardinal;
  wChankSize    : Cardinal;
  ID            : array[0..3] of Char;
  Header        : TWaveHeaderChank;
  RealFileSize  : Cardinal;
  
  wAvgBytesPerSec: Cardinal;
 
 
 
Begin
  FillChar(Result, SizeOf(Result), 0);
 
  Try
    f := TFileStream.Create(FileName, fmOpenRead);
    f.Seek(0, soFromBeginning);
    f.ReadBuffer(ID[0], 4);       //читаем тип файла
 
    if String(ID) <> 'RIFF'       //Определяем тип файла
    then
      Begin
        Result.ERROR := IncorectFileFormat;
        f.Free;
        exit;
      end;
      Form1.memo1.Lines.Add(String(ID));
       //////////////////////////
     f.ReadBuffer(wAvgBytesPerSec, 4);   //ТО, ЧТО МНЕ НУЖНО
     Form1.memo1.Lines.Add('bps ' + intToStr(wAvgBytesPerSec));
 
    //////////////////////////
    f.ReadBuffer(wFileSize, 4);   //ТО, КАК ВЫВОДИТ АВТОР
    Form1.memo1.Lines.Add('FileSize ' + intToStr(wFileSize));
    //////////////////////////
0
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
16.02.2014, 20:30  [ТС] 10
Я обгуглился на счет вывода параметров wav файла, нашел только уже готовую прогу без кодинга. Не подскажете ли Вы где глянуть кодинг подобной проги?
Вложения
Тип файла: rar WFI.rar (381.1 Кб, 20 просмотров)
0
0 / 0 / 1
Регистрация: 14.11.2012
Сообщений: 269
17.02.2014, 16:25  [ТС] 11
Эврика! Извините, что получается спамлю, но пишу я сюда сразу же как только возникает вопрос дабы ускорить процесс. С радостью удалял бы уже бесполезные сообщения, если бы мог... А проблема была глупой, надо было лишь добавить в вывод нужный параметр вот тут:
Delphi
1
2
3
4
5
6
7
8
 f.ReadBuffer(Header, Min(wChankSize, SizeOf(TWaveHeaderChank))); //×èòàåì çàãîëîâîê
      //////////////////////////               //ìåíüøå íàøåé ñòðóêòóðû
      Form1.memo1.Lines.Add('wFormatTag '     + intToStr(Header.wFormatTag));
      Form1.memo1.Lines.Add('wChannels '      + intToStr(Header.wChannels));
      Form1.memo1.Lines.Add('wSamplesPerSec ' + intToStr(Header.wSamplesPerSec));
      Form1.memo1.Lines.Add('wBlockAlign '    + intToStr(Header.wBlockAlign));
      Form1.memo1.Lines.Add('wBitsPerSample ' + intToStr(Header.wBitsPerSample));
      Form1.memo1.Lines.Add('wAvgBytesPerSec ' + intToStr(Header.wAvgBytesPerSec));
Вопрос по поводу считывания информации, о котором я очень много читал, но просто не понял: считывание происходит в буфер w1 и w2 по 2 байта, поэтому мы делим всю длину файла на 4, чтобы избежать повторений (это почти цитата сообщения cotseec), а что если не делить длину файла и считывать все одним буфером по байту? Разве это не универсальное решение?
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
procedure TForm1.Button1Click(Sender: TObject);
var
  r : TWaveResult;
  i : integer;
  W1 : SmallInt;
begin
Series1.clear;
 
  if opendialog1.Execute
  then
    r := ReadWave(opendialog1.FileName);
 
r.Data.seek(0, soFromBeginning);
 
 
  for i := 1 to r.Data.Size  
  do
   Begin
      r.Data.readBuffer(W1, 1);
   
      Series1.AddXY(i,w1,'',clgreen);
     
 
   end;
end;
Добавлено через 19 часов 27 минут
создаю новую тему, так как был получен ответ на вопрос, ради которого тема изначально создавалась, а вопросы задаваемые далее лишь на понимание кода.
0
17.02.2014, 16:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.02.2014, 16:25
Помогаю со студенческими работами здесь

Получение данных сервером от БД и отображение данных в клиенте DataGridView
Подскажите пожалуйста, как в C# полученные данные сервером из Базы данных(sqlite) передать клиенту...

Получение данных от SQL сервера и отображение данных в DataGridView
Подскажите, пожалуйста, как в шарпе вытащить данные из локальной sql базы данных(саму базу создано...

Передача данных в скрипт и получение данных из скрипта
Здравствуйте! Мучаюсь с задачей уже 4й день, в силу незнанания/плохого знания jQuery. Читаю,...

Получение данных из таблицы базы данных
Добрый день! Такой вопрос. Вот код: OleDbConnection dbCon = new OleDbConnection(...

Передача Аудиофайла
Здравствуйте! Думаю я не первый кто задает данный вопрос, но мне интересно, какими средствами...

Инвертирование аудиофайла
Верно, так же?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru