| AXFER-TRANSFER(1) | General Commands Manual | AXFER-TRANSFER(1) |
نام (NAME)
axfer-transfer - انتقالدهنده فریم داده صوتی برای دستگاهها و گرههای صوتی
خلاصه دستور (SYNOPSIS)
axfer transfer direction [ common-options ] [ backend-options ] [ filepath ]
axfer transfer direction [ common-options ] [ backend-options ] -I | --separate-channels filepath ...
direction = capture | playback
common-options = ( بخش گزینهها (OPTIONS) را بخوانید )
backend-options = ( بخش گزینهها (OPTIONS) را بخوانید )
filepaths = ( بخش گزینهها (OPTIONS) را بخوانید )
توضیحات (DESCRIPTION)
زیردستور transfer از axfer انتقال فریمهای داده صوتی را برای دستگاههای موجود در بکاندهای پشتیبانیشده انجام میدهد. این برنامه اساساً برای استفاده از APIهای alsa-lib (بکاند libasound) جهت مدیریت دستگاههای صوتی پشتیبانیشده توسط زیرسیستم صوتی لینوکس (ALSA) طراحی شده است.
گزینهها (OPTIONS)
جهت (Direction)
مسیر فایل (Filepath)
اگر مسیر فایل یک مسیر کامل از دایرکتوری ریشه نباشد، به عنوان مسیری نسبی نسبت به دایرکتوری کاری جاری در زمان اجرا در نظر گرفته میشود.
اگر مسیر فایل مشخص نشده باشد یا به صورت '-' داده شود، ورودی یا خروجی استاندارد استفاده میشود.
برای انتقال بازپخش (پخش)، قالب کانتینر filepath دادهشده به صورت خودکار شناسایی میشود و فراداده آن برای پارامترهای قالب نمونه، کانالها، نرخ نمونهبرداری و مدت زمان استفاده میشود. اگر چیزی شناسایی نشود، محتوای مسیر فایل دادهشده به عنوان داده خام پردازش میشود. در این حالت، پارامترها باید به صورت گزینهها مشخص شوند.
استفاده
از چندین filepath
با گزینه -I |
--separate-channels مجاز
است. در این
حالت،
ورودی و
خروجی
استاندارد
در دسترس
نخواهد بود.
مشخص کردن
filepath تکراری
مجاز نیست
مگر برای
مسیرهای
زیر:
- /dev/null
- /dev/zero
- /dev/full
- /dev/random
- /dev/urandom
گزینههای عمومی (Common options)
- -h, --help
- چاپ پیامهای راهنما و پایان اجرای برنامه.
- -q, --quiet
- حالت بیصدا. جلوگیری از چاپ پیامها (نه خود صدا :))
- -v, --verbose
- حالت پرحرف. زمان اجرا بر اساس تعداد دفعات استفاده از این گزینه در خط فرمان، اطلاعات تکمیلی بیشتری چاپ میکند.
- -d, --duration=#
- توقف پس از # ثانیه. مقدار صفر به معنای بینهایت است. مقدار پیشفرض صفر است، بنابراین در صورت عدم ذکر این گزینه، فرآیند انتقال تا زمان متوقف شدن دستی ادامه مییابد. فقط یکی از گزینههای -d یا -s میتواند استفاده شود.
- -s, --samples=#
- توقف پس از انتقال # فریم داده. مقدار صفر به معنای بینهایت است. مقدار پیشفرض صفر است، بنابراین در صورت عدم ذکر این گزینه، فرآیند انتقال تا زمان متوقف شدن دستی ادامه مییابد. فقط یکی از گزینههای -d یا -s میتواند استفاده شود.
- -f, --format=FORMAT
- مشخص کردن
قالب نمونه
صوتی. این
گزینه برای
انتقال ضبط
یا پخش
فایلهای
حاوی داده
خام صوتی
الزامی است.
قالبهای نمونه موجود در زیر فهرست شدهاند:
- [S8|U8|S16|U16|S32|U32][_LE|_BE]
- [S24|U24][_LE|_BE]
- FLOAT[_LE|_BE]
- FLOAT64[_LE|_BE]
- IEC958_SUBFRAME[_LE|_BE]
- MU_LAW
- A_LAW
- [S20|U20][_LE|_BE]
- [S24|U24][_3LE|_3BE]
- [S20|U20][_3LE|_3BE]
- [S18|U18][_3LE|_3BE]
- DSD_U8
- DSD_[U16|U32][_LE|_BE]اگر ترتیب بایتها (Endianness) مشخص نشود، از ترتیب بایتهای سیستم میزبان استفاده میشود.
برخی قالبهای ویژه نیز در دسترس هستند:
- cd (16 بیت little endian، 44100، استریو) [= -f S16_LE -c 2 -r 44100]
- cdr (16 بیت big endian، 44100، استریو) [= -f S16_BE -c 2 -f 44100]
- dat (16 بیت little endian، 48000، استریو) [= -f S16_LE -c 2 -r 48000]در صورت عدم ذکر، U8 به عنوان پیشفرض استفاده میشود. قالبهای واقعاً در دسترس توسط هر بکاند انتقال محدود میشوند.
قالبهای نمونه غیرقابل استفاده در زیر فهرست شدهاند. اندازه فریم داده این قالبها با واحد بایت تراز نیست.
- IMA_ADPCM
- MPEG
- GSM
- SPECIAL
- G723_24
- G723_24_1B
- G723_40
- G723_40_1B - -c, --channels=#
- مشخص کردن تعداد نمونههای داده صوتی در هر فریم. این گزینه برای انتقال ضبط یا پخش فایلهای حاوی داده صوتی خام الزامی است. مقدار باید بین 1 تا 256 باشد. در صورت عدم ذکر، 1 به عنوان پیشفرض استفاده میشود.
- -r, --rate=#
- مشخص کردن تعداد فریمهای داده صوتی در هر ثانیه (نرخ نمونهبرداری). این گزینه برای انتقال ضبط یا پخش فایلهای حاوی داده صوتی خام الزامی است. اگر مقدار کمتر از 1000 باشد، با واحد kHz تفسیر میشود. مقدار باید بین 2000 و 192000 باشد. در صورت عدم ذکر، 8000 به عنوان پیشفرض استفاده میشود.
- -t, --file-type=TYPE
- مشخص کردن
نوع فایل.
این گزینه
برای
انتقال ضبط
الزامی است.
انواع
موجود در
زیر فهرست
شدهاند:
- wav: قالب موجی Microsoft/IBM RIFF/Wave
- au, sparc: قالب Sparc AU
- voc: قالب صوتی Creative Tech. voice
- raw: داده خامهنگامی که مقداری مشخص نشود، برای انتقال ضبط، نوع بر اساس پسوند filepath تعیین میشود و نوع raw به عنوان حالت جایگزین (Fallback) استفاده میشود.
- -I, --separate-channels
- این گزینه را زمانی مشخص کنید که قرار است چندین فایل پردازش شوند. برای انتقال ضبط، اگر یک مسیر فایل به عنوان filepath داده شود، فهرستی از filepaths با الگوی '<filepath>-<sequential number>[.suffix]' تولید میشود. در صورت استفاده از قالب کانتینر خام، پسوند حذف میشود.
- --dump-hw-params
- تخلیه پارامترهای سختافزاری و پایان زمان اجرا در صورتی که بکاند از آن پشتیبانی کند.
- --xfer-backend=BACKEND
- انتخاب
بکاند
انتقال از
فهرست زیر.
مقدار
پیشفرض libasound
است.
- libasound
- libffado (اختیاری در صورت کامپایل شدن)
گزینههای بکاند برای libasound
- -D, --device=NODE
-
این گزینه برای انتخاب گره PCM در فضای پیکربندی libasound استفاده میشود. گرههای موجود توسط عملیات pcm از زیردستور list فهرست میشوند.
- -N, --nonblock
-
با این گزینه، زیرجریان PCM در حالت غیرانسدادی (Non-blocking) باز میشود. هنگامی که فریم داده صوتی در بافر زیرجریان PCM در دسترس نباشد، عملیات ورودی/خروجی بدون مسدود کردن فرآیند فوراً بازمیگردد. این گزینه به طور ضمنی از گزینه --waiter-type نیز برای جلوگیری از مصرف سنگین پردازنده استفاده میکند.
- -M, --mmap
-
با این گزینه، در صورتی که گره انتخابشده از این عملیات پشتیبانی کند، فریم داده صوتی مستقیماً در بافر زیرجریان PCM پردازش میشود. بدون این گزینه، از بافرهای موقت برای کپی کردن فریم داده صوتی به بافر زیرجریان PCM استفاده میشود. این گزینه به طور ضمنی از گزینه --waiter-type نیز برای جلوگیری از مصرف سنگین پردازنده استفاده میکند.
- -F, --period-size=#
-
این گزینه مقدار دادهشده را روی پارامتر سختافزاری period_size زیرجریان PCM تنظیم میکند. این پارامتر بیانگر تعداد فریمهای داده صوتی در هر پریود در بافر زیرجریان PCM است. مقدار واقعی در نتیجه تعامل بین پیادهسازی هر پلاگین PCM متصلشده از گره PCM انتخابشده، و درایور درون هسته یا پلاگینهای ورودی/خروجی PCM تعیین میشود.
در حالت ایدهآل، دقیقاً همان مقدار فریم داده صوتی مشخصشده باید در یک عملیات ورودی/خروجی مدیریت شود. در عمل، بسته به پیادهسازی پلاگینهای PCM، درایور درون هسته، پلاگینهای ورودی/خروجی PCM و مدل زمانبندی، ممکن است متفاوت باشد. برای پلاگین PCM نوع 'hw' در مدل زمانبندی 'irq'، این مقدار برای تعیین فواصل وقفه سختافزاری استفاده میشود، بنابراین انتظار میرود همان مقدار فریم داده صوتی برای یک عملیات ورودی/خروجی در دسترس باشد.
- --period-time=#
-
این گزینه مقدار دادهشده را روی پارامتر سختافزاری period_time زیرجریان PCM تنظیم میکند. این گزینه شبیه به گزینه --period-size است، اما واحد آن میکروثانیه است.
- -B, --buffer-size=#
-
این گزینه مقدار دادهشده را روی پارامتر سختافزاری buffer_size زیرجریان PCM تنظیم میکند. این پارامتر بیانگر تعداد فریمهای داده صوتی در بافر زیرجریان PCM است. مقدار واقعی در نتیجه تعامل بین پیادهسازی هر پلاگین PCM متصلشده از گره PCM انتخابشده، و درایور درون هسته یا پلاگینهای ورودی/خروجی PCM تعیین میشود.
در حالت ایدهآل، این مقدار باید مضربی از تعداد فریم داده صوتی در هر پریود (یعنی اندازه پریود) باشد. در عمل، بسته به پیادهسازی پلاگینهای PCM، درایور درون هسته و پلاگینهای ورودی/خروجی PCM، ممکن است متفاوت باشد.
- --buffer-time=#
-
این گزینه مقدار دادهشده را روی پارامتر سختافزاری buffer_time زیرجریان PCM تنظیم میکند. این گزینه شبیه به گزینه --buffer-size است، اما واحد آن میکروثانیه است.
- --waiter-type=TYPE
-
این گزینه نوع منتظرکننده (Waiter) را برای اعلان رخداد مشخص میکند. در حال حاضر، چهار نوع موجود است: default ، select ، poll و epoll . با نوع default ، تابع 'snd_pcm_wait()' استفاده میشود. با نوع select ، فراخوانی سیستمی 'select(2)' استفاده میشود. با نوع poll ، فراخوانی سیستمی 'poll(2)' استفاده میشود. با نوع epoll ، فراخوانی سیستمی اختصاصی لینوکس 'epoll(7)' استفاده میشود.
این گزینه باید با یکی از گزینههای --nonblock یا --mmap ، یا مقدار timer از گزینه --sched-model همخوانی داشته باشد. امکان استفاده همزمان از این گزینه و --test-nowait وجود ندارد.
- --sched-model=MODEL
-
این گزینه مدل زمانبندی را برای فرآیند این برنامه انتخاب میکند. یکی از مقادیر irq یا timer در دسترس است. برای جزئیات، لطفاً بخش «مدل زمانبندی» را بخوانید.
هنگامی که چیزی مشخص نشده باشد، مدل irq استفاده میشود.
- -A, --avail-min=#
-
این گزینه مقدار دادهشده را روی پارامتر نرمافزاری avail-min زیرجریان PCM تنظیم میکند. در حالت انسدادی (Blocking)، این مقدار به عنوان آستانه تعداد فریمهای داده صوتی موجود در بافر زیرجریان PCM برای بیدار کردن فرآیند مسدودشده توسط عملیات ورودی/خروجی استفاده میشود. در حالت غیرانسدادی، هر عملیات ورودی/خروجی مقدار -EAGAIN برمیگرداند تا زمانی که تعداد فریمهای داده صوتی موجود به این آستانه برسد.
این گزینه در مواردی کاربرد دارد که نه --mmap و نه مقدار timer از گزینه --sched-model استفاده نشده باشد.
- -R, --start-delay=#
-
این گزینه مقدار دادهشده را روی پارامتر نرمافزاری start_threshold زیرجریان PCM تنظیم میکند. این مقدار به عنوان آستانه برای شروع خودکار زیرجریان PCM استفاده میشود. در حال حاضر، این گزینه در مواردی کاربرد دارد که نه --mmap و نه مقدار timer از گزینه --sched-model استفاده نشده باشد.
برای انتقال بازپخش، هنگامی که تعداد فریمهای داده صوتی انباشتهشده در بافر زیرجریان PCM که این برنامه در آن مینویسد به این آستانه برسد، زیرجریان PCM به صورت خودکار بدون فراخوانی صریح snd_pcm_start() روی زیرجریان PCM شروع به کار میکند.
برای انتقال ضبط، این گزینه کاربردی ندارد. تعداد فریمهای داده صوتی انباشتهشده بدون فراخوانی صریح snd_pcm_start() روی زیرجریان PCM افزایش نمییابد.
این گزینه در مواردی کاربرد دارد که نه --mmap و نه مقدار timer از گزینه --sched-model استفاده نشده باشد.
- -T, --stop-delay=#
-
این گزینه مقدار دادهشده را روی پارامتر نرمافزاری stop_threshold زیرجریان PCM تنظیم میکند. این مقدار به عنوان آستانه برای متوقف کردن خودکار زیرجریان PCM استفاده میشود. در حال حاضر، این گزینه در مواردی کاربرد دارد که نه --mmap و نه مقدار timer از گزینه --sched-model استفاده نشده باشد.
برای انتقال ضبط، هنگامی که تعداد فریمهای داده صوتی انباشتهشده در بافر زیرجریان PCM که درایور یا پلاگینهای PCM کتابخانه alsa-lib در آن مینویسند به این آستانه برسد، زیرجریان PCM به صورت خودکار بدون فراخوانی صریح snd_pcm_stop() روی زیرجریان متوقف میشود. این حالتی است که برنامه برای مدتی فریمهای داده صوتی را بدون خواندن رها میکند.
برای انتقال بازپخش، هنگامی که تعداد فریمهای داده صوتی موجود در بافر زیرجریان PCM که درایور یا پلاگینهای PCM کتابخانه alsa-lib از آن میخوانند به این آستانه برسد، زیرجریان PCM به صورت خودکار بدون فراخوانی صریح snd_pcm_stop() روی زیرجریان متوقف میشود. این حالتی است که برنامه برای مدتی فریمهای داده صوتی را بدون نوشتن رها میکند.
این گزینه در مواردی کاربرد دارد که نه --mmap و نه مقدار timer از گزینه --sched-model استفاده نشده باشد.
- --disable-resample
-
این گزینه روی پلاگین 'plug' در alsa-lib اثر میگذارد تا از تبدیل نرخ نمونهبرداری برای فریم داده صوتی جلوگیری کند.
- --disable-channels
-
این گزینه روی پلاگین 'plug' در alsa-lib اثر میگذارد تا از تبدیل تعداد کانالها برای فریم داده صوتی جلوگیری کند.
- --disable-format
-
این گزینه روی پلاگین 'plug' در alsa-lib اثر میگذارد تا از تبدیل قالب نمونه برای فریم داده صوتی جلوگیری کند.
- --disable-softvol
-
این گزینه روی پلاگین 'softvol' در alsa-lib اثر میگذارد تا از تبدیل نمونهها برای فریم داده صوتی از طریق کنترلر ولوم نرمافزاری اضافی جلوگیری کند.
- --fatal-errors
-
این گزینه عملیات بازیابی از وضعیت خطای XRUN زیرجریان PCM در حال اجرا را سرکوب میکند و سپس فرآیند این برنامه طبق معمول پایان مییابد.
- --test-nowait
-
این گزینه هرگونه منتظرکننده (Waiter) برای اعلان رخدادهای ورودی/خروجی را غیرفعال میکند. عملیات ورودی/خروجی به صورت مداوم تکرار میشوند تا هر فریم داده صوتی در دسترس قرار گیرد. این گزینه بار سنگینی بر مصرف پردازنده تحمیل میکند.
گزینههای بکاند برای libffado
این بکاند زمانی که اسکریپت پیکربندی نماد ffado_streaming_init() را در شیء اشتراکی libffado تشخیص دهد، به طور خودکار در دسترس قرار میگیرد.
- -p, --port=#
-
این گزینه از مقدار دادهشده برای تعیین اینکه کدام کنترلکننده 1394 OHCI جهت ارتباط استفاده شود، بهره میبرد. هنگامی که سیستم لینوکس دارای دو کنترلکننده 1394 OHCI باشد، مقادیر 0 یا 1 در دسترس هستند. امکان استفاده همزمان از این گزینه و -g وجود ندارد. اگر چیزی مشخص نشود، libffado با دستگاههای موجود روی گذرگاه IEEE 1394 که توسط تمام کنترلکنندههای 1394 OHCI موجود در سیستم لینوکس مدیریت میشوند ارتباط برقرار میکند.
- -n, --node=#
-
این گزینه از مقدار دادهشده برای تعیین اینکه کدام واحد (Unit) جهت ارتباط استفاده شود، بهره میبرد. این گزینه نیازمند گزینه -p است تا مشخص کند کدام کنترلکننده 1394 OHCI برای ارتباط با واحد مشخصشده استفاده شود.
- -g, --guid=HEXADECIMAL
-
این گزینه از مقدار دادهشده برای تعیین واحد هدف جهت ارتباط استفاده میکند. مقدار باید با '0x' پیشوندگذاری شود و شامل نویسههای هگزادسیمال (0-9, a-f, A-F) باشد. امکان استفاده همزمان از این گزینه و -p وجود ندارد. اگر چیزی مشخص نشود، libffado با واحدهای موجود روی گذرگاه IEEE 1394 که توسط تمام کنترلکنندههای 1394 OHCI موجود در سیستم لینوکس مدیریت میشوند ارتباط برقرار میکند.
- --frames-per-period=#
-
این گزینه از مقدار دادهشده برای تعیین تعداد فریم داده صوتی در یک عملیات خواندن/نوشتن استفاده میکند. این عملیات تا زمانی که تعداد فریم داده صوتی موجود از مقدار دادهشده بیشتر شود مسدود میماند. مقدار پیشفرض ۵۱۲ فریم داده صوتی است.
- --periods-per-buffer=#
-
این گزینه از مقدار دادهشده برای تعیین اندازه بافر میانی بین این برنامه و libffado استفاده میکند. مقدار پیشفرض ۲ پریود در هر بافر است.
- --slave
-
این گزینه به برنامه امکان میدهد در حالت Slave (پیرو) اجرا شود. در این حالت، libffado دایرکتوری واحد را به رام پیکربندی کنترلکننده 1394 OHCI که سیستم لینوکس روی آن اجرا میشود اضافه میکند. این دایرکتوری واحد میتواند توسط گره دیگر روی همان گذرگاه پیدا شود. سیستم لینوکس در حال اجرا روی آن گره میتواند بسته همگامزمانی (Isochronous) حاوی فریم داده صوتی را به این واحد منتقل کند. این برنامه میتواند بسته را دریافت کرده و فریم داده صوتی را تفکیک (Demultiplex) کند.
- --snoop
-
این گزینه به برنامه امکان میدهد در حالت Snoop (شنود) اجرا شود. در این حالت، libffado به کانالهای همگامزمانی که دستگاه بستهها را روی آنها منتقل میکند گوش میدهد. هنگامی که ارتباط همگامزمانی توسط هر واحد روی همان گذرگاه آغاز شود، بستهها میتوانند توسط این برنامه پردازش شوند.
- --sched-priority=#
-
این گزینه تابع pthread_setschedparam() را در فراخوانی ffado_streaming_init() اجرا میکند تا سیاست زمانبندی و اولویت نخهای (Threads) مربوط به ارتباط همگامزمانی را با مقدار دادهشده تنظیم کند. مقدار دادهشده باید در محدوده پارامتر RLIMIT_RTPRIO فرآیند باشد. لطفاً برای جزئیات getrlimit(2) را بخوانید.
سیگنالهای پوزیکس (POSIX SIGNALS)
در طول انتقال، سیگنالهای SIGINT و SIGTERM فایلهای در حال استفاده و زیرجریان PCM را میبندند تا اجرای برنامه پایان یابد.
سیگنال SIGTSTP زیرجریان PCM را به حالت تعلیق (Suspend) درمیآورد و SIGCONT آن را از سر میگیرد. هیچ خطای XRUN رخ نخواهد داد. در بکاند libffado، تعلیق و ازسرگیری پشتیبانی نمیشود و زمان اجرا فوراً لغو میگردد.
سایر سیگنالها رفتارهای پیشفرض خود را انجام میدهند.
مثالها (EXAMPLES)
$ axfer transfer playback -d 1 something
دستور بالا فریم داده صوتی موجود در فایل 'something' را برای پخش به مدت ۱ ثانیه انتقال میدهد. تا زمانی که فایل با یکی از قالبهای صوتی Microsoft/IBM RIFF/Wave، Sparc AU یا Creative Tech. voice سازگار باشد، قالب نمونه با تجزیه 'something' به صورت خودکار شناسایی میشود. اگر چیزی شناسایی نشد، گزینههای -r ، -c و -f باید مشخص شوند، یا -f باید با یک قالب ویژه داده شود.
$ axfer transfer playback -r 22050 -c 1 -f S16_LE -t raw something
دستور بالا فریم داده صوتی در فایل 'something' را که فاقد اطلاعات قالب نمونه است، به عنوان قالب نمونه 22050 هرتز، مونو، PCM شانزده بیتی علامتدار little endian برای پخش منتقل میکند. انتقال تا زمان دریافت سیگنال SIGINT از صفحهکلید یا SIGTERM توسط kill(1) ادامه مییابد.
$ axfer transfer capture -d 10 -f cd something.wav
دستور بالا فریم داده صوتی را به فایل 'something.wav' با قالب نمونه 44.1 کیلوهرتز، ۲ کاناله، PCM شانزده بیتی علامتدار little endian به مدت ۱۰ ثانیه منتقل (ضبط) میکند. قالب فایل بر اساس پسوند filepath دادهشده، Microsoft/IBM RIFF/Wave است.
$ axfer transfer capture -s 1024 -r 48000 -c 2 -f S32_BE -I -t au channels
دستور بالا فریم داده صوتی را با قالب نمونه 48.0 کیلوهرتز، ۲ کاناله، PCM سی و دو بیتی علامتدار big endian به تعداد ۱,۰۲۴ فریم داده به فایلهایی به نامهای 'channels-1.au' و 'channels-2.au' منتقل (ضبط) میکند.
مدل زمانبندی (SCHEDULING MODEL)
در طراحی هسته PCM در ALSA، زمان اجرای زیرجریان PCM از دو حالت پشتیبانی میکند؛ period-wakeup و no-period-wakeup. این دو حالت برای مدلهای زمانبندی متفاوتی در نظر گرفته شدهاند.
مدل زمانبندی مبتنی بر IRQ (IRQ-based scheduling model)
به عنوان پیشفرض، حالت period-wakeup استفاده میشود. در این حالت، درایورهای درون هسته باید سختافزار را طوری به کار گیرند که اعلانهای دورهای برای انتقال فریم داده صوتی تولید کند. فاصله زمانی اعلانها بر حسب زمان واقعی معادل همان مقدار فریم داده صوتی به اندازه یک پریود بافر است.
در گردانندهای (Handler) که به این اعلان اختصاص داده شده است، یک تابع کمکی از هسته ALSA PCM فراخوانی میشود تا موقعیت سرِ انتقال سختافزاری را بهروزرسانی کند، سپس آن را با موقعیت سرِ عملیات برنامه مقایسه میکند تا سرریز/افت بافر (XRUN) را تشخیص داده و فرآیندهای مسدودشده را بیدار کند.
برای این منظور، معمولاً از وقفه سختافزاری (IRQ) کنترلکننده برای گذرگاههای صوتی سریال مانند Inter-IC sound (I2S) استفاده میشود. در این حالت، کنترلکننده وقفه را بر اساس انتقال روی گذرگاه صوتی سریال تولید میکند. در گرداننده اختصاصیافته به وقفه، انتقال دسترسی مستقیم به حافظه (DMA) بین حافظه اختصاصی میزبان و حافظه دستگاه درخواست میشود.
اگر سختافزار هدف از این نوع سازوکار پشتیبانی نکند، اعلان دورهای باید توسط یک تایمر (مانند hrtimer یا تایمر کرنل) شبیهسازی شود. پلاگینهای خارجی PCM تولیدشده توسط SDK پلاگین PCM در alsa-lib نیز باید رفتار فوق را شبیهسازی کنند.
در این حالت، برنامههای PCM بر اساس شیوه معمول عملیات ورودی/خروجی برنامهنویسی میشوند. آنها فراخوانیهای سیستمی انسدادی را برای خواندن/نوشتن فریم داده صوتی در بافر زیرجریان PCM، یا فراخوانیهای انسدادی را برای انتظار تا زمان در دسترس قرار گرفتن هر فریم داده صوتی اجرا میکنند. در axfer ، به این حالت مدل زمانبندی مبتنی بر IRQ گفته میشود و رفتار پیشفرض است. کاربران میتوانند با استفاده از گزینه --sched-model با مقدار irq این حالت را صریحاً پیکربندی کنند.
مدل زمانبندی مبتنی بر تایمر (Timer-based scheduling model)
حالت no-period-wakeup یک حالت اختیاری در زمان اجرای زیرجریان PCM است. این حالت نیازمند یک ویژگی خاص در سختافزار و همکاری درایور درون هسته و برنامههای PCM است. در این حالت، درایورهای درون هسته سختافزار را برای تولید اعلانهای دورهای جهت انتقال فریم داده صوتی به کار نمیگیرند. سختافزار باید به صورت خودکار بدون عملیات دورهای درایورها به انتقال فریم داده صوتی ادامه دهد؛ مثلاً بر اساس انتقال خودکار فعالشده DMA یا زنجیرهای از توصیفکنندههای ثبتشده.
در این حالت، هیچ رویدادی فرآیندهای مسدودشده را بیدار نمیکند، بنابراین برنامههای PCM باید بدون هیچ عملیات انسدادی برنامهنویسی شوند. به همین دلیل، برای جلوگیری از اختلال در برنامههای موجود، این حالت زمانی فعال میشود که برنامههای PCM پارامترهای سختافزاری را صریحاً در زمان اجرای زیرجریان PCM پیکربندی کنند. علاوه بر این، هیچ عنصری زمانبندی انتقال فریم داده صوتی را حفظ نمیکند، بنابراین برنامههای PCM باید داوطلبانه تایمری را برای قرار دادن فریمهای داده صوتی در بافر زیرجریان PCM با گذشت زمان مدیریت کنند. افزون بر این، برنامه PCM باید به جای درایور، یک تابع کمکی هسته ALSA PCM را برای بهروزرسانی موقعیت سرِ انتقال سختافزاری و بررسی خطای XRUN فراخوانی کند.
در axfer ، این حالت مدل زمانبندی مبتنی بر تایمر نامیده میشود و تا زمانی که سختافزار/درایور از زمان اجرای no-period-wakeup پشتیبانی کند در دسترس است. کاربران باید با استفاده از گزینه --sched-model با مقدار timer این حالت را صریحاً تنظیم کنند.
در این مدل زمانبندی، برنامههای PCM باید فضای خالی موجود در بافر PCM را با گذشت زمان، معمولاً با واگذاری پردازنده (Yield) و انتظار برای زمانبندی مجدد مدیریت کنند. برای واگذاری پردازنده، مهلت زمانی (Timeout) برای مقدار بهینه فریمهای PCM جهت پردازش محاسبه میشود. این روش برای دستهای از برنامهها مانند سرورهای صدا بسیار مناسب است. هنگامی که یک نخ ورودی/خروجی سرور منتظر مهلت زمانی است، سایر نخها میتوانند فریمهای داده صوتی را برای کلاینتهای سرور پردازش کنند. علاوه بر این، با استفاده از بازگردانی به عقب/جلوبردن (Rewinding/Forwarding)، برنامهها میتوانند تاخیر کمی بین موقعیت انتقال و موقعیت پردازش ایجاد کنند، حتی اگر از بافرهای بزرگ PCM استفاده کنند.
مزایا و چالشها (Advantages and issues)
در حالت ایدهآل، مدل زمانبندی مبتنی بر تایمر مزایایی نسبت به مدل مبتنی بر IRQ دارد. نخست آنکه هیچ بافت وقفهای (Interrupt context) برای زیرجریان PCM اجرا نمیشود. زیرجریان PCM فقط در بافت فرآیند مدیریت میشود. نیازی به نگرانی درباره شرایط رقابتی (Race conditions) بین وقفهها و بافت فرآیند نیست. این امر برخی دغدغههای توسعهدهندگان درایورها و برنامهها را کاهش میدهد. دوم اینکه زمان پردازنده برای گردانندهها در بافت وقفه مصرف نمیشود و میتواند به وظایف دیگر اختصاص یابد؛ این ویژگی در سیستمهای اشتراک زمانی (Time Sharing) بسیار مفید است. سوم آنکه سختافزار برای تولید وقفه پیکربندی نمیشود که احتمالاً باعث کاهش مصرف کلی انرژی میگردد.
در هر دو مدل زمانبندی، سختافزار باید به درایورها اجازه دهد تعداد فریمهای داده صوتی منتقلشده بین حافظه اختصاصی و حافظه دستگاه برای گذرگاه صوتی سریال را بخوانند. با این حال، در مدل مبتنی بر تایمر، دقت و ریزدانگی (Granularity) این مقدار بسیار مهم است. در واقعیت، سختافزار انتقال بین حافظه اختصاصی و حافظه دستگاه را برای دستهای کوچک از فریمها یا بایتهای داده صوتی انجام میدهد. از دید برنامههای PCM، ریزدانگی در انتقال جاری برای تعیین مهلت زمانی صحیح در هر عملیات ورودی/خروجی الزامی است. تا نسخه 4.21 هسته لینوکس، رابط ALSA PCM بین هسته و فضای کاربری قابلیتی برای گزارش آن ندارد.
سازگاری با APLAY (COMPATIBILITY TO APLAY)
زیردستور transfer از axfer به گونهای طراحی شده است که سازگاری با aplay(1) را حفظ کند. با این حال، برخی از گزینههای زیر به دلایل فنی ناسازگار هستند.
- -I, --separate-channels
- این گزینه صرفاً برای ذخیره فریمهای داده صوتی متناظر با هر کانال در فایلهای جداگانه پشتیبانی میشود. در پیادهسازی aplay(1)، این گزینه اثر اضافی دیگری داشت که در صورت پشتیبانی دستگاه هدف، از بافر PCM با ترتیب غیردرهمبافته (Non-interleaved) استفاده میکرد. از سال ۲۰۱۸ به بعد، بافر PCM با ترتیب غیردرهمبافته به ندرت توسط دستگاههای صوتی استفاده میشود.
- -A, --avail-min=#
- این گزینه آستانه بیدار شدن فرآیند مسدودشده را بر حسب واحد فریم داده صوتی مشخص میکند. برخلاف پیادهسازی aplay(1)، این گزینه با گزینه --mmap و همچنین مقدار timer از گزینه --sched-model اثری ندارد.
- -R, --start-delay=#
- این گزینه آستانه شروع زیرجریان PCM آمادهشده را بر حسب واحد فریم داده صوتی مشخص میکند. برخلاف پیادهسازی aplay(1)، این گزینه با گزینه --mmap و همچنین مقدار timer از گزینه --sched-model اثری ندارد.
- -T, --stop-delay=#
- این گزینه آستانه توقف زیرجریان PCM در حال اجرا را بر حسب واحد فریم داده صوتی مشخص میکند. برخلاف پیادهسازی aplay(1)، این گزینه با گزینه --mmap و همچنین مقدار timer از گزینه --sched-model اثری ندارد.
- --max-file-time=#
- این گزینه پشتیبانی نمیشود. در پیادهسازی aplay(1)، این گزینه برای انتقال ضبط عمل میکرد تا فایلها را تا حداکثر تعداد فریم داده معادل مقدار دادهشده بر حسب ثانیه، یا حداکثر تعداد فریم داده پشتیبانیشده توسط قالب فایل ذخیره کند. هنگام رسیدن به این محدودیت، فایل جاری بسته شده و فایل جدیدی باز میشد و فریمهای داده صوتی در آن نوشته میشدند. با این حال، این گزینه نیازمند مدیریت فایل اضافی است و پیچیدگی حلقه اصلی axfer را افزایش میدهد.
- --use-strftime=FORMAT
- این گزینه پشتیبانی نمیشود. در پیادهسازی aplay(1)، این گزینه در انتقال ضبط اثر میکرد تا مسیرهای فایل را بر اساس قالب دادهشده تولید کند که در آن فرمتهای اضافی علاوه بر فرمتهای strftime(3) موجود بود. اما این گزینه نیازمند پردازش رشته اضافی برای مسیرهای فایل است و پیادهسازی آن در زبان C زحمت زیادی دارد.
- --process-id-file=FILEPATH
- این گزینه پشتیبانی نمیشود. در پیادهسازی aplay(1)، این گزینه فایلی برای مقدار دادهشده ایجاد کرده و شناسه فرآیند (PID) را در آن مینوشت. این فایل به کاربران اجازه میداد شناسه فرآیند را دریافت کرده و هر سیگنال پوزیکسی را به فرآیند aplay ارسال کنند. اما این ایده هنگام اجرای چند فرآیند aplay با یک فایل، مشکلاتی در قفلگذاری فایل ایجاد میکرد.
- -V, --vumeter=TYPE
- این گزینه در حال حاضر پشتیبانی نمیشود. در پیادهسازی aplay(1)، این گزینه خروجی استاندارد (stdout) را با نویسههای کنترلی ترمینال اشغال میکرد و نمایشگر VU (سطحسنج صدا) را برای کانالهای مونو و استریو نشان میداد. با این حال، مشکلاتی وجود دارد؛ این ویژگی صرفاً برای فریمهای داده صوتی با فرمت PCM است، باعث بههمریختگی ترمینال پس از قطع برنامه میشود، و خروجی استاندارد را برای پایپلاین غیرقابل استفاده میکند.
- -i, --interactive
- این گزینه در حال حاضر پشتیبانی نمیشود. در پیادهسازی aplay(1)، این گزینه ورودی استاندارد (stdin) را برای دریافت کلید اشغال میکرد و با فشردن کلید Enter زیرجریان PCM را تعلیق/ازسرگیری میکرد. با این حال، این ویژگی نیازمند مدیریت ورودی اضافی در حلقه اصلی است و نگهداری زیرجریان PCM را پیچیده میکند.
- -m, --chmap=CH1,CH2,...
- هسته PCM و هسته کنترلی ALSA از این ویژگی پشتیبانی نمیکنند، بنابراین بازنگاشت کانالها باید در فضای کاربری انجام شود. این امر بار اضافی (Overhead) برای تراز فریمهای داده صوتی، به ویژه برای عملیات mmap ایجاد میکند. علاوه بر این، تا نسخه 1.1.8 کتابخانه alsa-lib، برخی پلاگینها آنطور که انتظار میرود از این ویژگی پشتیبانی نمیکنند، بنابراین این گزینه فاقد عملکرد شفاف است. در حال حاضر، برای جلوگیری از سردرگمی کاربران، این گزینه هنوز پشتیبانی نمیشود.
- SIGTSTP, SIGCONT
- این سیگنالها تعلیق و ازسرگیری زیرجریان PCM را انجام میدهند. در پیادهسازی aplay(1)، این عملیاتها زیرجریان را به وضعیت XRUN میبردند و تعلیق/ازسرگیری در حالت تعاملی فوق انجام میشد. برخی توسعهدهندگان از این سیگنال برای آزمایش بازیابی از XRUN استفاده میکنند. در حال حاضر هیچ جایگزینی برای این آزمایش پشتیبانی نمیشود.
- SIGUSR1
- این سیگنال پشتیبانی نمیشود. در پیادهسازی aplay(1)، این سیگنال به یک گرداننده اختصاص داده شده بود تا فایل جاری ذخیره فریمهای داده صوتی را ببندد و فایل جدیدی برای ادامه پردازش باز کند. با این حال، همانند گزینه --max-file-time ، این گزینه نیز پیچیدگی حلقه اصلی axfer را افزایش میدهد.
طراحی (DESIGN)
ساختار ماژولار (Modular structure)
این برنامه از سه ماژول تشکیل شده است: xfer ، mapper و container . هر ماژول دارای یک لایه انتزاعی برای فعالسازی پیادهسازی واقعی است.
-------- ---------- -------------
device <-> | xfer | <-> | mapper | <-> | container | <-> file
-------- ---------- -------------
libasound single wav
libffado multiple au
voc
raw
ماژول xfer انتقال واقعی را به دستگاهها و گرهها انجام میدهد. این ماژول میتواند چندین بکاند انتقال داشته باشد. به عنوان بکاند پیشفرض، بکاند libasound برای انجام انتقال از طریق APIهای alsa-lib استفاده میشود. این ماژول به هر بکاند اجازه میدهد گزینههای خط فرمان خود را تجزیه کند.
ماژول container عملیات خواندن/نوشتن فریم داده صوتی را از طریق توصیفگر فایل/جریان کانتینر چندرسانهای یا داده خام انجام میدهد. این ماژول به طور خودکار نوع کانتینر چندرسانهای را تشخیص داده و پارامترها را در فراداده هدر آن تجزیه میکند. در حال حاضر، سه نوع کانتینر چندرسانهای پشتیبانی میشوند: Microsoft/IBM RIFF/Wave ( wav )، Sparc AU ( au ) و Creative Technology voice ( voc ). علاوه بر این، یک کانتینر ویژه برای دادههای صوتی خام ( raw ) آماده شده است.
ماژول mapper چیدمان و تراز بافر را برای انتقال فریمهای داده صوتی مدیریت میکند. این ماژول دارای دو پیادهسازی است: single و multiple . بکاند single از یک کانتینر برای ساخت بافر استفاده میکند. بکاند multiple از چندین کانتینر برای ساخت آن بهره میبرد.
مراقبت از کپی فریم داده صوتی (Care of copying audio data frame)
بین ماژول xfer و ماژول mapper ، یک اشارهگر به بافر حاوی فریمهای داده صوتی منتقل میشود. این بافر دارای دو ساختار برای ترتیب درهمبافته (Interleaved) و غیردرهمبافته (Non-interleaved) است. در حالت نخست، اشارهگر به یک بافر اشاره میکند. در حالت دوم، اشارهگر به آرایهای اشاره میکند که هر عنصر آن به یک بافر اشاره دارد. بین ماژول mapper و ماژول container ، اشارهگر به یک بافر منتقل میشود، زیرا کانتینرهای رسانهای پشتیبانیشده از جمله نوع خام، فریمهای داده صوتی را با ترتیب درهمبافته ذخیره میکنند.
در انتقال فریم داده صوتی بین ماژولها، axfer طوری برنامهنویسی شده است که تا حد امکان از کپی کردن بین یک بافر به بافر دیگر خودداری کند. به عنوان مثال، در برخی سناریوهای زیر هیچ کپی کردنی بین ماژولها رخ نمیدهد:
- xfer(mmap/interleaved), mapper(single), container(any)
- xfer(mmap/non-interleaved), mapper(multiple), containers(any)
آزمون واحد (Unit test)
برای هر دو ماژول mapper و container ، آزمون واحد در دسترس است. برای اجرای آزمونها، دستور زیر را اجرا کنید:
$ make test
هر آزمون نوشتن در فایل و خواندن از فایل را چندین بار تکرار میکند و پایان آن زمان زیادی میبرد. لطفاً در صورت اجرا در محیطهای یکپارچهسازی مداوم (CI) به زمان اجرای آن توجه داشته باشید.
همچنین ببینید (SEE ALSO)
axfer(1), axfer-list(1), alsamixer(1), amixer(1)
نویسنده (AUTHOR)
Takashi Sakamoto <o-takashi@sakamocchi.jp>
| 28 November 2018 | alsa-utils |