رایتCDوDVD در LINUX


GnomeBaker : امـروزه کــمتر کـامپیوتری را مـی‌توان یـافت کـه بـه یـک دستگاه نوشتن دیسک‌های CD-R یا CD-RW مجهز نباشد. حتی کامپیوترهای همراه مدرن نیز از این موضوع مستثنی نیسـتند. قـیمت دستگاه‌های نوشتن DVD نیز به سرعت رو به افول است و با افزایش حجم داده‌ها انتظار می‌رود تا در آینده‌ای نزدیک جایگزین CD-R و CD-RW شوند.

نگاهی اجمالی به نوشتن CD و DVD در گنو/لینوکس
قـلـب اصـلی سیستم نگارش CD و DVD در گنو/لینوکس را چنـد بـسـته نـرم‌افـزاری تشـکـیل مـی‌دهـند کـه عـبـارتنـد از cdrecord،cdrdao و dvd+rw-tools. تمـامی ابــزارهـای نـوشـتـن CD و DVD در گنو/لینوکس – لااقل انواع بازمتن آن – در حقیقت پوسته‌هایی گرافیکی برای این ابزارها هستند که امکانات جانبی دیگری نیز در اختیار دارند. مانند ایجاد فایل‌های iso با استفاده از برنامه mkisofs، ایجاد دیسک‌های صوتی با استفاده از cdda2wav و mpg321، ایجاد VCD با استفاده از vcdimager و امکانات دیگر.

GnomeBaker
ابـزار نـوشـتـن و ایـجـاد CD و DVD جـدیـد Gnomebaker ابزاری است که در مراحل اولیه توسعه قرار داشته و گستردگی امکانات آن همانند ابزارهای پیشرفته‌ای مانند k3b نمی‌بـاشـد. ایــن ابـزار در هنــگام نگارش این مقاله در نسخه 0.3 قرار دارد. کاربرانی که از محیط میزکار Gnome برای انجام امور روزمره خود استفاده مــی‌کـنند، از داشتن چنین ابزاری با اینکه امکانات کمتری نسبت به k3b دارد، بسیار خشنود خواهند بود.
در ابتدای کار استفاده از این نرم‌افزار به جای k3b کمی ممکن است شما را دلــزده کند. ایــن دلـزدگی را چیزی جز کمتر بـودن امکانات آن نمی‌بینم، ولی عملکرد کلی آن مطلوب است و به سرعت به وضع کمی عجیب آن عادت خواهید کرد!
Gnomebaker به نرمی کار کرده و دیسک‌های شما را ایجاد مــی‌کـند یـا فـایل‌های ISO را بر روی دیسک می‌نویسد و از آنجایی که یک نرم‌افزار مبتنی بر GTK است، در محیط Gnome به نرمی و سـرعت اجــرا مــی‌شـود و کـنـدی اجرای k3b را در محیط Gnome دارا نیست.
Gnomebaker یـک نـرم‌افـزار آزاد بـوده و تحـت مـجـوز GNU LGPL مـنـتــشر مــی‌شـود. بـرای دیـدن تـصاویـر بــیـشتـری از Gnomebaker در حال کار می‌توانید به ] مراجعه کنید.


GnomeBaker در حال نوشتن یک فایل ISO بر روی دیسک

امکانات
اگر بخواهیم نگاهی کلی به امکانات آن داشته باشیم، موارد زیر چشمگیر هستند:
۱) ایجاد دیسک‌های Data CD با قابلیت Multisession
۲) ایجاد دیسک‌های Audio CD
۳) نوشتن ISO Images
۴) کپی از Data CD و ایجاد ISO از آن
۵) فرمت CD-RW
۶) فرمت DVD-RW
۷) کپی دیسک‌های Audio CD
۸) ایجاد Data DVD
۹) سیستم مدیرفایل توکار برای اضافه کردن فایل‌ها و دایرکتوری‌ها برای ایجاد Data CD یا Data DVD
۱۰) ایجاد فایل ISO از فایل‌هایی که برای ایجاد Data CD یا Data DVD انتخاب می‌شوند.
۱۱) پشتیبانی از Burn Free
۱۲) خارج کردن خودکار دیسک از درایو پس از اتمام نوشتن
۱۳) شناسایی خودکار و اضافه کردن ابزارهای خواننده و یا نویسنده CD و DVD به لیست ابزارهای برنامه.

