Подписаться  на наше издание быстро и дешевле чем где-либо Вы можете прямо сейчас! Подписаться! 

 


Сегодня оцифрованный звук может храниться в различных форматах — от старого доброго PCM до новомодных MP3, AAC, WMA, OGG и т.д. В этой статье речь пойдет о том, как прочесть большинство из этих форматов и использовать звуки, в них содержащиеся.


Для осуществления задуманного мы воспользуемся бесплатной многоплатформенной библиотекой для чтения и конвертации звуковых форматов — Libsndfile.

 

Досье


Libsndfile — это C-библиотека, написанная Эриком де Кастро Лопо (Erik de Castro Lopo) для чтения и записи файлов, содержащих оцифрованный звук разных форматов через единый программный интерфейс. Эта библиотека изначально проектировалась так, чтоб компилироваться на разных платформах (*nix, MacOS, Win32 и др.).

 

Перечень поддерживаемых форматов поражает воображение:

  • PCM WAV;
  • Unsigned 8 bit PCM;
  • Signed 8 bit PCM;
  • Signed 16 bit;
  • Signed 24;
  • Signed 32 bit;
  • 32 bit float;
  • bit double;
  • u-law encoding;
  • A-law encoding;
  • IMA ADPCM;
  • MS ADPCM;
  • GSM 6.10;
  • G721 ADPCM 32kbps;
  • G723 ADPCM 24kbps;
  • G723 ADPCM 40kbps;
  • 12 bit DWVW;
  • 16 bit DWVW;
  • 2 bit DWVW;
  • Ok Dialogic ADPCM;
  • 8 bit DPCM;
  • 16bitDPCM.

Отметим также возможность работы как с Littleendian (стандартный WAV), так и с Big-endian-форматами (типа AIFF). Кроме того, для программистов, знающих С, предусмотрено быстрое расширение поддерживаемых форматов (более подробно о них — на домашней страничке libsndfile: www.mega-nerd.com/libsndfile).


Среди основных возможностей libsndfile, помимо мультиплатформенности и многоформатности данных:

  • возможность конвертирования форматов "на лету", включая конвертацию типов и разрядности звука, а также порядка байтов;
  • опциональная возможность нормализации звука;
  • запрашивание     поддерживаемых     форматов и описания для каждого из них.

Применение


Как и любая другая многоплатформенная библиотека, libsndfile полностью написана на C — ни на сайте разработчика, ни на бескрайних просторах интернета не удалось найти портированного на Delphi API для подключения этой библиотеки. Поэтому было принято решение конвертировать его самостоятельно (файл sndfile.pas вы можете найти на моем сайте:
www.gigabyte.iatp.org.ua). Конечно, этот процесс значительно упростила утилита h2pas, поставляющаяся в составе FreePascal.


Теперь, когда мощное оружие против обилия звуковых форматов в наших руках, можно приступать к его освоению.

 

Пример 1


Итак, для начала нам потребуется звуковой файл нестандартного формата. К примеру, MS ADPCM. Нельзя сказать, чтобы этот формат был очень уж нестандартным, тем не менее без предварительной подготовки проиграть его программными средствами Delphi невозможно, а уж о какой-нибудь обработке сигнала говорить и вовсе неуместно.


Выбрав такой файл размером 20 Мб (в оригинале — 80 Мб), попробуем конвертировать его в стандартный PCM-формат (и заодно проверим скорость работы библиотеки). Код, выполняющий задуманное, приводим ниже:

 

procedure TForm1.Button2Click
(Sender: TObject);
var Buf:Array[0..88199] of Smallint;
Info:TSF_INFO;
SND,Snd1:PSNDFILE;
r,res:cardinal;
begin
Snd:=sf_open
('tst.wav',SFM_READ,@info);
info.format:=SF_FORMAT_WAV
or SF_FORMAT_PCM_16;
Snd1:=sf_open
('dest.wav',SFM_WRITE,@info);
try
r:=High(Buf)+1;
Res:=0;
while r<>0 do
begin
r:=sf_read_short
(snd,@buf,High(Buf)+1);
sf_write_short
(Snd1,@buf,High(Buf)+1);
Inc(res,r);
Button2.Caption:=IntToStr(res);
end;
finally
sf_close(snd);
sf_close(snd1);
end;
end;

 

