//! デバイスを開く
    //! 開くデバイスの指定は、現在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;
	}
Esempio n. 2
0
/**
 * 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();
}
Esempio n. 3
0
	// --------------------------------------------------------------
	/// 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();
	}
Esempio n. 4
0
 ~download_thread_control() { if (thread.joinable()) thread.detach(); }