drumstick 0.5.0
|
00001 /* 00002 MIDI Sequencer C++ library 00003 Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl@users.sf.net> 00004 00005 This library is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License along 00016 with this program; if not, write to the Free Software Foundation, Inc., 00017 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "alsatimer.h" 00021 #include <QReadLocker> 00022 #include <QWriteLocker> 00023 #include <cmath> 00024 #include <cstdio> 00025 00031 namespace drumstick { 00032 00088 TimerInfo::TimerInfo() 00089 { 00090 snd_timer_info_malloc(&m_Info); 00091 } 00092 00097 TimerInfo::TimerInfo(const snd_timer_info_t *other) 00098 { 00099 snd_timer_info_malloc(&m_Info); 00100 snd_timer_info_copy(m_Info, other); 00101 } 00102 00107 TimerInfo::TimerInfo(const TimerInfo& other) 00108 { 00109 snd_timer_info_malloc(&m_Info); 00110 snd_timer_info_copy(m_Info, other.m_Info); 00111 } 00112 00116 TimerInfo::~TimerInfo() 00117 { 00118 snd_timer_info_free(m_Info); 00119 } 00120 00125 TimerInfo* 00126 TimerInfo::clone() 00127 { 00128 return new TimerInfo(m_Info); 00129 } 00130 00135 TimerInfo& 00136 TimerInfo::operator=(const TimerInfo& other) 00137 { 00138 snd_timer_info_copy(m_Info, other.m_Info); 00139 return *this; 00140 } 00141 00146 bool 00147 TimerInfo::isSlave() 00148 { 00149 return (snd_timer_info_is_slave(m_Info) != 0); 00150 } 00151 00156 int 00157 TimerInfo::getCard() 00158 { 00159 return snd_timer_info_get_card(m_Info); 00160 } 00161 00166 QString 00167 TimerInfo::getId() 00168 { 00169 return QString(snd_timer_info_get_id(m_Info)); 00170 } 00171 00176 QString 00177 TimerInfo::getName() 00178 { 00179 return QString(snd_timer_info_get_name(m_Info)); 00180 } 00181 00186 long 00187 TimerInfo::getResolution() 00188 { 00189 return snd_timer_info_get_resolution(m_Info); 00190 } 00191 00196 long 00197 TimerInfo::getFrequency() 00198 { 00199 long res = getResolution(); 00200 if (res > 0) 00201 { 00202 return 1000000000L / res; 00203 } 00204 return 0; 00205 } 00206 00211 int 00212 TimerInfo::getSizeOfInfo() const 00213 { 00214 return snd_timer_info_sizeof(); 00215 } 00216 00222 long 00223 TimerInfo::getTicks() 00224 { 00225 return snd_timer_info_get_ticks(m_Info); 00226 } 00227 00231 TimerId::TimerId() 00232 { 00233 snd_timer_id_malloc(&m_Info); 00234 } 00235 00240 TimerId::TimerId(const snd_timer_id_t *other) 00241 { 00242 snd_timer_id_malloc(&m_Info); 00243 snd_timer_id_copy(m_Info, other); 00244 if (getCard() < 0) 00245 setCard(0); 00246 if (getDevice() < 0) 00247 setDevice(0); 00248 if (getSubdevice() < 0) 00249 setSubdevice(0); 00250 } 00251 00256 TimerId::TimerId(const TimerId& other) 00257 { 00258 snd_timer_id_malloc(&m_Info); 00259 snd_timer_id_copy(m_Info, other.m_Info); 00260 if (getCard() < 0) 00261 setCard(0); 00262 if (getDevice() < 0) 00263 setDevice(0); 00264 if (getSubdevice() < 0) 00265 setSubdevice(0); 00266 } 00267 00276 TimerId::TimerId(int cls, int scls, int card, int dev, int sdev) 00277 { 00278 snd_timer_id_malloc(&m_Info); 00279 setClass(cls); 00280 setSlaveClass(scls); 00281 setCard(card); 00282 setDevice(dev); 00283 setSubdevice(sdev); 00284 } 00285 00289 TimerId::~TimerId() 00290 { 00291 snd_timer_id_free(m_Info); 00292 } 00293 00298 TimerId* 00299 TimerId::clone() 00300 { 00301 return new TimerId(m_Info); 00302 } 00303 00309 TimerId& 00310 TimerId::operator=(const TimerId& other) 00311 { 00312 snd_timer_id_copy(m_Info, other.m_Info); 00313 if (getCard() < 0) 00314 setCard(0); 00315 if (getDevice() < 0) 00316 setDevice(0); 00317 if (getSubdevice() < 0) 00318 setSubdevice(0); 00319 return *this; 00320 } 00321 00332 void 00333 TimerId::setClass(int devclass) 00334 { 00335 snd_timer_id_set_class(m_Info, devclass); 00336 } 00337 00343 int 00344 TimerId::getClass() 00345 { 00346 return snd_timer_id_get_class(m_Info); 00347 } 00348 00353 void 00354 TimerId::setSlaveClass(int devsclass) 00355 { 00356 snd_timer_id_set_sclass(m_Info, devsclass); 00357 } 00358 00363 int 00364 TimerId::getSlaveClass() 00365 { 00366 return snd_timer_id_get_sclass(m_Info); 00367 } 00368 00373 void 00374 TimerId::setCard(int card) 00375 { 00376 snd_timer_id_set_card(m_Info, card); 00377 } 00378 00383 int 00384 TimerId::getCard() 00385 { 00386 return snd_timer_id_get_card(m_Info); 00387 } 00388 00393 void 00394 TimerId::setDevice(int device) 00395 { 00396 snd_timer_id_set_device(m_Info, device); 00397 } 00398 00403 int 00404 TimerId::getDevice() 00405 { 00406 return snd_timer_id_get_device(m_Info); 00407 } 00408 00413 void 00414 TimerId::setSubdevice(int subdevice) 00415 { 00416 snd_timer_id_set_subdevice (m_Info, subdevice); 00417 } 00418 00423 int 00424 TimerId::getSubdevice() 00425 { 00426 return snd_timer_id_get_subdevice(m_Info); 00427 } 00428 00433 int 00434 TimerId::getSizeOfInfo() const 00435 { 00436 return snd_timer_id_sizeof(); 00437 } 00438 00444 TimerQuery::TimerQuery(const QString& deviceName, int openMode) 00445 { 00446 CHECK_WARNING( snd_timer_query_open( &m_Info, 00447 deviceName.toLocal8Bit().data(), 00448 openMode )); 00449 readTimers(); 00450 } 00451 00458 TimerQuery::TimerQuery( const QString& deviceName, int openMode, 00459 snd_config_t* conf ) 00460 { 00461 CHECK_WARNING( snd_timer_query_open_lconf( &m_Info, 00462 deviceName.toLocal8Bit().data(), 00463 openMode, conf )); 00464 readTimers(); 00465 } 00466 00470 TimerQuery::~TimerQuery() 00471 { 00472 freeTimers(); 00473 snd_timer_query_close(m_Info); 00474 } 00475 00479 void 00480 TimerQuery::readTimers() 00481 { 00482 TimerId tid; 00483 snd_timer_id_set_class(tid.m_Info, SND_TIMER_CLASS_NONE); 00484 for(;;) 00485 { 00486 int rc = snd_timer_query_next_device(m_Info, tid.m_Info); 00487 if ((rc < 0) || (tid.getClass() < 0)) { 00488 break; 00489 } 00490 m_timers.append(tid); 00491 } 00492 } 00493 00497 void 00498 TimerQuery::freeTimers() 00499 { 00500 m_timers.clear(); 00501 } 00502 00507 TimerGlobalInfo& 00508 TimerQuery::getGlobalInfo() 00509 { 00510 snd_timer_query_info(m_Info, m_GlobalInfo.m_Info); 00511 return m_GlobalInfo; 00512 } 00513 00518 void 00519 TimerQuery::setGlobalParams(snd_timer_gparams_t* params) 00520 { 00521 snd_timer_query_params(m_Info, params); 00522 } 00523 00528 void 00529 TimerQuery::getGlobalParams(snd_timer_gparams_t* params) 00530 { 00531 snd_timer_query_params(m_Info, params); 00532 } 00533 00538 void 00539 TimerQuery::getGlobalStatus(snd_timer_gstatus_t *status) 00540 { 00541 snd_timer_query_status(m_Info, status); 00542 } 00543 00547 TimerGlobalInfo::TimerGlobalInfo() 00548 { 00549 snd_timer_ginfo_malloc(&m_Info); 00550 } 00551 00556 TimerGlobalInfo::TimerGlobalInfo(const snd_timer_ginfo_t* other) 00557 { 00558 snd_timer_ginfo_malloc(&m_Info); 00559 snd_timer_ginfo_copy(m_Info, other); 00560 } 00561 00566 TimerGlobalInfo::TimerGlobalInfo(const TimerGlobalInfo& other) 00567 { 00568 snd_timer_ginfo_malloc(&m_Info); 00569 snd_timer_ginfo_copy(m_Info, other.m_Info); 00570 } 00571 00575 TimerGlobalInfo::~TimerGlobalInfo() 00576 { 00577 snd_timer_ginfo_free(m_Info); 00578 } 00579 00584 TimerGlobalInfo* 00585 TimerGlobalInfo::clone() 00586 { 00587 return new TimerGlobalInfo(m_Info); 00588 } 00589 00595 TimerGlobalInfo& 00596 TimerGlobalInfo::operator=(const TimerGlobalInfo& other) 00597 { 00598 snd_timer_ginfo_copy(m_Info, other.m_Info); 00599 return *this; 00600 } 00601 00606 void 00607 TimerGlobalInfo::setTimerId(const TimerId& tid) 00608 { 00609 m_Id = tid; 00610 snd_timer_ginfo_set_tid (m_Info, m_Id.m_Info); 00611 } 00612 00617 TimerId& 00618 TimerGlobalInfo::getTimerId() 00619 { 00620 m_Id = TimerId(snd_timer_ginfo_get_tid (m_Info)); 00621 return m_Id; 00622 } 00623 00628 unsigned int 00629 TimerGlobalInfo::getFlags() 00630 { 00631 return snd_timer_ginfo_get_flags (m_Info); 00632 } 00633 00638 int 00639 TimerGlobalInfo::getCard() 00640 { 00641 return snd_timer_ginfo_get_card (m_Info); 00642 } 00643 00648 QString 00649 TimerGlobalInfo::getId() 00650 { 00651 return QString(snd_timer_ginfo_get_id (m_Info)); 00652 } 00653 00658 QString 00659 TimerGlobalInfo::getName() 00660 { 00661 return QString(snd_timer_ginfo_get_name (m_Info)); 00662 } 00663 00668 unsigned long 00669 TimerGlobalInfo::getResolution() 00670 { 00671 return snd_timer_ginfo_get_resolution (m_Info); 00672 } 00673 00678 unsigned long 00679 TimerGlobalInfo::getMinResolution() 00680 { 00681 return snd_timer_ginfo_get_resolution_min (m_Info); 00682 } 00683 00688 unsigned long 00689 TimerGlobalInfo::getMaxResolution() 00690 { 00691 return snd_timer_ginfo_get_resolution_max(m_Info); 00692 } 00693 00698 unsigned int 00699 TimerGlobalInfo::getClients() 00700 { 00701 return snd_timer_ginfo_get_clients(m_Info); 00702 } 00703 00708 int 00709 TimerGlobalInfo::getSizeOfInfo() const 00710 { 00711 return snd_timer_ginfo_sizeof(); 00712 } 00713 00717 TimerParams::TimerParams() 00718 { 00719 snd_timer_params_malloc (&m_Info); 00720 } 00721 00726 TimerParams::TimerParams(const snd_timer_params_t *other) 00727 { 00728 snd_timer_params_malloc (&m_Info); 00729 snd_timer_params_copy (m_Info, other); 00730 } 00731 00736 TimerParams::TimerParams(const TimerParams& other) 00737 { 00738 snd_timer_params_malloc (&m_Info); 00739 snd_timer_params_copy (m_Info, other.m_Info); 00740 } 00741 00746 TimerParams::~TimerParams() 00747 { 00748 snd_timer_params_free (m_Info); 00749 } 00750 00755 TimerParams* 00756 TimerParams::clone() 00757 { 00758 return new TimerParams(m_Info); 00759 } 00760 00766 TimerParams& 00767 TimerParams::operator=(const TimerParams& other) 00768 { 00769 snd_timer_params_copy (m_Info, other.m_Info); 00770 return *this; 00771 } 00772 00777 void 00778 TimerParams::setAutoStart(bool auto_start) 00779 { 00780 snd_timer_params_set_auto_start (m_Info, auto_start ? 1 : 0); 00781 } 00782 00787 bool 00788 TimerParams::getAutoStart() 00789 { 00790 return (snd_timer_params_get_auto_start (m_Info) != 0); 00791 } 00792 00797 void 00798 TimerParams::setExclusive(bool exclusive) 00799 { 00800 snd_timer_params_set_exclusive (m_Info, exclusive ? 1 : 0); 00801 } 00802 00807 bool 00808 TimerParams::getExclusive() 00809 { 00810 return (snd_timer_params_get_exclusive (m_Info) != 0); 00811 } 00812 00817 void 00818 TimerParams::setEarlyEvent(bool early_event) 00819 { 00820 snd_timer_params_set_early_event (m_Info, early_event ? 1 : 0); 00821 } 00822 00827 bool 00828 TimerParams::getEarlyEvent() 00829 { 00830 return (snd_timer_params_get_early_event (m_Info) != 0); 00831 } 00832 00837 void 00838 TimerParams::setTicks(long ticks) 00839 { 00840 snd_timer_params_set_ticks (m_Info, ticks); 00841 } 00842 00847 long 00848 TimerParams::getTicks() 00849 { 00850 return snd_timer_params_get_ticks (m_Info); 00851 } 00852 00857 void 00858 TimerParams::setQueueSize(long queue_size) 00859 { 00860 snd_timer_params_set_queue_size (m_Info, queue_size); 00861 } 00862 00867 long 00868 TimerParams::getQueueSize() 00869 { 00870 return snd_timer_params_get_queue_size (m_Info); 00871 } 00872 00877 void 00878 TimerParams::setFilter(unsigned int filter) 00879 { 00880 snd_timer_params_set_filter (m_Info, filter); 00881 } 00882 00887 unsigned int 00888 TimerParams::getFilter() 00889 { 00890 return snd_timer_params_get_filter (m_Info); 00891 } 00892 00897 int 00898 TimerParams::getSizeOfInfo() const 00899 { 00900 return snd_timer_params_sizeof(); 00901 } 00902 00906 TimerStatus::TimerStatus() 00907 { 00908 snd_timer_status_malloc (&m_Info); 00909 } 00910 00915 TimerStatus::TimerStatus(const snd_timer_status_t *other) 00916 { 00917 snd_timer_status_malloc (&m_Info); 00918 snd_timer_status_copy (m_Info, other); 00919 } 00920 00925 TimerStatus::TimerStatus(const TimerStatus& other) 00926 { 00927 snd_timer_status_malloc (&m_Info); 00928 snd_timer_status_copy (m_Info, other.m_Info); 00929 } 00930 00934 TimerStatus::~TimerStatus() 00935 { 00936 snd_timer_status_free (m_Info); 00937 } 00938 00943 TimerStatus* 00944 TimerStatus::clone() 00945 { 00946 return new TimerStatus(m_Info); 00947 } 00948 00954 TimerStatus& 00955 TimerStatus::operator=(const TimerStatus& other) 00956 { 00957 snd_timer_status_copy (m_Info, other.m_Info); 00958 return *this; 00959 } 00960 00965 snd_htimestamp_t 00966 TimerStatus::getTimestamp() 00967 { 00968 return snd_timer_status_get_timestamp (m_Info); 00969 } 00970 00975 long 00976 TimerStatus::getResolution() 00977 { 00978 return snd_timer_status_get_resolution (m_Info); 00979 } 00980 00985 long 00986 TimerStatus::getLost() 00987 { 00988 return snd_timer_status_get_lost (m_Info); 00989 } 00990 00995 long 00996 TimerStatus::getOverrun() 00997 { 00998 return snd_timer_status_get_overrun (m_Info); 00999 } 01000 01005 long 01006 TimerStatus::getQueue() 01007 { 01008 return snd_timer_status_get_queue (m_Info); 01009 } 01010 01015 int 01016 TimerStatus::getSizeOfInfo() const 01017 { 01018 return snd_timer_status_sizeof(); 01019 } 01020 01032 Timer::Timer( const QString& deviceName, int openMode, QObject* parent ) 01033 : QObject(parent), 01034 m_asyncHandler(NULL), 01035 m_handler(NULL), 01036 m_thread(NULL), 01037 m_deviceName(deviceName) 01038 { 01039 CHECK_ERROR( snd_timer_open( &m_Info, m_deviceName.toLocal8Bit().data(), 01040 openMode )); 01041 } 01042 01055 Timer::Timer( const QString& deviceName, int openMode, snd_config_t* conf, 01056 QObject* parent ) 01057 : QObject(parent), 01058 m_asyncHandler(NULL), 01059 m_handler(NULL), 01060 m_thread(NULL), 01061 m_deviceName(deviceName) 01062 { 01063 CHECK_ERROR( snd_timer_open_lconf( &m_Info, 01064 m_deviceName.toLocal8Bit().data(), 01065 openMode, conf )); 01066 } 01067 01079 Timer::Timer( TimerId& id, int openMode, QObject* parent ) 01080 : QObject(parent), 01081 m_asyncHandler(NULL), 01082 m_handler(NULL), 01083 m_thread(NULL) 01084 { 01085 m_deviceName = QString("hw:CLASS=%1,SCLASS=%2,CARD=%3,DEV=%4,SUBDEV=%5") 01086 .arg(id.getClass()) 01087 .arg(id.getSlaveClass()) 01088 .arg(id.getCard()) 01089 .arg(id.getDevice()) 01090 .arg(id.getSubdevice()); 01091 CHECK_ERROR( snd_timer_open( &m_Info, 01092 m_deviceName.toLocal8Bit().data(), 01093 openMode )); 01094 } 01095 01111 Timer::Timer( int cls, int scls, int card, int dev, int sdev, 01112 int openMode, QObject* parent ) 01113 : QObject(parent), 01114 m_asyncHandler(NULL), 01115 m_handler(NULL), 01116 m_thread(NULL) 01117 { 01118 m_deviceName = QString("hw:CLASS=%1,SCLASS=%2,CARD=%3,DEV=%4,SUBDEV=%5") 01119 .arg(cls) 01120 .arg(scls) 01121 .arg(card) 01122 .arg(dev) 01123 .arg(sdev); 01124 CHECK_ERROR( snd_timer_open( &m_Info, 01125 m_deviceName.toLocal8Bit().data(), 01126 openMode )); 01127 } 01128 01132 Timer::~Timer() 01133 { 01134 stopEvents(); 01135 if (m_thread != NULL) 01136 delete m_thread; 01137 CHECK_WARNING(snd_timer_close(m_Info)); 01138 } 01139 01145 void 01146 Timer::addAsyncTimerHandler(snd_async_callback_t callback, void *private_data) 01147 { 01148 CHECK_WARNING(snd_async_add_timer_handler(&m_asyncHandler, m_Info, callback, private_data)); 01149 } 01150 01155 snd_timer_t* 01156 Timer::getTimerHandle() 01157 { 01158 return snd_async_handler_get_timer(m_asyncHandler); 01159 } 01160 01165 int 01166 Timer::getPollDescriptorsCount() 01167 { 01168 return snd_timer_poll_descriptors_count(m_Info); 01169 } 01170 01176 void 01177 Timer::pollDescriptors(struct pollfd *pfds, unsigned int space) 01178 { 01179 CHECK_WARNING(snd_timer_poll_descriptors(m_Info, pfds, space)); 01180 } 01181 01188 void 01189 Timer::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds, unsigned short *revents) 01190 { 01191 CHECK_WARNING(snd_timer_poll_descriptors_revents(m_Info, pfds, nfds, revents)); 01192 } 01193 01198 TimerInfo& 01199 Timer::getTimerInfo() 01200 { 01201 snd_timer_info (m_Info, m_TimerInfo.m_Info); 01202 return m_TimerInfo; 01203 } 01204 01209 void 01210 Timer::setTimerParams(const TimerParams& params) 01211 { 01212 CHECK_WARNING( snd_timer_params(m_Info, params.m_Info) ); 01213 } 01214 01219 TimerStatus& 01220 Timer::getTimerStatus() 01221 { 01222 CHECK_WARNING( snd_timer_status(m_Info, m_TimerStatus.m_Info) ); 01223 return m_TimerStatus; 01224 } 01225 01229 void 01230 Timer::start() 01231 { 01232 CHECK_WARNING(snd_timer_start(m_Info)); 01233 } 01234 01238 void 01239 Timer::stop() 01240 { 01241 CHECK_WARNING(snd_timer_stop(m_Info)); 01242 } 01243 01247 void 01248 Timer::continueRunning() 01249 { 01250 CHECK_WARNING(snd_timer_continue(m_Info)); 01251 } 01252 01259 ssize_t 01260 Timer::read(void *buffer, size_t size) 01261 { 01262 return snd_timer_read(m_Info, buffer, size); 01263 } 01264 01273 void 01274 Timer::doEvents() 01275 { 01276 snd_timer_tread_t tr; 01277 while ( read(&tr, sizeof(tr)) == sizeof(tr) ) { 01278 int msecs = ((tr.tstamp.tv_sec - m_last_time.tv_sec) * 1000) + 01279 round((tr.tstamp.tv_nsec - m_last_time.tv_nsec) / 1000000.0); 01280 m_last_time = tr.tstamp; 01281 if ( m_handler != NULL ) 01282 m_handler->handleTimerEvent(tr.val, msecs); 01283 else 01284 emit timerExpired(tr.val, msecs); 01285 } 01286 } 01287 01291 void Timer::startEvents() 01292 { 01293 m_last_time = getTimerStatus().getTimestamp(); 01294 if (m_thread == NULL) { 01295 m_thread = new TimerInputThread(this, 500); 01296 m_thread->start(); 01297 } 01298 } 01299 01303 void Timer::stopEvents() 01304 { 01305 int counter = 0; 01306 if (m_thread != NULL) { 01307 m_thread->stop(); 01308 while (!m_thread->wait(500) && (counter < 10)) { 01309 counter++; 01310 } 01311 if (!m_thread->isFinished()) { 01312 m_thread->terminate(); 01313 } 01314 delete m_thread; 01315 } 01316 } 01317 01324 TimerId 01325 Timer::bestGlobalTimerId() 01326 { 01327 TimerId id; 01328 snd_timer_t* timer; 01329 snd_timer_info_t* info; 01330 long res, best_res = LONG_MAX; 01331 char timername[64]; 01332 int test_devs[] = { 01333 SND_TIMER_GLOBAL_SYSTEM 01334 , SND_TIMER_GLOBAL_RTC 01335 #ifdef SND_TIMER_GLOBAL_HPET 01336 , SND_TIMER_GLOBAL_HPET 01337 #endif 01338 #ifdef SND_TIMER_GLOBAL_HRTIMER 01339 , SND_TIMER_GLOBAL_HRTIMER 01340 #endif 01341 }; 01342 int max_global_timers = sizeof(test_devs)/sizeof(int); 01343 int clas = SND_TIMER_CLASS_GLOBAL; 01344 int scls = SND_TIMER_SCLASS_NONE; 01345 int card = 0; 01346 int dev = SND_TIMER_GLOBAL_SYSTEM; 01347 int sdev = 0; 01348 int err = 0; 01349 int is_slave = 0; 01350 int i; 01351 snd_timer_info_alloca(&info); 01352 // default system timer 01353 id.setClass(clas); 01354 id.setSlaveClass(scls); 01355 id.setCard(card); 01356 id.setDevice(dev); 01357 id.setSubdevice(sdev); 01358 // select a non slave timer with the lowest resolution value 01359 for( i = 0; i < max_global_timers; ++i ) 01360 { 01361 dev = test_devs[i]; 01362 sprintf( timername, "hw:CLASS=%i,SCLASS=%i,CARD=%i,DEV=%i,SUBDEV=%i", 01363 clas, scls, card, dev, sdev ); 01364 err = snd_timer_open(&timer, timername, SND_TIMER_OPEN_NONBLOCK); 01365 if (err < 0) continue; 01366 err = snd_timer_info(timer, info); 01367 if (err == 0) { 01368 is_slave = snd_timer_info_is_slave(info); 01369 res = snd_timer_info_get_resolution(info); 01370 if ((is_slave == 0) && (best_res > res)) { 01371 best_res = res; 01372 id.setDevice(dev); 01373 } 01374 } 01375 snd_timer_close(timer); 01376 } 01377 return id; 01378 } 01379 01387 Timer* 01388 Timer::bestGlobalTimer(int openMode, QObject* parent) 01389 { 01390 TimerId id = bestGlobalTimerId(); 01391 return new Timer(id, openMode, parent); 01392 } 01393 01397 void 01398 Timer::TimerInputThread::run() 01399 { 01400 int err, count; 01401 struct pollfd *fds; 01402 if (m_timer == NULL) return; 01403 01404 count = m_timer->getPollDescriptorsCount(); 01405 fds = (pollfd *) calloc(count, sizeof(struct pollfd)); 01406 if (fds == NULL) { 01407 qWarning() << "allocation error!"; 01408 return; 01409 } 01410 fds->events = POLLIN; 01411 fds->revents = 0; 01412 01413 try { 01414 while (!stopped() && (m_timer != NULL)) { 01415 m_timer->pollDescriptors(fds, count); 01416 if ((err = poll(fds, count, m_Wait)) < 0) { 01417 qWarning() << "poll error " << err << "(" << strerror(err) << ")"; 01418 return; 01419 } 01420 if (err == 0) { 01421 qWarning() << "timer time out"; 01422 return; 01423 } 01424 m_timer->doEvents(); 01425 } 01426 } catch (...) { 01427 qWarning() << "exception in input thread"; 01428 } 01429 free(fds); 01430 } 01431 01436 bool 01437 Timer::TimerInputThread::stopped() 01438 { 01439 QReadLocker locker(&m_mutex); 01440 return m_Stopped; 01441 } 01442 01446 void 01447 Timer::TimerInputThread::stop() 01448 { 01449 QWriteLocker locker(&m_mutex); 01450 m_Stopped = true; 01451 } 01452 01453 } /* namespace drumstick */