U materiale di l'articulu hè pigliatu da u mo
Crià un generatore di tonu
In u precedente
Oghje creeremu una applicazione chì pò generà un signalu di tonu nantu à una carta di sonu. Per risolve stu prublema, avemu bisognu di cunnette i filtri in u circuitu generatore di sonu mostratu quì sottu:
Leghjemu u diagramma da manca à diritta, questu hè a direzzione in quale u nostru flussu di dati si move. E frecce indicanu ancu questu. I rectanguli indicanu filtri chì processanu blocchi di dati è pruduce u risultatu. Dentru u rettangulu, u so rolu hè indicatu è u tipu di filtru hè indicatu in lettere maiuscule ghjustu sottu. E frecce chì culliganu i rectanguli sò file di dati à traversu quali blocchi di dati sò mandati da filtru à filtru. In generale, un filtru pò avè assai inputs è outputs.
Tuttu principia cù a fonte di u clock, chì stabilisce u tempu à quale data hè calculata in i filtri. Sicondu u so ciclu di clock, ogni filtru processa tutti i blocchi di dati chì sò in u so input. È mette blocchi cù u risultatu in a fila. Prima, u filtru più vicinu à a fonte di u clock realiza calculi, dopu i filtri cunnessi à i so outputs (ci ponu esse assai outputs), è cusì. Dopu chì l'ultimu filtru in a catena finisci di trasfurmà, l'esekzione si ferma finu à chì un novu clock arriva. Beats, per difettu, seguitanu un intervallu di 10 millisecondi.
Riturnemu à u nostru schema. I cicli di clock arrivanu à l'input di a fonte di silenziu; questu hè un filtru, chì hè occupatu à generà un bloccu di dati chì cuntenenu zeri à a so output per ogni ciculu di clock. Se cunsideremu stu bloccu cum'è un bloccu di campioni di sonu, allora questu hè nunda più cà u silenziu. À u primu sguardu, pare stranu di generà blocchi di dati cù u silenziu - dopu à tuttu, ùn pò micca esse intesu, ma questi blocchi sò necessarii per u funziunamentu di u generatore di signali di sonu. U generatore usa questi blocchi cum'è un fogliu di carta in biancu, registrandu campioni di sonu in elli. In u so statu normale, u generatore hè disattivatu è simpricimenti trasmette blocchi di input à l'output. Cusì, i blocchi di silenziu passanu senza cambià per tuttu u circuitu da manca à diritta, finiscinu in a carta di sonu. Chì silenziu piglia blocchi da a fila cunnessa à a so input.
Ma tuttu cambia se u generatore hè datu un cumandamentu per ghjucà u sonu, cumencia à generà campioni di sonu è li rimpiazza cù campioni in i blocchi di input è mette i blocchi cambiati à l'output. A carta di sonu principia à ghjucà u sonu. Quì sottu hè un prugramma chì implementa u schema di travagliu descrittu sopra:
/* Файл 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);
}
Dopu avè inizializatu u media streamer, trè filtri sò creati: voidsource, dtmfgen, snd_card_write. Una fonte di clock hè creata.
Allora avete bisognu di cunnette i filtri in cunfurmità cù u nostru circuitu, è a fonte di u clock deve esse cunnessu l'ultimu, postu chì dopu à questu u circuitu principia immediatamente à funziunà. Se cunnette una fonte di u clock à un circuitu infinitu, pò accade chì u streamer media s'hè lampatu s'ellu rileva almenu un filtru in a catena cù tutti l'inputs o tutti i outputs "pendu in l'aria" (micca cunnessu).
A cunnessione di i filtri hè fatta cù a funzione
ms_filter_link(src, src_out, dst, dst_in)
induve u primu argumentu hè un punteru à u filtru fonte, u sicondu argumentu hè u numeru di output di fonte (nota chì l'inputs è i outputs sò numerati partendu da zero). U terzu argumentu hè un punteru à u filtru di u receptore, u quartu hè u numeru di input di u receptore.
Tutti i filtri sò cunnessi è a fonte di u clock hè cunnessu l'ultimu (da quì in seguitu chjameremu solu un ticker). Dopu chì u nostru circuitu di sonu cumencia à travaglià, ma nunda ùn pò esse intesu in i parlanti di l'urdinatore - u generatore di sonu hè disattivatu è passa solu per i blocchi di dati di input cun silenziu. Per cumincià à generà un tonu, avete bisognu di eseguisce u metudu di filtru generatore.
Avemu da generà un signalu di dui toni (DTMF) currispundenti à appughjà u buttone "1" in u telefunu. Per fà questu, avemu aduprà a funzione ms_filter_call_method() Chjamemu u metu MS_DTMF_GEN_PLAY, passendu com'è argumentu un punteru à u codice chì u signale di riproduzione deve currisponde.
Il ne reste plus qu'à compiler le programme :
$ gcc mstest2.c -o mstest2 `pkg-config mediastreamer --libs --cflags`
E corre:
$ ./mstest2
Dopu avè principiatu u prugramma, sentirete un brevi signali di sonu custituitu da dui toni in u parlante di l'urdinatore.
Avemu custruitu è lanciatu u nostru primu circuitu di sonu. Avemu vistu cumu per creà istanze di filtru, cumu per cunnette è cumu chjamà i so metudi. Mentre simu cuntenti di u nostru successu iniziale, avemu sempre bisognu di attentu à u fattu chì u nostru prugramma ùn libera micca a memoria assignata prima di esce. In u prossimu
Source: www.habr.com