Как видим, перед лаконичностью libsndfile трудно устоять. Никаких лишних действий.

 

Весь алгоритм конвертации сводится к следующему:

  1. Открытие исходного файла (sf_open).
  2. Изменение формата файла на простой 16-битный PCM.
  3. Открытие файла, в который мы записываем результат.
  4. Чтение из первого и запись во второй файл в цикле.
  5. Закрытие файлов.

Никаких записей заголовков, никаких манипуляций с данными не потребовалось.


При таком алгоритме конвертации скорость зависит, в первую очередь, от оптимизации самой библиотеки. И, как видно из рисунка вверху, скорость такой операции тоже на уровне — 5,9 Мб/с (очень неплохо даже для моего не слишком современного 633-го "Целерона").

 


Скорость конвертации из MS ADPCM в PCM

 

Пример 2

 

Воспроизведение звука с использованием библиотеки libsndfile тоже не должно вызывать особых трудностей. Все, что потребуется, это правильно настроить параметры воспроизведения (частота, разрядность и т.п.). Далее вы просто читаете данные из звукового файла через функции библиотеки и отправляете его на звуковой выход. Наиболее простой вариант этой операции приведен ниже (процедура воспроизведения блока данных):

 

procedure PlayBuffer
(Buffer:Pointer;Size:Integer);
var Fmt:tWAVEFORMATEX;
Hdr:TWaveHdr;
Evt:THandle;WO:HWaveOut;
begin
ZeroMemory(@Fmt,SizeOf(Fmt));
Evt:=CreateEvent(nil,False,False,nil);
Fmt.wFormatTag:=WAVE_FORMAT_PCM;
Fmt.nChannels:=2;
Fmt.nSamplesPerSec:=44100;
Fmt.nBlockAlign:=4;
Fmt.wBitsPerSample:=16;
fmt.cbSize:=SizeOf(Fmt);
if waveOutOpen(@WO,0,@Fmt,Evt,0,
CALLBACK_EVENT)<>MMSYSERR_NOERROR
then Exit;
ZeroMemory(@Hdr,SizeOf(Hdr));
Hdr.lpData:=Buffer;
Hdr.dwBufferLength:=Size;
waveOutPrepareHeader
(WO,@Hdr,SizeOf(Hdr));
ResetEvent(Evt);
if waveOutWrite
(WO,@Hdr,SizeOf(Hdr))<>
MMSYSERR_NOERROR then Exit;
WaitForSingleObject(Evt,Infinite);
waveOutUnprepareHeader
(WO,@Hdr,SizeOf(Hdr));
waveOutClose(WO);
CloseHandle(Evt);
end;


Процедура воспроизведения файла:

 

procedure TForm1.Button2Click
(Sender: TObject);
var Buf:Array[0..88199] of Smallint;
Info:TSF_INFO;
SND,Snd1:PSNDFILE;
r,res:cardinal;
c:Cardinal;
begin
Snd:=sf_open('tst.wav',SFM_READ,@info);
try
r:=High(Buf)+1;
Res:=0;
while r<>0 do
begin
r:=sf_read_short
(snd,@buf,High(Buf)+1);
PlayBuffer(@Buf,High(Buf));
end;
finally
sf_close(snd);
end;
end;

 

Хотя такой метод воспроизведения и не является оптимальным, он все же дает представление о возможностях библиотеки libsndfile.


Правильные параметры настройки звука вы можете получить из переменной info, где записана информация о частоте дискретизации и количестве каналов. Разрядность сигнала определяется форматом той функции, которую вы используете для чтения. В нашем примере используется функция sf_read_short — значит, мы читаем данные типа short, который, соответственно, имеет разрядность 16 бит. Следовательно, и звуковая карта должна быть настроена на воспроизведение 16-битного звука.


