OSDN Git Service

WASAPIの排他モード・共有モードを切り替えられるようにした。 master
authorSFPGMR <sfpg@git.sourceforge.jp>
Sun, 9 Oct 2011 00:36:54 +0000 (09:36 +0900)
committerSFPGMR <sfpg@git.sourceforge.jp>
Sun, 9 Oct 2011 00:36:54 +0000 (09:36 +0900)
async/application.cpp
async/application.h
async/async.rc
async/audio_base.h
async/resource.h
async/sf_windows.h
async/toplevel_window.cpp
async/wasapi.cpp
async/wasapi_exclusive_timer.cpp

index f13a59a..7cd9d3b 100644 (file)
@@ -53,7 +53,7 @@ namespace sf {
   application::application() : 
     event_output_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE)),
     event_reader_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE)),
-    not_enqueue_(false),output_counter_(0),repeat_mode_(false)
+    not_enqueue_(false),output_counter_(0),repeat_mode_(false),exclusive_mode_(false)
   {
     instance_handle_ = HINST_THISCOMPONENT;
     status_.store(player_stop);
@@ -105,6 +105,9 @@ namespace sf {
       return 0;
     }
 
+    // プロセスの優先順位
+    SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+
     // コモンコントロールの初期化 
     static const INITCOMMONCONTROLSEX common_ctrls =
     {
@@ -272,7 +275,7 @@ loop_end:
 
     // MMCSSの初期化
     sf::av_mm_thread_characteristics avmm(wstring(L"Pro Audio"));
-    avmm.set_priority(AVRT_PRIORITY::AVRT_PRIORITY_CRITICAL);
+    avmm.set_priority(AVRT_PRIORITY::AVRT_PRIORITY_HIGH);
 
     while(true)
     { 
@@ -350,13 +353,7 @@ loop_end:
       source_file_path_ = file_path;
 //      reader_.reset(new wave_file_reader(file_path,false));
       reader_.reset(new async_reader(file_path,repeat_mode_));
-      if(wasapi_)
-      {wasapi_.reset();};
-      wasapi_.reset(new sf::wasapi_exclusive_timer(reader_->get_wave_format()));
-      if(!wasapi_->is_enabled())
-      {
-        throw sf::win32_error_exception(*wasapi_->result());
-      }
+      wasapi_setup();
       read_index_ = 0;
       //
       for(int i = 0,size = read_buffer_.size();i < size;++i)
@@ -399,5 +396,33 @@ loop_end:
   {
     return status_.load(o);
   }
+
+  void application::exclusive_mode(bool v)
+  {
+    assert(get_status() == player_stop || get_status() == player_ready);
+    exclusive_mode_ = v;
+    if(wasapi_)
+    {
+      wasapi_setup();
+    }
+  };
+
+  void application::wasapi_setup()
+  {
+    if(wasapi_)
+    {
+      wasapi_.reset();
+    }
+    if(exclusive_mode_){
+      wasapi_.reset(new sf::wasapi_exclusive_timer(reader_->get_wave_format()));
+    } else {
+      wasapi_.reset(new sf::wasapi_shared_timer(reader_->get_wave_format()));
+    }
+    if(!wasapi_->is_enabled())
+    {
+      throw sf::win32_error_exception(*wasapi_->result());
+    }
+  }
+
 }
 
index ab7bcad..0d12bf2 100644 (file)
@@ -80,9 +80,13 @@ public:
 
   uint64_t get_play_position() { return output_counter_;};
   void set_play_position(uint64_t pos);
-  uint64_t get_data_size() { return reader_->total_data_bytes(); };
+  uint64_t get_data_size() { return reader_->total_data_bytes(); }
   void repeat_mode(bool v) { repeat_mode_ = v ;reader_->repeat_mode(v);}
+  void exclusive_mode(bool v);
+  bool exclusive_mode() const { return exclusive_mode_;}
+
 private:
+  void wasapi_setup();
   HINSTANCE instance_handle_;
   int return_code_;
 
@@ -97,7 +101,7 @@ private:
 
   handle_holder event_output_;
   boost::thread output_thread_;
-  std::unique_ptr<sf::wasapi_exclusive_timer> wasapi_;
+  std::unique_ptr<audio_base> wasapi_;
   uint64_t output_counter_;
   bool repeat_mode_;
 
@@ -106,6 +110,8 @@ private:
   sf::ringbuffer_t ringbuffer_;
   bool not_enqueue_;
 
+  bool exclusive_mode_;
+
   sf::toplevel_window_ptr window_;
   static std::wstring app_id_;
 
index 27d834a..5cb4d27 100644 (file)
@@ -27,7 +27,8 @@ FONT 9, "
     CONTROL         "", IDC_SLIDER, TRACKBAR_CLASS, WS_TABSTOP | WS_DISABLED | TBS_BOTH | TBS_NOTICKS, 6, 29, 309, 15\r
     CONTROL         "", IDC_WAVEFORM, WC_STATIC, SS_BLACKFRAME, 10, 155, 301, 88\r
     LTEXT           "Static", IDC_INFO, 10, 49, 301, 99, SS_LEFT, WS_EX_STATICEDGE\r
-    AUTOCHECKBOX    "\83\8a\83s\81[\83g", IDC_REPEAT_CHECK, 182, 11, 43, 8, WS_DISABLED\r
+    AUTOCHECKBOX    "\83\8a\83s\81[\83g", IDC_REPEAT_CHECK, 182, 15, 43, 8, WS_DISABLED\r
+    AUTOCHECKBOX    "WASAPI\94r\91¼\83\82\81[\83h", IDC_EXC_MODE, 182, 5, 78, 8\r
 }\r
 \r
 \r
index 7b5a809..8057aab 100644 (file)
 
   ==============================================================================
 */
+#include "exception.h"
 namespace sf {
 struct audio_base : boost::noncopyable
 {
-
+  virtual ~audio_base() {};
+  virtual bool is_enabled () const  = 0;
+  /// \83T\83E\83\93\83h\8dÄ\90\8f\88\97\9d
+  virtual void play_buffer(BYTE* buffer) = 0;
+  virtual void stop() = 0;
+  virtual void reset() = 0;
+  virtual uint32_t get_buffer_byte_size () const  = 0;
+  virtual win32_error_exception* const result()  = 0;
 };
 }
 
index 454a6a7..d53fac9 100644 (file)
@@ -11,4 +11,5 @@
 #define IDC_PLAY                                1005
 #define IDC_REPEAT_CHECK                        1006
 #define IDC_PAUSE                               1007
+#define IDC_EXC_MODE                            1008
 #define IDC_STOP                                1009
index 1f078b3..69f91c6 100644 (file)
@@ -461,33 +461,33 @@ namespace sf{
     WNDPROC proc_backup_;
   };
 
-  struct av_mm_thread_characteristics
+struct av_mm_thread_characteristics
+{
+  av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
   {
-    av_mm_thread_characteristics(std::wstring& str) : task_name_(str)
-    {
-      handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
-    }
-
-    bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
+    handle_ = ::AvSetMmThreadCharacteristicsW(str.c_str(),(LPDWORD)&task_index_);
+  }
 
-    ~av_mm_thread_characteristics()
-    {
-      ::AvRevertMmThreadCharacteristics(handle_);
-    }
+  bool set_priority(AVRT_PRIORITY p){return (::AvSetMmThreadPriority(handle_,p) == TRUE);}
 
-  private:
-    std::wstring task_name_;
-    uint32_t task_index_;
-    HANDLE handle_;
-  };
-
-  struct widget
+  ~av_mm_thread_characteristics()
   {
-    void draw();
-    float x_,y_;
-  };
-
-  typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
-  typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
+    ::AvRevertMmThreadCharacteristics(handle_);
+  }
+
+private:
+  std::wstring task_name_;
+  uint32_t task_index_;
+  HANDLE handle_;
+};
+
+struct widget
+{
+  void draw();
+  float x_,y_;
+};
+
+typedef sf::begin_draw<ID2D1BitmapRenderTargetPtr> begin_draw_bitmap;
+typedef sf::begin_draw<ID2D1HwndRenderTargetPtr> begin_draw_hwnd;
   
 }
