Udforskning af Mediastreamer2 VoIP-motoren. Del 2

Artiklens materiale er hentet fra min zen kanal.

Udforskning af Mediastreamer2 VoIP-motoren. Del 2

Oprettelse af en tonegenerator

I det foregående artiklen Vi installerede mediestreamer-biblioteket, udviklingsværktøjer og testede deres funktionalitet ved at bygge en prøveapplikation.

I dag vil vi lave en applikation, der kan generere et tonesignal på et lydkort. For at løse dette problem skal vi tilslutte filtrene til lydgeneratorkredsløbet vist nedenfor:

Udforskning af Mediastreamer2 VoIP-motoren. Del 2

Vi læser diagrammet fra venstre mod højre, det er den retning, som vores dataflow bevæger sig i. Pilene antyder også dette. Rektangler angiver filtre, der behandler datablokke og udsender resultatet. Inde i rektanglet er dets rolle angivet, og filtertypen er angivet med store bogstaver lige nedenfor. Pilene, der forbinder rektanglerne, er datakøer, hvorigennem datablokke leveres fra filter til filter. Generelt kan et filter have mange ind- og udgange.

Det hele starter med urkilden, som sætter det tempo, som data beregnes med i filtrene. I henhold til dets clock-cyklus behandler hvert filter alle datablokke, der er ved dets input. Og sætter klodser med resultatet ud i køen. Først udfører det filter, der er tættest på urkilden, beregninger, derefter udfører de filtre, der er tilsluttet dets udgange (der kan være mange udgange) og så videre. Efter at det sidste filter i kæden er færdig med at behandle, stopper udførelsen, indtil der kommer et nyt ur. Beats følger som standard et interval på 10 millisekunder.

Lad os vende tilbage til vores diagram. Klokkecyklusserne ankommer til indgangen til tavshedskilden; dette er et filter, som er i gang med at generere en blok af data, der indeholder nuller ved dens udgang for hver klokcyklus. Hvis vi betragter denne blok som en blok af lydeksempler, så er dette intet andet end stilhed. Ved første øjekast virker det mærkeligt at generere datablokke med stilhed - det kan trods alt ikke høres, men disse blokke er nødvendige for driften af ​​lydsignalgeneratoren. Generatoren bruger disse blokke som et blankt ark papir og optager lydeksempler i dem. I sin normale tilstand er generatoren slukket og sender blot inputblokke videre til udgangen. Således passerer blokke af stilhed uændret gennem hele kredsløbet fra venstre mod højre og ender i lydkortet. Som lydløst tager blokke fra køen forbundet til dens input.

Men alt ændrer sig, hvis generatoren får en kommando til at afspille lyd, den begynder at generere lydeksempler og erstatter dem med samples i inputblokkene og sætter de ændrede blokke på outputtet. Lydkortet begynder at afspille lyd. Nedenfor er et program, der implementerer arbejdsskemaet 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);   
}

Efter initialisering af mediestreameren oprettes tre filtre: voidsource, dtmfgen, snd_card_write. Der oprettes en urkilde.

Derefter skal du tilslutte filtrene i overensstemmelse med vores kredsløb, og urkilden skal tilsluttes sidst, da kredsløbet herefter straks begynder at fungere. Hvis du tilslutter en urkilde til et ufærdigt kredsløb, kan det ske, at mediestreameren går ned, hvis den registrerer mindst et filter i kæden med alle indgange eller alle udgange "hængende i luften" (ikke tilsluttet).

Tilslutning af filtre sker ved hjælp af funktionen

ms_filter_link(src, src_out, dst, dst_in)

hvor det første argument er en pegepind til kildefilteret, er det andet argument kildens outputnummer (bemærk, at input og output er nummereret fra nul). Det tredje argument er en pointer til modtagerfilteret, det fjerde er modtagerens inputnummer.

Alle filtre er tilsluttet, og urkilden er tilsluttet sidst (herefter vil vi blot kalde det en ticker). Hvorefter vores lydkredsløb begynder at virke, men der kan ikke høres noget i computerens højttalere endnu - lydgeneratoren er slukket og passerer simpelthen gennem input-datablokkene med tavshed. For at begynde at generere en tone skal du køre generatorfiltermetoden.

Vi vil generere et to-tone (DTMF) signal svarende til at trykke på "1" knappen på telefonen. For at gøre dette bruger vi funktionen ms_filter_call_method() Vi kalder MS_DTMF_GEN_PLAY-metoden og sender den som et argument en pointer til den kode, som afspilningssignalet skal svare til.

Tilbage er blot at kompilere programmet:

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

Og løb:

$ ./mstest2

Efter opstart af programmet vil du høre et kort lydsignal bestående af to toner i computerens højttaler.

Vi byggede og lancerede vores første lydkredsløb. Vi så, hvordan man opretter filterforekomster, hvordan man forbinder dem, og hvordan man kalder deres metoder. Selvom vi er tilfredse med vores første succes, skal vi stadig være opmærksomme på, at vores program ikke frigør den tildelte hukommelse, før det afsluttes. I den næste artiklen vi lærer at rydde op efter os selv.

Kilde: www.habr.com

Tilføj en kommentar