Помимо Short, для чтения из файла могут быть использованы следующие типы данных:

  • Raw — чтение информации из файла без ее преобразования;
  • Int — преобразование к 32-разрядному знаковому виду;
  • Float, double — преобразование к 64-битному значению с плавающей точкой.

Кроме того, существует возможность чтения данных разными порциями — по байтам и по фреймам.

 

Дополнительные функции

 

Помимо основных возможностей (прозрачное конвертирование форматов и поддержка разных типов данных), libsndfile поддерживает еще кучу полезных вещей, в частности:

  • получение данных о версии libsndfile;
  • получение информации о количестве поддерживаемых форматов, а также их описаний;
  • измерение максимума звукового сигнала;
  • нормализация и т.д.

Все это производится при помощи функции sf_command. Она очень подробно описана в документации libsndfile, а пример ее работы приведен на рисунке, а также в листинге:

 

procedure TForm1.
FormCreate(Sender: TObject);
var version:String;
formats,i:integer;
fi:TSF_FORMAT_INFO;
begin
SetLength(version,128);
sf_command(nil,SFC_GET_LIB_VERSION,
PChar(version),128);
sf_command
(nil,SFC_GET_SIMPLE_FORMAT_COUNT,
@formats,SizeOf(formats));
ListBox1.Items.Add(version);
ListBox1.Items.Add(inttoStr
(formats));
for i:=0 to formats-1 do
begin
ZeroMemory(@fi,SizeOf(fi));
fi.format:=i;
sf_command(nil,SFC_GET_SIMPLE_
FORMAT,@fi,SizeOf(fi));
Listbox1.Items.Add
(fi.name+' ('+fi.extension+')');
end;
end;

 


Версия libsndfile и список поддерживаемых форматов


Итоги

 

Итак, использование библиотеки libsndfile позволяет значительно сократить время разработки приложений, работающих со звуковыми данными разных форматов. Более того, изначально библиотека libsndfile была ориентирована на исследовательскую деятельность в области анализа звуковых сигналов, распознавания речи и т.п., что, в свою очередь, привело к наличию функций конвертации сигнала в формат с плавающей точкой, где все данные приводятся в числовой промежуток (-1..1).

 

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

2005.11.30
19.03.2009
В IV квартале 2008 г. украинский рынок серверов по сравнению с аналогичным периодом прошлого года сократился в денежном выражении на 34% – до $30 млн (в ценах для конечных пользователей), а за весь календарный год – более чем на 5%, до 132 млн долл.


12.03.2009
4 марта в Киеве компания Telco провела конференцию "Инновационные телекоммуникации", посвященную новым эффективным телекоммуникационным технологиям для решения задач современного бизнеса.


05.03.2009
25 февраля в Киеве компания IBM, при информационной поддержке "1С" и Canonical, провела конференцию "Как сохранить деньги в условиях кризиса?"


26.02.2009
18-19 февраля в Киеве прошел юбилейный съезд ИТ-директоров Украины. Участниками данного мероприятия стали ИТ-директора, ИТ-менеджеры, поставщики ИТ-решений из Киева, Николаева, Днепропетровска, Чернигова и других городов Украины...


19.02.2009
10 февраля в Киеве состоялась пресс-конференция, посвященная итогам деятельности компании "DiaWest – Комп’ютерний світ" в 2008 году.


12.02.2009
С 5 февраля 2009 г. в Киеве начали работу учебные курсы по использованию услуг "электронного предприятия/ учреждения" на базе сети информационно-маркетинговых центров (ИМЦ).


04.02.2009
29 января 2009 года в редакции еженедельника "Computer World/Украина" состоялось награждение победителей акции "Оформи подписку – получи приз!".


29.01.2009
22 января в Киеве компания "МУК" и представительство компании Cisco в Украине провели семинар для партнеров "Обзор продуктов и решений Cisco Small Business"

 

 
 
Copyright © 1997-2008 ИД "Комиздат".