در دنیای نرمافزار آزاد تعدد و تکثر کتابخانههای برنامهنویسی یکی از دلایل پیشرفت اینگونه نرمافزارها شده است. یکی از کتابخانههای معروف که نرمافزارهای معروفی همچون VLC و Audacity از آن استفاده میکنند کتابخانه portaudio میباشد.
همانطور که از اسم آن پیداست، این کتابخانه یک voice handler میباشد.
هر سیستمعاملی در چندین سطح و حداقل و با دو سه نوع درایور باید با voice ارتباط برقرار کند. نکته مهم اینجاست که اگر درایور کارت صدا تغییر کند باید کد مربوط نیز تغییر کند.
این کتابخانه multi platform میباشد و این بدانمعناست که در چندین سیستمعامل و مستقل از درایور و نوع sound server همانند ALSA در لینوکس و Core Audio در Mac OS X یا انواع Sound Server که تعدادشان در ویندوز کم نیست کار میکند. به شکل زیر توجه کنید.
این شکل نشان میدهد که این کتابخانه مستقل از سیستمعامل، درایور، Sound Server و توابع مربوطشان کار میکند و برای کاربر یک SDK فراهم کرده است که نه تنها کار کاربر ساده گشته، بلکه زمان کد زدن، و مانور برنامهنویس بیشتر گشته است. همچنین شما برنامه خود را میتوانید در سه سیستم عامل معروف کامپایل نمایید بدون آنکه در کد آن تغییر ایجاد نمایید.
۳ گونه توابع این کتابخانه ارایه میدهد:
۱. توابع Host
۲. توابع Deviceهای صدا
۳. توابع Stream های صدا
۱. توابع host
اینگونه توابع مخصوص یک سیستمعامل خاص میباشند و یک معماری و. یا یک Sound Server خاص را پشتیبانی مینمایند. به عنوان مثال توابعی که WMME و یا توابعی که ALSA و همچنین توابعی که Core Audio را پشتیبانی نمایند و در این سطح توابع باشند که در دیاگرام بالا نیز نشان داده شدهاند جزو این دسته از توابع هستند.
درواقع سطح بالاترین گروهبندی توابع همین توایع Host میباشند.
توابع Host معمولاً با یک اندیس ارجاع داده میشوند: نوع دادهای با نام PaHostApiIndex که یک نوع integer است این اندیسها را handle میکند.
نکته: در کتابخانه portaudio تمام توابع با _Pa شروع میشوند و تمام انواع داده با Pa بدون ـ شروع میشوند. به توابع زیر دقت کنید:
1 2 |
typedef int PaHostApiIndex; PaHostApiIndex Pa_GetHostApiCount (void ); |
با نوع داده PaHostApiIndex بین ۰ و (Pa_GetHostApiCount() – ۱ ) یک محدوده اندیس گذاری میشود. که میتوان تمام توابع قابل دسترس Host در این بازه را شمرد.
میتوان با تابع Pa_GetDefaultHostApi اندیس پیشفرض Host را اخذ کرد.
اطلاعاتی راجعبه یک تابع Host ، همچون نام آن و سرویسهای پیشفرضش همگی در یک struct به نام PaHostApiInfo ذخیره میشوند. با تابع زیر میتوان به اطلاعات struct مذکور دسترسی پیدا کرد:
1 2 |
const PaHostApiInfo* Pa_GetHostApiInfo (PaHostApiIndex hostApi); |
نکته: نامگذاری در این کتابخانه، به گونهای fork شده از camel Case میباشد.
۲. توابع Deviceهای صدا
Deviceها واسطهای سختافزاری یا پورتهای منحصر به فرد خاصی را ارایه میدهند. Device های دارای نامها و قابلیتهای خاص از sample rate و کانالهای ورودی خروجی حمایت میکنند. Portaudio توابعی را برای شمارش دستگاههای قابل دسترس و قابلیت پرسجو فراهم کرده است.
یک Device نشاندهنده یک endpoint ی میباشد که توسط یک تابع صدای بومی سیستمعامل فراهم شده است. و واسط شما و آن سیستمعامل شده است. این موضوع معمولاً متناظر با پورتهای ورودی/خروجی روی یک سختافزار واسط صدا میباشد. هر تابع Host به صورت غیر مستقل عمل مینماید، در نتیجه یک پورت فیزیکی صدا ممکن است از طریق Device های در معرض گذاشته شده توسط توابع مختلف Host قابل آدرس دهی شوند.
یک Device یک نام دارد که به یک تابع Host مربوط میشود، و بالاترین تعداد کانالهای خروجی/ورودی را پشتیبانی مینماید. کتابخانه portaudio برای هر Device چندین sample rate و مقدارهای نهفته پیشفرض توضیه شده را آماده کرده است.برای فراهم آوردن اطلاعات جزیی و بیشتر راجعبه قابلیتهای device میتوانید از تابع Pa_IsFormatSupported استفاده نمایید.
اگرچه هر Device به طور مفهومی مال یک تابع ويژه Host میباشد، بیشتر توابع portaudio و ساختمان داده آن ارجاع به استفاده global از Device ها ارجاع داده میشوند.
اندیس نوع PaDeviceIndex که مستقل از Host ها میباشد ، یک عدد integer بین ۰ و (Pa_GetDeviceCount() – ۱) میباشد. تا حدی برای این امر دلایل تازیخی وجود دارد، اما اصل قضیه آسانسازی برای برنامه است که توابع Host از توابع Device جدا شدهاند و به یکدیگر کاری ندارند.
برای محسوب داشتن توابع Device به هنگام شمارش، میتوان از متغیر زیر بهره برد:
1 |
PaHostApiInfo::deviceCount – 1; |
اطلاعات راجعبه Device ها همگی در یک struct به نام PaDeviceInfo ذخیره شدهاند. شما با صدا کردن تابع زیر میتوانید اطلاعات راجعبه یک Device را اخذ نمایید:
1 2 |
const PaHostApiInfo* Pa_GetHostApiInfo (PaHostApiIndex hostApi); |
۳. توابع Stream های صدا
یک Stream یک جریان فعال میان دادههای صدا و Device صدا را نمایش میدهد. ۳ عنصر در Stream ها نقش اساسی را بازی میکنند و Stream ها بر روی آنها عمل میکنند:
۱. Sample Rate
۲. Sample Format
۳. Buffer Size
روشهای I/O:
portaudio دو روش برای برقراری ارتباط دادههای صدا میان یک open Stream و برنامه شما ارایه داده است:
۱. callback function
۲. read/write
در روش اول، یک تابع callback غیرهمزمان زمانی که نیاز به صدا یا صدایی در دسترس باشد توسط portaudio صدا زده میشود. کاربر میتواند در این تابع هر چه میخواهد بنویسد. در شماره بعد بیشتر توضیح خواهیم داد.
روش دوم درواقع یک روش جایگزین برای روش اول در حالاتی است که زبان برنامهنویسی callback functions را پشتیبانی نکند و یا برنامههایی که به کمترین عکسالعمل احتمالی احتیاج ندارند مفید خواهد بود.
باز کردن و بستن Stream:
برای باز کردن یک Steram باید تابع Pa_OpenStream را صدا زد. تابع مذکور به صورت زیر میباشد:
1 2 3 4 5 6 7 8 9 |
PaError Pa_OpenStream ( PaStream ** stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback * streamCallback, void * userData ) |
همچینین برای بستن یک Stream باید از تابع Pa_CloseStream استفاده کرد که ساختار کلی آن در زیر آمده است:
1 2 |
PaError Pa_CloseStream ( PaStream *stream); |
تواناییهایی کتابخانه portaudio:
-
بارگذاری و به unload کردن کتابخانه.
-
برشمدرن توابع قابل دسترس Host
-
برشمردن Device های موجود یا در سطح عمومی، و یا در درون هر یک ازتوابع میزبان
-
کشف پیش فرض و یا Device های توصیه شده و تنظیمات Device
-
کشف قابلیت های Device از جمله پشتیبانی Sample Format و Sample Rate
-
ایجاد و کنترل جریان از Audio Stream به Device و گرفتن Audio Stream از Device
-
بازیابی نسخه و اطلاعات خطا.
سلام محسن جان
مطالب خوبی گذاشتیی البته یه سریش رو هنوز وقت نکردم بخونم که ایشالاه اون ها رو هم می خونم
فقط محسن جان چند تا کار اگه انجام بدی خیلی خوب میشه
یه قسمت برای ارتباط یا نظر خواهی جدا قرار بده که بشه پیشنهادها رو اونجا داد
یه قالبی هم برای سایت در نظر بگیری هم خیلی عالی میشه
یه موضوع کلی هم برای سایت بزنی هم که دیگه خیلی خوب میشه
موفق باشی
بازم سر میزنم و از مطالب شما استفاده میکنم (;