Gnomebaker از Cdهای تـا ۷۰۰ مـگـابـایت و DVD هـای تا ۸.۵ گیگابایت پشتیبانی می‌کند. یکی از قابلیت‌های جالب آن امکان اضافه کردن دستی ابزارهای نوشتن CD و DVD است.

دریافت و نصب
صفحه خانگی پروژه Gnomebaker در آدرس ] قرار دارد. شما می‌توانید بسته‌های مختلف قابل نصب را از ] دریافت و بر روی سیستم خود نصب کنید. حتی بسته‌هایی برای نصب بر روی FreeBSD و لینوکس‌های Gentoo و Arch نیز موجود می‌باشد. از آنجایی که بسته deb این ابزار مفید در مخــازن unstable و testing دبیان اضافه شده است، کاربران دبیان و تـوزیـع‌هـای مبـتنی بر آن که مخازن دبیان را در sources.list خود دارا هستند، می‌تـوانـند بـا دسـتـور زیـر Gnomebaker را دریافت و نصب کنند:

# apt-get install gnomebaker

نقاط ضعف
همـانطـور کـه گـفته شـد، Gnomebaker هنوز در مراحل بسیار ابتدایی توسعه است و به همین دلیل چندان نمی‌توان از کمی امکانات در آن خــرده گرفت. با اینکه هنوز در نسخه 0.3 می‌باشد، امکانات ارائه شده به نسبت خوب بوده‌اند. یکی از مواردی اشکالی که زیاد بــه چشم می‌آید، عدم توانایی آن در تشخیص این است که اکنون یک دیسک درون درایو قرار داده شده. شما باید به صورت دستی به آن اعلام کنید که اکنون دیسک درون درایو موجود است، روی آن بنویس!
اضافه شدن امکانات ایجاد VCD نیـز می‌تواند مفید باشد، ولی امکان ذخیره فایل‌های ایحاد شده برای Data CD یا Audio CD به نحوی که در دفعات بعدی امـکان فراخوانی آسان آنها فراهم باشد، مفیدتر است. با اینکه اکنون امکان ایجاد ISO از این فایل‌ها وجود دارد، ولی در مــواردی کــه مـشـکل فضای دیسک وجود داشته باشد، ذخیره کردن آدرس‌ها و فراخوانی مجدد برای نوشته شدن روی دیسک لازم به نظر می‌رسد.
داشتن امکان Clone CD همانند k3b در مواردی که کپی دیسـک بنا با دلایلی با دشواری همراه است، نیز می‌تواند مفید باشد.

نتیجه‌گیری کلی
اگر بخواهیم یک نتیــجه‌گــیری کــلی از آن داشـته باشیم، Gnomebaker مجموعه ابزارهای Gnome را کامل می‌کند. این ابزار با اینکه در مراحل ابتدای توسعه است، بســیار راحــت‌تــر و قــابـل قبول‌تر از Nautilus Burner عمل می‌کند و با روند توسعه آن امید آن می‌رود تا در آینده به سطح امکانات ابزارهای قدرتمنددی مانند k3b برسد.

منبع :foss.ir 

irantux.com

درس 14 : آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

قسمت دوم

 

 Semaphore:

 

سمافر در لغت به معنی با پرچم به هم علامت دادن است و کار ان شبیه کار موتکس است با این فرق که بیشتر از دو مقدار locked و unlocked می تواند به خود بگیرد.و سمافر ها حاوی یک مقدار عددی هستند که بسته به شرایط می تواند مقادیر مثبت منفی و صفر به خود بگیرد و تصمیم می گیرد thread ها منتظر بمانند یا کارشان را انجام دهند.سمافرها راه بهتری را برای برنامه ریزی thread ها در اختیار ما می گذارند.

البته برای برنامه های ساده Multi-threading موتکس ها کافی به نظر می رسند.

 

برخلاف موتکس که دارای دو مقدارمیباشد یک سمافر در SDL دارای 2 به توان 32 حالت می باشد تمام مقادیری که یک Uint32 می تواند به خود بگیرد و وقتی مقدار ان صفر است

شبیه موتکس قفل شده رفتار می کند.

 

برای ساخت semaphore می توانید از تابع SDL_CreateSemaphore استفاده کنید.

SDL_sem *SDL_CreateSemaphore(Uint32 initial_value);

این تابع مقدار اولیه سمافر را دریافت می کند سپس یک اشاره گر به SDL_sem بر می گرداند.

برای نابود کردن یک سمافر هم می توانید از تابع SDL_DestroySemaphore استفاده کنید.

void SDL_DestroySemaphore(SDL_sem *sem);

که یک سمافردریافت و ان را از بین می برد.

 

سمافرها از Locked و Unlocked استفاده نمی کنند و به جای ان از Wait و Post استفاده می کنند.این دو مثل lock و unlock رفتار می کنند وقتی که در یک سمافر wait کنید اگر مقدار ان بزرگتر از صفر باشد یک واحد از ان کم می شود و سپس thread مورد نظر کار خود را به پایان می رساند.اگر مقدار ان برابر صفر باشد می ایستد تا مقدار ان بزرگتر از صفر شود و سپس اجرا می شود.

وقتی یک سمافر را post می کنید مثل unlock کردن ان می ماند ویکی به مقدار ان اضافه می شود تا thread های دیگر بتوانند کار خود را انجام دهند.

برای wait کردن بر روی سمافر شما باید از تابع SDL_SemWait استفاده کنید.

int SDL_SemWait(SDL_sem *sem);

این تابع صبر می کند تا مقدار سمافر مثبت سود سپس یکی از ان کم می کند و مقدار را بر می گرداند در صورت بروز خطا مقدار 1- را بر می گرداند.

 

همچنین شما می توانید با تایین زمان منتظر یک سمافر باشید

int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);

شما می توانید مقدار یک سمافر را با post کردن ان زیاد کنید.

int SDL_SemPost(SDL_sem *sem);

همچنین شما می توانید مقدار یک سمافر را بوسیله تابع SDL_SemValue تشخیص دهید

Uint32 SDL_SemValue(SDL_sem *sem);

که یک سمافر می گیرد و مقدار ان را بر می گرداند.

در زیر مثالی از سمافر امده است توجه کنید متغییر ها قبلا تعریف شده اند :

//create semaphore

g_pSemaphore=SDL_CreateSemaphore(0);

//create three threads

g_pThread[0]=SDL_CreateThread(ThreadFunction,(void*)1);

g_pThread[1]=SDL_CreateThread(ThreadFunction,(void*)2);

g_pThread[2]=SDL_CreateThread(ThreadFunction,(void*)3);

//wait for a second

SDL_Delay(1000);

//post to the semaphore

SDL_SemPost(g_pSemaphore);

در اول کار ما یک سمافر با مقدار اولیه صفر تعریف می کنیم که تا وقتی سمافر post نشود همه thread ها باید منتظر بمانند.سپس 3 thread تعریف می کنیم بعد یک ثانیه صبر می کنیم تا thread ها اماده شوند و سپس سمافر را post می کنیم تا thread ها شروع به کار کنند.

 

وتابع thread ما هم به شکل زیر است.

//thread function

int ThreadFunction(void* data)

{

          //grab thread number

          int threadnumber=(int)data;

          //wait for semaphore

          fprintf(stdout,”Thread %d: Initialized. ”,threadnumber);

          fprintf(stdout,”Thread %d: Waiting for semaphore. ”,threadnumber);

          SDL_SemWait(g_pSemaphore);

          //post to semaphore

          fprintf(stdout,”Thread %d: Done waiting for semaphore. ”,threadnumber);

          fprintf(stdout,”Thread %d: Posting semaphore. ”,threadnumber);

          SDL_SemPost(g_pSemaphore);

          //wait for semaphore again before terminating

          fprintf(stdout,”Thread %d: Waiting for semaphore before terminating.

          ”,threadnumber);

          SDL_SemWait(g_pSemaphore);

          //terminate

          fprintf(stdout,”Thread %d: Terminating. ”,threadnumber);

          SDL_SemPost(g_pSemaphore);

          //return 0

          return(0);

}

