Materialet i artiklen er taget fra min .

Vi laver en tonegenerator
I den forrige Vi har installeret mediestrømmere, udviklingsværktøjer og kontrolleret deres funktionalitet ved at samle en prøveapplikation.
I dag vil vi skabe en applikation, der kan generere en tone på lydkortet. For at løse denne opgave skal vi forbinde filtrene i det nedenfor viste skema for lydgeneratoren:
![]()
Vi læser skemaet fra venstre mod højre, da dataflowet bevæger sig i denne retning. Pilene antyder også dette. Filtrene, der repræsenteres af rektangler, behandler datablokke og præsenterer resultatet på udgangen. Inden i rektanglet angives filterets rolle og lige under med store bogstaver filtertypen. Pilerne, der forbinder rektanglerne, er datakøer, hvor datablokke transporteres fra filter til filter. Generelt kan der være mange indgange og udgange for et filter.
Det hele begynder med taktkilden, der sætter tempoet for behandlingen af dataene i filtrene. Ved hvert takt behandler hvert filter alle datablokke, der er på dets indgang. Og præsenterer blokke med resultatet på udgangen — i køen. Først udfører det nærmeste filter til taktkilden behandlingen, derefter de filtre, der er tilsluttet dets udgange (der kan være mange udgange), og sådan fortsætter det. Efter at det sidste filter i kæden har afsluttet behandlingen, stopper udførelsen, indtil der kommer et nyt takt. Takterne følger som standard med et interval på 10 millisekunder.
Lad os vende tilbage til vores skema. Taktene føres ind i stillekilden, som er et filter, der genererer en blok af data bestående af nuller ved hver takt. Hvis vi betragter denne blok som en blok af lydprøver, er det ikke andet end stilhed. På første øjekast virker det mærkeligt at generere datablokke med stilhed — for man kan ikke høre den, men disse blokke er nødvendige for at generere lydsignal. Generatoren bruger disse blokke som et blankt ark papir, hvorpå den indskriver lydprøver. I sin normale tilstand er generatoren slukket og sender blot de indkommende blokke igennem til udgangen. Således passerer stilhedsbidragene uændret gennem hele skemaet fra venstre mod højre og ankommer til lydkortet, som lydløst henter blokke fra køen tilsluttet dens indgang.
Men alt ændrer sig, hvis generatoren modtager kommandoen til at afspille lyd; den begynder at generere lydprøver og erstatter dem i de indkomne blokke og præsenterer de ændrede blokke ved udgangen. Lydkortet begynder at afspille lyd. Nedenfor er programmet, der implementerer det ovenfor beskrevne arbejdsschema:
/* Файл 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 initialiseringen af mediestrømmeren oprettes tre filtre: voidsource, dtmfgen, snd_card_write. En taktsignal kilde oprettes.
Derefter er det nødvendigt at forbinde filtrene i overensstemmelse med vores skema, hvor taktsignal kilden skal tilsluttes sidst, da arbejdet med skemaet straks begynder efter dette. Hvis man tilslutter taktsignal kilden til et uafsluttet skema, kan det ske, at mediestrømmeren afsluttes uventet, hvis den opdager mindst ét filter i kæden, hvor alle indgange eller alle udgange "hænger i luften" (ikke tilsluttet).
Forbindelsen af filtrene udføres ved hjælp af funktionen
ms_filter_link(src, src_out, dst, dst_in), hvor det første argument er en peger til kildfilteret, det andet argument — er kildeudgangens nummer (vær opmærksom på, at indgange og udgange nummereres fra nul). Det tredje argument er en peger til modtagfilteret, det fjerde — nummeret på modtagerens indgang.
Alle filtre er forbundet, og kilden til takten tilsluttes sidst (herefter vil vi blot kalde den en ticker). Herefter aktiveres vores lydskema, men der høres endnu intet i computerens højttaler — lydgeneratoren er slukket og sender blot dataindgangsblokke igennem med stilhed. For at starte genereringen af et tonalt signal skal vi udføre metoden for generatorens filter.
Vi vil generere et dobbelt-tonesignal (DTMF), der svarer til tryk på telefonens tast "1". For dette bruger vi funktionen ms_filter_call_method() til at kalde metoden MS_DTMF_GEN_PLAY og sender den som argument en peger til den kode, som det reproducerede signal skal svare til.
Det er tilbage at kompilere programmet:
$ gcc mstest2.c -o mstest2 `pkg-config mediastreamer --libs --cflags`Og starte det:
$ ./mstest2Når programmet er startet, vil du høre et kort lydsignal fra computerens højttaler, der består af to toner.
Vi har bygget og startet vores første lydskema. Vi har set, hvordan man opretter instanser af filtre, hvordan man forbinder dem, og hvordan man kalder deres metoder. Selvom vi glæder os over den første succes, skal vi dog bemærke, at vores program ikke frigiver det tildelte hukommelse før afslutning. I næste vil vi lære at rydde op efter os.
Kilde: habr.com
