Explorant el motor de VoIP Mediastreamer2. Part 2

El material de l'article està extret del meu canal zen.

Explorant el motor de VoIP Mediastreamer2. Part 2

Creació d'un generador de tons

A l’anterior article Hem instal·lat la biblioteca multimèdia, les eines de desenvolupament i hem provat la seva funcionalitat mitjançant la creació d'una aplicació de prova.

Avui crearem una aplicació que pot generar un senyal de to en una targeta de so. Per resoldre aquest problema hem de connectar els filtres al circuit generador de so que es mostra a continuació:

Explorant el motor de VoIP Mediastreamer2. Part 2

Llegim el diagrama d'esquerra a dreta, aquesta és la direcció en què es mou el nostre flux de dades. Les fletxes també insinuen això. Els rectangles indiquen filtres que processen blocs de dades i produeixen el resultat. Dins del rectangle, s'indica el seu paper i el tipus de filtre s'indica en majúscules just a sota. Les fletxes que connecten els rectangles són cues de dades a través de les quals s'entreguen blocs de dades de filtre a filtre. En general, un filtre pot tenir moltes entrades i sortides.

Tot comença amb la font del rellotge, que estableix el tempo al qual es calculen les dades als filtres. Segons el seu cicle de rellotge, cada filtre processa tots els blocs de dades que es troben a la seva entrada. I posa blocs amb el resultat a la cua. Primer, el filtre més proper a la font del rellotge realitza els càlculs, després els filtres connectats a les seves sortides (pot haver-hi moltes sortides), etc. Un cop finalitza el processament de l'últim filtre de la cadena, l'execució s'atura fins que arriba un nou rellotge. Els ritmes, per defecte, segueixen un interval de 10 mil·lisegons.

Tornem al nostre diagrama. Els cicles de rellotge arriben a l'entrada de la font de silenci; aquest és un filtre, que està ocupat generant un bloc de dades que conté zeros a la seva sortida per a cada cicle de rellotge. Si considerem aquest bloc com un bloc de mostres de so, això no és més que silenci. A primera vista, sembla estrany generar blocs de dades amb silenci; després de tot, no es pot escoltar, però aquests blocs són necessaris per al funcionament del generador de senyal de so. El generador utilitza aquests blocs com un full de paper en blanc, gravant-hi mostres de so. En el seu estat normal, el generador està apagat i simplement envia els blocs d'entrada a la sortida. Així, els blocs de silenci passen sense canvis per tot el circuit d'esquerra a dreta, acabant a la targeta de so. Que agafa silenciosament blocs de la cua connectada a la seva entrada.

Però tot canvia si al generador se li dóna una ordre per reproduir so, comença a generar mostres de so i les substitueix per mostres als blocs d'entrada i posa els blocs modificats a la sortida. La targeta de so comença a reproduir so. A continuació es mostra un programa que implementa l'esquema de treball descrit anteriorment:

/* Файл 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);   
}

Després d'inicialitzar l'emissió multimèdia, es creen tres filtres: voidsource, dtmfgen, snd_card_write. Es crea una font de rellotge.

Aleshores, heu de connectar els filtres d'acord amb el nostre circuit i la font del rellotge s'ha de connectar l'última, ja que després d'això, el circuit començarà a funcionar immediatament. Si connecteu una font de rellotge a un circuit inacabat, pot passar que el reproductor multimèdia es bloquegi si detecta almenys un filtre a la cadena amb totes les entrades o totes les sortides "penjades a l'aire" (no connectades).

La connexió dels filtres es fa mitjançant la funció

ms_filter_link(src, src_out, dst, dst_in)

on el primer argument és un punter al filtre d'origen, el segon argument és el número de sortida d'origen (tingueu en compte que les entrades i sortides es numeren a partir de zero). El tercer argument és un punter al filtre del receptor, el quart és el número d'entrada del receptor.

Tots els filtres estan connectats i la font del rellotge es connecta per darrera (d'ara endavant simplement l'anomenarem ticker). Després d'això, el nostre circuit de so comença a funcionar, però encara no es pot escoltar res als altaveus de l'ordinador: el generador de so s'apaga i simplement passa pels blocs de dades d'entrada amb silenci. Per començar a generar un to, heu d'executar el mètode de filtre del generador.

Generarem un senyal de dos tons (DTMF) corresponent a prémer el botó "1" del telèfon. Per fer-ho, utilitzem la funció ms_filter_call_method() Anomenem el mètode MS_DTMF_GEN_PLAY, passant-lo com a argument com a punter al codi al qual hauria de correspondre el senyal de reproducció.

Només queda compilar el programa:

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

I corre:

$ ./mstest2

Després d'iniciar el programa, sentireu un breu senyal de so format per dos tons a l'altaveu de l'ordinador.

Vam construir i posar en marxa el nostre primer circuit de so. Hem vist com crear instàncies de filtre, com connectar-les i com cridar els seus mètodes. Tot i que estem contents amb el nostre èxit inicial, encara hem de parar atenció al fet que el nostre programa no allibera la memòria assignada abans de sortir. En el següent article aprendrem a netejar-nos després de nosaltres mateixos.

Font: www.habr.com

Afegeix comentari