wasapi_shared_timer::wasapi_shared_timer(::WAVEFORMATEXTENSIBLE& wfx)
: is_enabled_(false),position_(0),is_start_(false)/*,buffer_control_event_(::CreateEventEx(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE))*/
{
- //if(buffer_control_event_ == NULL)
- //{
- // return;
- //}
try {
-// thread_priority_.set_priority(AVRT_PRIORITY_NORMAL);
+ // thread_priority_.set_priority(AVRT_PRIORITY_NORMAL);
// WASAPIの初期化処理
// IMMDeviceEnumeratorの取得
THROW_IF_ERR(
CoCreateInstance(
- __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
- IID_PPV_ARGS(&device_enumerator_)));
-
+ __uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&device_enumerator_)));
+
// デフォルトのオーディオデバイスを取得する
THROW_IF_ERR(
device_enumerator_
- ->GetDefaultAudioEndpoint(eRender,eMultimedia,¤t_device_)
- );
+ ->GetDefaultAudioEndpoint(eRender,eMultimedia,¤t_device_)
+ );
// オーディオクライアントを取得
THROW_IF_ERR(
current_device_
- ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
- NULL, reinterpret_cast<void **>(&audio_client_))
+ ->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
+ NULL, reinterpret_cast<void **>(&audio_client_))
);
- // フォーマット定義
- //audio_client_->GetMixFormat(&mix_format_);
- //WAVEFORMATEXTENSIBLE *waveFormatExtensible = reinterpret_cast<WAVEFORMATEXTENSIBLE *>((WAVEFORMATEX*)mix_format_.get());
- //waveFormatExtensible->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- //waveFormatExtensible->Format.wBitsPerSample = 16;
- //waveFormatExtensible->Format.nBlockAlign = (mix_format_->wBitsPerSample / 8) * mix_format_->nChannels;
- //waveFormatExtensible->Format.nAvgBytesPerSec = waveFormatExtensible->Format.nSamplesPerSec*waveFormatExtensible->Format.nBlockAlign;
- //waveFormatExtensible->Samples.wValidBitsPerSample = 16;
-
- //mix_format_->wFormatTag = WAVE_FORMAT_PCM;
- //mix_format_->wBitsPerSample = 16;
- //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;
-
+
+ // 読みこもうとしているWAVファイルのフォーマットをサポートしているか?
HRESULT hr = audio_client_->IsFormatSupported(
- AUDCLNT_SHAREMODE_SHARED ,reinterpret_cast<::WAVEFORMATEX*>(&wfx.Format),&alt_format);
+ AUDCLNT_SHAREMODE_SHARED ,&wfx.Format,&alt_format);
bool sample_rate_convert = false;
float sample_rate_backup = 0.0f;
- if(hr != S_OK)
+ if(hr != S_OK) // S_FALSEならそのフォーマットをサポートしていないらしい..
{
// サンプルレートのコンバート
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));
+ AUDCLNT_SHAREMODE_SHARED ,&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 | AUDCLNT_STREAMFLAGS_RATEADJUST,
- buffer_duration,
- buffer_period,
- &(wfx.Format),
- NULL));
+ AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_RATEADJUST,
+ buffer_duration,
+ buffer_period,
+ &(wfx.Format),
+ NULL));
- audio_client_->Reset();
// バッファサイズの取得
THROW_IF_ERR(audio_client_->GetBufferSize(&buffer_size_));
if(sample_rate_convert)
{
THROW_IF_ERR(audio_client_->GetService(IID_PPV_ARGS(&audio_clock_adjustment_)));
+ // 本来のサンプルレートをセットする
audio_clock_adjustment_->SetSampleRate(sample_rate_backup);
}
for (size_t i = 0 ; i < render_data_length ; i += mix_format_.Format.nChannels)
{
- double sinValue = sin( theta );
- for(size_t j = 0 ;j < mix_format_.Format.nChannels; j++)
- {
- tone_buffer_.push_back((short)(sinValue * _I16_MAX));
- }
- theta += sampleIncrement;
+ double sinValue = sin( theta );
+ for(size_t j = 0 ;j < mix_format_.Format.nChannels; j++)
+ {
+ tone_buffer_.push_back((short)(sinValue * _I16_MAX));
+ }
+ theta += sampleIncrement;
}
};
if(!is_start_)
{
-
+
// 最初にバッファを埋める
THROW_IF_ERR(audio_render_client_->GetBuffer(buffer_size_,&buffer));
::CopyMemory(buffer,source_buffer,get_buffer_byte_size());
{
Sleep(latency_ms_);
}
- }
+ }
}
void wasapi_shared_timer::reset()
{