/// <returns>WASAPIエラーコード。</returns> private int Setup(int deviceId, PcmDataLib.PcmData format) { int ercd = 0; var mixFormat = mWasapi.GetMixFormat(deviceId); if (WasapiCS.ShareMode.Shared == mShareMode) { // 共有モード。 ercd = mWasapi.Setup(deviceId, WasapiCS.DeviceType.Play, WasapiCS.StreamType.PCM, mixFormat.sampleRate, WasapiCS.SampleFormatType.Sfloat, mixFormat.numChannels, mixFormat.dwChannelMask, WasapiCS.MMCSSCallType.Enable, WasapiCS.MMThreadPriorityType.High, WasapiCS.SchedulerTaskType.ProAudio, mShareMode, mDataFeedMode, mBufferSizeMillisec, mZeroFlushMillisec, 10000, true); if (ercd < 0) { Console.WriteLine("Wasapi.Setup({0} {1}) failed", mixFormat.sampleRate, WasapiCS.SampleFormatType.Sfloat); mWasapi.Unsetup(); } else { Console.WriteLine("Wasapi.Setup({0} {1}) success", mixFormat.sampleRate, WasapiCS.SampleFormatType.Sfloat); mDeviceFormat.Set(mixFormat.numChannels, mixFormat.sampleRate, WasapiCS.SampleFormatType.Sfloat, mixFormat.dwChannelMask); } } else { // 排他モード。 // ビットデプスの候補をすべて試す。 var sampleFormatCandidates = SampleFormatCandidates(format.ValidBitsPerSample); for (int i = 0; i < sampleFormatCandidates.Length; ++i) { ercd = mWasapi.Setup(deviceId, WasapiCS.DeviceType.Play, WasapiCS.StreamType.PCM, format.SampleRate, sampleFormatCandidates[i], mixFormat.numChannels, mixFormat.dwChannelMask, WasapiCS.MMCSSCallType.Enable, WasapiCS.MMThreadPriorityType.High, WasapiCS.SchedulerTaskType.ProAudio, mShareMode, mDataFeedMode, mBufferSizeMillisec, mZeroFlushMillisec, 10000, true); if (ercd < 0) { Console.WriteLine("Wasapi.Setup({0} {1}) failed", format.SampleRate, sampleFormatCandidates[i]); mWasapi.Unsetup(); } else { Console.WriteLine("Wasapi.Setup({0} {1}) success", format.SampleRate, sampleFormatCandidates[i]); mDeviceFormat.Set(mixFormat.numChannels, format.SampleRate, sampleFormatCandidates[i], WasapiCS.GetTypicalChannelMask(format.NumChannels)); break; } } } return(ercd); }
private void SetSampleDataToWasapiStart(int idx, WWFlacRWCS.FlacRW flac) { WWFlacRWCS.Metadata meta; flac.GetDecodedMetadata(out meta); mFromFormat = new DeviceFormat(); mFromFormat.Set(meta.channels, meta.sampleRate, WasapiCS.BitAndFormatToSampleFormatType(meta.bitsPerSample, meta.bitsPerSample, WasapiCS.BitFormatType.SInt)); long totalBytes = meta.totalSamples * mDeviceFormat.BytesPerFrame(); mWasapi.AddPlayPcmDataAllocateMemory(idx, totalBytes); mDecodedPcmOffs = 0; }
private int SetSampleDataToWasapiStart(int idx, WWFlacRWCS.FlacRW flac) { int hr = 0; mDecodedPcmOffs = 0; WWFlacRWCS.Metadata meta; flac.GetDecodedMetadata(out meta); mFromFormat = new DeviceFormat(); mFromFormat.Set(meta.channels, meta.sampleRate, WasapiCS.BitAndFormatToSampleFormatType( meta.bitsPerSample, meta.bitsPerSample, WasapiCS.BitFormatType.SInt), WasapiCS.GetTypicalChannelMask(meta.channels)); if (WasapiCS.ShareMode.Exclusive == mShareMode) { // 排他モードの時。サンプルレート変換しないので // サンプル数がFromと同じ。 long totalBytes = meta.totalSamples * mDeviceFormat.BytesPerFrame(); mWasapi.AddPlayPcmDataAllocateMemory(idx, totalBytes); } else { // 共有モードの時。サンプルレート変換する。 long totalBytes = (meta.totalSamples * mDeviceFormat.SampleRate / mFromFormat.SampleRate) * mDeviceFormat.BytesPerFrame(); mWasapi.AddPlayPcmDataAllocateMemory(idx, totalBytes); var resampleFrom = new WWMFResamplerCs.WWPcmFormat(WWMFResamplerCs.WWPcmFormat.SampleFormat.SF_Int, mFromFormat.NumChannels, mFromFormat.UseBitsPerSample(), mFromFormat.SampleRate, WasapiCS.GetTypicalChannelMask(mFromFormat.NumChannels), mFromFormat.ValidBitsPerSample()); var resampleTo = new WWMFResamplerCs.WWPcmFormat(WWMFResamplerCs.WWPcmFormat.SampleFormat.SF_Float, mDeviceFormat.NumChannels, mDeviceFormat.UseBitsPerSample(), mDeviceFormat.SampleRate, mDeviceFormat.DwChannelMask, mDeviceFormat.ValidBitsPerSample()); hr = mMfResampler.Init(resampleFrom, resampleTo, 60); if (hr < 0) { Console.WriteLine("mMfResampler.Init() failed {0:X8}", hr); } } return(hr); }