private byte[] ConvCommon(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args, ConversionLoop convLoop) { var from = pcmFrom.GetSampleArray(); long nSample = from.LongLength * 8 / pcmFrom.BitsPerSample; var to = new byte[nSample * WasapiCS.SampleFormatTypeToUseBitsPerSample(toFormat) / 8]; convLoop(from, to, nSample, args.noiseShaping); return(to); }
private bool WriteWavFile(PcmData pcmData, string path) { using (BinaryWriter bw = new BinaryWriter( File.Open(path, FileMode.Create, FileAccess.Write, FileShare.Write))) { var wavW = new WavWriter(); wavW.Set(pcmData.NumChannels, pcmData.BitsPerSample, pcmData.ValidBitsPerSample, pcmData.SampleRate, pcmData.SampleValueRepresentationType, pcmData.NumFrames, pcmData.GetSampleArray()); wavW.Write(bw); } return(true); }
private void buttonPlayA_Click(object sender, RoutedEventArgs e) { int hr; PcmData pcmData = ReadWavFile(textBoxPathA.Text); if (null == pcmData) { MessageBox.Show( string.Format("WAVファイル A 読み込み失敗: {0}", textBoxPathA.Text)); return; } /* * hr = wasapi.ChooseDevice(comboBoxDeviceA.SelectedIndex); * if (hr < 0) { * MessageBox.Show(string.Format("Wasapi.ChooseDevice()失敗 {0:X8}", hr)); * UnchooseRecreateDeviceList(); * return; * } */ hr = WasapiSetup( comboBoxDeviceA.SelectedIndex, radioButtonExclusiveA.IsChecked == true, radioButtonEventDrivenA.IsChecked == true, pcmData.SampleRate, pcmData.BitsPerSample, pcmData.ValidBitsPerSample, pcmData.SampleValueRepresentationType, Int32.Parse(textBoxLatencyA.Text)); if (hr < 0) { MessageBox.Show(string.Format("Wasapi.Setup失敗 {0:X8}", hr)); UnchooseRecreateDeviceList(); return; } var pcmUtil = new PcmUtil(pcmData.NumChannels); pcmData = pcmUtil.BitsPerSampleConvAsNeeded(pcmData, m_sampleFormat.GetSampleFormatType(), null); wasapi.ClearPlayList(); wasapi.AddPlayPcmDataStart(); wasapi.AddPlayPcmData(0, pcmData.GetSampleArray()); wasapi.AddPlayPcmDataEnd(); hr = wasapi.StartPlayback(0); m_playWorker.RunWorkerAsync(); m_status = Status.Play; UpdateAbxTabUIStatus(); }
public static bool WriteWav(BinaryWriter bw, PcmData pcm, List <WavChunkParams> wavParamList) { var writer = new WavWriterLowLevel(); bool isDs64 = wavParamList.Find((WavChunkParams p) => { return(p.ChunkType == WavChunkType.DS64); }) != null; long posDS64 = -1; long posRiff = -1; foreach (var i in wavParamList) { switch (i.ChunkType) { case WavChunkType.RIFF: { // 仮。ファイルサイズが決まった時に書き直す。 posRiff = bw.BaseStream.Position; writer.RiffChunkWrite(bw, -1); } break; case WavChunkType.fmt: { var fmt = i as FmtChunkParams; switch (fmt.StructType) { case FmtChunkParams.WaveFormatStructType.WaveFormat: writer.FmtChunkWrite(bw, (short)pcm.NumChannels, (int)pcm.SampleRate, (short)pcm.BitsPerSample); break; case FmtChunkParams.WaveFormatStructType.WaveFormatEx: writer.FmtChunkWriteEx(bw, (short)pcm.NumChannels, (int)pcm.SampleRate, (short)pcm.BitsPerSample, pcm.SampleValueRepresentationType == PcmData.ValueRepresentationType.SFloat ? WavWriterLowLevel.WAVE_FORMAT_IEEE_FLOAT : WavWriterLowLevel.WAVE_FORMAT_PCM, (short)fmt.CbSize); break; case FmtChunkParams.WaveFormatStructType.WaveFormatExtensible: { int dwChannelMask = 0; if (pcm.NumChannels == 2) { dwChannelMask = 3; } writer.FmtChunkWriteExtensible(bw, (short)pcm.NumChannels, (int)pcm.SampleRate, (short)pcm.BitsPerSample, (short)pcm.ValidBitsPerSample, pcm.SampleValueRepresentationType, (int)dwChannelMask); } break; default: System.Diagnostics.Debug.Assert(false); break; } } break; case WavChunkType.DATA: { var data = i as DataChunkParams; long posDataStart = bw.BaseStream.Position; writer.DataChunkWrite(bw, isDs64, pcm.GetSampleArray()); if (!isDs64 && 0 < data.ExtraChunkBytes) { // 実際よりも長いチャンクサイズを書き込む。 long posDataEnd = bw.BaseStream.Position; bw.BaseStream.Seek(posDataStart + 4, SeekOrigin.Begin); int chunkSize = pcm.GetSampleArray().Length + data.ExtraChunkBytes; bw.Write(chunkSize); bw.BaseStream.Seek(posDataEnd, SeekOrigin.Begin); } } break; case WavChunkType.JUNK: { var junk = i as JunkChunkParams; writer.JunkChunkWrite(bw, (ushort)junk.ContentBytes); } break; case WavChunkType.bext: { var bext = i as BextChunkParams; writer.BextChunkWrite(bw, bext.Description, bext.Originator, bext.OriginatorReference, bext.OriginationDate, bext.OriginationTime, bext.TimeReference, null, 0, 0, 0, 0, 0, null); } break; case WavChunkType.DS64: { posDS64 = bw.BaseStream.Position; var ds64 = i as DS64ChunkParams; writer.Ds64ChunkWrite(bw, ds64.RiffSize, ds64.DataSize, ds64.SampleCount); } break; case WavChunkType.ID3: { var id3 = i as ID3ChunkParams; writer.ID3ChunkWrite(bw, id3.Title, id3.Album, id3.Artists, id3.AlbumCoverArt, id3.AlbumCoverArtMimeType); } break; } } long posEnd = bw.BaseStream.Position; RiffChunkParams riff = wavParamList.Find((WavChunkParams p) => { return(p.ChunkType == WavChunkType.RIFF); }) as RiffChunkParams; if (!isDs64) { // RIFFのサイズが決まったので書き込む int riffSize = (int)(posEnd - posRiff - 8); riffSize += riff.ExtraChunkBytes; bw.BaseStream.Seek(posRiff, SeekOrigin.Begin); writer.RiffChunkWrite(bw, riffSize); bw.BaseStream.Seek(posEnd, SeekOrigin.Begin); } else { // DS64のサイズが決まったので書き込む DataChunkParams dcp = wavParamList.Find((WavChunkParams p) => { return(p.ChunkType == WavChunkType.DATA); }) as DataChunkParams; long riffSize = posEnd - posRiff - 8; riffSize += riff.ExtraChunkBytes; long dataSize = pcm.GetSampleArray().LongLength; if (0 < dcp.ExtraChunkBytes) { dataSize += dcp.ExtraChunkBytes; } long sampleCount = pcm.NumFrames; bw.BaseStream.Seek(posDS64, SeekOrigin.Begin); writer.Ds64ChunkWrite(bw, riffSize, dataSize, sampleCount); bw.BaseStream.Seek(posEnd, SeekOrigin.Begin); } if (0 < riff.GarbageBytes) { // ファイルの最後にごみを書き込む var zeroes = new byte[riff.GarbageBytes]; bw.Write(zeroes); } return(true); }
private byte[] ConvClone(PcmData from, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args) { return((byte[])from.GetSampleArray().Clone()); }