BASS (BASS audio library) — звуковая библиотека, предназначена для использования в операционных системах Windows и Mac OS X; также доступна для Linux, Win64, WinCE, Android и iOS-платформ.
Кликните здесь для просмотра всего текста
Цель библиотеки заключается в том, чтобы предоставить разработчикам образец аудио-центра, в частности, обеспечить работу с потоками (MP3, MP2, MP1, OGG, WAV, AIFF), MOD файлами (XM, IT, S3M, MOD, MTM, UMX), MO3 файлами (mp3, ogg и сжатых MOD файлов), функциями записи, редактирования тегов аудиофайлов, конвертирования популярных форматов, «граббить» AudioCD, потребляя малое количество системных ресурсов.
Весь набор возможностей предоставляется в виде динамической библиотеки размером около 100 Kb.
Для работы BASS в операционной системе Windows, требуется DirectX 3 или выше, библиотека использует DirectSound и DirectSound3D для воспроизведения и записи звука. В Mac OS X BASS использует CoreAudio.
С 21 ноября 2011 на официальном сайте доступна версия библиотеки для Android.
Bass.dll, хелп и примеры можно скачать на http://www.un4seen.com/ вес 1 Гб или же без примеров Bass.rar вес 360 кб.
1. Инициализация библиотеки
Шаг №1. Необходимо в папку с проектом положить три файла: bass.dll, bass.h и bass.lib
Шаг №2. Подключить к проекту файлы bass.h и bass.lib:
для Rad 2010 это так: Project => Add to Project (Shift + F11) => выбрать два файла и нажать "Открыть"
Шаг №3. Откомпилировать проект и если ошибок не выдало то переходить к работе с библиотекой.
Если выдало ошибку аналогичную:
Цитата:
[ILINK32 Error] Fatal: Unable to open file '!䈨T盶ꗛ盷褂寚Ǜ눺E.OBJ'
в инспекторе объектов ("Object Inspector") проверить путь ("Full Path") к файлам возможно он не прописался при подключении.
2. Инициализация звукового потока
C++ | 1
| BASS_Init(-1, 44100, 0, 0, NULL); |
|
где Fд=44100 Гц
3. Загрузка аудио файла в поток и его прослушивание
C++ | 1
2
3
4
| HSTREAM str; //поток
String FileName="audio.mp3"; //аудио файл
str=BASS_StreamCreateFile(FALSE, PChar(FileName.t_str()), 0, 0, 0); //загрузка файла в поток
BASS_ChannelPlay(str, true); // проигрывание файла |
|
4. Остановка или пауза проигрывания
C++ | 1
2
3
4
| void __fastcall TForm3::Button2Click(TObject *Sender)
{
BASS_ChannelStop(str); //Остановка или пауза
} |
|
если трек закончился нужно делать:
C++ | 1
2
| BASS_ChannelStop(str);//остановить проигрывание
BASS_StreamFree(str);//освободить поток |
|
5. Возобновление проигрывания с прежнего места проигрывания
возобновление проигрывания осуществляется в случае если не инициализируемый новый поток "BASS_Init"
C++ | 1
2
3
4
| void __fastcall TForm3::Button3Click(TObject *Sender)
{
BASS_ChannelPlay(str,0); //возобновление проигрывания
} |
|
6. Расчет длительности трека
C++ | 1
2
3
4
| QWORD len=BASS_ChannelGetLength(str, BASS_POS_BYTE); // длина трека в байтах
double val=BASS_ChannelBytes2Seconds(str, len); // перевод из байт в секунды
TDateTime times = val/86400; // (24 часа * 3600 секунд в часе) = 86400 сек. в сутках
String S = times.FormatString("hh:mm:ss.zzz").Delete(1,3); // получаем длительность в секундах и убираем часовую размерность |
|
7. Информация об аудио файле
C++ | 1
2
3
4
5
6
| BASS_CHANNELINFO chaninfo;
BASS_ChannelGetInfo(str,&chaninfo);
Memo1->Lines->Add("Частота fд = " + String(chaninfo.freq) +" Гц");//Частота дискретизации
if(chaninfo.chans==1) Memo1->Lines->Add("Тип звучания: моно"); //кол-во каналов
else Memo1->Lines->Add("Тип звучания: стерео"); //кол-во каналов
Memo1->Lines->Add("Разрядность: " + String(chaninfo.origres)+"-бит(а)"); |
|
8. Позиция проигрывания файла и отображение на скролбаре
C++ | 1
2
3
4
| float size_p=BASS_ChannelGetLength(str,BASS_POS_BYTE); //длина трека
float size_p1=BASS_ChannelGetPosition(str,BASS_POS_BYTE); //текущая позиция
float pos=((size_p1)/(size_p/100)); //пересчет позиции для скролбара
ScrollBar1->Position=pos; |
|
9. реализация ФФТ и получение отсчетов
расчет BASS_ChannelGetData необходим для построения спектра или эквалайзера
C++ | 1
2
| float fft[1024];
BASS_ChannelGetData(chan0, fft, BASS_DATA_FFT2048); |
|
от сюда получаем
fft[i] - амплитуда на частоте
расчет частоты i*32,8125 = i*67200/2048
---где 67200 - частота дискитезациии по BASS_CHANNELINFO
---где 2048 - из BASS_DATA_FFT2048, количество взятых отсчетов
10. Построение элементарного эквалайзера
Выводить будем по таймеру с интервалом равном 1 в PaintBox1 где Width=1024 (кол-во элементов в fft)
C++ | 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
| float fft[1024];
BASS_ChannelGetData(chan0, fft, BASS_DATA_FFT2048);
int Step = Form3->PaintBox1->Width/1024;
Graphics::TBitmap *bmp = new Graphics::TBitmap();
bmp->Width = Form3->PaintBox1->Width;
bmp->Height = Form3->PaintBox1->Height;
bmp->Canvas->Pen->Color=clBlack;
bmp->Canvas->Brush->Color=clBlack;
bmp->Canvas->Rectangle(0,0,Form3->PaintBox1->Width,Form3->PaintBox1->Height);
bmp->Canvas->Pen->Color = clRed;
float ZZz=0;
int ZZY=0;
for (int i = 0; i < 1024; i+=Step)
{
if(fft[i]>ZZz)
{
ZZz=fft[i];
ZZY=i;
}
fft[i]=fft[i]*600; //усиление амплитуды
int hg=Form3->PaintBox1->Height-Int(fft[i]);
if (hg<0)hg=0;
bmp->Canvas->Rectangle(i,Form3->PaintBox1->Height,i+Step,hg);
}
Form3->PaintBox1->Canvas->Draw(0,0,bmp);
bmp->Canvas->ClipRect;
Application->ProcessMessages(); |
|
В результате проигрывания файла с помехой на частоте 7 и 19кГц получим:
11. Построение спектра
для построения спектра необходимо представить в трех проекциях сигнал где:
ось Х - время
ось Y - частота
ось Z - амплитуда
отображение производится в PaintBox где Height = 512
например так:
C++ | 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
| Graphics::TBitmap *bmpSPEC = new Graphics::TBitmap();
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
StepS=0;
bmpSPEC->Width = Form1->PaintBox1->Width;
bmpSPEC->Height = Form1->PaintBox1->Height;
bmpSPEC->Canvas->Pen->Color=clBlack;
bmpSPEC->Canvas->Brush->Color=clBlack;
bmpSPEC->Canvas->Rectangle(0,0,Form1->PaintBox1->Width,Form1->PaintBox1->Height);
bmpSPEC->Canvas->Pen->Color = clLime;
Application->ProcessMessages();
}
void __fastcall MUSIC_SPECTRUM(HSTREAM chan2, TPaintBox* pbr)
{
StepS++;
float fftK[512];
BASS_ChannelGetData(chan2, fftK, BASS_DATA_FFT1024);
if(StepS>1024)StepS=1;
for (int i = 0; i < 512; i++)
{
fftK[i]=fftK[i]*500;
bmpSPEC->Canvas->Pen->Color=RGB(0,Int(fftK[i]*2.6),0);
bmpSPEC->Canvas->Rectangle(StepS,Form1->PaintBox1->Height-i-1,StepS+1,Form1->PaintBox1->Height-i+1);
}
//прорисовка красного маркера положения
bmpSPEC->Canvas->Pen->Color=RGB(255,0,0);
bmpSPEC->Canvas->Rectangle(StepS+1,0,StepS+2,Form1->PaintBox1->Height);
/////////
pbr->Canvas->Draw(0,0,bmpSPEC);
Application->ProcessMessages();
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
MUSIC_SPECTRUM(str, Form1->PaintBox1);
} |
|
в итоге получим спектр на котором отображена помеха с Fн=18730 Гц:
|