/// <summary> /// 排他モード用。ビットデプスとチャンネル数を変更する。 /// </summary> private byte[] PcmDepthChannelConvert(byte[] from, int fromOffs, int fromBytes, DeviceFormat fromFormat, DeviceFormat toFormat) { System.Diagnostics.Debug.Assert(fromFormat.SampleRate == toFormat.SampleRate); int numFrames = fromBytes / (fromFormat.NumChannels * WasapiCS.SampleFormatTypeToUseBitsPerSample(fromFormat.SampleFormat) / 8); var pcmFrom = new PcmDataLib.PcmData(); pcmFrom.SetFormat(fromFormat.NumChannels, WasapiCS.SampleFormatTypeToUseBitsPerSample(fromFormat.SampleFormat), WasapiCS.SampleFormatTypeToValidBitsPerSample(fromFormat.SampleFormat), fromFormat.SampleRate, PcmDataLib.PcmData.ValueRepresentationType.SInt, numFrames); pcmFrom.SetSampleLargeArray(new WWUtil.LargeArray <byte>(from, fromOffs, fromBytes)); // ビットデプスを変更する。 var conv = new WasapiPcmUtil.PcmFormatConverter(fromFormat.NumChannels); var pcmTo = conv.Convert(pcmFrom, toFormat.SampleFormat, new WasapiPcmUtil.PcmFormatConverter.BitsPerSampleConvArgs(WasapiPcmUtil.NoiseShapingType.None)); // チャンネル数を変更する。 var toBytes = WasapiPcmUtil.PcmFormatConverter.ChangeChannelCount( fromFormat.SampleFormat, WasapiCS.StreamType.PCM, fromFormat.NumChannels, pcmTo.GetSampleLargeArray().ToArray(), toFormat.NumChannels); return(toBytes); }
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); }
private void SetSampleDataToWasapiEnd(int idx, WWFlacRWCS.FlacRW flac) { if (WasapiCS.ShareMode.Shared == mShareMode) { // 共有モードの場合。サンプルレート変換のFIFOをドレインする。 byte[] toBytes = new byte[0]; int hr = mMfResampler.Drain(out toBytes); if (hr < 0) { Console.WriteLine("mMfResampler.Drain() failed {0:X8}", hr); // ここでエラーが出ても特にすることは無い。 } mWasapi.AddPlayPcmDataSetPcmFragment(idx, mDecodedPcmOffs, toBytes); mDecodedPcmOffs += toBytes.Length; mMfResampler.Term(); } mFromFormat = null; mDecodedPcmOffs = 0; }
private void SetSampleDataToWasapiEnd(int idx, WWFlacRWCS.FlacRW flac) { mFromFormat = null; mDecodedPcmOffs = 0; }