Utforsker Mediastreamer2 VoIP-motoren. Del 2

Stoffet til artikkelen er hentet fra min zen-kanal.

Utforsker Mediastreamer2 VoIP-motoren. Del 2

Opprette en tonegenerator

I forrige artikkel Vi installerte mediastreamer-biblioteket, utviklingsverktøy og testet funksjonaliteten ved å bygge en prøveapplikasjon.

I dag skal vi lage en applikasjon som kan generere et tonesignal på et lydkort. For å løse dette problemet må vi koble filtrene til lydgeneratorkretsen vist nedenfor:

Utforsker Mediastreamer2 VoIP-motoren. Del 2

Vi leser diagrammet fra venstre til høyre, dette er retningen som dataflyten vår beveger seg i. Pilene antyder også dette. Rektangler indikerer filtre som behandler blokker med data og sender ut resultatet. Inne i rektangelet er dets rolle angitt og filtertypen er angitt med store bokstaver rett under. Pilene som forbinder rektanglene er datakøer der blokker med data blir levert fra filter til filter. Generelt kan et filter ha mange innganger og utganger.

Det hele starter med klokkekilden, som setter tempoet som data beregnes med i filtrene. I henhold til klokkesyklusen behandler hvert filter alle datablokker som er på inngangen. Og setter klosser med resultatet ut i køen. Først utfører filteret nærmest klokkekilden beregninger, deretter filtrene koblet til utgangene (det kan være mange utganger), og så videre. Etter at det siste filteret i kjeden er ferdig behandlet, stopper utførelsen til en ny klokke kommer. Slag følger som standard et intervall på 10 millisekunder.

La oss gå tilbake til diagrammet vårt. Klokkesyklusene kommer til inngangen til stillhetskilden; dette er et filter som er opptatt med å generere en blokk med data som inneholder nuller ved utgangen for hver klokkesyklus. Hvis vi betrakter denne blokken som en blokk med lydprøver, er dette ikke noe mer enn stillhet. Ved første øyekast virker det rart å generere datablokker med stillhet - det kan tross alt ikke høres, men disse blokkene er nødvendige for driften av lydsignalgeneratoren. Generatoren bruker disse blokkene som et blankt ark, og registrerer lydprøver i dem. I normal tilstand slås generatoren av og sender ganske enkelt inngangsblokker til utgangen. Dermed passerer blokker av stillhet uendret gjennom hele kretsen fra venstre til høyre, og ender opp i lydkortet. Som stille tar blokker fra køen koblet til sin inngang.

Men alt endres hvis generatoren får en kommando for å spille av lyd, den begynner å generere lydprøver og erstatter dem med prøver i inngangsblokkene og setter de endrede blokkene på utgangen. Lydkortet begynner å spille av lyd. Nedenfor er et program som implementerer arbeidsskjemaet beskrevet ovenfor:

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

Etter initialisering av mediastreameren opprettes tre filtre: voidsource, dtmfgen, snd_card_write. En klokkekilde opprettes.

Deretter må du koble til filtrene i samsvar med vår krets, og klokkekilden må kobles til sist, siden etter dette vil kretsen umiddelbart begynne å fungere. Hvis du kobler en klokkekilde til en uferdig krets, kan det hende at mediastreameren krasjer hvis den oppdager minst ett filter i kjeden med alle innganger eller alle utganger "hengende i luften" (ikke tilkoblet).

Tilkobling av filtre gjøres ved hjelp av funksjonen

ms_filter_link(src, src_out, dst, dst_in)

der det første argumentet er en peker til kildefilteret, er det andre argumentet kildeutgangsnummeret (merk at innganger og utganger er nummerert fra null). Det tredje argumentet er en peker til mottakerfilteret, det fjerde er mottakerens inngangsnummer.

Alle filtre er tilkoblet og klokkekilden kobles til sist (heretter vil vi ganske enkelt kalle det en ticker). Deretter begynner lydkretsen vår å fungere, men ingenting kan høres i datamaskinens høyttalere ennå - lydgeneratoren er slått av og passerer ganske enkelt gjennom inngangsdatablokkene med stillhet. For å begynne å generere en tone, må du kjøre generatorfiltermetoden.

Vi vil generere et to-tone (DTMF) signal som tilsvarer å trykke på "1"-knappen på telefonen. For å gjøre dette bruker vi funksjonen ms_filter_call_method() Vi kaller MS_DTMF_GEN_PLAY-metoden, og sender den som et argument en peker til koden som avspillingssignalet skal tilsvare.

Alt som gjenstår er å kompilere programmet:

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

Og løp:

$ ./mstest2

Etter å ha startet programmet vil du høre et kort lydsignal bestående av to toner i datamaskinens høyttaler.

Vi bygde og lanserte vår første lydkrets. Vi så hvordan man lager filterforekomster, hvordan man kobler dem til og hvordan man kaller metodene deres. Selv om vi er fornøyde med vår første suksess, må vi fortsatt være oppmerksom på at programmet vårt ikke frigjør det tildelte minnet før det avsluttes. I neste artikkel vi skal lære å rydde opp etter oss.

Kilde: www.habr.com

Legg til en kommentar