//! デバイスを開く //! 開くデバイスの指定は、現在WAVE_MAPPER固定。 //! 簡単のため例外安全性などはあまり考慮されていない点に注意。 bool OpenDevice(size_t sampling_rate, size_t channel, size_t block_size, size_t multiplicity, callback_function_t callback) { BOOST_ASSERT(0 < block_size); BOOST_ASSERT(0 < multiplicity); BOOST_ASSERT(0 < channel && channel <= 2); BOOST_ASSERT(callback); BOOST_ASSERT(!process_thread_.joinable()); block_size_ = block_size; channel_ = channel; callback_ = callback; multiplicity_ = multiplicity; //! デバイスがオープン完了するまでcallbackが呼ばれないようにするためのロック boost::unique_lock<boost::mutex> lock(initial_lock_mutex_); terminated_ = false; process_thread_ = boost::thread([this] { ProcessThread(); }); WAVEFORMATEX wf; wf.wFormatTag = WAVE_FORMAT_PCM; wf.nChannels = 2; wf.wBitsPerSample = 16; wf.nBlockAlign = wf.nChannels * (wf.wBitsPerSample / 8); wf.nSamplesPerSec = sampling_rate; wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec; wf.cbSize = sizeof(WAVEFORMATEX); headers_.resize(multiplicity_); for(auto &header: headers_) { header.reset(new WaveHeader(block_size * channel * sizeof(short))); } //! WAVEHDR使用済み通知を受け取る方式として //! CALLBACK_FUNCTIONを指定。 //! 正常にデバイスがオープンできると、 //! waveOutWriteを呼び出した後でWaveOutProcessor::waveOutProcに通知が来るようになる。 MMRESULT const result = waveOutOpen( &hwo_, 0, &wf, reinterpret_cast<DWORD>(&WaveOutProcessor::waveOutProc), reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION ); if(result != MMSYSERR_NOERROR) { terminated_ = true; process_thread_.join(); terminated_ = false; hwo_ = NULL; return false; } return true; }
/** * Disables the timer sub-system. */ void Timer::Uninitialize(void) { { boost::mutex::scoped_lock lock(l_TimerMutex); l_StopTimerThread = true; l_TimerCV.notify_all(); } if (l_TimerThread.joinable()) l_TimerThread.join(); }
// -------------------------------------------------------------- /// Indicates if the thread has stopped. /// @return - true if *this refers to a thread of execution, false otherwise. virtual bool joinable() const { return _thread.joinable(); }
~download_thread_control() { if (thread.joinable()) thread.detach(); }