Mediastreamer2:n VoIP-moottorin tutkiminen. Osa 2

Artikkelin materiaali on otettu minun zen kanava.

Mediastreamer2:n VoIP-moottorin tutkiminen. Osa 2

Äänigeneraattorin luominen

Edellisessä статье Asensimme mediastriimauskirjaston, kehitystyökalut ja testasimme niiden toimivuutta rakentamalla kokeilusovelluksen.

Tänään luomme sovelluksen, joka voi luoda äänisignaalin äänikortille. Tämän ongelman ratkaisemiseksi meidän on kytkettävä suodattimet alla näkyvään äänigeneraattoripiiriin:

Mediastreamer2:n VoIP-moottorin tutkiminen. Osa 2

Luemme kaavion vasemmalta oikealle, tämä on suunta, johon tietovirtamme liikkuu. Myös nuolet viittaavat tähän. Suorakulmiot osoittavat suodattimia, jotka käsittelevät tietolohkoja ja tulostavat tuloksen. Suorakulmion sisällä on osoitettu sen rooli ja suodattimen tyyppi isoilla kirjaimilla aivan alla. Suorakulmioita yhdistävät nuolet ovat datajonoja, joiden kautta datalohkoja toimitetaan suodattimesta suodattimeen. Yleensä suodattimella voi olla useita tuloja ja lähtöjä.

Kaikki alkaa kellolähteestä, joka asettaa tempon, jolla data lasketaan suodattimissa. Kellojaksonsa mukaan kukin suodatin käsittelee kaikki sen syötteessä olevat datalohkot. Ja laittaa lohkot tuloksella jonoon. Ensin kellolähdettä lähinnä oleva suodatin suorittaa laskelmia, sitten sen lähtöihin kytketyt suodattimet (lähtöjä voi olla useita) ja niin edelleen. Kun ketjun viimeinen suodatin on lopettanut käsittelyn, suoritus pysähtyy, kunnes uusi kello saapuu. Iskut seuraavat oletusarvoisesti 10 millisekunnin aikaväliä.

Palataan kaavioomme. Kellojaksot saapuvat hiljaisuuslähteen tuloon; tämä on suodatin, joka on varattu generoimaan datalohkon, joka sisältää nollia jokaiselle kellojaksolle. Jos pidämme tätä lohkoa ääninäytteiden lohkona, tämä ei ole muuta kuin hiljaisuutta. Ensi silmäyksellä näyttää oudolta luoda datalohkoja hiljaisuudessa - loppujen lopuksi sitä ei voida kuulla, mutta nämä lohkot ovat välttämättömiä äänisignaaligeneraattorin toiminnalle. Generaattori käyttää näitä lohkoja kuin tyhjää paperia ja tallentaa niihin ääninäytteitä. Normaalitilassaan generaattori sammuu ja yksinkertaisesti välittää tulolohkot ulostuloon. Siten hiljaisuuslohkot kulkevat muuttumattomina koko piirin läpi vasemmalta oikealle päätyen äänikorttiin. Joka ottaa hiljaa lohkoja sen tuloon liitetystä jonosta.

Mutta kaikki muuttuu, jos generaattorille annetaan käsky soittaa ääntä, se alkaa generoida ääninäytteitä ja korvaa ne näytteillä tulolohkoissa ja laittaa muutetut lohkot lähtöön. Äänikortti alkaa toistaa ääntä. Alla on ohjelma, joka toteuttaa yllä kuvatun työsuunnitelman:

/* Файл mstest2.c */
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msticker.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/mssndcard.h>
int main()
{
    ms_init();

    /* Создаем экземпляры фильтров. */
    MSFilter  *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);
    MSFilter  *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
    MSSndCard *card_playback = ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
    MSFilter  *snd_card_write = ms_snd_card_create_writer(card_playback);

    /* Создаем тикер. */
    MSTicker *ticker = ms_ticker_new();

    /* Соединяем фильтры в цепочку. */
    ms_filter_link(voidsource, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, snd_card_write, 0);

   /* Подключаем источник тактов. */
   ms_ticker_attach(ticker, voidsource);

   /* Включаем звуковой генератор. */
   char key='1';
   ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY, (void*)&key);

   /* Даем, время, чтобы все блоки данных были получены звуковой картой.*/
   ms_sleep(2);   
}

Mediastriimerin alustamisen jälkeen luodaan kolme suodatinta: voidsource, dtmfgen, snd_card_write. Kellolähde luodaan.

Sitten sinun on kytkettävä suodattimet piirimme mukaisesti, ja kellolähde on kytkettävä viimeisenä, koska tämän jälkeen piiri alkaa välittömästi toimia. Jos kytket kellolähteen keskeneräiseen piiriin, voi tapahtua, että mediastriimeri kaatuu, jos se havaitsee ketjussa vähintään yhden suodattimen, jonka kaikki tulot tai kaikki lähdöt roikkuvat ilmassa (ei kytketty).

Suodattimien liittäminen tapahtuu toiminnolla

ms_filter_link(src, src_out, dst, dst_in)

jossa ensimmäinen argumentti on osoitin lähdesuodattimeen, toinen argumentti on lähteen lähtönumero (huomaa, että tulot ja lähdöt numeroidaan nollasta alkaen). Kolmas argumentti on osoitin vastaanottimen suodattimeen, neljäs on vastaanottimen tulonumero.

Kaikki suodattimet on kytketty ja kellolähde on kytketty viimeiseksi (tästä lähtien kutsumme sitä yksinkertaisesti tikkeriksi). Sen jälkeen äänipiirimme alkaa toimia, mutta tietokoneen kaiuttimista ei kuulu vielä mitään - äänigeneraattori sammuu ja kulkee yksinkertaisesti sisääntulotietolohkojen läpi hiljaa. Voit aloittaa äänen generoinnin suorittamalla generaattorisuodatusmenetelmän.

Luomme kaksiäänisen (DTMF) signaalin, joka vastaa puhelimen "1"-painikkeen painamista. Tätä varten käytämme funktiota ms_filter_call_method() Kutsumme menetelmää MS_DTMF_GEN_PLAY ja välitämme sen argumenttina osoittimena koodiin, jota toistosignaalin tulee vastata.

Jäljelle jää vain ohjelman kokoaminen:

$ gcc mstest2.c -o mstest2 `pkg-config mediastreamer --libs --cflags`

Ja juokse:

$ ./mstest2

Ohjelman käynnistämisen jälkeen kuulet tietokoneen kaiuttimesta lyhyen äänimerkin, joka koostuu kahdesta äänestä.

Rakensimme ja lanseerasimme ensimmäisen äänipiirimme. Näimme kuinka luodaan suodatininstanssit, miten ne yhdistetään ja miten niiden menetelmiä kutsutaan. Vaikka olemmekin tyytyväisiä alkuperäiseen menestykseemme, meidän on silti kiinnitettävä huomiota siihen, että ohjelmamme ei vapauta varattua muistia ennen poistumista. Seuraavassa статье opimme siivoamaan jälkemme.

Lähde: will.com

Lisää kommentti