public void Setup(WWFlacRWCS.Metadata metaW, byte[] picture) { mDsfW = new WWDsfRW.WWDsfWriter(); mDsfW.EncodeInit(metaW); if (picture != null) { mDsfW.EncodeSetPicture(picture); } // サンプルデータ置き場。 mSampleData = new SampleData1ch[metaW.channels]; for (int ch = 0; ch < metaW.channels; ++ch) { mSampleData[ch] = new SampleData1ch((metaW.totalSamples + 7) / 8); } // ノイズシェイピングフィルターmLoopFiltersを作る。 mLoopFilter.Design(FILTER_ORDER, metaW.channels); if (FILTER_ORDER == 5) { mLoopFilter.SetDelayValues( new double[] { 1.43681852625616E-06, -9.4526383335642E-05, -0.00124416475447812, -0.00212062453327017, 0.0391562027012161, } ); } }
private long FlacWriteConvertTo24bitPcm(double [] y, WWFlacRWCS.Metadata metaW, LargeArray <byte> pcmW, long posY) { var yPcm = ConvertToIntegerPcm(y, metaW.BytesPerSample); pcmW.CopyFrom(yPcm, 0, posY, yPcm.Length); posY += yPcm.Length; return(posY); }
public void Setup(WWFlacRWCS.Metadata metaW, byte[] picture) { mFlacW = new WWFlacRWCS.FlacRW(); mFlacW.EncodeInit(metaW); if (picture != null) { mFlacW.EncodeSetPicture(picture); } }
// FLACからPCMのバイト列を取得し、最大値1のdouble型のサンプル値の配列を作る。 private double[] InputSamples(WWFlacRWCS.FlacRW flacR, WWFlacRWCS.Metadata meta, int ch, long posSamples, int nSamples) { // 1ch分のnサンプルのPCMデータ。 int nBytes = nSamples * meta.BytesPerSample; var pcm = new byte[nBytes]; nSamples = flacR.GetPcmOfChannel(ch, posSamples, ref pcm, nSamples); if (nSamples <= 0) { return(new double[0]); } double[] result = new double[nSamples]; switch (meta.bitsPerSample) { case 16: for (int i = 0; i < nSamples; ++i) { short v = (short)(pcm[i * 2] + (pcm[i * 2 + 1] << 8)); result[i] = v / 32768.0; } break; case 20: case 24: for (int i = 0; i < nSamples; ++i) { int v = (int)((pcm[i * 3] << 8) + (pcm[i * 3 + 1] << 16) + (pcm[i * 3 + 2] << 24)); result[i] = v / 2147483648.0; } break; default: throw new NotSupportedException(); } return(result); }
public int EncodeInit(WWFlacRWCS.Metadata meta) { mMeta = meta; mDsdData = new List<byte[]>(); return 0; }
public void EncodeEnd() { mDsdData = null; mPictureData = null; mMeta = null; }
public RunWorkerCompletedResult BackgroundDoWorkImpl(DoWorkEventArgs e, string rootPath, bool background) { mContentList.Clear(); var result = new RunWorkerCompletedResult(); result.fileCount = 0; result.path = rootPath; if (background) { mBw.ReportProgress(0, new ReportProgressArgs(string.Format(Properties.Resources.LogCountingFiles, rootPath))); } var flacList = WWUtil.DirectoryUtil.CollectFilesOnFolder(rootPath, ".FLAC"); if (background) { mBw.ReportProgress(0, new ReportProgressArgs(string.Format(Properties.Resources.LogReportCount, flacList.Length))); } if (mBw.CancellationPending) { Console.WriteLine("D: BackgroundContentListBuilder::BackgroundDoWorkImpl() canceled 1"); e.Cancel = true; return(result); } int finished = 0; mStopWatch.Start(); // Parallel.Forにした時はforの中に持っていく必要あり。 if (background) { System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest; } try { for (int i = 0; i < flacList.Length; ++i) { if (mBw.CancellationPending) { Console.WriteLine("D: BackgroundContentListBuilder::BackgroundDoWorkImpl() canceled 2"); e.Cancel = true; return(result); } string path = flacList[i]; var flacrw = new WWFlacRWCS.FlacRW(); int ercd = flacrw.DecodeHeader(path); lock (mBw) { if (0 <= ercd) { ++result.fileCount; var m = new WWFlacRWCS.Metadata(); flacrw.GetDecodedMetadata(out m); var pic = new byte[0]; if (0 < m.pictureBytes) { pic = new byte[m.pictureBytes]; flacrw.GetDecodedPicture(out pic, m.pictureBytes); } mContentList.Add(path, m.titleStr, 1, m.albumStr, m.artistStr, pic, m.channels, m.bitsPerSample, m.sampleRate, m.PcmBytes / (m.channels * m.bitsPerSample / 8)); } else { Console.WriteLine("FLAC decode failed {0} {1}", WWFlacRWCS.FlacRW.ErrorCodeToStr(ercd), path); } flacrw.DecodeEnd(); ++finished; if (1000 < mStopWatch.ElapsedMilliseconds) { if (background) { var text = string.Format(Properties.Resources.LogCreatingMusicList, 100 * finished / flacList.Length); mBw.ReportProgress((int)(1000000L * finished / flacList.Length), new ReportProgressArgs(text)); } mStopWatch.Restart(); } } } } catch (System.IO.IOException ex) { //Console.WriteLine(ex); } catch (System.Exception ex) { Console.WriteLine(ex); } mStopWatch.Stop(); return(result); }
public void EncodeEnd() { mSdmData = null; mPictureData = null; mMeta = null; }
public int EncodeInit(WWFlacRWCS.Metadata meta) { mMeta = meta; mSdmData = new List <WWUtil.LargeArray <byte> >(); return(0); }
public int EncodeInit(WWFlacRWCS.Metadata meta) { mMeta = meta; mDsdData = new List <byte[]>(); return(0); }
public BWCompletedParam DoWork(BWStartParams param, ProgressReportDelegate ReportProgress) { int rv = 0; var flacR = new WWFlacRWCS.FlacRW(); do { // FLACファイルからメタデータ、画像、音声を取り出す。 WWFlacRWCS.Metadata metaR; rv = flacR.DecodeAll(param.inputFile); if (rv < 0) { // do-whileを抜けたところでflacR.DecodeEndする。 break; } flacR.GetDecodedMetadata(out metaR); byte[] picture = null; if (0 < metaR.pictureBytes) { rv = flacR.GetDecodedPicture(out picture, metaR.pictureBytes); if (rv < 0) { // do-whileを抜けたところでflacR.DecodeEndする。 break; } } // flacRはまだ使用するのでここではDecodeEndしない。 long lcm = WWMath.Functions.LCM(metaR.sampleRate, param.targetSampleRate); int upsampleScale = (int)(lcm / metaR.sampleRate); int downsampleScale = (int)(lcm / param.targetSampleRate); // IIRフィルターを設計。 // ストップバンド最小周波数fs。 double fs = metaR.sampleRate / 2 * STOPBAND_FREQ_RATIO; if (param.targetSampleRate / 2 * STOPBAND_FREQ_RATIO < fs) { fs = param.targetSampleRate / 2 * STOPBAND_FREQ_RATIO; } // カットオフ周波数fc。 double fc = CUTOFF_STOPBAND_RATIO * fs; mIIRFilterDesign = new IIRFilterDesign(); mIIRFilterDesign.Design(fc, fs, lcm, param.method); ReportProgress(CONVERT_START_PERCENT, new BWProgressParam(State.FilterDesigned, string.Format("Read FLAC completed.\nSource sample rate = {0}kHz.\nTarget sample rate = {1}kHz. ratio={2}/{3}\n", metaR.sampleRate / 1000.0, param.targetSampleRate / 1000.0, lcm / metaR.sampleRate, lcm / param.targetSampleRate))); double RESAMPLE_RATIO = param.targetSampleRate / metaR.sampleRate; mSw.Restart(); // 書き込み準備。 WWFlacRWCS.Metadata metaW = new WWFlacRWCS.Metadata(metaR); metaW.sampleRate = param.targetSampleRate; metaW.pictureBytes = metaR.pictureBytes; metaW.bitsPerSample = 24; metaW.totalSamples = metaR.totalSamples * upsampleScale / downsampleScale; if (param.isTargetPcm) { mFlacWrite = new FlacWrite(); mFlacWrite.Setup(metaW, picture); } else { mDsfWrite = new DsfWrite(); mDsfWrite.Setup(metaW, picture); } var stat = new SampleValueStatistics(); long totalSamplesOfAllChannels = metaR.totalSamples * metaR.channels; long processedSamples = 0; // Mathematica用の設定。 WWComplex.imaginaryUnit = "I"; // 変換する for (int ch = 0; ch < metaR.channels; ++ch) { //Parallel.For(0, metaR.channels, (int ch) => { var pcmW = new WWUtil.LargeArray <byte>(metaW.totalSamples * metaW.BytesPerSample); #if USE_ZOH_UPSAMPLE // 零次ホールドのハイ落ち補償フィルター。 # if USE_CPP var zohCompensation = new WWFilterCpp(); zohCompensation.BuildZohCompensation(); # else var zohCompensation = new WWIIRFilterDesign.ZohNosdacCompensation(33); # endif