لگو بازی با گنو/لینوکس: کنترل سطح صدای N900 در ترمینال
سلام
من کار با ترمینال رو دوست دارم البته از شما چه پنهمون بعضی وقتا حوصلم ازش سر می ره ولی در مجموع دوست دارم بیشتر کارهام رو با اون انجام بدم. لابد میگین خودآزاری دارم شایدم دارم D:
چند وقت پیش تصمیم گرفتم کم و زیاد کردن صدای گوشی رو هم منتقل کنم به ترمینال پس:
هدف: کنترل سطح صدای گوشی (N900) از طریق ترمینال.
چرا: دلیل اصلیش در پستهای آینده ( ;) ) معلوم خواهد شد و فعلاً باید صبر کنید. یه دلیل دیگه می تونه این باشه که دوست ندارم وقتی دارم با ترمینال کار می کنم برای کم و زیاد کردن صدا سوئیچ کنم بیرون و بعد برگردم و دلیل دیگه میتونه این باشه که می خوام و به قول جادی یه ابزار خوب هم دارم: گنو/لینوکس پس می تونم. :)
خوب برای این کار من می گردم ببینم اصلاً می تونم چیزی در مورد این موضوع پیدا کنم که بتونم برای شروع کمکم کنه. [بعد مدتی جستجو]. بله نتایج امیدوار کننده بود. راه حل DBus هست. DBus رو جادی این جوری توضیح میده:
یک مفهوم بسیار جذاب و کاربردی توی گنو/لینوکس ها که توسط ردهت توسعه پیدا کرده و الان همه ازش استفاده می کنن. ایده کار اینه: هر برنامه ای که اجرا می شه اگر بخواد به بقیه هم سرویس بده خودش رو روی دی.باس (اتوبوس دسکتاپ) رجیستر می کنه و اعلام می کنه که یکسری سرویس داده و یکسری قابلیت. بعد بقیه برنامه ها می تونن به همین خط اتوبوس (دی.باس) وصل بشن و از برنامه های متنوع درخواست کارهایی که دارن رو بدن.
یه سری از برنامه هایی که روی گوشی وجود دارن سرویس هاشون رو روی DBus هم ارائه می دن برای دونستن اینها و نحوه ی استفادشون به Jebba/DBus و Phoen_Control رجوع کنید.
توی هر دو لینک به همراه کلی مطلب جذاب دیگه نحوه ی کنترل سطح صدا رو این جوری توضیح دادن که برای دونستن سطح صدای فعلی از این دستور که خروجیش با awk فـیلتر شده استفاده می کنیم:
1 |
dbus-send --print-reply --type=method_call --dest=com.nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer /com/nokia/mafw/renderer/gstrenderer com.nokia.mafw.extension.get_extension_property string:volume|awk '/nt/ {print $3}' |
و برای تغییر سطح صدای فعلی هم از این دستور:
1 |
dbus-send --type=method_call --dest=com.nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer /com/nokia/mafw/renderer/gstrenderer com.nokia.mafw.extension.set_extension_property string:volume variant:uint32:50 |
استفاده می کنیم و به جای عدد ۵۰ آخر سطح دلخواهمون رو وارد می کنیم. ولی منم مثه شما نه می تونم و نه دوست دارن دستورات به این بلندی رو حفظ کنم. پس تصمیم رو می گیرم تا هر دوی اینها رو به شکل یه دستور مفیدتر در بیارم در نتیجه می رم سراغ ایجاد یه شل اسکریپت.
خوب من می خوام اسکریپت رو اجرا کنم و مقدار صدایی رو که می خوام اضافه یا کم کنم رو به عنوان پارامتر بهش بدم و خودش تنظیم کنه. مثلاً من وقتی به عنوان پارامتر نوشتم +۲۰ اون سطح صدا رو ۲۰ تا اضافه کنه یا برای -۱۵ سطح صدا رو ۱۵ تا کم کنه.
برای اینکار باید اسکریپت با استفاده از دستور اوّلی سطح صدا رو پیدا کنه و مقدار اون رو با مقدار پارامتر ورودی جمع/تفریق بزنه و اون رو برای سطح صداست کنه. پس اسکریپت رو این جوری می نویسم:
1 2 3 4 |
#!/bin/bash declare -i vol vol=`dbus-send --print-reply --type=method_call --dest=com .nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer /com\ /nokia/mafw/renderer/gstrenderer com.nokia.mafw.extension .get_extension_property string:volume|awk '/nt/ {print $3}'` vol=$vol$1 |
خب تا اینجا من یه متغیر از نوع اعداد صحیح به نام vol تعریف کردم و در خط سوّم سطح صدای فعلی رو درونش ذخیره کردم. یعنی دستوری که بین دو کاراکتر گراو قرار می گیره اجرا می شه و خروجیش درون منغیر vol ذخیره می شه . در ادامه مقدار اون رو قرار دادم
1 |
vol=$vol$1 |
خب من باید کاراکتر اوّل آرگومان بررسی می کردم تا اگر مثبت هست بنویسم
1 |
vol=$vol+$1 |
و اگر منفی هست بنویسم vol=$vol-$1 تازه باید کاراکتر اوّل رو هم ازش جدا می کردم یا کاراکتر و مقدار رو جدا از هم به عنوان پارامترهای جداگانه بنویسم. ولی من به جای اینها می نویسم
1 |
vol=$vol$1 |
که مقدار پارامتر اوّل رو همونجوری که وارد کردم قرار بده و عبارت رو کامل کنه. برای مثال اگر پارامتر رو بزارم +۲۵ عبارت به شکل
1 |
vol=$vol+25 |
و اگر بزارم -۱۶ عبارت به شکل
1 |
vol=$vol-16 |
در میاد. :)
بعد از بدست آوردن سطح صدای جدید باید با دستوری که بالا بهش اشاره کردیم اون رو اعمال کنیم پس متغیر vol رو به جای عددی که باید سطح صدا رو مشخص می کنه بزاریم:
1 |
dbus-send --type=method_call --dest=com.nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer /com/nokia/mafw/renderer/gstrenderer com.nokia.mafw.extension.set_extension_property string:volume variant:uint32:$vol |
این دستور رو هم می زاریم بعد از دستورات قبلی.
تا اینجا تقریباً حله ولی یه مشکل جدید پیش میاد اگر سطح صدای فعلی باید ۷۰ و من بخوام ۵۰ تا دیگه افزایش بدم (با فرض اینکه من سطح فعلی رو نمی دونم) ماکزیمم سطح صدا که همون ۱۰۰ هست اعمال میشه البته تا اینجا مشکلی نیست مشکل وقتی هست که سطح صدا باشه ۳۰ و من بدونه اطلاع از این موضوع بخوام سطح صدا رو ۵۰ تا کم کنم! نخیر اشتباه حدس زدین سطح صدا در یک آن میره روی ۱۰۰ یعنی فاجعه رخ می ده. برای حل این مشکل من می خوام قبل از اعمال سطح صدا اون رو بررسی کنم و اگر منفی بود اون بزارم صفر و اگر بیشتر از ۱۰۰ بود اون رو بزارم ۹۹ تا مثلاً به اسپسکر ها آسیب نزنه. پس ساده هست باید با دوتا دستور if این شرط ها رو بررسی کنم. می نویسم:
1 2 3 4 5 |
if [$vol < 0]; then vol=0; elif [$vol > 100]; then vol=99; fi |
من این روش رو debug کردم و در کمال تعجب خطای زیر رو دیدم:
1 |
0: No such file or directory |
و در یک آن به خطای مفتضح خودم پی بردم و فوری طلب آمرزش کردم. اگر تا چند خط قبل شما هم مثه من فکر می کردین پیشنهاد می کنم شما هم توبه کنید. توی bash ما از کاراکتر های < و > برای انتقال خروجی و وردی استفاده می کنیم و با دستوری که من نوشتم انگار خواستم $vol از فایلی به اسم صفر ورودی بگیره (!!!) و چون همچین فایلی وجود نداره طبیعی هست که خطا بر می گرده. خب حالا چی کار کنیم برای این مقایسه ها؟ دست به دامن گوگل می شیم و به جدول زیر می رسیم:
و دستور if رو به شکل زیر تصحیح می کنیم:
1 2 3 4 5 |
if [$vol -le 0]; then vol=0; elif [$vol -ge 100]; then vol=99; fi |
بله این مشکل هم حل شد و در نهایت با جمع بندی مطالب بالا اسکریپت به شکل زیر در میاد:
1 2 3 4 5 6 7 8 9 10 11 12 |
#!/bin/bash declare -i vol; vol=`dbus-send --print-reply --type=method_call --dest=com.nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer /com/nokia/mafw/renderer/gstrenderer com.nokia.mafw.extension.get_extension_property string:volume|awk '/nt/ {print $3}'`; vol=$vol$1; if [ $vol -le 0 ] ; then vol=11; elif [ $vol -ge 100 ] ; then vol=99; fi dbus-send --type=method_call --dest=com.nokia.mafw.renderer.Mafw-Gst-Renderer-Plugin.gstrenderer /com/nokia/mafw/renderer/gstrenderer com.nokia.mafw.extension.set_extension_property string:volume variant:uint32:$vol dbus-send --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint string:"Volume: $vol" exit 0 |
توی صفحات مروبط به dbus که بالا لینک دادم دستورات خیلی جالب دیگه ای هم هست که در آینده به اونها هم می رسیم ;)
منابع: