Explorando o mecanismo VoIP do Mediastreamer2. Parte 2

O material do artigo foi retirado do meu canal zen.

Explorando o mecanismo VoIP do Mediastreamer2. Parte 2

Criando um gerador de tons

No anterior статье Instalamos a biblioteca do streamer de mídia, as ferramentas de desenvolvimento e testamos sua funcionalidade criando um aplicativo de teste.

Hoje criaremos um aplicativo que pode gerar um sinal sonoro em uma placa de som. Para resolver este problema precisamos conectar os filtros ao circuito gerador de som mostrado abaixo:

Explorando o mecanismo VoIP do Mediastreamer2. Parte 2

Lemos o diagrama da esquerda para a direita, esta é a direção em que nosso fluxo de dados se move. As setas também sugerem isso. Retângulos indicam filtros que processam blocos de dados e geram o resultado. Dentro do retângulo está indicada sua função e o tipo de filtro é indicado em letras maiúsculas logo abaixo. As setas que conectam os retângulos são filas de dados através das quais blocos de dados são entregues de filtro para filtro. Em geral, um filtro pode ter muitas entradas e saídas.

Tudo começa com a fonte do clock, que define o ritmo em que os dados são calculados nos filtros. De acordo com o seu ciclo de clock, cada filtro processa todos os blocos de dados que estão em sua entrada. E coloca blocos com o resultado na fila. Primeiro, o filtro mais próximo da fonte do clock realiza os cálculos, depois os filtros conectados às suas saídas (podem haver várias saídas), e assim por diante. Depois que o último filtro da cadeia termina o processamento, a execução é interrompida até que um novo relógio chegue. As batidas, por padrão, seguem um intervalo de 10 milissegundos.

Voltemos ao nosso diagrama. Os ciclos de clock chegam na entrada da fonte de silêncio; este é um filtro, que está ocupado gerando um bloco de dados contendo zeros em sua saída para cada ciclo de clock. Se considerarmos este bloco como um bloco de amostras sonoras, então isso nada mais é do que silêncio. À primeira vista, parece estranho gerar blocos de dados com silêncio - afinal, não se ouve, mas esses blocos são necessários para o funcionamento do gerador de sinais sonoros. O gerador usa esses blocos como uma folha de papel em branco, gravando amostras sonoras neles. Em seu estado normal, o gerador é desligado e simplesmente encaminha os blocos de entrada para a saída. Assim, blocos de silêncio passam inalterados por todo o circuito da esquerda para a direita, terminando na placa de som. Que silenciosamente retira blocos da fila conectada à sua entrada.

Mas tudo muda se o gerador receber um comando para reproduzir som, ele começa a gerar amostras de som e as substitui por amostras nos blocos de entrada e coloca os blocos alterados na saída. A placa de som começa a reproduzir som. Abaixo está um programa que implementa o esquema de trabalho descrito acima:

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

Após inicializar o streamer de mídia, três filtros são criados: fonte nula, dtmfgen, snd_card_write. Uma fonte de relógio é criada.

Então você precisa conectar os filtros de acordo com nosso circuito, e a fonte do clock deve ser conectada por último, pois depois disso o circuito começará a funcionar imediatamente. Se você conectar uma fonte de clock a um circuito inacabado, pode acontecer que o streamer de mídia trave se detectar pelo menos um filtro na cadeia com todas as entradas ou todas as saídas “penduradas no ar” (não conectadas).

A conexão dos filtros é feita usando a função

ms_filter_link(src, src_out, dst, dst_in)

onde o primeiro argumento é um ponteiro para o filtro de origem, o segundo argumento é o número de saída da fonte (observe que as entradas e saídas são numeradas começando do zero). O terceiro argumento é um ponteiro para o filtro do receptor, o quarto é o número de entrada do receptor.

Todos os filtros são conectados e a fonte do relógio é conectada por último (doravante iremos simplesmente chamá-la de ticker). Depois disso, nosso circuito de som começa a funcionar, mas ainda não se ouve nada nos alto-falantes do computador - o gerador de som é desligado e simplesmente passa pelos blocos de dados de entrada em silêncio. Para começar a gerar um tom, você precisa executar o método de filtro do gerador.

Iremos gerar um sinal de dois tons (DTMF) correspondente ao pressionar o botão “1” do telefone. Para fazer isso, usamos a função ms_filter_call_method() Chamamos o método MS_DTMF_GEN_PLAY, passando-o como argumento um ponteiro para o código ao qual o sinal de reprodução deve corresponder.

Resta compilar o programa:

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

E corra:

$ ./mstest2

Depois de iniciar o programa, você ouvirá um breve sinal sonoro composto por dois tons no alto-falante do computador.

Construímos e lançamos nosso primeiro circuito sonoro. Vimos como criar instâncias de filtros, como conectá-las e como chamar seus métodos. Embora estejamos satisfeitos com nosso sucesso inicial, ainda precisamos prestar atenção ao fato de que nosso programa não libera a memória alocada antes de sair. Na próxima статье aprenderemos a limpar depois de nós mesmos.

Fonte: habr.com

Adicionar um comentário