کاوش در موتور VoIP Mediastreamer2. قسمت 2

مطالب مقاله از من گرفته شده است کانال ذن.

کاوش در موتور VoIP Mediastreamer2. قسمت 2

ایجاد یک Tone Generator

در قبلی مقاله ما کتابخانه پخش کننده رسانه، ابزارهای توسعه را نصب کردیم و عملکرد آنها را با ساخت یک برنامه آزمایشی آزمایش کردیم.

امروز ما یک برنامه کاربردی ایجاد خواهیم کرد که می تواند سیگنال آهنگ را روی کارت صدا ایجاد کند. برای حل این مشکل باید فیلترها را به مدار تولید کننده صدا که در زیر نشان داده شده است وصل کنیم:

کاوش در موتور VoIP Mediastreamer2. قسمت 2

ما نمودار را از چپ به راست می خوانیم، این جهتی است که جریان داده ما در آن حرکت می کند. فلش ها نیز به این موضوع اشاره می کنند. مستطیل ها فیلترهایی را نشان می دهند که بلوک های داده را پردازش کرده و نتیجه را به دست می آورند. در داخل مستطیل، نقش آن مشخص شده و نوع فیلتر دقیقا در زیر با حروف بزرگ مشخص شده است. فلش هایی که مستطیل ها را به هم متصل می کنند، صف های داده ای هستند که از طریق آن بلوک های داده از فیلتری به فیلتر دیگر تحویل داده می شوند. به طور کلی یک فیلتر می تواند ورودی و خروجی زیادی داشته باشد.

همه چیز با منبع ساعت شروع می شود، که سرعت محاسبه داده ها را در فیلترها تعیین می کند. با توجه به چرخه ساعت خود، هر فیلتر تمام بلوک های داده ای را که در ورودی آن هستند پردازش می کند. و بلوک هایی را با نتیجه در صف قرار می دهد. ابتدا فیلتر نزدیک به منبع ساعت محاسبات را انجام می دهد، سپس فیلترهای متصل به خروجی آن (خروجی های زیادی وجود دارد) و غیره. پس از اتمام پردازش آخرین فیلتر در زنجیره، اجرا متوقف می شود تا ساعت جدید برسد. ضربات، به طور پیش فرض، از فاصله 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)

در جایی که آرگومان اول یک اشاره گر به فیلتر منبع است، آرگومان دوم شماره خروجی منبع است (توجه داشته باشید که ورودی ها و خروجی ها با شروع از صفر شماره گذاری می شوند). آرگومان سوم یک اشاره گر به فیلتر گیرنده است و چهارمین شماره ورودی گیرنده است.

همه فیلترها متصل هستند و منبع ساعت آخرین بار متصل می شود (از این پس به سادگی آن را یک تیک تیک می نامیم). پس از آن مدار صوتی ما شروع به کار می کند، اما هنوز چیزی در بلندگوهای کامپیوتر شنیده نمی شود - مولد صدا خاموش است و به سادگی از بلوک های داده ورودی با سکوت عبور می کند. برای شروع تولید آهنگ، باید روش فیلتر ژنراتور را اجرا کنید.

ما یک سیگنال دو رنگی (DTMF) مربوط به فشار دادن دکمه "1" روی تلفن تولید می کنیم. برای این کار از تابع استفاده می کنیم ms_filter_call_method() ما متد MS_DTMF_GEN_PLAY را صدا می زنیم و آن را به عنوان یک آرگومان، نشانگر کدی که سیگنال پخش باید با آن مطابقت داشته باشد، ارسال می کنیم.

تنها چیزی که باقی می ماند این است که برنامه را کامپایل کنید:

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

و اجرا:

$ ./mstest2

پس از شروع برنامه، یک سیگنال صوتی کوتاه متشکل از دو تن را در بلندگوی کامپیوتر خواهید شنید.

ما اولین مدار صوتی خود را ساختیم و راه اندازی کردیم. ما نحوه ایجاد نمونه های فیلتر، نحوه اتصال آنها و نحوه فراخوانی روش های آنها را دیدیم. در حالی که ما از موفقیت اولیه خود راضی هستیم، هنوز باید به این نکته توجه کنیم که برنامه ما قبل از خروج، حافظه اختصاص داده شده را آزاد نمی کند. در بعدی مقاله ما یاد خواهیم گرفت که بعد از خودمان را تمیز کنیم.

منبع: www.habr.com

اضافه کردن نظر