Biblioteka BASS tutorial

maszynaz

Wstęp

Biblioteka BASS.dll służy do przetwarzania dźwięku na różne sposoby. Można ją ściągnąć ze strony http://www.un4seen.com/
lub bezpośrednio z linka http://us.un4seen.com/files/bass24.zip. Jest to natywna biblioteka napisana w C, dlatego aby ją użyć w C# trzeba zainstalować wrapper z linka http://us.un4seen.com/files/z/4/Bass24.Net.zip.

Przygotowanie projektu

Po utworzeniu pustego projektu należy skopiować do katalogu Debug 3 pliki: Bass.Net.dll, Bass.Net.xml oraz bass.dll.

Uwaga.Często popełnianym błędem przez programistów jest nie wgranie do katalogu biblioteki natywnej bass.dll i wskutek tego programy nie działają.

Następnie należy dodać w projekcie referencję do wrappera Bass.Net.dll i zaimportować jej metody konstrukcją:

using Un4seen.Bass;

Teraz można już zacząć programować dźwięk.

Przykłady

Słuchanie radia z internetu

{
        BassNet.Registration("twojmail@gmail.com", "42345397456575");
        Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
        Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PLAYLIST, 1);
        string strUrl = "http://sc9232.xpx.pl:9232/";
        stream = Bass.BASS_StreamCreateURL(strUrl, 0, 0, null, IntPtr.Zero);
            
        if (stream != 0)
        {             
               Bass.BASS_ChannelPlay(stream, false);
               timer1.Enabled = true; //linijka konieczna do następnego przykładu
        }
        else
        {
               MessageBox.Show("Wystąpił jakiś błąd");         
        }
}

Ten przykład w zupełności wystarcza by móc słuchać jakiegoś radia SHOUTcastowego (linki ICY).

Jak widać cała biblioteka Bass jest statyczna. Ponieważ jest stworzony strumień odtwarzający (BASS_StreamCreateURL) a nie nagrywający (co będzie pokazane w dalszej części tutorialu) to biblioteka musi być inicjowana metodą BASS_Init.

UWAGA! Nie każde radio może być odsłuchiwane np. linki zwierające .asf nie będą grały itp. Link w powyższym przykładzie działa więc można go próbować.

Wyświetlanie spectrum odtwarzanego dźwięku

Najpierw należy wrzucić na formatkę jakiegoś pictureBox-a.

private void timer1_Tick(object sender, EventArgs e)
{
        Un4seen.Bass.Misc.Visuals v = new Un4seen.Bass.Misc.Visuals();
            
        this.pictureBox1.Image = v.CreateSpectrum(stream,
                                 this.pictureBox1.Width,
                                 this.pictureBox1.Height,
                                 Color.Lime, Color.Red, Color.Black,
                                 false, false, false);       
}

Jak widać utworzenie spectrum to tylko dwie linijki. Trzeba zwrócić uwagę, że metoda CreateSpectrum nie jest statyczna, dlatego też wcześniej konieczne było utworzenie obiektu klasy, do której ona należała.

Nagrywanie dźwięku z mikrofonu i jego odtwarzanie

int rHandle;
private BASSBuffer monBuffer = new BASSBuffer(2f, 44100, 2, 16);

private RECORDPROC _myrecordproc;
private STREAMPROC _sproc;

{
            Bass.BASS_RecordInit(-1);
            
            /*Funkcja, która znajduje numer urządzenia jakim jest mikrofon*/
            int mic;
            BASSInputType flags;
            
            for (int n = 0; (flags = Bass.BASS_RecordGetInputType(n)) != BASSInputType.BASS_INPUT_TYPE_ERROR; n++)
            {
                if ((flags & BASSInputType.BASS_INPUT_TYPE_MASK) == BASSInputType.BASS_INPUT_TYPE_MIC)
                {
                    // found the mic!
                    mic = n;
                }
            }
            
            if (mic != -1)
                MessageBox.Show("Znaleziono mikrofon na kanale "+mic.ToString());
            else
                MessageBox.Show("Niestety nie znaleziono mikrofonu");
          

            /*Ustawienie mikrofonu na odpowiedni kanał. Wartość 0.2f oznacza, że mikrofon
            będzie nagrywał z głośnością 20%. Większych wartości nie ma co dawać bo będzie
            straszne sprzężenie zwrotne*/
            Bass.BASS_RecordSetInput(mic, BASSInput.BASS_INPUT_ON, 0.2f);
       
            _myrecordproc = new RECORDPROC(MyRecording);            
            rHandle = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, _myrecordproc, IntPtr.Zero);
                 
            Bass.BASS_ChannelPlay(rHandle, false);//rozpoczęcie przechwytywania dźwięku z mikrofonu

            Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero);
           _sproc = new STREAMPROC(MonitoringStream);    
            stream = Bass.BASS_StreamCreate(44100, 2,0, _sproc,IntPtr.Zero); 

            Bass.BASS_ChannelPlay(stream, false);//rozpoczęcie odtwarzania strumienia na głośnikach

            timer1.Enabled = true;//w timerze jak poprzednio mamy rysowanie spektrum
}

private bool MyRecording(int handle, IntPtr buffer, int length, IntPtr user)
{
            monBuffer.Write(buffer, length);

            return true;
}

private int MonitoringStream(int handle, IntPtr buffer, int length, IntPtr user)
{
            return monBuffer.Read(buffer, length, user.ToInt32());
}

private void timer1_Tick(object sender, EventArgs e)
{
            Un4seen.Bass.Misc.Visuals v = new Un4seen.Bass.Misc.Visuals();
            
            this.pictureBox1.Image = v.CreateSpectrum(rHandle,
                                              this.pictureBox1.Width,
                                              this.pictureBox1.Height,
                                              Color.Lime, Color.Red, Color.Black,
                                              false, false, false);       
}

W powyższym kodzie należy się kilka wyjaśnień. Po pierwsze, ponieważ jest używany do nagrywania strumień BASS_RecordStart to należało go najpierw zainicjować metodą BASS_RecordInit.

Uwaga! Metoda Bass.BASS_ChannelPlay(rHandle, false); nie oznacza, że dźwięk będzie odgrywany w głośnikach. Ta metoda powoduje jedynie rozpoczęcie zapisywania do strumienia, a ponieważ jest to tylko strumień nagrywający z mikrofonu to można go sobie obejrzeć na spektrogramie za pomocą uchwytu rHandle.

Aby odtworzyć dźwięk, trzeba utworzyć strumień do głośników BASS_StreamCreate i wystartować go metodą BASS_ChannelPlay.

W powyższym przykładzie widać, że strumień przechwytujący dźwięk z mikrofonu BASS_RecordStart używa delegata MyRecording do przepisywania strumienia do buforu, z którego potem inny strumień BASS_StreamCreate za pomocą delagaty MonitoringStream odczytuje bufor i odtwarza go na głośnikach.

Proszę poprawić artykuł jak ma jakieś błędy składniowe i logiczne (za pewne takie są) i jak ktoś może to niech rozbuduje ten tutorial.

2 komentarzy

To raczej nie tutorial, a gotowiec :/ Wolałbym się dowiedzieć po kolei co się robi, a nie wkleić kod ;d

Ubogi trochę ten tutorial... No więc tak -
Proszę poprawić artykuł jak ma jakieś błędy składniowe i logiczne (za pewne takie są) - mistrzostwo profesjonalizmu :>

Ale to mały problem bo cały tutorial to właściwie wklejenie kilku kodów źródłowych z minimalnymi opisami... Trochę mało.

Ale zawsze coś innego niż UFO :>