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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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());
 }