// wasapi出力スレッドの起動
output_thread_ = boost::thread(boost::bind(&application::output_thread_main,this));
- bool a = ringbuffer_.is_lock_free();
+ // bool a = ringbuffer_.is_lock_free();
// wdout << ( ? L"**** true ****":L"---- false ----") << std::endl;
//sf::dialogbox(L"asyncテスト",L"asyncテスト");
// メッセージループの実行
{
memset(read_buffer_[read_index_].get() + size,0,wasapi_->get_buffer_byte_size() - size);
}
- }
+ }
+
not_enqueue_ = false;
while(!ringbuffer_.enqueue(read_buffer_[read_index_].get()))
{
Sleep(0);
}
}
+
;
sf::wdout << boost::wformat(L"index:%d address:%x 差分:%x")
% read_index_ % read_buffer_[read_index_].get()
break;
case player_pause:
- //wasapi_->reset();
+ wasapi_->stop();
break;
case player_stop:
+ wasapi_->stop();
break;
}
Sleep(0);
source_file_path_ = file_path;
reader_.reset(new WaveFileReader(file_path.c_str(),FALSE));
THROW_IF_ERR(reader_->GetStreamStatus());
+ if(wasapi_)
+ {
+ wasapi_.reset();
+ }
wasapi_.reset(new sf::wasapi_shared_timer(reader_->GetWaveFormat()));
if(!wasapi_->is_enabled())
{
//\r
LANGUAGE LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN\r
IDD_MAINDIALOG DIALOG 0, 0, 320, 252\r
-STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_GROUP | WS_TABSTOP | WS_SYSMENU\r
-EXSTYLE WS_EX_ACCEPTFILES | WS_EX_APPWINDOW\r
+STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_SYSMENU\r
+EXSTYLE WS_EX_APPWINDOW\r
CAPTION "\94ñ\93¯\8aú\82Å\83t\83@\83C\83\8b\82ð\93Ç\82Ý\8d\9e\82Ý\81A\8dÄ\90¶\82·\82é\83e\83X\83g"\r
FONT 9, "\83\81\83C\83\8a\83I"\r
{\r
PUSHBUTTON "\83t\83@\83C\83\8b", IDC_FILE, 11, 5, 40, 14,WS_TABSTOP \r
PUSHBUTTON "\8dÄ\90¶", IDC_PLAY, 53, 5, 40, 14, WS_DISABLED | WS_TABSTOP \r
- CONTROL "", IDC_SLIDER, TRACKBAR_CLASS, WS_TABSTOP | WS_DISABLED | TBS_BOTH | TBS_NOTICKS, 6, 29, 309, 15\r
PUSHBUTTON "\88ê\8e\9e\92â\8e~", IDC_PAUSE, 95, 5, 40, 14, WS_DISABLED | WS_TABSTOP \r
PUSHBUTTON "\92â\8e~", IDC_STOP, 137, 5, 40, 14, WS_DISABLED | WS_TABSTOP \r
+ 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_TABSTOP, WS_EX_STATICEDGE \r
+ LTEXT "Static", IDC_INFO, 10, 49, 301, 99, SS_LEFT, WS_EX_STATICEDGE \r
}\r
\r
\r
struct dialog_message_loop
{
- dialog_message_loop(HWND dialog) : dialog_(dialog_) {};
+ dialog_message_loop(HWND dialog) : dialog_(dialog) {};
inline WPARAM operator()()
{
MSG msg;
* @author S.F. (Satoshi Fujiwara)
*/
#include "objbase.h"
+
+
+
namespace sf
{
+ template <class COM_SMART_PTR > inline void safe_release(COM_SMART_PTR& ptr)
+ {
+ if(ptr)
+ {
+ ptr.Release();
+ }
+ };
enum com_init
{
multi_threaded = 0x0,
_COM_SMARTPTR_TYPEDEF(ID3D11ShaderResourceView,__uuidof(ID3D11ShaderResourceView));
_COM_SMARTPTR_TYPEDEF(ID3D11SamplerState,__uuidof(ID3D11SamplerState));
-template <class COM_SMART_PTR > inline void safe_release(COM_SMART_PTR& ptr)
-{
- if(ptr)
- {
- ptr.Release();
- }
-};
+
namespace sf{
virtual void send_message(uint32_t message,uint32_t wparam,uint32_t lparam )
{
- ::SendMessage(hwnd_,message,wparam,lparam);
+ ::SendNotifyMessage(hwnd_,message,wparam,lparam);
}
virtual void post_message(uint32_t message,uint32_t wparam,uint32_t lparam )
};
-
+
// -------------------------------------------------------------------
// ウィンドウプロシージャ
// -------------------------------------------------------------------
break;
case WM_PLAY_PLAY:
play_();
- break;
+ return TRUE;
case WM_PLAY_STOP:
stop_();
return TRUE;
SendMessage(GetDlgItem(hwnd_,IDC_SLIDER), TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 30000));
}
+ void ready()
+ {
+ // プレイボタンは有効化
+ enable_control(IDC_PLAY,true);
+ focus(IDC_PLAY);
+ highlight(IDC_PLAY);
+ // その他のボタンは無効化
+ enable_control(IDC_PAUSE,false);
+ enable_control(IDC_SLIDER,true);
+ enable_control(IDC_STOP,false);
+ }
+
void play()
{
- send_message(WM_PLAY_PLAY,0,0);
+ post_message(WM_PLAY_PLAY,0,0);
}
void play_()
{
enable_control(IDC_PLAY,false);
enable_control(IDC_STOP,true);
+ focus(IDC_STOP);
+ highlight(IDC_STOP);
enable_control(IDC_PAUSE,true);
::SetWindowText(GetDlgItem(hwnd_,IDC_PAUSE),L"一時停止");
enable_control(IDC_SLIDER,true);
void stop()
{
- send_message(WM_PLAY_STOP,0,0);
+ post_message(WM_PLAY_STOP,0,0);
}
void stop_()
{
enable_control(IDC_PLAY,true);
+ focus(IDC_PLAY);
+ highlight(IDC_PLAY);
enable_control(IDC_STOP,false);
enable_control(IDC_PAUSE,false);
- enable_control(IDC_SLIDER,false);
+ enable_control(IDC_SLIDER,true);
}
void pause()
enable_control(IDC_PLAY,false);
enable_control(IDC_STOP,false);
enable_control(IDC_PAUSE,true);
+ focus(IDC_PAUSE);
+ highlight(IDC_PAUSE);
::SetWindowText(GetDlgItem(hwnd_,IDC_PAUSE),L"再開");
- enable_control(IDC_SLIDER,false);
+ enable_control(IDC_SLIDER,true);
}
virtual void create(){
create_device_independent_resources();
void create_dialog()
{
- hwnd_ = ::CreateDialog(HINST_THISCOMPONENT,MAKEINTRESOURCE(IDD_MAINDIALOG),0,thunk_proc_);
+ hwnd_ = ::CreateDialog(HINST_THISCOMPONENT,MAKEINTRESOURCE(IDD_MAINDIALOG),::GetDesktopWindow(),thunk_proc_);
// ::DialogBox(HINST_THISCOMPONENT,MAKEINTRESOURCE(IDD_MAINDIALOG),0,thunk_proc_);
}
}
}
}
- void ready()
- {
- // プレイボタンは有効化
- enable_control(IDC_PLAY,true);
-
- // その他のボタンは無効化
- enable_control(IDC_PAUSE,false);
- enable_control(IDC_SLIDER,false);
- enable_control(IDC_STOP,false);
- }
+
void create_window()
{
{
::EnableWindow(GetDlgItem(hwnd_,id),enable?TRUE:FALSE);
}
+
+ void focus(uint32_t id)
+ {
+ //::PostMessage(GetDlgItem(hwnd_,id),WM_SETFOCUS,NULL,NULL);
+ ::SetFocus(GetDlgItem(hwnd_,id));
+ //::PostMessage(hwnd_,WM_COMMAND,MAKEWPARAM(id,BN_SETFOCUS),(LPARAM)GetDlgItem(hwnd_,id));
+ }
+
+ void highlight(uint32_t id)
+ {
+ //Button_SetState(GetDlgItem(hwnd_,id),TRUE);
+ }
+
private:
void read_start() {};
//mix_format_->nBlockAlign = (mix_format_->wBitsPerSample / 8) * mix_format_->nChannels;
//mix_format_->nAvgBytesPerSec = mix_format_->nSamplesPerSec*mix_format_->nBlockAlign;
sf::co_task_memory<WAVEFORMATEX> alt_format;
- THROW_IF_ERR(
- audio_client_->IsFormatSupported(
- AUDCLNT_SHAREMODE_SHARED,reinterpret_cast<::WAVEFORMATEX*>(&wfx),&alt_format));
+
+ HRESULT hr = audio_client_->IsFormatSupported(
+ AUDCLNT_SHAREMODE_SHARED ,reinterpret_cast<::WAVEFORMATEX*>(&wfx.Format),&alt_format);
+ bool sample_rate_convert = false;
+ float sample_rate_backup = 0.0f;
+ if(hr != S_OK)
+ {
+ // サンプルレートのコンバート
+ if(alt_format->nSamplesPerSec != wfx.Format.nSamplesPerSec)
+ {
+ sample_rate_backup = wfx.Format.nSamplesPerSec;
+ wfx.Format.nSamplesPerSec = alt_format->nSamplesPerSec;
+ wfx.Format.nAvgBytesPerSec = alt_format->nSamplesPerSec * wfx.Format.nBlockAlign;
+ THROW_IF_ERR(audio_client_->IsFormatSupported(
+ AUDCLNT_SHAREMODE_SHARED ,reinterpret_cast<::WAVEFORMATEX*>(&wfx.Format),&alt_format));
+ sample_rate_convert = true;
+ } else {
+ throw win32_error_exception(hr);
+ }
+ }
// 再生クライアントの初期化
REFERENCE_TIME buffer_duration = buffer_period * periods_per_buffer_;
- THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_SHARED,
- AUDCLNT_STREAMFLAGS_NOPERSIST,
+ THROW_IF_ERR(audio_client_->Initialize(AUDCLNT_SHAREMODE_SHARED ,
+ AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_RATEADJUST,
buffer_duration,
buffer_period,
&(wfx.Format),
NULL));
-
+ audio_client_->Reset();
// バッファサイズの取得
THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));
// 再生クライアントの取得
THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_render_client_)));
- //
+ // サンプルレートコンバータ
+ if(sample_rate_convert)
+ {
+ THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_clock_adjustment_)));
+ audio_clock_adjustment_->SetSampleRate(sample_rate_backup);
+ }
+
num_of_frames_ = wfx.Format.nBlockAlign;
mix_format_ = wfx;
is_enabled_ = true;
wasapi_shared_timer::~wasapi_shared_timer()
{
+ safe_release(audio_clock_adjustment_);
+ safe_release(audio_render_client_);
- // WASAPIの終了処理
+ // WASAPIの終了処理
if(audio_client_)
{
audio_client_->Stop();
audio_client_.Release();
}
+
+ safe_release(current_device_);
+ safe_release(device_enumerator_);
}
void wasapi_shared_timer::create_wave_data(){
void wasapi_shared_timer::stop() {
//再生停止
THROW_IF_ERR(audio_client_->Stop());
+ reset();
is_start_ = false;
}
}
_COM_SMARTPTR_TYPEDEF(IMMDevice,__uuidof(IMMDevice));
_COM_SMARTPTR_TYPEDEF(IAudioClient,__uuidof(IAudioClient));
_COM_SMARTPTR_TYPEDEF(IAudioRenderClient,__uuidof(IAudioRenderClient));
+_COM_SMARTPTR_TYPEDEF(IAudioClockAdjustment,__uuidof(IAudioClockAdjustment));
namespace sf {
IMMDevicePtr current_device_;
IAudioClientPtr audio_client_;
IAudioRenderClientPtr audio_render_client_;
+ IAudioClockAdjustmentPtr audio_clock_adjustment_;
//handle_holder buffer_control_event_;
WAVEFORMATEXTENSIBLE mix_format_;
bool is_enabled_;