هر thread دو بار منتظر سمافر می شود یک بار در شروع thread و یکبار در موقع پایان thread . و نتایج را در فایل stdout.txt می ریزد.(که در اینجا کد مربوط به فایل را در اول کار ننوشتم)

 

1.thread 1 ساخته میشود و منتظر سمافر می شود.

2. thread 2 ساخته میشود و منتظر سمافر می شود.

3. thread3 ساخته میشود و منتظر سمافر می شود.

4.برنامه سمافر را post می کند.

5.ترید 1 از انتظار بیروم می اید و سمافر را post می کند و دوباره منتظر می شود.

6.ترید 2 از انتظار بیروم می اید و سمافر را post می کند و دوباره منتظر می شود.

7.ترید 3 از انتظار بیروم می اید و سمافر را post می کند و دوباره منتظر می شود.

8.سراخر هر 3 ترید بسته می شوند(با جزییاتی که خودتان حدث بزنید).

 

همانطور که می بینید سمافر راه بهتری جلوی روی ما می گذارد و مثلا اگر در برنامه 2 post را می فرستادیم 2 تا thread با هم کار می کردند.

 

 

متغییرهای شرطی :

سر اخر به متغییر های شرطی می رسیم که روشی است برای استفاده درست از موتکس و thread است و بر خلاف موتکس و سمافر دارای حالت (مثل locked یا unlocked) نیست

 

SDL_cond *SDL_CreateCond(void);

بوسیله این تابع می توانیم یک متغییر شرطی تعریف کنیم.

و به وسیله تابع زیر می توانیم یک متغییر شرطی را از بین ببریم.

void SDL_DestroyCond(SDL_cond *cond);

...

به منظور این که سمافر ها تمام نیاز ما را بر طرف می کنند من فعلا متغییر های شرطی را توضیح نمی دهم اگر کسی نیاز به توضیح داشت به من بگویید!

 

درس 14 : آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

درس 14 : آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

 (قسمت اول)

احتمالا چیزهایی در مورد برنامه ها Multi-threaded شنیده اید یا اسم فن اوری جدید Intel به اسم Hyper-Threading را شنیده اید که اگر این فناوری بر روی CPU فعال باشد CPU جوری رفتار می کند که سیستم عامل فرض کند به جای یک CPU 4 عدد CPU در سیستم موجود است که در ان موقع اگر سیستم عامل روی این قسمت کار کرده باشد می تواند به خوبی از این خاصیت استفاده کند و مثلا اجرا برنامه ها را بین 4 CPU تقسیم کند که سرعت به طرز قابل توجهی بالا می رود فعلا که دارم این مقاله را می نویسم بین سیستم عامل هایی که برای PC موجود است Linux Fedora Core بین سیستم عامل های دیگر می تواند به بهترین نحو از چند CPU در ان واحد استفاده کند که می تواند تا حدود 60-70 % از این قابلیت استفاده کند.و البته ویندوز هم به مقدار قابل توجهی از این خاصیت پشتیبانی می کند

و در حال حاضر این خاصیت SDL در سیستم عامل MacOS X کار گذاشته نشده است به خاطر این که اساسا PCهای Macintosh تک CPU هستند و نیازی به همچین کاری احساس نمی شد.

 

به این نوع برنامه نویسی برنامه نویسی موازی هم گفته می شود که قدرت فوق العاده ای به برنامه نویس می دهد که چند کار را در یک زمان انجام دهد.

 

Thread در برنامه نویسی به پروسه ای می گویند که بخشی از یک پروسه بزرگتر یا یک برنامه باشد.

 

همانطور که گفتم برنامه نویسی Multi-threading به شما قدرت فوق العاده ای برای اجرای چند کار در یک زمان را می دهد(البته بر روی سیستم های تک CPU این یک بحث تئوری است ولی فوق العاده به درد به خور حتی در ساخت بازی) در استفاده از thread ها باید نهایت دقت را بخرج دهید.

 

یک thread هم زمان با Main برنامه شما اجرا می شود و ازدر تمام منابع  برنامه مثل فایل ها حافظه و... باmain شریک می شود و مشکل وقتی پیش می اید که یک thread در چیزی با main شریک شود که نباید با ان در Main شریک شود مثل حافظه گرافیکی یا استفاده از صدا. و چیزی که باید یادتون باشد این است که یک thread هیچ وقت از حافظه گرافیکی به طور مستقیم استفاده نکند.

 