\ No newline at end of file
index f96cdcd..b47e247 100644 (file)
@@ -399,6 +399,9 @@ struct toplevel_window::impl : public base_win32_dialog_t
        case IDC_REPEAT_CHECK:
          application::instance()->repeat_mode(::SendMessage(GetDlgItem(hwnd_,IDC_REPEAT_CHECK),BM_GETCHECK,0,0) == BST_CHECKED);
          return TRUE;
+       case IDC_EXC_MODE:
+         application::instance()->exclusive_mode(::SendMessage(GetDlgItem(hwnd_,IDC_EXC_MODE),BM_GETCHECK,0,0) == BST_CHECKED);
+         return TRUE;
        }
  
       //if(HIWORD(wParam) == THBN_CLICKED ){
@@ -470,6 +473,7 @@ struct toplevel_window::impl : public base_win32_dialog_t
     enable_control(IDC_PAUSE,false);
     enable_control(IDC_SLIDER,true);
     enable_control(IDC_STOP,false);
+    enable_control(IDC_EXC_MODE,true);
   }
 
   void play()
@@ -488,6 +492,7 @@ struct toplevel_window::impl : public base_win32_dialog_t
     ::SetWindowText(GetDlgItem(hwnd_,IDC_PAUSE),L"一時停止");
     enable_control(IDC_SLIDER,true);
     enable_control(IDC_FILE,false);
+    enable_control(IDC_EXC_MODE,false);
   }
 
   void stop()
@@ -506,6 +511,7 @@ struct toplevel_window::impl : public base_win32_dialog_t
     enable_control(IDC_SLIDER,true);
     ::SendMessage(GetDlgItem(hwnd_,IDC_SLIDER), TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0);
     enable_control(IDC_FILE,true);
+    enable_control(IDC_EXC_MODE,true);
   }
   
   void pause()
@@ -524,6 +530,7 @@ struct toplevel_window::impl : public base_win32_dialog_t
     ::SetWindowText(GetDlgItem(hwnd_,IDC_PAUSE),L"再開");
     enable_control(IDC_SLIDER,true);
     enable_control(IDC_FILE,false);
+    enable_control(IDC_EXC_MODE,false);
   }
 
   virtual void create(){
index 56eaf3a..97fbde4 100644 (file)
@@ -138,6 +138,7 @@ namespace sf{
     if(audio_client_)
     {
       audio_client_->Stop();
+      audio_client_->Reset();
       audio_client_.Release();
     }
 
index d242f30..6087155 100644 (file)
@@ -106,6 +106,7 @@ namespace sf{
     if(audio_client_)
     {
       audio_client_->Stop();
+      audio_client_->Reset();
       audio_client_.Release();
     }