OSDN Git Service

Windows8上で動作するようにバグ修正。キャプチャ部分はまだ修正は完了していない。
authorsfpg <sfpg@users.sourceforge.jp>
Sat, 10 Nov 2012 05:44:00 +0000 (14:44 +0900)
committersfpg <sfpg@users.sourceforge.jp>
Sat, 10 Nov 2012 05:44:00 +0000 (14:44 +0900)
SF.props
wasapi2/application.cpp
wasapi2/audio_base.h
wasapi2/input_thread.cpp
wasapi2/stdafx.h
wasapi2/wasapi.h
wasapi2/wasapi2.vcxproj
wasapi2/wasapi_manager.cpp

index 1b9e770..34bcf5b 100644 (file)
--- a/SF.props
+++ b/SF.props
@@ -3,10 +3,10 @@
   <ImportGroup Label="PropertySheets" />
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
-    <IncludePath>H:\libs\DirectXTK\Inc;H:\libs\boost_1_51_0\boost_1_51_0;H:\libs\xbyak\xbyak;H:\libs\zlib125\zlib-1.2.5;H:\libs\lpng150\lpng150;$(IncludePath)</IncludePath>
+    <IncludePath>H:\libs\DirectXTK\Inc;H:\libs\boost\include\boost-1_52;H:\libs\xbyak\xbyak;H:\libs\zlib125\zlib-1.2.5;H:\libs\lpng150\lpng150;$(IncludePath)</IncludePath>
   </PropertyGroup>
   <PropertyGroup>
-    <LibraryPath>H:\libs\zlib125\zlib-1.2.5;$(LibraryPath)</LibraryPath>
+    <LibraryPath>H:\libs\zlib125\zlib-1.2.5;H:\libs\boost\lib;$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup>
     <ClCompile>
index 8c59c76..7b09df3 100644 (file)
@@ -94,7 +94,6 @@ namespace sf {
       return 0;\r
     }\r
 \r
-    // プロセスの優先順位\r
     SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);\r
 \r
     // コモンコントロールの初期化 \r
@@ -108,9 +107,15 @@ namespace sf {
 \r
     // COMの初期化\r
     sf::com_initialize init(0,multi_threaded);\r
+\r
+    // プロセスの優先順位\r
+    sf::av_mm_thread_characteristics avmm(wstring(L"Pro Audio"));\r
+    avmm.set_priority(AVRT_PRIORITY_HIGH);\r
+\r
     // アプリケーションIDの登録\r
     sf::throw_if_err<application::exception>()(SetCurrentProcessExplicitAppUserModelID(app_id_.c_str()));\r
     timeBeginPeriod(1);\r
+    sf::wasapi_device_manager::instance()->wait_enum_devices();\r
     sf::wasapi_device_manager::instance()->current_output_device();\r
 \r
     // ウィンドウの作成\r
@@ -119,10 +124,10 @@ namespace sf {
 \r
 \r
     //   bool a = reader_ringbuffer_.is_lock_free();\r
-    //    wdout << ( ? L"**** true ****":L"---- false ----") << std::endl;\r
-    // mixer スレッドの起動\r
-    //mixer_thread_.execute();\r
-    // ファイルリーダースレッドの起動\r
+    ///    wdout << ( ? L"**** true ****":L"---- false ----") << std::endl;\r
+   //  mixer スレッドの起動\r
+    mixer_thread_.execute();\r
+   //  ファイルリーダースレッドの起動\r
     reader_thread_.execute();\r
 \r
     input_thread_.execute();\r
@@ -136,10 +141,10 @@ namespace sf {
       output_thread_.wait_status(output_thread_t::status_device_config_ok);\r
       apply_output_device_config\r
         (wasapi_device_manager::instance()->current_output_device_index(),\r
-         wasapi_device_manager::instance()->current_output_device().params);\r
+        wasapi_device_manager::instance()->current_output_device().params);\r
       apply_input_device_config\r
         (wasapi_device_manager::instance()->current_input_device_index(),\r
-         wasapi_device_manager::instance()->current_input_device().params);\r
+        wasapi_device_manager::instance()->current_input_device().params);\r
     } catch (...) {\r
 \r
     }\r
@@ -150,16 +155,17 @@ namespace sf {
     // スレッドを終了する\r
     reader_thread_.change_status(reader_thread_t::status_exit);\r
     input_thread_.change_status(input_thread_t::status_exit);\r
-   // mixer_thread_.change_status(mixer_thread_t::status_exit);\r
+    mixer_thread_.change_status(mixer_thread_t::status_exit);\r
     output_thread_.change_status(output_thread_t::status_exit);\r
 \r
-    // スレッド終了待ち\r
-    //mixer_thread_.join();\r
+   //  スレッド終了待ち\r
+    mixer_thread_.join();\r
     reader_thread_.join();\r
     output_thread_.join();\r
     input_thread_.join();\r
\r
+\r
     // WASAPIをシャットダウンする\r
+    wasapi_device_manager::instance()->save_params();\r
     wasapi_device_manager::instance().reset();\r
 \r
     return ret;\r
@@ -169,8 +175,8 @@ namespace sf {
   {\r
     try {\r
       reader_thread_.setup(file_path);\r
-       window_->reader_ready();\r
-     } catch (win32_error_exception& e) {\r
+      window_->reader_ready();\r
+    } catch (win32_error_exception& e) {\r
       window_->message_box((boost::wformat(L"ファイル読み込み時にエラーが発生しました。%s") % e.error()).str(),wstring(L"ファイル読込エラー"));\r
     }\r
   }\r
@@ -178,34 +184,34 @@ namespace sf {
   void application::reader_read_file()\r
   {\r
     try {\r
-       reader_thread_.read_file();\r
-       window_->reader_read_file();\r
-     } catch (win32_error_exception& e) {\r
+      reader_thread_.read_file();\r
+      window_->reader_read_file();\r
+    } catch (win32_error_exception& e) {\r
       window_->message_box((boost::wformat(L"再生開始時にエラーが発生しました。%s") % e.error()).str(),wstring(L"再生エラー"));\r
     }\r
   }\r
-  \r
+\r
   void application::reader_pause()\r
   {\r
     try {\r
-       reader_thread_.pause();\r
-       if(reader_thread_.status() == reader_thread_t::status_pause_ok)\r
-       {\r
-         window_->reader_pause();\r
-       } else {\r
-         window_->reader_read_file();\r
-       }\r
-     } catch (win32_error_exception& e) {\r
+      reader_thread_.pause();\r
+      if(reader_thread_.status() == reader_thread_t::status_pause_ok)\r
+      {\r
+        window_->reader_pause();\r
+      } else {\r
+        window_->reader_read_file();\r
+      }\r
+    } catch (win32_error_exception& e) {\r
       window_->message_box((boost::wformat(L"一時停止時にエラーが発生しました。%s") % e.error()).str(),wstring(L"一時停止エラー"));\r
     }\r
   }\r
-  \r
+\r
   void application::reader_stop()\r
   {\r
     try {\r
-       reader_thread_.stop();\r
-       window_->reader_stop();\r
-     } catch (win32_error_exception& e) {\r
+      reader_thread_.stop();\r
+      window_->reader_stop();\r
+    } catch (win32_error_exception& e) {\r
       window_->message_box((boost::wformat(L"停止時にエラーが発生しました。%s") % e.error()).str(),wstring(L"停止エラー"));\r
     }\r
   }\r
@@ -221,8 +227,8 @@ namespace sf {
     int reader_status = reader_thread_.status();\r
     reader_thread_.change_and_wait(reader_thread_t::status_config,reader_thread_t::status_config_ok);\r
 \r
-   // int mixer_status = mixer_thread_.status();\r
-   // mixer_thread_.change_and_wait(mixer_thread_t::status_config,mixer_thread_t::status_config_ok);\r
+    // int mixer_status = mixer_thread_.status();\r
+    // mixer_thread_.change_and_wait(mixer_thread_t::status_config,mixer_thread_t::status_config_ok);\r
 \r
     int input_status = input_thread_.status();\r
     input_thread_.change_and_wait(input_thread_t::status_pause,input_thread_t::status_pause_ok);\r
@@ -230,8 +236,8 @@ namespace sf {
     // 出力の変更\r
     output_thread_.apply_config(device_index,params);\r
 \r
-  //  mixer_thread_.init_buffer();\r
-  //  mixer_thread_.change_and_wait(mixer_thread_t::status_process,mixer_thread_t::status_processing);\r
+    //  mixer_thread_.init_buffer();\r
+    //  mixer_thread_.change_and_wait(mixer_thread_t::status_process,mixer_thread_t::status_processing);\r
 \r
     reader_thread_.init_buffer();\r
     reader_thread_.change_and_wait(reader_thread_t::status_ready,reader_thread_t::status_ready_ok);\r
index 3bbb0a3..fbde1b4 100644 (file)
@@ -61,7 +61,9 @@ struct get_buffer
 \r
   ~get_buffer()\r
   {\r
-    audio_base_.release_buffer(buffer_size_);\r
+    if(buffer_ptr_ != nullptr && buffer_size_ != 0){\r
+      audio_base_.release_buffer(buffer_size_);\r
+    }\r
   }\r
  \r
   operator BYTE*(){return buffer_ptr_;}\r
index fd3116e..eff983e 100644 (file)
@@ -40,167 +40,172 @@ using namespace std;
 \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
index e187790..f354f5f 100644 (file)
@@ -13,7 +13,7 @@
 // STL\r
 \r
 #define DIRECTINPUT_VERSION 0x0800\r
-#define BOOST_ALL_NO_LIB\r
+//#define BOOST_ALL_NO_LIB\r
 \r
 #include <stdint.h>\r
 #include <tchar.h>\r
index 13afceb..d3517ef 100644 (file)
@@ -85,6 +85,11 @@ namespace sf {
 \r
        ref class DeviceWatcherAdapter \r
        {\r
+  public:\r
+    virtual ~DeviceWatcherAdapter()\r
+    {\r
+      added_.disconnect_all_slots();\r
+    };\r
        internal:\r
                DeviceWatcherAdapter(en::DeviceClass deviceClass = en::DeviceClass::AudioRender)\r
                {\r
@@ -95,7 +100,6 @@ namespace sf {
                        watcher_->Removed += ref new f::TypedEventHandler<en::DeviceWatcher^ , en::DeviceInformationUpdate^ >(this,&DeviceWatcherAdapter::Removed);\r
                        watcher_->Stopped += ref new f::TypedEventHandler<en::DeviceWatcher^ , Platform::Object^ >(this,&DeviceWatcherAdapter::Stopped);\r
                }\r
-\r
                boost::signals2::signal<void (en::DeviceWatcher^ sender\r
                        , en::DeviceInformation^ deviceInterface) >& added(){return added_;}\r
                boost::signals2::signal<void (en::DeviceWatcher^ sender,\r
@@ -108,11 +112,11 @@ namespace sf {
                        Platform::Object^ obj) >& stopped() {return stopped_;}\r
                void start()\r
                {\r
-                       watcher_->Start();\r
+                       watcher_->Start();\r
                }\r
                void stop()\r
                {\r
-                       watcher_->Stop();\r
+               watcher_->Stop();\r
                }\r
        private:\r
                void Added(en::DeviceWatcher^ sender, en::DeviceInformation^ deviceInterface)\r
@@ -246,7 +250,20 @@ namespace sf {
                int current_output_device_index() const {return output_device_index_;}\r
                int current_input_device_index() const {return input_device_index_;}\r
                static const std::wstring & base_directory() {return base_directory_;};\r
-       private:\r
+\r
+    // 列挙が関連するまで待つ\r
+    void wait_enum_devices()\r
+    {\r
+      while(!output_enum_completed_ || !input_enum_completed_)\r
+      {\r
+        Sleep(1);\r
+      }\r
+    }\r
+\r
+    void stop_watching();\r
+    void save_params();\r
+\r
+  private:\r
                void output_added(Windows::Devices::Enumeration::DeviceWatcher^ sender, Windows::Devices::Enumeration::DeviceInformation^ deviceInfo);\r
     void output_enumeration_completed(en::DeviceWatcher^ sender, Platform::Object^ obj);\r
                void output_updated(en::DeviceWatcher^ sender, en::DeviceInformationUpdate^ deviceInfo);\r
@@ -260,15 +277,30 @@ namespace sf {
                void input_stopped(en::DeviceWatcher^ sender, Platform::Object^ obj);\r
 \r
                int get_device_infos(Windows::Devices::Enumeration::DeviceClass data_flow, std::vector<device_info>& infos,const std::wstring& idd);\r
-               int output_device_index_;\r
+\r
+\r
+    int output_device_index_;\r
                int input_device_index_;\r
                std::vector<device_info> output_device_infos_;\r
                std::vector<device_info> input_device_infos_;\r
                static const std::wstring base_directory_;\r
                std::wstring config_path_;\r
-               DeviceWatcherAdapter^ output_watcher_adapter_;\r
+               // 出力デバイス監視アダプタ\r
+    DeviceWatcherAdapter^ output_watcher_adapter_;\r
+\r
+    // 入力デバイス監視アダプタ\r
                DeviceWatcherAdapter^ input_watcher_adapter_;\r
-    bool enum_completed_;\r
+\r
+    // 出力デバイスの列挙が完了したか\r
+    bool output_enum_completed_;\r
+               // 入力デバイスの列挙が完了したか\r
+    bool input_enum_completed_;\r
+\r
+    std::wstring output_id_;\r
+               std::wstring input_id_;\r
+    std::wstring default_output_id_;\r
+    std::wstring default_input_id_;\r
+\r
        };\r
 \r
        // タイマーモードのポリシークラス\r
@@ -422,6 +454,7 @@ namespace sf {
                // 再生レイテンシ\r
                REFERENCE_TIME latency_;/* ms */\r
                REFERENCE_TIME actual_latency_;\r
+\r
        };\r
 \r
        typedef wasapi_base<wasapi_shared_policy,wasapi_timer_policy> wasapi_shared_timer;\r
@@ -461,6 +494,7 @@ namespace sf {
                                        hr_ = S_OK;\r
                                        // Get the pointer for the Audio Client\r
                                        punkAudioInterface->QueryInterface( IID_PPV_ARGS(&ptr_) );\r
+          punkAudioInterface->Release();\r
                                        if( nullptr == ptr_ )\r
                                        {\r
                                                hr_ = E_FAIL;\r
index 02186e2..b257bba 100644 (file)
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120_CTP_Nov2012</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v110</PlatformToolset>
+    <PlatformToolset>v120_CTP_Nov2012</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
index be92d08..6300616 100644 (file)
@@ -41,474 +41,513 @@ using namespace Platform;
 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
@@ -518,21 +557,44 @@ namespace sf {
 //               }\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