خوب اول ببینیم چه گونه می توانیم یک thread ایجاد کنیم.

SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data);

این تابع دو پادامتر دریافت می کند یک اشاره گر به تابع و داده ای که باید تابع بپذیرد و نوع برگشتی ان هم از نوع اشاره گر به SDL_Thread است.

تابع شما شکلی مانند شکل زیر دارد

int ThreadFunction(void* data);

که این تابع یک پارامتر برای پردازش دریافت می کند و یک مقدار int برمیگرداند وقتی thread مرد این مقدار بر گشت داده می شود.

اگر به هر طریقی بخواهید یک Thread را متوقف کنید می توانید از تابع SDL_KillThread استفاده کنید یک مقدار خشن به نظر می رسد ولی تا حالا کسی پیدا نشده که از حقوق thread ها دفاع کند!!!

void SDL_KillThread(SDL_Thread *thread);

اگر می خواهید یک مقدار با حوصله تر یک thread را متوقف کنید می توانید از SDL_WaitThread استفاده کنید.

void SDL_WaitThread(SDL_Thread *thread, int *status);

این تابع یک thread را دریافت کرده و سپس یک اشاره گربه یک عدد صحیح می گیرد و منتظر اتمام کار thread می شود و مقدار برگشتی را در status قرار می دهد اگر به مقدار برگشتی اهمیتی نمی دهید می توانید مقدار NULL را به عنوان پارامتر دوم بفرستید.

 

هر thread یک ID 32 بیتی مخصوص خود است که برای مدیریت thread ها می تونید ازش استفاده کنید و به وسیله فراخوانی تابع SDL_ThreadID درون thread می توانید مقدار ان را بیابید.

Uint32 SDL_ThreadID(void);

البته اگر بخواهید از بیرون Thread شناسه ان را بدست اورید می توانید از تابع زیر استفاده کنید.

Uint32 SDL_GetThreadID(SDL_Thread *thread);

 

نکته : برای استفاده از thread ها حتما باید فایل SDL_Thread.h را بارگزاری نمایید و در thread ها نیازی به استفاده از SDL_Init نیز وجود ندارد.

 

MUTEX:

موتکس راه ساده ای برای بر قرار کردن ارتباط بین Thread ها است و یکی از این دو حالت رو به خودش می گیرد Locked و Unlocked . وقتی یک موتکس به وسیله یک thread قفل می شود و thread دیگری خواهان قفل کردن Mutex می شود باید منتظر بماند تا thread قبلی ان را از حالت قفل بیرون بیاورد.

شما به راحتی می توانید بوسیله تابعSDL_CreateMutex  یک Mutex بسازید.

SDL_mutex *SDL_CreateMutex(void);

این تابع هیچ پارامتری نمی گیرد و یک اشاره گر به SDL_mutex بر می گرداند.

برای نابود کردن یک موتکس هم می توانید از تابعSDL_DestroyMutex استفاده کنید

void SDL_DestroyMutex(SDL_mutex *mutex);

 

شما همچنین می توانید به وسیله تابع SDL_MutexP یا ماکرو SDL_LockMutex یک موتکس را قفل کنید.

int SDL_mutexP(SDL_mutex *mutex);

این تابع یکی از این دو کار را انجام می دهد اگر موتکس ازاد بود ان را قفل می کند و اگر قفل بود منتظر می شود تا ازاد شود سپس ان را قفل می کند.

همچنین از تابع SDL_mutexV می توانید برای ازاد کردن یک موتکس استفاده کنید.

int SDL_mutexV(SDL_mutex *mutex);

یا ازمیتوانید از ماکرو SDL_UnlockMutex استفاده کنید.

یک نمونه ساده ولی جالب از استفاده از Mutex :

 

g_pMutex=SDL_CreateMutex();

SDL_LockMutex(g_pMutex);

g_pThread=SDL_CreateThread(ThreadFunction,NULL);

SDL_UnlockMutex(g_pMutex);

SDL_WaitThread(g_pThread,NULL);

