\r
namespace sf {\r
\r
-void input_thread_t::thread_main()\r
-{\r
- // COMの初期化\r
- sf::com_initialize init(0,multi_threaded);\r
-\r
- // MMCSSの初期化\r
- sf::av_mm_thread_characteristics avmm(wstring(L"Pro Audio"));\r
- avmm.set_priority(AVRT_PRIORITY_HIGH);\r
- \r
- //// input デバイスの初期化\r
- //wasapi_device_manager::ptr m(wasapi_device_manager::instance());\r
- //apply_config_(\r
- // m->current_input_device_index(),\r
- // m->current_input_device().params\r
- //);\r
- change_status(status_pause);\r
- application& app(*application::instance());\r
- int status = STATUS_ERROR;\r
- BYTE *buffer = 0;\r
- index_ = 0;\r
- int source_counter ,dest_counter;\r
- source_counter = dest_counter = 0;\r
- //// 出力デバイスが稼働するまで待つ\r
- //app.output_thread().wait_status(output_thread_t::status_processing,10);\r
- //apply_config_(\r
- //wasapi_device_manager::instance()->current_input_device_index(),\r
- //wasapi_device_manager::instance()->current_input_device().params);\r
- change_status(status_device_config);\r
- while(status = status_.load(),status != status_exit)\r
+ void input_thread_t::thread_main()\r
{\r
- // イベントを待つ\r
- switch(status)\r
+ // COMの初期化\r
+ sf::com_initialize init(0,multi_threaded);\r
+\r
+ // MMCSSの初期化\r
+ sf::av_mm_thread_characteristics avmm(wstring(L"Pro Audio"));\r
+ avmm.set_priority(AVRT_PRIORITY_HIGH);\r
+\r
+ //// input デバイスの初期化\r
+ //wasapi_device_manager::ptr m(wasapi_device_manager::instance());\r
+ //apply_config_(\r
+ // m->current_input_device_index(),\r
+ // m->current_input_device().params\r
+ //);\r
+ change_status(status_pause);\r
+ application& app(*application::instance());\r
+ int status = STATUS_ERROR;\r
+ BYTE *buffer = 0;\r
+ index_ = 0;\r
+ int source_counter ,dest_counter;\r
+ source_counter = dest_counter = 0;\r
+ //// 出力デバイスが稼働するまで待つ\r
+ //app.output_thread().wait_status(output_thread_t::status_processing,10);\r
+ //apply_config_(\r
+ //wasapi_device_manager::instance()->current_input_device_index(),\r
+ //wasapi_device_manager::instance()->current_input_device().params);\r
+ change_status(status_device_config);\r
+ while(status = status_.load(),status != status_exit)\r
{\r
- case status_device_config:\r
- if(wasapi_input_)\r
+ // イベントを待つ\r
+ switch(status)\r
{\r
- wasapi_input_->stop();\r
- dest_counter = 0;\r
- }\r
- change_status(status_device_config_ok);\r
- break;\r
- case status_process:\r
- if(!wasapi_input_->is_start()){\r
- wasapi_input_->start();\r
- }\r
- change_status(status_processing);\r
- case status_processing:\r
- {\r
- wasapi_input_->wait();// 入力待ち\r
- get_buffer g(*wasapi_input_);// キャプチャバッファの取得\r
- if(g.size() && g != 0)\r
+ case status_device_config:\r
+ if(wasapi_input_)\r
{\r
- source_counter = 0;\r
- while(source_counter != g.size())\r
- {\r
- BYTE * src = g + source_counter * wasapi_input_->get_frame_size();\r
- int size_byte_src = g.size_byte() - source_counter * wasapi_input_->get_frame_size();\r
- int size_src = g.size() - source_counter;\r
-\r
- BYTE * dest = buffer_[index_].get() + dest_counter * app.output_device().get_frame_size();\r
- int size_byte_dest = app.output_device().get_buffer_byte_size() - dest_counter * app.output_device().get_frame_size();\r
- int size_dest = app.output_device().get_buffer_size() - dest_counter;\r
-\r
- if(size_src <= size_dest)\r
- {\r
- ::CopyMemory(dest,src,size_byte_src);\r
- source_counter += size_src;\r
- dest_counter += size_src;\r
- } else if(size_src > size_dest)\r
- {\r
- ::CopyMemory(dest,src,size_byte_dest);\r
- source_counter += size_dest;\r
- dest_counter += size_dest;\r
- }\r
- if(dest_counter == app.output_device().get_buffer_size())\r
- {\r
- if(ringbuffer_.enqueue(buffer_[index_].get()))\r
- {\r
- index_ = (index_ + 1) & (buffer_.size() - 1);\r
- }\r
- dest_counter = 0;\r
- }\r
- }\r
+ wasapi_input_->stop();\r
+ dest_counter = 0;\r
}\r
+ change_status(status_device_config_ok);\r
+ break;\r
+ case status_process:\r
+ if(!wasapi_input_->is_start()){\r
+ wasapi_input_->start();\r
+ }\r
+ change_status(status_processing);\r
+ case status_processing:\r
+ {\r
+ wasapi_input_->wait();// 入力待ち\r
+ //try{\r
+ // get_buffer g(*wasapi_input_);// キャプチャバッファの取得\r
+ // if(g.size() && g != 0)\r
+ // {\r
+ // source_counter = 0;\r
+ // while(source_counter != g.size())\r
+ // {\r
+ // BYTE * src = g + source_counter * wasapi_input_->get_frame_size();\r
+ // int size_byte_src = g.size_byte() - source_counter * wasapi_input_->get_frame_size();\r
+ // int size_src = g.size() - source_counter;\r
+\r
+ // BYTE * dest = buffer_[index_].get() + dest_counter * app.output_device().get_frame_size();\r
+ // int size_byte_dest = app.output_device().get_buffer_byte_size() - dest_counter * app.output_device().get_frame_size();\r
+ // int size_dest = app.output_device().get_buffer_size() - dest_counter;\r
+\r
+ // if(size_src <= size_dest)\r
+ // {\r
+ // ::CopyMemory(dest,src,size_byte_src);\r
+ // source_counter += size_src;\r
+ // dest_counter += size_src;\r
+ // } else if(size_src > size_dest)\r
+ // {\r
+ // ::CopyMemory(dest,src,size_byte_dest);\r
+ // source_counter += size_dest;\r
+ // dest_counter += size_dest;\r
+ // }\r
+ // if(dest_counter == app.output_device().get_buffer_size())\r
+ // {\r
+ // if(ringbuffer_.enqueue(buffer_[index_].get()))\r
+ // {\r
+ // index_ = (index_ + 1) & (buffer_.size() - 1);\r
+ // }\r
+ // dest_counter = 0;\r
+ // }\r
+ // }\r
+ // }\r
+ //} catch (...) {\r
+ // ;\r
+ //}\r
+ }\r
+\r
+ break;\r
+ case status_pause:\r
+ if(wasapi_input_)\r
+ {\r
+ wasapi_input_->stop();\r
+ }\r
+ change_status(status_pause_ok);\r
+ break;\r
+ default:\r
+ WaitForSingleObject(event_.get(),WAIT_TIMEOUT_DEFAULT);\r
+ break;\r
}\r
- break;\r
- case status_pause:\r
- if(wasapi_input_)\r
- {\r
- wasapi_input_->stop();\r
- }\r
- change_status(status_pause_ok);\r
- break;\r
- default:\r
- WaitForSingleObject(event_.get(),WAIT_TIMEOUT_DEFAULT);\r
- break;\r
}\r
- }\r
loop_end:\r
- ;\r
- DOUT(L"##### input_threadは終了!" << endl);\r
- if(wasapi_input_ && wasapi_input_->is_start())\r
- {\r
- wasapi_input_->stop();\r
- }\r
- wasapi_input_.reset();\r
-};\r
-\r
-void input_thread_t::apply_config(int device_index,wasapi_device_manager::device_info::params_t& params)\r
-{\r
- if(status() != status_device_config_ok){\r
- change_and_wait(status_device_config,status_device_config_ok);\r
- }\r
- apply_config_(device_index,params);\r
- init_buffer();\r
- change_and_wait(status_process,status_processing);\r
-}\r
-\r
-void input_thread_t::apply_config_(int device_index,wasapi_device_manager::device_info::params_t& params)\r
-{\r
- \r
- WAVEFORMATEXTENSIBLE form;\r
- if(wasapi_input_)\r
- {\r
- if(wasapi_input_->is_start())\r
+ ;\r
+ DOUT(L"##### input_threadは終了!" << endl);\r
+ if(wasapi_input_ && wasapi_input_->is_start())\r
{\r
wasapi_input_->stop();\r
}\r
wasapi_input_.reset();\r
};\r
\r
- //bits_pair bits = {params.bits,params.valid_bits};\r
- //make_wave_format(form,params.sample_rate,params.channel,bits);\r
+ void input_thread_t::apply_config(int device_index,wasapi_device_manager::device_info::params_t& params)\r
+ {\r
+ if(status() != status_device_config_ok){\r
+ change_and_wait(status_device_config,status_device_config_ok);\r
+ }\r
+ apply_config_(device_index,params);\r
+ init_buffer();\r
+ change_and_wait(status_process,status_processing);\r
+ }\r
+\r
+ void input_thread_t::apply_config_(int device_index,wasapi_device_manager::device_info::params_t& params)\r
+ {\r
\r
- try {\r
- if(params.exclusive_mode)\r
+ WAVEFORMATEXTENSIBLE form;\r
+ if(wasapi_input_)\r
{\r
- if(params.event_mode){\r
- wasapi_input_.reset(new sf::wasapi_capture_exclusive_event(device_index,params));\r
- } else {\r
- wasapi_input_.reset(new sf::wasapi_capture_exclusive_timer(device_index,params));\r
- };\r
- } else {\r
- if(params.event_mode)\r
+ if(wasapi_input_->is_start())\r
+ {\r
+ wasapi_input_->stop();\r
+ }\r
+ wasapi_input_.reset();\r
+ };\r
+\r
+ //bits_pair bits = {params.bits,params.valid_bits};\r
+ //make_wave_format(form,params.sample_rate,params.channel,bits);\r
+\r
+ try {\r
+ if(params.exclusive_mode)\r
{\r
- wasapi_input_.reset(new sf::wasapi_capture_shared_event(device_index,params));\r
+ if(params.event_mode){\r
+ wasapi_input_.reset(new sf::wasapi_capture_exclusive_event(device_index,params));\r
+ } else {\r
+ wasapi_input_.reset(new sf::wasapi_capture_exclusive_timer(device_index,params));\r
+ };\r
} else {\r
- wasapi_input_.reset(new sf::wasapi_capture_shared_timer(device_index,params));\r
+ if(params.event_mode)\r
+ {\r
+ wasapi_input_.reset(new sf::wasapi_capture_shared_event(device_index,params));\r
+ } else {\r
+ wasapi_input_.reset(new sf::wasapi_capture_shared_timer(device_index,params));\r
+ }\r
}\r
- }\r
- } catch (win32_error_exception& e)\r
- {\r
+ } catch (win32_error_exception& e)\r
+ {\r
\r
- //window_->message_box((boost::wformat(L"WASAPI初期化エラーが発生しました。設定パラメータを見なおしてください。%s") % e.error()).str(),wstring(L"WASAPI初期化エラー"));\r
- throw;\r
- }\r
+ //window_->message_box((boost::wformat(L"WASAPI初期化エラーが発生しました。設定パラメータを見なおしてください。%s") % e.error()).str(),wstring(L"WASAPI初期化エラー"));\r
+ throw;\r
+ }\r
\r
- wasapi_device_manager::instance()->select_input_device(device_index);\r
- wasapi_device_manager::instance()->current_input_device().params = params;\r
+ wasapi_device_manager::instance()->select_input_device(device_index);\r
+ wasapi_device_manager::instance()->current_input_device().params = params;\r
\r
-}\r
+ }\r
\r
//void input_thread_t::init_buffer()\r
//{\r
using namespace Microsoft::WRL;\r
\r
namespace sf {\r
- const wstring wasapi_device_manager::base_directory_(L""/* Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data() */);\r
- const int wasapi_device_manager::sample_rates[NUM_SAMPLE_RATE] = {8000,11025,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000};\r
- const bits_pair wasapi_device_manager::sample_bits[NUM_SAMPLE_BITS] = {{8,8},{16,16},{24,24},{32,24},{32,32},{32,WAVE_FORMAT_IEEE_FLOAT}};\r
-\r
- void make_wave_format(WAVEFORMATEXTENSIBLE& format,int sample_rate,int channels,bits_pair b,uint32_t type,const GUID& sub_type)\r
- {\r
- ZeroMemory(&format,sizeof(WAVEFORMATEXTENSIBLE));\r
- format.Format.wFormatTag = type;\r
- format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);\r
- format.SubFormat = sub_type;\r
- format.Format.nSamplesPerSec = sample_rate;\r
- format.Format.nChannels = channels;\r
- format.Format.wBitsPerSample = b.bits_per_sample;\r
- format.Format.nBlockAlign = (format.Format.wBitsPerSample / 8) * format.Format.nChannels;\r
- format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign;\r
- format.Samples.wValidBitsPerSample = b.valid_bits_per_sample;\r
-\r
- format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;\r
- };\r
-\r
- void make_wave_format(WAVEFORMATEX& format,int sample_rate,int channels,int bits,uint32_t type)\r
- {\r
- ZeroMemory(&format,sizeof(WAVEFORMATEX));\r
- format.wFormatTag = type;\r
- format.nSamplesPerSec = sample_rate;\r
- format.nChannels = channels;\r
- format.wBitsPerSample = bits;\r
- format.nBlockAlign = (format.wBitsPerSample / 8) * format.nChannels;\r
- format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;\r
- };\r
-\r
- struct prop_variant \r
- {\r
- prop_variant()\r
- {\r
- PropVariantInit(&value_);\r
- }\r
-\r
- ~prop_variant()\r
- {\r
- PropVariantClear(&value_);\r
- }\r
-\r
- PROPVARIANT* get(){ return &value_;};\r
-\r
- PROPVARIANT* operator &(){return get();}\r
-\r
- operator PROPVARIANT*() {return get();}\r
-\r
- private:\r
- PROPVARIANT value_;\r
- };\r
-\r
-\r
- wasapi_device_manager::wasapi_device_manager() \r
- : output_device_index_(0),input_device_index_(0),enum_completed_(false)\r
- {\r
-\r
- config_path_.append(base_directory_).append(L"\\wasapi_device_manager.config.xml");\r
- boost::filesystem::wpath config_path(config_path_);\r
-\r
- std::wstring output_id;\r
- std::wstring input_id;\r
-\r
- if(boost::filesystem::exists(config_path))\r
- {\r
- try {\r
- boost::filesystem::wifstream f(config_path);\r
- boost::archive::xml_wiarchive ar(f);\r
- ar & boost::serialization::make_nvp("output_device_id",output_id);\r
- ar & boost::serialization::make_nvp("input_device_id" ,input_id);\r
- } catch(...)\r
- {\r
- output_id = input_id = L"";\r
- boost::filesystem::remove(config_path);\r
- }\r
- }\r
-\r
- //watcher_ = DeviceInformation::CreateWatcher();\r
- //adapter_ = ref new typed_event_handler_adapter<DeviceWatcher^,DeviceInformation^>(boost::bind(&wasapi_device_manager::added,this,_1,_2));\r
- // watcher_->Added += adapter_->get();\r
- //watcher_->Added += (ref new typed_event_handler_adapter<DeviceWatcher^,DeviceInformation^>(boost::bind(&wasapi_device_manager::added,this,_1,_2)))->get();\r
- //watcher_->Start();\r
-\r
- output_watcher_adapter_ = ref new DeviceWatcherAdapter(en::DeviceClass::AudioRender);\r
- output_watcher_adapter_->added().connect(boost::bind(&wasapi_device_manager::output_added,this,_1,_2));\r
- output_watcher_adapter_->enumration_completed().connect(boost::bind(&wasapi_device_manager::output_enumeration_completed,this,_1,_2));\r
- output_watcher_adapter_->removed().connect(boost::bind(&wasapi_device_manager::output_removed,this,_1,_2));\r
- output_watcher_adapter_->updated().connect(boost::bind(&wasapi_device_manager::output_updated,this,_1,_2));\r
- output_watcher_adapter_->stopped().connect(boost::bind(&wasapi_device_manager::output_stopped,this,_1,_2));\r
- output_watcher_adapter_->start();\r
+ const wstring wasapi_device_manager::base_directory_(L"."/* Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data() */);\r
+ const int wasapi_device_manager::sample_rates[NUM_SAMPLE_RATE] = {8000,11025,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000};\r
+ const bits_pair wasapi_device_manager::sample_bits[NUM_SAMPLE_BITS] = {{8,8},{16,16},{24,24},{32,24},{32,32},{32,WAVE_FORMAT_IEEE_FLOAT}};\r
+\r
+ void make_wave_format(WAVEFORMATEXTENSIBLE& format,int sample_rate,int channels,bits_pair b,uint32_t type,const GUID& sub_type)\r
+ {\r
+ ZeroMemory(&format,sizeof(WAVEFORMATEXTENSIBLE));\r
+ format.Format.wFormatTag = type;\r
+ format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);\r
+ format.SubFormat = sub_type;\r
+ format.Format.nSamplesPerSec = sample_rate;\r
+ format.Format.nChannels = channels;\r
+ format.Format.wBitsPerSample = b.bits_per_sample;\r
+ format.Format.nBlockAlign = (format.Format.wBitsPerSample / 8) * format.Format.nChannels;\r
+ format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign;\r
+ format.Samples.wValidBitsPerSample = b.valid_bits_per_sample;\r
+\r
+ format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;\r
+ };\r
+\r
+ void make_wave_format(WAVEFORMATEX& format,int sample_rate,int channels,int bits,uint32_t type)\r
+ {\r
+ ZeroMemory(&format,sizeof(WAVEFORMATEX));\r
+ format.wFormatTag = type;\r
+ format.nSamplesPerSec = sample_rate;\r
+ format.nChannels = channels;\r
+ format.wBitsPerSample = bits;\r
+ format.nBlockAlign = (format.wBitsPerSample / 8) * format.nChannels;\r
+ format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;\r
+ };\r
+\r
+ struct prop_variant \r
+ {\r
+ prop_variant()\r
+ {\r
+ PropVariantInit(&value_);\r
+ }\r
+\r
+ ~prop_variant()\r
+ {\r
+ PropVariantClear(&value_);\r
+ }\r
+\r
+ PROPVARIANT* get(){ return &value_;};\r
+\r
+ PROPVARIANT* operator &(){return get();}\r
+\r
+ operator PROPVARIANT*() {return get();}\r
+\r
+ private:\r
+ PROPVARIANT value_;\r
+ };\r
+\r
+\r
+ wasapi_device_manager::wasapi_device_manager() \r
+ : output_device_index_(-1),input_device_index_(-1),output_enum_completed_(false),input_enum_completed_(false)\r
+ {\r
+\r
+ config_path_.append(base_directory_).append(L"\\wasapi_device_manager.config.xml");\r
+ boost::filesystem::wpath config_path(config_path_);\r
+\r
+\r
+ if(boost::filesystem::exists(config_path))\r
+ {\r
+ try {\r
+ boost::filesystem::wifstream f(config_path);\r
+ boost::archive::xml_wiarchive ar(f);\r
+ ar & boost::serialization::make_nvp("output_device_id",output_id_);\r
+ ar & boost::serialization::make_nvp("input_device_id" ,input_id_);\r
+ } catch(...)\r
+ {\r
+ output_id_ = input_id_ = L"";\r
+ boost::filesystem::remove(config_path);\r
+ }\r
+ }\r
+\r
+ default_output_id_ = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default)->Data();\r
+ default_input_id_ = MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default)->Data();\r
+\r
+ //watcher_ = DeviceInformation::CreateWatcher();\r
+ //adapter_ = ref new typed_event_handler_adapter<DeviceWatcher^,DeviceInformation^>(boost::bind(&wasapi_device_manager::added,this,_1,_2));\r
+ // watcher_->Added += adapter_->get();\r
+ //watcher_->Added += (ref new typed_event_handler_adapter<DeviceWatcher^,DeviceInformation^>(boost::bind(&wasapi_device_manager::added,this,_1,_2)))->get();\r
+ //watcher_->Start();\r
+\r
+ output_watcher_adapter_ = ref new DeviceWatcherAdapter(en::DeviceClass::AudioRender);\r
+ output_watcher_adapter_->added().connect(boost::bind(&wasapi_device_manager::output_added,this,_1,_2));\r
+ output_watcher_adapter_->enumration_completed().connect(boost::bind(&wasapi_device_manager::output_enumeration_completed,this,_1,_2));\r
+ output_watcher_adapter_->removed().connect(boost::bind(&wasapi_device_manager::output_removed,this,_1,_2));\r
+ output_watcher_adapter_->updated().connect(boost::bind(&wasapi_device_manager::output_updated,this,_1,_2));\r
+ output_watcher_adapter_->stopped().connect(boost::bind(&wasapi_device_manager::output_stopped,this,_1,_2));\r
+ output_watcher_adapter_->start();\r
\r
input_watcher_adapter_ = ref new DeviceWatcherAdapter(en::DeviceClass::AudioCapture);\r
- input_watcher_adapter_->added().connect(boost::bind(&wasapi_device_manager::input_added,this,_1,_2));\r
- input_watcher_adapter_->enumration_completed().connect(boost::bind(&wasapi_device_manager::input_enumeration_completed,this,_1,_2));\r
- input_watcher_adapter_->removed().connect(boost::bind(&wasapi_device_manager::input_removed,this,_1,_2));\r
- input_watcher_adapter_->updated().connect(boost::bind(&wasapi_device_manager::input_updated,this,_1,_2));\r
- input_watcher_adapter_->stopped().connect(boost::bind(&wasapi_device_manager::input_stopped,this,_1,_2));\r
- input_watcher_adapter_->start();\r
-\r
- //// IMMDeviceEnumeratorの取得\r
- //THROW_IF_ERR(\r
- // CoCreateInstance(\r
- // __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,\r
- // IID_PPV_ARGS(&device_collection_)));\r
- //task<DeviceInformationCollection^> t(DeviceInformation::FindAllAsync(DeviceClass::AudioRender));\r
- //device_collection_ = t.get();\r
-\r
- // 出力エンドポイントの取得\r
- /*\r
- output_device_index_ = get_device_infos(Windows::Devices::Enumeration::DeviceClass::AudioRender,output_device_infos_,output_id);\r
- // 出力エンドポイントの能力を調査する\r
- for(int d = 0;d < output_device_infos_.size();++d)\r
- {\r
- IAudioClient2Ptr c;\r
- // オーディオクライアントを取得\r
- // THROW_IF_ERR(ActivateAudioInterface(output_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),&c));\r
- {\r
- ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
- IActivateAudioInterfaceAsyncOperation* asyncOp;\r
- ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
- HRESULT hr = ActivateAudioInterfaceAsync(output_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);\r
- asyncOpPtr.Attach(asyncOp);\r
- if(SUCCEEDED(hr)){\r
- handler->wait();\r
- if(handler->ResultCode() == S_OK)\r
- {\r
- c = handler->AudioClient();\r
- } else {\r
- throw win32_error_exception(handler->ResultCode());\r
- }\r
- } else {\r
- throw win32_error_exception(handler->ResultCode());\r
- }\r
- }\r
- c->GetDevicePeriod(&(output_device_infos_[d].latency_default_),&(output_device_infos_[d].latency_minimum_));\r
- if(output_device_infos_[d].params.latency == 0 \r
- || output_device_infos_[d].params.latency < output_device_infos_[d].latency_minimum_ )\r
- {\r
- output_device_infos_[d].params.latency = output_device_infos_[d].latency_default_;\r
- }\r
-\r
- #ifdef _DEBUG\r
- wdout << output_device_infos_[d].name_ << endl;\r
- wdout << boost::wformat(L"latency default:%d min:%d") % output_device_infos_[d].latency_default_ % output_device_infos_[d].latency_minimum_ << endl;\r
- #endif\r
- for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)\r
- {\r
- for(int channel = 1;channel < 3;++channel)\r
- {\r
- for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)\r
- {\r
- sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;\r
- WAVEFORMATEXTENSIBLE f;\r
-\r
- // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);\r
- if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)\r
- {\r
- bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};\r
- make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);\r
- } else {\r
- make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);\r
- }\r
-\r
- // 排他モード\r
- HRESULT hr = c->IsFormatSupported(\r
- AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));\r
- if(hr == S_OK){\r
- output_device_infos_[d].support_formats_[AUDCLNT_SHAREMODE_EXCLUSIVE][ sample_bits[bits].bits_per_sample ][sample_bits[bits].valid_bits_per_sample][channel][sample_rates[rate]] = 0;\r
- #ifdef _DEBUG\r
- wdout << boost::wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") % sample_bits[bits].bits_per_sample % sample_bits[bits].valid_bits_per_sample % channel % sample_rates[rate] % (hr == S_OK?L"OK":L"NG") << endl;\r
- #endif }\r
-\r
- // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);\r
- // 共有モード\r
- hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));\r
- if(hr == S_OK){\r
- output_device_infos_[d]\r
- .support_formats_\r
- [AUDCLNT_SHAREMODE_SHARED]\r
- [ sample_bits[bits].bits_per_sample ]\r
- [sample_bits[bits].valid_bits_per_sample]\r
- [channel][sample_rates[rate]] \r
- = 0;\r
- #ifdef _DEBUG\r
- wdout << boost::wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")\r
- % sample_bits[bits].bits_per_sample \r
- % sample_bits[bits].valid_bits_per_sample \r
- % channel % sample_rates[rate] \r
- % (hr == S_OK?L"OK":L"NG") << endl;\r
-\r
- #endif\r
- }\r
- }\r
- }\r
- }\r
- #ifdef _DEBUG\r
- wdout << "-------------------------------" << std::endl;\r
- #endif\r
- }\r
- // safe_release(c);\r
- }\r
-\r
- // 入力エンドポイントの取得\r
- input_device_index_ = get_device_infos(DeviceClass::AudioCapture,input_device_infos_,input_id);\r
- // 出力エンドポイントの能力を調査する\r
- for(int d = 0;d < input_device_infos_.size();++d)\r
- {\r
- IAudioClient2Ptr c;\r
- // オーディオクライアントを取得\r
- // THROW_IF_ERR(ActivateAudioInterface(input_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),&c) ); \r
- {\r
- ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
- IActivateAudioInterfaceAsyncOperation* asyncOp;\r
- ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
- HRESULT hr = ActivateAudioInterfaceAsync(input_device_infos_[d].id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),&asyncOp);\r
- asyncOpPtr.Attach(asyncOp);\r
- if(SUCCEEDED(hr)){\r
- handler->wait();\r
- if(handler->ResultCode() == S_OK)\r
- {\r
- c = handler->AudioClient();\r
- } else {\r
- throw win32_error_exception(handler->ResultCode());\r
- }\r
- } else {\r
- throw win32_error_exception(handler->ResultCode());\r
- }\r
- }\r
- c->GetDevicePeriod(&(input_device_infos_[d].latency_default_),&(input_device_infos_[d].latency_minimum_));\r
- if(input_device_infos_[d].params.latency == 0 || input_device_infos_[d].params.latency < input_device_infos_[d].latency_minimum_ ){\r
- input_device_infos_[d].params.latency = input_device_infos_[d].latency_default_;\r
- }\r
-\r
- #ifdef _DEBUG\r
- wdout << input_device_infos_[d].display_name_ << endl;\r
- wdout << boost::wformat(L"latency default:%d min:%d") % input_device_infos_[d].latency_default_ % input_device_infos_[d].latency_minimum_ << endl;\r
- #endif\r
- for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)\r
- {\r
- for(int channel = 1;channel < 3;++channel)\r
- {\r
- for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)\r
- {\r
- sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;\r
- WAVEFORMATEXTENSIBLE f;\r
-\r
- // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);\r
- if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)\r
- {\r
- bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};\r
- make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);\r
- } else {\r
- make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);\r
- }\r
-\r
- // 排他モード\r
- HRESULT hr = c->IsFormatSupported(\r
- AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));\r
- if(hr == S_OK){\r
- input_device_infos_[d]\r
- .support_formats_\r
- [AUDCLNT_SHAREMODE_EXCLUSIVE]\r
- [ sample_bits[bits].bits_per_sample ]\r
- [sample_bits[bits].valid_bits_per_sample]\r
- [channel]\r
- [sample_rates[rate]] = 0;\r
- #ifdef _DEBUG\r
- wdout << boost::wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") \r
- % sample_bits[bits].bits_per_sample \r
- % sample_bits[bits].valid_bits_per_sample \r
- % channel % sample_rates[rate] \r
- % (hr == S_OK?L"OK":L"NG") << endl;\r
- #endif }\r
-\r
- // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);\r
- // 共有モード\r
- hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));\r
- if(hr == S_OK){\r
- input_device_infos_[d].\r
- support_formats_\r
- [AUDCLNT_SHAREMODE_SHARED]\r
- [sample_bits[bits].bits_per_sample ]\r
- [sample_bits[bits].valid_bits_per_sample]\r
- [channel]\r
- [sample_rates[rate]] = 0;\r
- #ifdef _DEBUG\r
- wdout << boost::wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") \r
- % sample_bits[bits].bits_per_sample \r
- % sample_bits[bits].valid_bits_per_sample \r
- % channel \r
- % sample_rates[rate] \r
- % (hr == S_OK?L"OK":L"NG") << endl;\r
-\r
- #endif\r
- }\r
- }\r
- }\r
- }\r
- #ifdef _DEBUG\r
- wdout << "-------------------------------" << std::endl;\r
- #endif\r
- }\r
- // safe_release(c);\r
- }\r
- */\r
- }//\r
-\r
- int wasapi_device_manager::get_device_infos(DeviceClass data_flow, std::vector<device_info>& infos,const std::wstring& idd)\r
- {\r
-\r
- // 対象デバイスを列挙する\r
- task<DeviceInformationCollection^> t((DeviceInformation::FindAllAsync(data_flow)));\r
- t.wait();\r
- DeviceInformationCollection^ collection = t.get();\r
- int current_index = 0;\r
- bool found = false;\r
- Platform::String^ default_id = ref new Platform::String();\r
- switch(data_flow)\r
- {\r
- case Windows::Devices::Enumeration::DeviceClass::AudioRender:\r
- default_id = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);\r
- break;\r
- case Windows::Devices::Enumeration::DeviceClass::AudioCapture:\r
- default_id = MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default);\r
- break;\r
- }\r
-\r
-\r
- for(int i = 0 ,end = collection->Size;i < end;++i)\r
- {\r
- DeviceInformation^ info = collection->GetAt(i);\r
- infos.push_back(device_info(info));\r
- if(info->Id == default_id)\r
- {\r
- infos[i].is_default_ = true;\r
- }\r
-\r
- if(idd == wstring(info->Id->Data()) )\r
- {\r
- infos[i].is_selected_ = true;\r
- current_index = i;\r
- found = true;\r
- }\r
- }\r
-\r
- if(!found)\r
- {\r
- for(int i = 0,end = infos.size();i < end;++i)\r
- {\r
- if(infos[i].is_default_)\r
- {\r
- current_index = i;\r
- infos[i].is_selected_ = true;\r
- }\r
- }\r
-\r
- }\r
- return current_index;\r
- }\r
-\r
- wasapi_device_manager::~wasapi_device_manager()\r
- {\r
- input_watcher_adapter_->stop();\r
- output_watcher_adapter_->stop();\r
- //for(int i = 0; i < \r
- //safe_release(device_collection_);\r
- //safe_release(device_collection_);\r
- //safe_release(device_collection_);\r
-\r
- // 設定の保存\r
- try{\r
- boost::filesystem::wpath config_path(config_path_);\r
- boost::filesystem::wofstream f(config_path,std::ios_base::out | std::ios_base::trunc);\r
- boost::archive::xml_woarchive ar(f);\r
- ar & boost::serialization::make_nvp("output_device_id",current_output_device().id_);\r
- ar & boost::serialization::make_nvp("input_device_id" ,current_input_device().id_);\r
- }catch(...) {\r
-\r
- }\r
-\r
- }\r
-\r
- wasapi_device_manager::device_info::device_info\r
- (DeviceInformation^ info)\r
- : id_(info->Id->Data()),\r
- name_(info->Name->Data()), \r
- display_name_(dynamic_cast<String^>(info->Properties->Lookup(L"System.ItemNameDisplay"))->Data()),\r
- is_enabled_(info->IsEnabled),is_selected_(false),is_default_(info->IsDefault)\r
- {\r
- boost::filesystem::wpath \r
- config_path(wasapi_device_manager::base_directory() + L"\\" + id_ + L".xml");\r
- if(boost::filesystem::exists(config_path))\r
- {\r
- try{\r
- boost::filesystem::wifstream ifile(config_path);\r
- boost::archive::xml_wiarchive ar(ifile);\r
- ar >> BOOST_SERIALIZATION_NVP(params);\r
- } catch (...) \r
- {\r
- // ファイル読み込みに問題がある場合はファイルを消す。\r
- boost::filesystem::remove(config_path);\r
- }\r
- }\r
+ input_watcher_adapter_->added().connect(boost::bind(&wasapi_device_manager::input_added,this,_1,_2));\r
+ input_watcher_adapter_->enumration_completed().connect(boost::bind(&wasapi_device_manager::input_enumeration_completed,this,_1,_2));\r
+ input_watcher_adapter_->removed().connect(boost::bind(&wasapi_device_manager::input_removed,this,_1,_2));\r
+ input_watcher_adapter_->updated().connect(boost::bind(&wasapi_device_manager::input_updated,this,_1,_2));\r
+ input_watcher_adapter_->stopped().connect(boost::bind(&wasapi_device_manager::input_stopped,this,_1,_2));\r
+ input_watcher_adapter_->start();\r
+\r
+ }//\r
+\r
+ int wasapi_device_manager::get_device_infos(DeviceClass data_flow, std::vector<device_info>& infos,const std::wstring& idd)\r
+ {\r
+\r
+ // 対象デバイスを列挙する\r
+ task<DeviceInformationCollection^> t((DeviceInformation::FindAllAsync(data_flow)));\r
+ t.wait();\r
+ DeviceInformationCollection^ collection = t.get();\r
+ int current_index = 0;\r
+ bool found = false;\r
+ Platform::String^ default_id = ref new Platform::String();\r
+ switch(data_flow)\r
+ {\r
+ case Windows::Devices::Enumeration::DeviceClass::AudioRender:\r
+ default_id = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);\r
+ break;\r
+ case Windows::Devices::Enumeration::DeviceClass::AudioCapture:\r
+ default_id = MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default);\r
+ break;\r
+ }\r
+\r
+\r
+ for(int i = 0 ,end = collection->Size;i < end;++i)\r
+ {\r
+ DeviceInformation^ info = collection->GetAt(i);\r
+ infos.push_back(device_info(info));\r
+ if(info->Id == default_id)\r
+ {\r
+ infos[i].is_default_ = true;\r
+ }\r
+\r
+ if(idd == wstring(info->Id->Data()) )\r
+ {\r
+ infos[i].is_selected_ = true;\r
+ current_index = i;\r
+ found = true;\r
+ }\r
+ }\r
+\r
+ if(!found)\r
+ {\r
+ for(int i = 0,end = infos.size();i < end;++i)\r
+ {\r
+ if(infos[i].is_default_)\r
+ {\r
+ current_index = i;\r
+ infos[i].is_selected_ = true;\r
+ }\r
+ }\r
+\r
+ }\r
+ return current_index;\r
+ }\r
+\r
+ wasapi_device_manager::~wasapi_device_manager()\r
+ {\r
+ // stop_watching();\r
+ }\r
+\r
+ wasapi_device_manager::device_info::device_info\r
+ (DeviceInformation^ info)\r
+ : id_(info->Id->Data()),\r
+ name_(info->Name->Data()), \r
+ display_name_(dynamic_cast<String^>(info->Properties->Lookup(L"System.ItemNameDisplay"))->Data()),\r
+ is_enabled_(info->IsEnabled),is_selected_(false),is_default_(info->IsDefault)\r
+ {\r
+ boost::filesystem::wpath \r
+ config_path(wasapi_device_manager::base_directory() + L"\\" + Windows::Foundation::Uri::EscapeComponent(info->Id)->Data() + L".xml");\r
+ if(boost::filesystem::exists(config_path))\r
+ {\r
+ try{\r
+ boost::filesystem::wifstream ifile(config_path);\r
+ boost::archive::xml_wiarchive ar(ifile);\r
+ ar >> BOOST_SERIALIZATION_NVP(params);\r
+ } catch (...) \r
+ {\r
+ // ファイル読み込みに問題がある場合はファイルを消す。\r
+ boost::filesystem::remove(config_path);\r
+ }\r
+ }\r
#ifdef _DEBUG\r
- wdout << L"================================================" << std::endl;\r
- wdout << id_ << L"\n" << display_name_ << std::endl;\r
- wdout << params.latency << std::endl;\r
- wdout << L"================================================" << std::endl;\r
+ wdout << L"================================================" << std::endl;\r
+ wdout << id_ << L"\n" << display_name_ << std::endl;\r
+ wdout << params.latency << std::endl;\r
+ wdout << L"================================================" << std::endl;\r
#endif\r
\r
- }\r
-\r
- wasapi_device_manager::device_info::~device_info()\r
- {\r
- try {\r
- boost::filesystem::wpath \r
- config_path(wasapi_device_manager::base_directory() + L"\\" + id_ + L".xml");\r
- boost::filesystem::wofstream ofile(config_path,std::ios_base::out | ios_base::trunc);\r
- boost::archive::xml_woarchive ar(ofile);\r
- ar << BOOST_SERIALIZATION_NVP(params);\r
- } catch(...)\r
- {\r
-\r
- }\r
- }\r
-\r
- void wasapi_device_manager::output_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo)\r
- {\r
- std::vector<device_info> * infos = nullptr;\r
+ }\r
+\r
+ void wasapi_device_manager::stop_watching()\r
+ {\r
+ input_watcher_adapter_->stop();\r
+ output_watcher_adapter_->stop();\r
+ }\r
+\r
+ void wasapi_device_manager::save_params()\r
+ {\r
+ // watcherの停止\r
+ // stop_watching();\r
+\r
+ // 設定の保存\r
+ try{\r
+ boost::filesystem::wpath config_path(config_path_);\r
+ boost::filesystem::wofstream f(config_path,std::ios_base::out | std::ios_base::trunc);\r
+ boost::archive::xml_woarchive ar(f);\r
+ ar & boost::serialization::make_nvp("output_device_id",current_output_device().id_);\r
+ ar & boost::serialization::make_nvp("input_device_id" ,current_input_device().id_);\r
+ }catch(...) {\r
+\r
+ }\r
+\r
+ // 出力デバイスパラメータの保存\r
+ for(device_info& inf : output_device_infos_)\r
+ {\r
+\r
+ try {\r
+ boost::filesystem::wpath \r
+ config_path(wasapi_device_manager::base_directory() + L"\\" + Windows::Foundation::Uri::EscapeComponent(ref new Platform::String(inf.id_.c_str()))->Data() + L".xml");\r
+ boost::filesystem::wofstream ofile(config_path,std::ios_base::out | ios_base::trunc);\r
+ boost::archive::xml_woarchive ar(ofile);\r
+ ar << BOOST_SERIALIZATION_NVP(inf.params);\r
+ } catch(...)\r
+ {\r
+\r
+ }\r
+ }\r
+\r
+ // 入力デバイスパラメータの保存\r
+ for(device_info& inf : input_device_infos_)\r
+ {\r
+\r
+ try {\r
+ boost::filesystem::wpath \r
+ config_path(wasapi_device_manager::base_directory() + L"\\" + Windows::Foundation::Uri::EscapeComponent(ref new Platform::String(inf.id_.c_str()))->Data() + L".xml");\r
+ boost::filesystem::wofstream ofile(config_path,std::ios_base::out | ios_base::trunc);\r
+ boost::archive::xml_woarchive ar(ofile);\r
+ ar << BOOST_SERIALIZATION_NVP(inf.params);\r
+ } catch(...)\r
+ {\r
+\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ wasapi_device_manager::device_info::~device_info()\r
+ {\r
+ }\r
+\r
+ void wasapi_device_manager::output_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo)\r
+ {\r
+ device_info info(deviceInfo);\r
+\r
+ IAudioClient2Ptr c;\r
+ // オーディオクライアントを取得\r
+ {\r
+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
+ HRESULT hr = ActivateAudioInterfaceAsync(info.id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),asyncOpPtr.GetAddressOf());\r
+ if(SUCCEEDED(hr)){\r
+ handler->wait();\r
+ if(handler->ResultCode() == S_OK)\r
+ {\r
+ c = handler->AudioClient();\r
+ } else {\r
+ throw win32_error_exception(handler->ResultCode());\r
+ }\r
+ } else {\r
+ throw win32_error_exception(handler->ResultCode());\r
+ }\r
+ }\r
+ c->GetDevicePeriod(&(info.latency_default_),&(info.latency_minimum_));\r
+ if(info.params.latency == 0 \r
+ || info.params.latency < info.latency_minimum_ )\r
+ {\r
+ info.params.latency = info.latency_default_;\r
+ }\r
+\r
#ifdef _DEBUG\r
-// if(deviceInfo->IsEnabled){\r
- wdout << deviceInfo->Name->Data() << std::endl;\r
- \r
-// auto i = deviceInfo->Properties->First();\r
-// while(i->HasCurrent)\r
-// {\r
-//// wdout << iCurrent->Key->Data() << L"," << i->Current->Value->ToString()->Data() << std::endl;\r
-// wdout << i->\r
-// i->MoveNext();\r
-// }\r
-// }\r
+ wdout << info.name_ << endl;\r
+ wdout << boost::wformat(L"latency default:%d min:%d") % info.latency_default_ % info.latency_minimum_ << endl;\r
+#endif\r
+ for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)\r
+ {\r
+ for(int channel = 1;channel < 3;++channel)\r
+ {\r
+ for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)\r
+ {\r
+ sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;\r
+ WAVEFORMATEXTENSIBLE f;\r
+\r
+ // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);\r
+ if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)\r
+ {\r
+ bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};\r
+ make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);\r
+ } else {\r
+ make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);\r
+ }\r
+\r
+ // 排他モード\r
+ HRESULT hr = c->IsFormatSupported(\r
+ AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));\r
+ if(hr == S_OK){\r
+ info.support_formats_[AUDCLNT_SHAREMODE_EXCLUSIVE][ sample_bits[bits].bits_per_sample ][sample_bits[bits].valid_bits_per_sample][channel][sample_rates[rate]] = 0;\r
+#ifdef _DEBUG\r
+ wdout << boost::wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") % sample_bits[bits].bits_per_sample % sample_bits[bits].valid_bits_per_sample % channel % sample_rates[rate] % (hr == S_OK?L"OK":L"NG") << endl;\r
+#endif }\r
+\r
+ // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);\r
+ // 共有モード\r
+ hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));\r
+ if(hr == S_OK){\r
+ info\r
+ .support_formats_\r
+ [AUDCLNT_SHAREMODE_SHARED]\r
+ [ sample_bits[bits].bits_per_sample ]\r
+ [sample_bits[bits].valid_bits_per_sample]\r
+ [channel][sample_rates[rate]] \r
+ = 0;\r
+#ifdef _DEBUG\r
+ wdout << boost::wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|")\r
+ % sample_bits[bits].bits_per_sample \r
+ % sample_bits[bits].valid_bits_per_sample \r
+ % channel % sample_rates[rate] \r
+ % (hr == S_OK?L"OK":L"NG") << endl;\r
+\r
+#endif\r
+ }\r
+ }\r
+ }\r
+ }\r
+#ifdef _DEBUG\r
+ wdout << "-------------------------------" << std::endl;\r
#endif\r
- }\r
+ }\r
+\r
+ if(output_id_ == deviceInfo->Id->Data())\r
+ {\r
+ info.is_selected_ = true;\r
+ }\r
+ if(default_output_id_ == deviceInfo->Id->Data())\r
+ {\r
+ info.is_default_ = true;\r
+ }\r
+ output_device_infos_.push_back(info);\r
\r
- void wasapi_device_manager::output_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
- {\r
- }\r
+#ifdef _DEBUG\r
+ wdout << deviceInfo->Name->Data() << std::endl;\r
+#endif\r
+}\r
+\r
+void wasapi_device_manager::output_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
+{\r
+\r
+ for(int i = 0;i < output_device_infos_.size();++i)\r
+ {\r
+ device_info& inf(output_device_infos_[i]);\r
+ if(inf.is_selected_ && inf.is_enabled_)\r
+ {\r
+ output_device_index_ = i;\r
+ }\r
+ }\r
+\r
+ if(output_device_index_ == -1)\r
+ {\r
+ for(int i = 0;i < output_device_infos_.size();++i)\r
+ {\r
+ device_info& inf(output_device_infos_[i]);\r
+ if(inf.is_default_)\r
+ {\r
+ output_device_index_ = i;\r
+ inf.is_selected_ = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ output_enum_completed_ = true;\r
+}\r
+\r
+void wasapi_device_manager::output_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
+{\r
+}\r
+\r
+void wasapi_device_manager::output_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
+{\r
+}\r
+\r
+void wasapi_device_manager::output_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
+{\r
+}\r
+\r
+void wasapi_device_manager::input_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo)\r
+{\r
+ device_info info(deviceInfo);\r
+ IAudioClient2Ptr c;\r
+ // オーディオクライアントを取得\r
+ // THROW_IF_ERR(ActivateAudioInterface(info.id_.c_str(),__uuidof(IAudioClient2),&c) ); \r
+ {\r
+ ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOpPtr;\r
+// IActivateAudioInterfaceAsyncOperation* asyncOp;\r
+ ComPtr<ActivateAudioInterfaceCompletionHandler> handler(Make<ActivateAudioInterfaceCompletionHandler>());\r
+ HRESULT hr = ActivateAudioInterfaceAsync(info.id_.c_str(),__uuidof(IAudioClient2),nullptr,handler.Get(),asyncOpPtr.GetAddressOf());\r
+// asyncOpPtr.Attach(asyncOp);\r
+ if(SUCCEEDED(hr)){\r
+ handler->wait();\r
+ if(handler->ResultCode() == S_OK)\r
+ {\r
+ c = handler->AudioClient();\r
+ } else {\r
+ throw win32_error_exception(handler->ResultCode());\r
+ }\r
+ } else {\r
+ throw win32_error_exception(handler->ResultCode());\r
+ }\r
+ }\r
+ c->GetDevicePeriod(&(info.latency_default_),&(info.latency_minimum_));\r
+ if(info.params.latency == 0 || info.params.latency < info.latency_minimum_ ){\r
+ info.params.latency = info.latency_default_;\r
+ }\r
+#ifdef _DEBUG\r
+ wdout << info.display_name_ << endl;\r
+ wdout << boost::wformat(L"latency default:%d min:%d") % info.latency_default_ % info.latency_minimum_ << endl;\r
+#endif\r
+ for(int bits = 0;bits < NUM_SAMPLE_BITS;++bits)\r
+ {\r
+ for(int channel = 1;channel < 3;++channel)\r
+ {\r
+ for(int rate = 0;rate < NUM_SAMPLE_RATE;++rate)\r
+ {\r
+ sf::co_task_memory<WAVEFORMATEXTENSIBLE> a,a1;\r
+ WAVEFORMATEXTENSIBLE f;\r
+\r
+ // make_wave_fomat(f,sample_rates[rate],channel,sample_bits[bits]);\r
+ if(sample_bits[bits].valid_bits_per_sample == WAVE_FORMAT_IEEE_FLOAT)\r
+ {\r
+ bits_pair b ={sample_bits[bits].bits_per_sample,sample_bits[bits].bits_per_sample};\r
+ make_wave_format(f,sample_rates[rate],channel,b,WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);\r
+ } else {\r
+ make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE,KSDATAFORMAT_SUBTYPE_PCM);\r
+ }\r
+\r
+ // 排他モード\r
+ HRESULT hr = c->IsFormatSupported(\r
+ AUDCLNT_SHAREMODE_EXCLUSIVE,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a));\r
+ if(hr == S_OK){\r
+ info\r
+ .support_formats_\r
+ [AUDCLNT_SHAREMODE_EXCLUSIVE]\r
+ [ sample_bits[bits].bits_per_sample ]\r
+ [sample_bits[bits].valid_bits_per_sample]\r
+ [channel]\r
+ [sample_rates[rate]] = 0;\r
+#ifdef _DEBUG\r
+ wdout << boost::wformat(L"|exc |bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") \r
+ % sample_bits[bits].bits_per_sample \r
+ % sample_bits[bits].valid_bits_per_sample \r
+ % channel % sample_rates[rate] \r
+ % (hr == S_OK?L"OK":L"NG") << endl;\r
+#endif }\r
+\r
+ // make_wave_format(f,sample_rates[rate],channel,sample_bits[bits],WAVE_FORMAT_EXTENSIBLE);\r
+ // 共有モード\r
+ hr = c->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<WAVEFORMATEX*>(&f),reinterpret_cast<WAVEFORMATEX**>(&a1));\r
+ if(hr == S_OK){\r
+ info.\r
+ support_formats_\r
+ [AUDCLNT_SHAREMODE_SHARED]\r
+ [sample_bits[bits].bits_per_sample ]\r
+ [sample_bits[bits].valid_bits_per_sample]\r
+ [channel]\r
+ [sample_rates[rate]] = 0;\r
+#ifdef _DEBUG\r
+ wdout << boost::wformat(L"|share|bits:%02d|vbits:%02d|channel:%02d|rate:%06d|%s|") \r
+ % sample_bits[bits].bits_per_sample \r
+ % sample_bits[bits].valid_bits_per_sample \r
+ % channel \r
+ % sample_rates[rate] \r
+ % (hr == S_OK?L"OK":L"NG") << endl;\r
\r
- void wasapi_device_manager::output_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
- {\r
- }\r
+#endif\r
+ }\r
+ }\r
+ }\r
+ }\r
+#ifdef _DEBUG\r
+ wdout << "-------------------------------" << std::endl;\r
+#endif\r
+}\r
\r
- void wasapi_device_manager::output_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
- {\r
- }\r
+if(input_id_ == deviceInfo->Id->Data())\r
+{\r
+ info.is_selected_ = true;\r
+}\r
+if(default_input_id_ == deviceInfo->Id->Data())\r
+{\r
+ info.is_default_ = true;\r
+}\r
\r
- void wasapi_device_manager::output_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
- {\r
- }\r
+input_device_infos_.push_back(info);\r
\r
- void wasapi_device_manager::input_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo)\r
- {\r
- std::vector<device_info> * infos = nullptr;\r
#ifdef _DEBUG\r
// if(deviceInfo->IsEnabled){\r
- wdout << deviceInfo->Name->Data() << std::endl;\r
- \r
+wdout << deviceInfo->Name->Data() << std::endl;\r
+\r
// auto i = deviceInfo->Properties->First();\r
// while(i->HasCurrent)\r
// {\r
// }\r
// }\r
#endif\r
- }\r
-\r
- void wasapi_device_manager::input_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
- {\r
- }\r
-\r
- void wasapi_device_manager::input_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
- {\r
- }\r
-\r
- void wasapi_device_manager::input_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
- {\r
- }\r
-\r
- void wasapi_device_manager::input_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
- {\r
- }\r
+ }\r
+\r
+ void wasapi_device_manager::input_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
+ {\r
+\r
+ for(int i = 0;i < input_device_infos_.size();++i)\r
+ {\r
+ device_info& inf(input_device_infos_[i]);\r
+ if(inf.is_selected_ && inf.is_enabled_)\r
+ {\r
+ input_device_index_ = i;\r
+ }\r
+ }\r
+\r
+ if(input_device_index_ == -1)\r
+ {\r
+ for(int i = 0;i < input_device_infos_.size();++i)\r
+ {\r
+ device_info& inf(input_device_infos_[i]);\r
+ if(inf.is_default_)\r
+ {\r
+ input_device_index_ = i;\r
+ inf.is_selected_ = true;\r
+ }\r
+ }\r
+ }\r
+ input_enum_completed_ = true;\r
+ }\r
+\r
+ void wasapi_device_manager::input_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
+ {\r
+ }\r
+\r
+ void wasapi_device_manager::input_removed(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo)\r
+ {\r
+ }\r
+\r
+ void wasapi_device_manager::input_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj)\r
+ {\r
+ }\r
}
\ No newline at end of file