Explorando o motor VoIP Mediastreamer2. Parte 2

O conteúdo deste artigo foi retirado do meu canal Zen.

Explorando o motor VoIP Mediastreamer2. Parte 2

Criamos um gerador de tons

Na anterior artigo executamos a instalação da biblioteca de streaming de mídia, das ferramentas de desenvolvimento e verificamos seu funcionamento, construindo um aplicativo de teste.

Hoje vamos criar um aplicativo que pode gerar um sinal tonal na placa de som. Para resolver essa tarefa, precisamos conectar os filtros no esquema do gerador de som mostrado abaixo:

Explorando o motor VoIP Mediastreamer2. Parte 2

Lemos o esquema da esquerda para a direita, que é a direção em que o fluxo de dados se move. As setas também indicam isso. Os retângulos representam os filtros que processam os blocos de dados e apresentam o resultado na saída. Dentro do retângulo, sua função é indicada e logo abaixo, em letras maiúsculas, o tipo de filtro. As setas que conectam os retângulos são filas de dados, pelas quais os blocos de dados são entregues de filtro para filtro. Em geral, um filtro pode ter várias entradas e saídas.

Tudo começa com uma fonte de clock, que define o ritmo em que os dados são processados pelos filtros. A cada pulso, cada filtro processa todos os blocos de dados que estão em sua entrada. E apresenta os blocos com o resultado na saída — na fila. O filtro mais próximo da fonte de clock é o primeiro a processar, depois os filtros conectados às suas saídas (pode haver várias saídas) e assim por diante. Após o último filtro na cadeia concluir o processamento, a execução para até que um novo pulso chegue. Os pulsos, por padrão, seguem em um intervalo de 10 milissegundos.

Voltamos ao nosso diagrama. Os pulsos entram na fonte de silêncio, que é um filtro ocupado em gerar, a cada pulso, um bloco de dados que contém zeros. Se considerarmos esse bloco como um bloco de amostras sonoras, na verdade, ele é apenas silêncio. À primeira vista, parece estranho gerar blocos de dados de silêncio — afinal, não é possível ouvir isso, mas esses blocos são necessários para o funcionamento do gerador de sinal sonoro. O gerador usa esses blocos como uma folha de papel em branco, registrando neles as amostras de áudio. Em seu estado normal, o gerador está desligado e simplesmente transfere os blocos de entrada para a saída. Assim, os blocos de silêncio passam inalterados por todo o diagrama da esquerda para a direita, chegando na placa de som. Que silenciosamente retira os blocos da fila conectada à sua entrada.

Mas tudo muda quando um comando é enviado ao gerador para reproduzir som, ele começa a gerar amostras de áudio e substitui as amostras nos blocos de entrada, colocando os blocos alterados na saída. A placa de som começa a reproduzir o som. Abaixo está o 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 a inicialização do media streamer, três filtros são criados: voidsource, dtmfgen, snd_card_write. Uma fonte de sinal de relógio é criada.

Em seguida, é necessário conectar os filtros de acordo com nosso diagrama, sendo que a fonte de relógio deve ser conectada por último, pois isso iniciará imediatamente a operação do esquema. Se conectar a fonte de relógio a um esquema inacabado, pode acontecer que o media streamer encerre abruptamente ao encontrar pelo menos um filtro em que todas as entradas ou todas as saídas "estão no ar" (não conectadas).

A conexão dos filtros é feita através da 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 da saída da fonte (note que as entradas e saídas são numeradas a partir de zero). O terceiro argumento é um ponteiro para o filtro de receptor, e o quarto é o número da entrada do receptor.

Todos os filtros estão conectados e a fonte de clock é conectada por último (a partir de agora, vamos chamá-la simplesmente de 'ticker'). Após isso, nosso esquema de som começa a funcionar, mas, na dinâmica do computador, ainda não se ouve nada — o gerador de som está desligado e apenas passa os blocos de dados de entrada silenciosamente. Para iniciar a geração de um sinal tonal, é necessário executar o método do gerador de filtro.

Vamos gerar um sinal de tom duplo (DTMF) correspondente ao pressionar do botão "1" no telefone. Para isso, utilizamos a função ms_filter_call_method() chamamos o método MS_DTMF_GEN_PLAY, passando como argumento o ponteiro para o código que deverá corresponder ao sinal reproduzido.

Agora, resta compilar o programa:

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

E executar:

$ ./mstest2

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

Criamos e colocamos em funcionamento nosso primeiro esquema de som. Vimos como criar instâncias de filtros, como conectá-los e como chamar seus métodos. Após a primeira conquista, ainda precisamos observar que nosso programa não libera a memória alocada antes de ser encerrado. Na próxima artigo nosso foco será em limpar após nós mesmos.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster