Εξερευνώντας τη μηχανή VoIP Mediastreamer2. Μέρος 2

Το υλικό του άρθρου είναι παρμένο από το δικό μου κανάλι ζεν.

Εξερευνώντας τη μηχανή VoIP Mediastreamer2. Μέρος 2

Δημιουργία Tone Generator

Στο προηγούμενο άρθρο Εγκαταστήσαμε τη βιβλιοθήκη του media streamer, τα εργαλεία ανάπτυξης και δοκιμάσαμε τη λειτουργικότητά τους δημιουργώντας μια δοκιμαστική εφαρμογή.

Σήμερα θα δημιουργήσουμε μια εφαρμογή που μπορεί να δημιουργήσει ένα ηχητικό σήμα σε μια κάρτα ήχου. Για να λύσουμε αυτό το πρόβλημα, πρέπει να συνδέσουμε τα φίλτρα στο κύκλωμα της γεννήτριας ήχου που φαίνεται παρακάτω:

Εξερευνώντας τη μηχανή VoIP Mediastreamer2. Μέρος 2

Διαβάζουμε το διάγραμμα από αριστερά προς τα δεξιά, αυτή είναι η κατεύθυνση προς την οποία κινείται η ροή των δεδομένων μας. Τα βέλη υποδηλώνουν επίσης αυτό. Τα ορθογώνια υποδεικνύουν φίλτρα που επεξεργάζονται μπλοκ δεδομένων και εξάγουν το αποτέλεσμα. Μέσα στο παραλληλόγραμμο, υποδεικνύεται ο ρόλος του και ο τύπος του φίλτρου υποδεικνύεται με κεφαλαία γράμματα ακριβώς από κάτω. Τα βέλη που συνδέουν τα ορθογώνια είναι ουρές δεδομένων μέσω των οποίων παραδίδονται μπλοκ δεδομένων από φίλτρο σε φίλτρο. Γενικά, ένα φίλτρο μπορεί να έχει πολλές εισόδους και εξόδους.

Όλα ξεκινούν από την πηγή ρολογιού, η οποία ορίζει τον ρυθμό με τον οποίο υπολογίζονται τα δεδομένα στα φίλτρα. Σύμφωνα με τον κύκλο του ρολογιού του, κάθε φίλτρο επεξεργάζεται όλα τα μπλοκ δεδομένων που βρίσκονται στην είσοδό του. Και βάζει μπλοκ με το αποτέλεσμα στην ουρά. Αρχικά, το φίλτρο που βρίσκεται πιο κοντά στην πηγή ρολογιού εκτελεί υπολογισμούς, μετά τα φίλτρα που συνδέονται με τις εξόδους του (μπορεί να υπάρχουν πολλές έξοδοι) και ούτω καθεξής. Αφού ολοκληρωθεί η επεξεργασία του τελευταίου φίλτρου στην αλυσίδα, η εκτέλεση σταματά μέχρι να φτάσει ένα νέο ρολόι. Τα beats, από προεπιλογή, ακολουθούν ένα διάστημα 10 χιλιοστών του δευτερολέπτου.

Ας επιστρέψουμε στο διάγραμμα μας. Οι κύκλοι του ρολογιού φτάνουν στην είσοδο της πηγής σίγασης· αυτό είναι ένα φίλτρο, το οποίο είναι απασχολημένο με τη δημιουργία ενός μπλοκ δεδομένων που περιέχει μηδενικά στην έξοδό του για κάθε κύκλο ρολογιού. Αν θεωρήσουμε αυτό το μπλοκ ως ένα μπλοκ δειγμάτων ήχου, τότε αυτό δεν είναι τίποτα άλλο από σιωπή. Με την πρώτη ματιά, φαίνεται περίεργο να δημιουργείτε μπλοκ δεδομένων με σιωπή - τελικά, δεν μπορεί να ακουστεί, αλλά αυτά τα μπλοκ είναι απαραίτητα για τη λειτουργία της γεννήτριας σήματος ήχου. Η γεννήτρια χρησιμοποιεί αυτά τα μπλοκ σαν ένα κενό φύλλο χαρτιού, καταγράφοντας δείγματα ήχου σε αυτά. Στην κανονική της κατάσταση, η γεννήτρια είναι απενεργοποιημένη και απλώς προωθεί τα μπλοκ εισόδου στην έξοδο. Έτσι, τα μπλοκ σιωπής περνούν αμετάβλητα σε όλο το κύκλωμα από αριστερά προς τα δεξιά, καταλήγοντας στην κάρτα ήχου. Το οποίο παίρνει αθόρυβα μπλοκ από την ουρά που είναι συνδεδεμένη με την είσοδό του.

Αλλά όλα αλλάζουν εάν δοθεί στη γεννήτρια εντολή για αναπαραγωγή ήχου, αρχίζει να παράγει δείγματα ήχου και τα αντικαθιστά με δείγματα στα μπλοκ εισόδου και βάζει τα αλλαγμένα μπλοκ στην έξοδο. Η κάρτα ήχου αρχίζει να παίζει ήχο. Ακολουθεί ένα πρόγραμμα που υλοποιεί το σχήμα εργασίας που περιγράφεται παραπάνω:

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

Μετά την προετοιμασία της ροής πολυμέσων, δημιουργούνται τρία φίλτρα: voidsource, dtmfgen, snd_card_write. Δημιουργείται μια πηγή ρολογιού.

Στη συνέχεια, πρέπει να συνδέσετε τα φίλτρα σύμφωνα με το κύκλωμά μας και η πηγή ρολογιού πρέπει να συνδεθεί τελευταία, αφού μετά από αυτό το κύκλωμα θα αρχίσει αμέσως να λειτουργεί. Εάν συνδέσετε μια πηγή ρολογιού σε ένα ημιτελές κύκλωμα, μπορεί να συμβεί να κολλήσει η ροή πολυμέσων εάν εντοπίσει τουλάχιστον ένα φίλτρο στην αλυσίδα με όλες τις εισόδους ή όλες τις εξόδους «κρεμασμένες στον αέρα» (δεν είναι συνδεδεμένο).

Η σύνδεση των φίλτρων γίνεται χρησιμοποιώντας τη λειτουργία

ms_filter_link(src, src_out, dst, dst_in)

όπου το πρώτο όρισμα είναι δείκτης στο φίλτρο πηγής, το δεύτερο όρισμα είναι ο αριθμός εξόδου της πηγής (σημειώστε ότι οι είσοδοι και οι έξοδοι αριθμούνται ξεκινώντας από το μηδέν). Το τρίτο όρισμα είναι ένας δείκτης στο φίλτρο του δέκτη, το τέταρτο είναι ο αριθμός εισόδου του δέκτη.

Όλα τα φίλτρα είναι συνδεδεμένα και η πηγή του ρολογιού είναι συνδεδεμένη τελευταία (εφεξής θα το ονομάζουμε απλά ticker). Μετά από αυτό το κύκλωμα ήχου αρχίζει να λειτουργεί, αλλά τίποτα δεν ακούγεται ακόμα στα ηχεία του υπολογιστή - η γεννήτρια ήχου είναι απενεργοποιημένη και απλώς περνά μέσα από τα μπλοκ δεδομένων εισόδου με σιωπή. Για να ξεκινήσετε να δημιουργείτε έναν τόνο, πρέπει να εκτελέσετε τη μέθοδο φίλτρου γεννήτριας.

Θα δημιουργήσουμε ένα σήμα δύο τόνων (DTMF) που αντιστοιχεί στο πάτημα του κουμπιού "1" στο τηλέφωνο. Για να το κάνουμε αυτό, χρησιμοποιούμε τη συνάρτηση ms_filter_call_method() Καλούμε τη μέθοδο MS_DTMF_GEN_PLAY, περνώντας την ως όρισμα ως δείκτη στον κώδικα στον οποίο πρέπει να αντιστοιχεί το σήμα αναπαραγωγής.

Το μόνο που μένει είναι να μεταγλωττίσουμε το πρόγραμμα:

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

Και τρέξε:

$ ./mstest2

Μετά την εκκίνηση του προγράμματος, θα ακούσετε ένα σύντομο ηχητικό σήμα που αποτελείται από δύο τόνους στο ηχείο του υπολογιστή.

Κατασκευάσαμε και ξεκινήσαμε το πρώτο μας κύκλωμα ήχου. Είδαμε πώς να δημιουργήσουμε στιγμιότυπα φίλτρων, πώς να τα συνδέσουμε και πώς να καλέσουμε τις μεθόδους τους. Αν και είμαστε ευχαριστημένοι με την αρχική μας επιτυχία, πρέπει να δώσουμε προσοχή στο γεγονός ότι το πρόγραμμά μας δεν ελευθερώνει τη μνήμη που έχει εκχωρηθεί πριν από την έξοδο. Στην επόμενη άρθρο θα μάθουμε να καθαρίζουμε τον εαυτό μας.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο