private byte[] ConvF32toI32(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    float fv = System.BitConverter.ToSingle(from, fromPos);
                    if (SAMPLE_VALUE_MAX_FLOAT <= fv)
                    {
                        fv = SAMPLE_VALUE_MAX_FLOAT_TO_I24;
                        IncrementClippedCounter();
                    }
                    if (fv < SAMPLE_VALUE_MIN_FLOAT)
                    {
                        fv = SAMPLE_VALUE_MIN_FLOAT;
                        IncrementClippedCounter();
                    }
                    int iv = (int)(fv * 8388608.0f);

                    to[toPos++] = 0;
                    to[toPos++] = (byte)(iv & 0xff);
                    to[toPos++] = (byte)((iv >> 8) & 0xff);
                    to[toPos++] = (byte)((iv >> 16) & 0xff);
                    fromPos += 4;
                }
            }));
        }
        /// <summary>
        /// Converts sample format to toFormat and returns new instance of PcmData.
        /// pcmFrom is not changed.
        /// </summary>
        /// <param name="toFormat">sample format to convert</param>
        /// <returns>Newly instanciated PcmData</returns>
        public PcmData Convert(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            if (args == null)
            {
                args = new BitsPerSampleConvArgs(NoiseShapingType.None);
            }

            var fromFormat = WasapiCS.BitAndFormatToSampleFormatType(pcmFrom.BitsPerSample, pcmFrom.ValidBitsPerSample,
                                                                     SampleFormatInfo.VrtToBft(pcmFrom.SampleValueRepresentationType));

            if (fromFormat == WasapiCS.SampleFormatType.Unknown ||
                toFormat == WasapiCS.SampleFormatType.Unknown)
            {
                return(null);
            }

            var newSampleArray = mConvert[(int)fromFormat][(int)toFormat](pcmFrom, toFormat, args);

            PcmData newPcmData = new PcmData();

            newPcmData.CopyHeaderInfoFrom(pcmFrom);
            newPcmData.SetFormat(pcmFrom.NumChannels,
                                 WasapiCS.SampleFormatTypeToUseBitsPerSample(toFormat),
                                 WasapiCS.SampleFormatTypeToValidBitsPerSample(toFormat), pcmFrom.SampleRate,
                                 SampleFormatInfo.BftToVrt(WasapiCS.SampleFormatTypeToBitFormatType(toFormat)), pcmFrom.NumFrames);
            newPcmData.SetSampleArray(newSampleArray);

            return(newPcmData);
        }
        private byte[] ConvF64toF32(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    double dv = System.BitConverter.ToDouble(from, fromPos);
                    float fv = (float)dv;
                    if (SAMPLE_VALUE_MAX_FLOAT <= fv)
                    {
                        fv = SAMPLE_VALUE_MAX_FLOAT_TO_I24;
                        IncrementClippedCounter();
                    }
                    if (fv < SAMPLE_VALUE_MIN_FLOAT)
                    {
                        fv = SAMPLE_VALUE_MIN_FLOAT;
                        IncrementClippedCounter();
                    }
                    byte [] b = System.BitConverter.GetBytes(fv);
                    to[toPos++] = b[0];
                    to[toPos++] = b[1];
                    to[toPos++] = b[2];
                    to[toPos++] = b[3];
                    fromPos += 8;
                }
            }));
        }
        public SampleDataAsset(string name, WaveFile wave)
        {
            if (name == null)
            {
                throw new ArgumentNullException("An asset must be given a valid name.");
            }
            assetName = name;
            SamplerChunk smpl = wave.FindChunk <SamplerChunk>();

            if (smpl != null)
            {
                sampleRate = (int)(44100.0 * (1.0 / (smpl.SamplePeriod / 22675.0)));
                rootKey    = (short)smpl.UnityNote;
                tune       = (short)(smpl.PitchFraction * 100);
                if (smpl.Loops.Length > 0)
                {
                    //--WARNING ASSUMES: smpl.Loops[0].Type == SamplerChunk.SampleLoop.LoopType.Forward
                    loopStart = smpl.Loops[0].Start;
                    loopEnd   = smpl.Loops[0].End + smpl.Loops[0].Fraction + 1;
                }
            }
            else
            {
                sampleRate = wave.Format.SampleRate;
            }
            byte[] data = wave.Data.RawSampleData;
            if (wave.Format.ChannelCount != audioChannels) //reformat to supported channels
            {
                data = WaveHelper.GetChannelPcmData(data, wave.Format.BitsPerSample, wave.Format.ChannelCount, audioChannels);
            }
            sampleData = PcmData.Create(wave.Format.BitsPerSample, data, true);
            start      = 0;
            end        = sampleData.Length;
        }
        private byte[] ConvF64toI32(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    double dv = System.BitConverter.ToDouble(from, fromPos);

                    int iv = 0;
                    if ((long)Int32.MaxValue < (long)(dv * Int32.MaxValue))
                    {
                        iv = Int32.MaxValue;
                        IncrementClippedCounter();
                    }
                    else if ((long)(-dv * Int32.MinValue) < (long)Int32.MinValue)
                    {
                        iv = Int32.MinValue;
                        IncrementClippedCounter();
                    }
                    else
                    {
                        iv = (int)(-dv * Int32.MinValue);
                    }

                    to[toPos++] = (byte)((iv >> 0) & 0xff);
                    to[toPos++] = (byte)((iv >> 8) & 0xff);
                    to[toPos++] = (byte)((iv >> 16) & 0xff);
                    to[toPos++] = (byte)((iv >> 24) & 0xff);
                    fromPos += 8;
                }
            }));
        }
Beispiel #6
0
        /// <summary>
        /// 量子化ビット数を、もし必要なら変更する。
        /// </summary>
        /// <param name="pd">入力PcmData</param>
        /// <returns>変更後PcmData</returns>
        public PcmData BitsPerSampleConvAsNeeded(PcmData pd, WasapiCS.SampleFormatType fmt, WasapiPcmUtil.PcmFormatConverter.BitsPerSampleConvArgs args)
        {
            switch (fmt)
            {
            case WasapiCS.SampleFormatType.Sfloat:
                // System.Console.WriteLine("Converting to Sfloat32bit...");
                pd = mConv.Convert(pd, WasapiCS.SampleFormatType.Sfloat, args);
                break;

            case WasapiCS.SampleFormatType.Sint16:
                // System.Console.WriteLine("Converting to SInt16bit...");
                pd = mConv.Convert(pd, WasapiCS.SampleFormatType.Sint16, args);
                break;

            case WasapiCS.SampleFormatType.Sint24:
                // System.Console.WriteLine("Converting to SInt24...");
                pd = mConv.Convert(pd, WasapiCS.SampleFormatType.Sint24, args);
                break;

            case WasapiCS.SampleFormatType.Sint32V24:
                // System.Console.WriteLine("Converting to SInt32V24...");
                pd = mConv.Convert(pd, WasapiCS.SampleFormatType.Sint32V24, args);
                break;

            case WasapiCS.SampleFormatType.Sint32:
                // System.Console.WriteLine("Converting to SInt32bit...");
                pd = mConv.Convert(pd, WasapiCS.SampleFormatType.Sint32, args);
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }
            return(pd);
        }
        private byte[] ConvF64toI24orI32V24(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;
                bool writePad = toFormat == WasapiCS.SampleFormatType.Sint32V24;

                for (int i = 0; i < nSample; ++i)
                {
                    double dv = System.BitConverter.ToDouble(from, fromPos);
                    if (SAMPLE_VALUE_MAX_DOUBLE <= dv)
                    {
                        dv = SAMPLE_VALUE_MAX_DOUBLE_TO_I24;
                        IncrementClippedCounter();
                    }
                    if (dv < SAMPLE_VALUE_MIN_DOUBLE)
                    {
                        dv = SAMPLE_VALUE_MIN_DOUBLE;
                        IncrementClippedCounter();
                    }
                    int iv = (int)(dv * 8388608.0);

                    if (writePad)
                    {
                        to[toPos++] = 0;
                    }
                    to[toPos++] = (byte)(iv & 0xff);
                    to[toPos++] = (byte)((iv >> 8) & 0xff);
                    to[toPos++] = (byte)((iv >> 16) & 0xff);
                    fromPos += 8;
                }
            }));
        }
        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);
        }
        /// <summary>
        /// WAVファイルのヘッダ部分を読み込む。
        /// </summary>
        /// <returns>読めたらtrue</returns>
        private bool ReadWavFileHeader(string path)
        {
            bool result = false;
            var  pd     = new PcmData();

            var wavR = new WavReader();

            using (BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))) {
                if (wavR.ReadHeader(br))
                {
                    // WAVヘッダ読み込み成功。PcmDataを作って再生リストに足す。

                    pd.SetFormat(wavR.NumChannels, wavR.BitsPerSample, wavR.ValidBitsPerSample,
                                 (int)wavR.SampleRate, wavR.SampleValueRepresentationType, wavR.NumFrames);

                    if (wavR.SampleDataType == WavReader.DataType.DoP)
                    {
                        pd.SampleDataType = PcmData.DataType.DoP;
                    }

                    if ("RIFFINFO_INAM".Equals(wavR.Title) &&
                        "RIFFINFO_IART".Equals(wavR.ArtistName))
                    {
                        // Issue 79 workaround
                    }
                    else
                    {
                        if (wavR.Title != null)
                        {
                            pd.DisplayName = wavR.Title;
                        }
                        if (wavR.AlbumName != null)
                        {
                            pd.AlbumTitle = wavR.AlbumName;
                        }
                        if (wavR.ArtistName != null)
                        {
                            pd.ArtistName = wavR.ArtistName;
                        }
                        if (wavR.ComposerName != null)
                        {
                            pd.ComposerName = wavR.ComposerName;
                        }
                    }
                    pd.SetPicture(wavR.PictureBytes, wavR.PictureData);
                    result = CheckAddPcmData(path, pd, true);
                }
                else
                {
                    LoadErrorMessageAdd(string.Format(CultureInfo.InvariantCulture, Properties.Resources.ReadFileFailed + ": {1} : {2}{3}",
                                                      "WAV", path, wavR.ErrorReason, Environment.NewLine));
                }
            }

            return(result);
        }
        /// <summary>
        /// 1曲再生のプレイリストをap.PcmDataListForPlayに作成。
        /// </summary>
        public void CreateOneTrackPlayList(int wavDataId)
        {
            var pcmData = new PcmData();

            pcmData.CopyFrom(m_pcmDataListForDisp.FindById(wavDataId));
            pcmData.GroupId = 0;

            m_pcmDataListForPlay = new PcmDataList();
            m_pcmDataListForPlay.Add(pcmData);
        }
 /// <summary>
 /// 全曲が表示順に並んでいる再生リストap.PcmDataListForPlayを作成。
 /// </summary>
 public void CreateAllTracksPlayList()
 {
     m_pcmDataListForPlay = new PcmDataList();
     for (int i = 0; i < m_pcmDataListForDisp.Count(); ++i)
     {
         var pcmData = new PcmData();
         pcmData.CopyFrom(m_pcmDataListForDisp.At(i));
         m_pcmDataListForPlay.Add(pcmData);
     }
 }
Beispiel #12
0
        public override void Perform(AudioData audio, PreviewImageQuery query)
        {
            int     desiredWidth  = query.DesiredWidth;
            int     desiredHeight = query.DesiredHeight;
            int     oggHash       = audio.OggVorbisData.GetCombinedHashCode();
            int     oggLen        = audio.OggVorbisData.Length;
            PcmData pcm           = OggVorbis.LoadChunkFromMemory(audio.OggVorbisData, 500000);

            short[] sdata  = pcm.data;
            short   maxVal = 1;

            for (int i = 0; i < pcm.dataLength; i++)
            {
                maxVal = Math.Max(maxVal, Math.Abs(pcm.data[i]));
            }

            Bitmap    result        = new Bitmap(desiredWidth, desiredHeight);
            int       channelLength = pcm.dataLength / pcm.channelCount;
            int       yMid          = result.Height / 2;
            int       stepWidth     = (channelLength / (2 * result.Width)) - 1;
            const int samples       = 10;

            using (Graphics g = Graphics.FromImage(result))
            {
                Color baseColor = ExtMethodsColor.ColorFromHSV(
                    (float)(oggHash % 90) * (float)(oggLen % 4) / 360.0f,
                    0.5f,
                    1f);
                Pen linePen = new Pen(Color.FromArgb(MathF.RoundToInt(255.0f / MathF.Pow((float)samples, 0.65f)), baseColor));
                g.Clear(Color.Transparent);
                for (int x = 0; x < result.Width; x++)
                {
                    float invMaxVal      = 2.0f / ((float)maxVal + (float)short.MaxValue);
                    float timePercentage = (float)x / (float)result.Width;
                    int   i = MathF.RoundToInt(timePercentage * channelLength);
                    float left;
                    float right;
                    short channel1;
                    short channel2;

                    for (int s = 0; s <= samples; s++)
                    {
                        int offset = stepWidth * s / samples;
                        channel1 = sdata[(i + offset) * pcm.channelCount + 0];
                        channel2 = sdata[(i + offset) * pcm.channelCount + 1];
                        left     = (float)Math.Abs(channel1) * invMaxVal;
                        right    = (float)Math.Abs(channel2) * invMaxVal;
                        g.DrawLine(linePen, x, yMid, x, yMid + MathF.RoundToInt(left * yMid));
                        g.DrawLine(linePen, x, yMid, x, yMid - MathF.RoundToInt(right * yMid));
                    }
                }
            }

            query.Result = result;
        }
Beispiel #13
0
 public SampleDataAsset(SampleHeader sample, SoundFontSampleData sampleData)
 {
     this.assetName  = sample.Name;
     this.sampleRate = sample.SampleRate;
     this.rootKey    = sample.RootKey;
     this.tune       = sample.Tune;
     this.start      = sample.Start;
     this.end        = sample.End;
     this.loopStart  = sample.StartLoop;
     this.loopEnd    = sample.EndLoop;
     this.sampleData = PcmData.Create(sampleData.BitsPerSample, sampleData.SampleData, true);
 }
Beispiel #14
0
        /// <summary>
        /// 読み込み処理を終了する。
        /// </summary>
        /// <returns>Error code</returns>
        public int StreamEnd()
        {
            int rv = 0;

            mMD5SumInMetadata = null;
            mMD5SumOfPcm      = null;

            switch (m_format)
            {
            case Format.FLAC:
                rv = mFlacR.ReadEnd();
                mMD5SumInMetadata = mFlacR.MD5SumInMetadata;
                mMD5SumOfPcm      = mFlacR.MD5SumOfPcm;
                break;

            case Format.AIFF:
                mAiffR.ReadStreamEnd();
                break;

            case Format.WAVE:
                mWaveR.ReadStreamEnd();
                break;

            case Format.DSF:
                mDsfR.ReadStreamEnd();
                break;

            case Format.DSDIFF:
                mDsdiffR.ReadStreamEnd();
                break;

            case Format.MP3:
                mMp3Reader.ReadStreamEnd();
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }

            if (null != mBr)
            {
                mBr.Close();
                mBr = null;
            }
            mPcmData = null;
            mFlacR   = null;
            mAiffR   = null;
            mWaveR   = null;
            mDsfR    = null;

            return(rv);
        }
Beispiel #15
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 #16
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();
        }
        private PcmData FlacScanDopMarker(PcmData pcmData, FlacDecodeIF fdif)
        {
            // 1個PCMデータを読み出す。
            int  ercd = 0;
            var  buff = fdif.ReadStreamReadOne(PcmDataLib.PcmData.DOP_SCAN_FRAMES, out ercd);
            bool bDoP = pcmData.ScanDopMarker(buff);

            if (bDoP)
            {
                pcmData.SampleDataType = PcmData.DataType.DoP;
            }

            return(pcmData);
        }
Beispiel #18
0
        public SampleDataAsset(SampleHeader sample, SoundFontSampleData sampleData)
        {
            Channels = 1;

            Name       = sample.Name;
            SampleRate = sample.SampleRate;
            RootKey    = sample.RootKey;
            Tune       = sample.Tune;
            Start      = sample.Start;
            End        = sample.End;
            LoopStart  = sample.StartLoop;
            LoopEnd    = sample.EndLoop;
            SampleData = PcmData.Create(sampleData.BitsPerSample, sampleData.SampleData, true);
        }
        private byte[] ConvI16toI24(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    // Lower 8-bit: fill 0s
                    to[toPos++] = 0;

                    // Higher 16-bit: copy PCM
                    to[toPos++] = from[fromPos++];
                    to[toPos++] = from[fromPos++];
                }
            }));
        }
        private byte[] ConvI32V24toI24(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    // truncate lower 8-bit of 32-bit PCM to create 24-bit PCM
                    to[toPos++] = from[fromPos + 1];
                    to[toPos++] = from[fromPos + 2];
                    to[toPos++] = from[fromPos + 3];

                    fromPos += 4;
                }
            }));
        }
        /// <summary>
        /// シャッフルした再生リストap.PcmDataListForPlayを作成する
        /// </summary>
        public void CreateShuffledPlayList()
        {
            // 適当にシャッフルされた番号が入っている配列pcmDataIdxArrayを作成。
            var pcmDataIdxArray = new int[PcmDataListForDisp.Count()];

            for (int i = 0; i < pcmDataIdxArray.Length; ++i)
            {
                pcmDataIdxArray[i] = i;
            }

            var gen = new RNGCryptoServiceProvider();
            int N   = pcmDataIdxArray.Length;

            for (int i = 0; i < N * 100; ++i)
            {
                var a = GetRandomNumber(gen, N);
                var b = GetRandomNumber(gen, N);
                if (a == b)
                {
                    // 入れ替え元と入れ替え先が同じ。あんまり意味ないのでスキップする。
                    continue;
                }

                // a番目とb番目を入れ替える
                var tmp = pcmDataIdxArray[a];
                pcmDataIdxArray[a] = pcmDataIdxArray[b];
                pcmDataIdxArray[b] = tmp;
            }

            // ap.PcmDataListForPlayを作成。
            m_pcmDataListForPlay = new PcmDataList();
            for (int i = 0; i < pcmDataIdxArray.Length; ++i)
            {
                var idx = pcmDataIdxArray[i];

                // 再生順番号Ordinalを付け直す
                // GroupIdをバラバラの番号にする(1曲ずつ読み込む)
                var pcmData = new PcmData();
                pcmData.CopyFrom(m_pcmDataListForDisp.At(idx));
                pcmData.Ordinal = i;
                pcmData.GroupId = i;

                m_pcmDataListForPlay.Add(pcmData);
            }
        }
        private byte[] ConvI32V24toI32(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    // discard lower 8-bit because it is garbage
                    to[toPos++] = 0;
                    to[toPos++] = from[fromPos + 1];
                    to[toPos++] = from[fromPos + 2];
                    to[toPos++] = from[fromPos + 3];

                    fromPos += 4;
                }
            }));
        }
Beispiel #23
0
        private PcmData ReadWavFile(string path)
        {
            PcmData pcmData = new PcmData();

            using (BinaryReader br = new BinaryReader(
                       File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))) {
                var  wavR        = new WavReader();
                bool readSuccess = wavR.ReadHeaderAndSamples(br, 0, -1);
                if (!readSuccess)
                {
                    return(null);
                }
                pcmData.SetFormat(wavR.NumChannels, wavR.BitsPerSample, wavR.BitsPerSample,
                                  wavR.SampleRate, wavR.SampleValueRepresentationType, wavR.NumFrames);
                pcmData.SetSampleArray(wavR.GetSampleArray());
            }

            return(pcmData);
        }
        private byte[] ConvF32toF64(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    float fv = System.BitConverter.ToSingle(from, fromPos);
                    double dv = (double)fv;

                    byte [] b = System.BitConverter.GetBytes(dv);
                    for (int j = 0; j < 8; ++j)
                    {
                        to[toPos++] = b[j];
                    }
                    fromPos += 4;
                }
            }));
        }
Beispiel #25
0
        public SampleDataAsset(int size, BinaryReader reader)
        {
            assetName  = IOHelper.Read8BitString(reader, 20);
            sampleRate = reader.ReadInt32();
            rootKey    = reader.ReadInt16();
            tune       = reader.ReadInt16();
            loopStart  = reader.ReadDouble();
            loopEnd    = reader.ReadDouble();
            byte bits  = reader.ReadByte();
            byte chans = reader.ReadByte();

            byte[] data = reader.ReadBytes(size - 46);
            if (chans != audioChannels) //reformat to supported channels
            {
                data = WaveHelper.GetChannelPcmData(data, bits, chans, audioChannels);
            }
            sampleData = PcmData.Create(bits, data, true);
            start      = 0;
            end        = sampleData.Length;
        }
Beispiel #26
0
        public SampleDataAsset(SampleHeader sample, SoundFontSampleData sampleData)
        {
            Channels = 1;

            Name       = sample.Name;
            SampleRate = sample.SampleRate;
            RootKey    = sample.RootKey;
            Tune       = sample.Tune;
            Start      = sample.Start;
            End        = sample.End;
            LoopStart  = sample.StartLoop;
            LoopEnd    = sample.EndLoop;
            if ((sample.SoundFontSampleLink & SFSampleLink.OggVobis) != 0)
            {
                throw new Exception("Ogg Vobis encoded soundfonts not supported");
            }
            else
            {
                SampleData = PcmData.Create(sampleData.BitsPerSample, sampleData.SampleData, true);
            }
        }
Beispiel #27
0
        public void StreamAbort()
        {
            switch (m_format)
            {
            case Format.FLAC:
                mFlacR.ReadStreamAbort();
                break;

            case Format.AIFF:
                mAiffR.ReadStreamEnd();
                break;

            case Format.WAVE:
                mWaveR.ReadStreamEnd();
                break;

            case Format.DSF:
                mDsfR.ReadStreamEnd();
                break;

            case Format.DSDIFF:
                mDsdiffR.ReadStreamEnd();
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }

            if (null != mBr)
            {
                mBr.Close();
                mBr = null;
            }
            mPcmData = null;
            mFlacR   = null;
            mAiffR   = null;
            mWaveR   = null;
            mDsfR    = null;
        }
        private byte[] ConvI16toF32(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    short iv = (short)(from[fromPos]
                                       + (from[fromPos + 1] << 8));
                    float fv = ((float)iv) * (1.0f / 32768.0f);

                    byte [] b = System.BitConverter.GetBytes(fv);

                    to[toPos++] = b[0];
                    to[toPos++] = b[1];
                    to[toPos++] = b[2];
                    to[toPos++] = b[3];
                    fromPos += 2;
                }
            }));
        }
        private byte[] ConvI16toF64(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            return(ConvCommon(pcmFrom, toFormat, args, (from, to, nSample, noiseShaping) => {
                int fromPos = 0;
                int toPos = 0;

                for (int i = 0; i < nSample; ++i)
                {
                    short iv = (short)(from[fromPos]
                                       + (from[fromPos + 1] << 8));
                    double dv = ((double)iv) * (1.0 / 32768.0);

                    byte [] b = System.BitConverter.GetBytes(dv);

                    for (int j = 0; j < 8; ++j)
                    {
                        to[toPos++] = b[j];
                    }
                    fromPos += 2;
                }
            }));
        }
Beispiel #30
0
        public static PcmData ReadWav(BinaryReader br)
        {
            var reader = new WavReader();

            if (!reader.ReadHeaderAndSamples(br, 0, -1))
            {
                return(null);
            }

            var pcm = new PcmData();

            pcm.AlbumTitle  = reader.AlbumName;
            pcm.ArtistName  = reader.ArtistName;
            pcm.DisplayName = reader.Title;

            pcm.SetFormat(reader.NumChannels, reader.BitsPerSample,
                          reader.ValidBitsPerSample, reader.SampleRate,
                          reader.SampleValueRepresentationType, reader.NumFrames);

            pcm.SetSampleArray(reader.GetSampleArray());

            return(pcm);
        }
Beispiel #31
0
		// --- functions ---
		
		/// <summary>Reads wave data from a RIFF/WAVE/PCM file.</summary>
		/// <param name="fileName">The file name of the RIFF/WAVE/PCM file.</param>
		/// <returns>The wave data.</returns>
		/// <remarks>Both RIFF and RIFX container formats are supported by this function.</remarks>
		internal static WaveData LoadFromFile(string fileName) {
			string fileTitle = Path.GetFileName(fileName);
			byte[] fileBytes = File.ReadAllBytes(fileName);
			using (MemoryStream stream = new MemoryStream(fileBytes)) {
				using (BinaryReader reader = new BinaryReader(stream)) {
					// RIFF/RIFX chunk
					Endianness endianness;
					uint headerCkID = reader.ReadUInt32(); /* Chunk ID is character-based */
					if (headerCkID == 0x46464952) {
						endianness = Endianness.Little;
					} else if (headerCkID == 0x58464952) {
						endianness = Endianness.Big;
					} else {
						throw new InvalidDataException("Invalid chunk ID in " + fileTitle);
					}
					uint headerCkSize = ReadUInt32(reader, endianness);
					uint formType = ReadUInt32(reader, endianness);
					if (formType != 0x45564157) {
						throw new InvalidDataException("Unsupported format in " + fileTitle);
					}
					// data chunks
					WaveFormat format = new WaveFormat();
					FormatData data = null;
					byte[] dataBytes = null;
					while (stream.Position + 8 <= stream.Length) {
						uint ckID = reader.ReadUInt32(); /* Chunk ID is character-based */
						uint ckSize = ReadUInt32(reader, endianness);
						if (ckID == 0x20746d66) {
							// "fmt " chunk
							if (ckSize < 14) {
								throw new InvalidDataException("Unsupported fmt chunk size in " + fileTitle);
							}
							ushort wFormatTag = ReadUInt16(reader, endianness);
							ushort wChannels = ReadUInt16(reader, endianness);
							uint dwSamplesPerSec = ReadUInt32(reader, endianness);
							if (dwSamplesPerSec >= 0x80000000) {
								throw new InvalidDataException("Unsupported dwSamplesPerSec in " + fileTitle);
							}
							uint dwAvgBytesPerSec = ReadUInt32(reader, endianness);
							ushort wBlockAlign = ReadUInt16(reader, endianness);
							if (wFormatTag == 1) {
								// PCM
								if (ckSize < 16) {
									throw new InvalidDataException("Unsupported fmt chunk size in " + fileTitle);
								}
								ushort wBitsPerSample = ReadUInt16(reader, endianness);
								stream.Position += ckSize - 16;
								if (wBitsPerSample < 1) {
									throw new InvalidDataException("Unsupported wBitsPerSample in " + fileTitle);
								}
								if (wBlockAlign != ((wBitsPerSample + 7) / 8) * wChannels) {
									throw new InvalidDataException("Unexpected wBlockAlign in " + fileTitle);
								}
								format.SampleRate = (int)dwSamplesPerSec;
								format.BitsPerSample = (int)wBitsPerSample;
								format.Channels = (int)wChannels;
								PcmData pcmData = new PcmData();
								pcmData.BlockSize = (int)wBlockAlign;
								data = pcmData;
							} else if (wFormatTag == 2) {
								// Microsoft ADPCM
								if (ckSize < 22) {
									throw new InvalidDataException("Unsupported fmt chunk size in " + fileTitle);
								}
								ushort wBitsPerSample = ReadUInt16(reader, endianness);
								if (wBitsPerSample != 4) {
									throw new InvalidDataException("Unsupported wBitsPerSample in " + fileTitle);
								}
								ushort cbSize = ReadUInt16(reader, endianness);
								MicrosoftAdPcmData adpcmData = new MicrosoftAdPcmData();
								adpcmData.SamplesPerBlock = ReadUInt16(reader, endianness);
								if (adpcmData.SamplesPerBlock == 0 | adpcmData.SamplesPerBlock > 2 * ((int)wBlockAlign - 6)) {
									throw new InvalidDataException("Unexpected nSamplesPerBlock in " + fileTitle);
								}
								ushort wNumCoef = ReadUInt16(reader, endianness);
								if (ckSize < 22 + 4 * wNumCoef) {
									throw new InvalidDataException("Unsupported fmt chunk size in " + fileTitle);
								}
								adpcmData.Coefficients = new short[wNumCoef][];
								for (int i = 0; i < wNumCoef; i++) {
									unchecked {
										adpcmData.Coefficients[i] = new short[] {
											(short)ReadUInt16(reader, endianness),
											(short)ReadUInt16(reader, endianness)
										};
									}
								}
								stream.Position += ckSize - (22 + 4 * wNumCoef);
								format.SampleRate = (int)dwSamplesPerSec;
								format.BitsPerSample = 16;
								format.Channels = (int)wChannels;
								adpcmData.BlockSize = wBlockAlign;
								data = adpcmData;
							} else {
								// unsupported format
								throw new InvalidDataException("Unsupported wFormatTag in " + fileTitle);
							}
						} else if (ckID == 0x61746164) {
							// "data" chunk
							if (ckSize >= 0x80000000) {
								throw new InvalidDataException("Unsupported data chunk size in " + fileTitle);
							}
							if (data is PcmData) {
								// PCM
								int bytesPerSample = (format.BitsPerSample + 7) / 8;
								int samples = (int)ckSize / (format.Channels * bytesPerSample);
								int dataSize = samples * format.Channels * bytesPerSample;
								dataBytes = reader.ReadBytes(dataSize);
								stream.Position += ckSize - dataSize;
							} else if (data is MicrosoftAdPcmData) {
								// Microsoft ADPCM
								MicrosoftAdPcmData adpcmData = (MicrosoftAdPcmData)data;
								int blocks = (int)ckSize / adpcmData.BlockSize;
								dataBytes = new byte[2 * blocks * format.Channels * adpcmData.SamplesPerBlock];
								int position = 0;
								for (int i = 0; i < blocks; i++) {
									unchecked {
										MicrosoftAdPcmData.ChannelData[] channelData = new MicrosoftAdPcmData.ChannelData[format.Channels];
										for (int j = 0; j < format.Channels; j++) {
											channelData[j].bPredictor = (int)reader.ReadByte();
											if (channelData[j].bPredictor >= adpcmData.Coefficients.Length) {
												throw new InvalidDataException("Invalid bPredictor in " + fileTitle);
											}
											channelData[j].iCoef1 = (int)adpcmData.Coefficients[channelData[j].bPredictor][0];
											channelData[j].iCoef2 = (int)adpcmData.Coefficients[channelData[j].bPredictor][1];
										}
										for (int j = 0; j < format.Channels; j++) {
											channelData[j].iDelta = (short)ReadUInt16(reader, endianness);
										}
										for (int j = 0; j < format.Channels; j++) {
											channelData[j].iSamp1 = (short)ReadUInt16(reader, endianness);
										}
										for (int j = 0; j < format.Channels; j++) {
											channelData[j].iSamp2 = (short)ReadUInt16(reader, endianness);
										}
										for (int j = 0; j < format.Channels; j++) {
											dataBytes[position] = (byte)(ushort)channelData[j].iSamp2;
											dataBytes[position + 1] = (byte)((ushort)channelData[j].iSamp2 >> 8);
											position += 2;
										}
										for (int j = 0; j < format.Channels; j++) {
											dataBytes[position] = (byte)(ushort)channelData[j].iSamp1;
											dataBytes[position + 1] = (byte)((ushort)channelData[j].iSamp1 >> 8);
											position += 2;
										}
										uint nibbleByte = 0;
										bool nibbleFirst = true;
										for (int j = 0; j < adpcmData.SamplesPerBlock - 2; j++) {
											for (int k = 0; k < format.Channels; k++) {
												int lPredSample =
													(int)channelData[k].iSamp1 * channelData[k].iCoef1 +
													(int)channelData[k].iSamp2 * channelData[k].iCoef2 >> 8;
												int iErrorDeltaUnsigned;
												if (nibbleFirst) {
													nibbleByte = (uint)reader.ReadByte();
													iErrorDeltaUnsigned = (int)(nibbleByte >> 4);
													nibbleFirst = false;
												} else {
													iErrorDeltaUnsigned = (int)(nibbleByte & 15);
													nibbleFirst = true;
												}
												int iErrorDeltaSigned =
													iErrorDeltaUnsigned >= 8 ? iErrorDeltaUnsigned - 16 : iErrorDeltaUnsigned;
												int lNewSampInt =
													lPredSample + (int)channelData[k].iDelta * iErrorDeltaSigned;
												short lNewSamp =
													lNewSampInt <= -32768 ? (short)-32768 :
													lNewSampInt >= 32767 ? (short)32767 :
													(short)lNewSampInt;
												channelData[k].iDelta = (short)(
													(int)channelData[k].iDelta *
													(int)MicrosoftAdPcmData.AdaptionTable[iErrorDeltaUnsigned] >> 8
												);
												if (channelData[k].iDelta < 16) {
													channelData[k].iDelta = 16;
												}
												channelData[k].iSamp2 = channelData[k].iSamp1;
												channelData[k].iSamp1 = lNewSamp;
												dataBytes[position] = (byte)(ushort)lNewSamp;
												dataBytes[position + 1] = (byte)((ushort)lNewSamp >> 8);
												position += 2;
											}
										}
									}
									stream.Position += adpcmData.BlockSize - (format.Channels * (adpcmData.SamplesPerBlock - 2) + 1 >> 1) - 7 * format.Channels;
								}
								stream.Position += (int)ckSize - blocks * adpcmData.BlockSize;
							} else {
								// invalid
								throw new InvalidDataException("No fmt chunk before the data chunk in " + fileTitle);
							}
						} else {
							// unsupported chunk
							stream.Position += (long)ckSize;
						}
						// pad byte
						if ((ckSize & 1) == 1) {
							stream.Position++;
						}
					}
					// finalize
					if (dataBytes == null)
						throw new InvalidDataException("No data chunk before the end of the file in " + fileTitle);
					return new WaveData(format, dataBytes);
				}
			}
		}