вторник, 16 сентября 2014 г.

Разбираем WAV файл на части

Сегодня 16 число и этой ночью мне почему-то захотелось немного разобраться в аудио формате под названием wav

Точнее, захотелось нарисовать и посмотреть на спектр аудио сигнала моей любимой песни. 



Первое, с чего стоит начать, это собственно, как же устроена структура данного формата, ведь нам надо читать из файла данные.

Из всей просмотренной информации мне больше всего понравилась данная схемка:

структура WAV файла

Для тех кто не очень дружит с иностранщиной предлагаю перевод:

Файл начинается с RIFF
заголовка:


Отступ
(байт)
Длина
(байта)
Название поля
Описание
0
4
ChunkID
Содержит буквы "RIFF" в ASCII
4
4
ChunkSize
Это размер всего файла в байтах за исключением 
8 байт для 2 полей
8
4
Format
Содержит буквы "WAVE"



Файл формата "WAVE" содержит 2 более мелкие блоки: "fmt " and "data": 

"fmt" описывает формат аудио данных:

Отступ
(байта)
Длина
(байта)
Название поля
Описание
12
4
Subchunk1ID
Содержит буквы "fmt "
16
4
Subchunk1Size
16 для PCM.Это размер оставшейся части блока после данных чисел.й
20
2
AudioFormat
PCM = 1
22
2
NumChannels
Mono = 1, Stereo = 2, и т.д.
24
4
SampleRate
8000, 44100, и т.д.
28
4
ByteRate
== SampleRate * NumChannels * BitsPerSample/8
32
2
BlockAlign
Количество байт отведенное под 1 семпл, включая все каналы == NumChannels * BitsPerSample/8
34
2
BitsPerSample
8 bits = 8, 16 bits = 16, etc.
2
ExtraParamSize
если PCM, значит не существует
x
ExtraParams
место для дополнительных параметров

"data" содержит информацию о размере аудио данных и сами данные:

Отступ
(байта)
Длина
(байта)
Название поля
Описание
36
4
Subchunk2ID
Содержит буквы "data"
40
4
Subchunk2Size
Это размер самих аудио данных
44
*
Data
Собственно, сами данные, которые нам в основном и нужны

Собственно, был написал  класс отражающий структуру формата и содержащий простейшие методы для работы с байтовым представлением файла.

В итоге при обработки такого вот файла:

  • Длительность: { 0 минут : 37 секунд }
  • Тип файла: WAVE
  • Количество каналов: 2
  • Частота дискретизации (Гц) : 44100
  • Скорость передачи (байт/секунду) : 176400

При количестве семплов на пиксель при отрисовке равному 1 получился вот такой неплохой график:


Как видите кол-во точек 3млн - 1, и это только 37 секунд!!!

При увеличении количества семплов на пиксель до 10000:


Похож на кардиограмму, если честно) Живем. Товарищи!)

Рисуем мы с использованием элемента Chart

Может не самый лучший вариант, но на мой взгляд наиболее простой в применении.

Конечно, в коде "куча" ереси и бывают случаи вылета на переполнении, но как правило все работает как надо)

По крайней мере мою душу на сегодня это успокоило)

Код программы (С#) на Github

Комментариев нет:

Отправить комментарий