در اینجا ما در ابتدا یک موتکس می سازیم سپس  ان را قفل می کنیم سپس یک thread می سازیم و بعد از ان mutex را از حالت قفل بیرون می اوریم و منتظر توقف thread می شویم.

تابع thread مان هم به شرح زیر است.

int ThreadFunction(void* data)

{

    fprintf(stdout,”Thread %d: Initialized! ”,SDL_ThreadID());

    fprintf(stdout,”Thread %d: Attempting to lock mutex. ”,SDL_ThreadID());

    SDL_LockMutex(g_pMutex);

    fprintf(stdout,”Thread %d: Mutex is locked. ”,SDL_ThreadID());

    fprintf(stdout,”Thread %d: Unlocking mutex. ”,SDL_ThreadID());

    SDL_UnlockMutex(g_pMutex);

    fprintf(stdout,”Thread %d: Terminating. ”,SDL_ThreadID());

    return(0);

}

این تابع کار خهصی انجام نمی دهد غیر از دادن گزارش کار به ما; در ابتدای کار سعی میکند موتکس را قفل کند ولی چون قبلا قفل شده می ایستد تا ازاد شود سپس قفل میکند و ازاد می کند و متوقف می شود.

خسته از زندگی

درس ۱۳ : قسمت چهارم

Effect :

اخرین قسمت این بحث در مورد effect ها است.effect ها در SDL_Mixer به دو قسمت تقسیم می شوند یک قسمت effect های ایست که از قبل موجود است مثل paning(تنظیم صوت بین دو کانال استریو) و دیگر effect های 3 بعدی و قسمت دوم effect هایی هستند که به وسیله خود شما درست می شوند.

قسمت مهم کار با effect ها ثبت effect ها بر روی کانال ها است وتا وقتی که از حالت register در نیامده باشند فعال هستند.

 

Effect های موجود :

Effect های موجود شامل Panning (تنظیم صوت بین دو کانال استریو)distance یا همان فاصله صدایی است که در حال پخش است.

و تعیین مکانی که صدا از انجا می اید.

و عوض کردن کانال های صدا در حالت stereo است.

 

برای استفاده از panning شما باید از تابع Mix_SetPanning استفاده کنید.

int Mix_SetPanning(int channel, Uint8 left, Uint8 right);

این تابع شماره کانال مورد نظر را می گیرد و همچنین مقدار volume باند های چپ و راست را می توان با left و right تعیین کرد که volume می تواند عددی از بین 0 تا 255 باشد در صورت موفقیت مقدار غیر 0 بر میگرداند.برای Unregister کردن این effect باید هم left و هم right را به 255 تنظیم کرد.

 

برای تنظیم فاصله هم باید از تابع Mix_SetDistance استفاده کرد.

int Mix_SetDistance(int channel, Uint8 distance);

اول شماره کانال را می گیرد و سپس یک عدد بین 0 تا 255 به عنوان فاصله دریافت می کند در صورت وارد کردن 0 effect فاصله Unregister می شود.

در صورت درست اجرا شدن مقدار غیر صفز بر می گرداند.

 

همچنین می توانید به وسیله تابع Mix_SetPosition می توانید یک شبیه سازی سه بعدی انجام دهید.

int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance);

این تابع اول شماره کانال را می گیرد سپس زاویه مورد نظر وسپس فاصله را به عنوان پارامتر سوم می گیرد.angle یک عدد از صفر تا 360 می باشد.

شکل زیر توضیح کاملی بر این تابع می باشد.

 

 aloo

وسر اخر نوبت تابع Mix_SetReverseStereo می شود که کارش معکوس کردن جای باند ها است.

int Mix_SetReverseStereo(int channel, int flip);

در صورت اینکه flip غیر صفر باشد effect فعال می شود.

همچنین شما می توانید با توابعی مثل :

int Mix RegisterEffect(int chan, Mix_EffectFunc_t f, Mix_EffectDone_t d,

void *arg)

خود برای خود effect بسازید چون همین مقدار توضیح برای ساخت بازی کافی است من روی این توابع توضیح خاصی نمی دهم.می توانید به مستندات SDL_Mixer رجوع کنید.

 

پایان درس 13

 

منابع :

SDL_Mixer Documents.1

Focus on SDL.2