/// <summary> /// FLACファイルからPCMデータを取り出し開始。 /// </summary> /// <param name="flacFilePath">読み込むファイルパス。</param> /// <param name="skipFrames">ファイルの先頭からのスキップするフレーム数。0以外の値を指定するとMD5のチェックが行われなくなる。</param> /// <param name="pcmData">出てきたデコード後のPCMデータ。</param> /// <returns>0: 成功。負: 失敗。</returns> public int ReadStreamBegin(string flacFilePath, long skipFrames, out PcmDataLib.PcmData pcmData_return) { pcmData_return = new PcmDataLib.PcmData(); mFlacRW = new WWFlacRWCS.FlacRW(); // ここでファイルをオープンし、メタデータ部分を読み込んで // ストリームデータの頭のところでFLACデコードを止める。 int ercd = mFlacRW.DecodeStreamStart(flacFilePath); if (ercd < 0) { return(ercd); } CreatePcmData(flacFilePath, mFlacRW, out pcmData_return); mNumFrames = pcmData_return.NumFrames; mBytesPerFrame = pcmData_return.BitsPerFrame / 8; // ストリームデータを頭出しする。 if (0 < skipFrames) { mFlacRW.DecodeStreamSeekAbsolute(skipFrames); } if (CalcMD5 && skipFrames == 0) { md5 = new MD5CryptoServiceProvider(); mMD5SumOfPcm = new byte[MD5_BYTES]; mMD5TmpBuffer = new byte[WWFlacRWCS.FlacRW.PCM_FRAGMENT_BUFFER_BYTES]; } return(0); }
public void LoadAddEnd(ContentList.AudioFile af) { SetSampleDataToWasapiEnd(af.Idx, mFlac); mLoadedGroupId = af.GroupId; mFlac.DecodeEnd(); mFlac = null; }
public void Setup(WWFlacRWCS.Metadata metaW, byte[] picture) { mFlacW = new WWFlacRWCS.FlacRW(); mFlacW.EncodeInit(metaW); if (picture != null) { mFlacW.EncodeSetPicture(picture); } }
public void ReadStreamAbort() { mFlacRW.DecodeEnd(); mFlacRW = null; if (md5 != null) { md5.Dispose(); md5 = null; mMD5TmpBuffer = null; } }
private static int ReadFlacFile(string path, out AudioData ad) { ad = new AudioData(); var flac = new WWFlacRWCS.FlacRW(); int rv = flac.DecodeAll(path); if (rv < 0) { return(rv); } rv = flac.GetDecodedMetadata(out ad.meta); if (rv < 0) { return(rv); } rv = flac.GetDecodedPicture(out ad.picture, ad.meta.pictureBytes); if (rv < 0) { return(rv); } ad.pcm = new List <AudioDataPerChannel>(); for (int ch = 0; ch < ad.meta.channels; ++ch) { byte[] pcm; long lrv = flac.GetDecodedPcmBytes(ch, 0, out pcm, ad.meta.totalSamples * (ad.meta.bitsPerSample / 8)); if (lrv < 0) { return((int)lrv); } var pcm24 = PcmDataLib.Util.ConvertTo24bit(ad.meta.bitsPerSample, ad.meta.totalSamples, PcmDataLib.PcmData.ValueRepresentationType.SInt, pcm); var adp = new AudioDataPerChannel(); adp.data = pcm24; adp.offsBytes = 0; adp.bitsPerSample = 24; adp.totalSamples = ad.meta.totalSamples; ad.pcm.Add(adp); } // converted to 24bit ad.meta.bitsPerSample = 24; ad.preferredSaveFormat = FileFormatType.FLAC; flac.DecodeEnd(); return(0); }
/// <returns>負の値: FLACのエラー FlacErrorCode</returns> public int LoadAddStart(ContentList.AudioFile af) { mFlac = new WWFlacRWCS.FlacRW(); int ercd = mFlac.DecodeStreamStart(af.Path); if (ercd < 0) { return(ercd); } SetSampleDataToWasapiStart(af.Idx, mFlac); return(ercd); }
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 static int ReadFlacFile(string path, out AudioData ad) { ad = new AudioData(); ad.fileFormat = FileFormatType.FLAC; var flac = new WWFlacRWCS.FlacRW(); int rv = flac.DecodeAll(path); if (rv < 0) { return(rv); } rv = flac.GetDecodedMetadata(out ad.meta); if (rv < 0) { return(rv); } rv = flac.GetDecodedPicture(out ad.picture, ad.meta.pictureBytes); if (rv < 0) { return(rv); } ad.pcm = new List <AudioDataPerChannel>(); for (int ch = 0; ch < ad.meta.channels; ++ch) { byte[] data; long lrv = flac.GetDecodedPcmBytes(ch, 0, out data, ad.meta.totalSamples * (ad.meta.bitsPerSample / 8)); if (lrv < 0) { return((int)lrv); } var adp = new AudioDataPerChannel(); adp.data = data; adp.offsBytes = 0; adp.bitsPerSample = ad.meta.bitsPerSample; adp.totalSamples = ad.meta.totalSamples; ad.pcm.Add(adp); } flac.DecodeEnd(); return(0); }
public int ReadEnd() { mFlacRW.DecodeEnd(); mFlacRW = null; if (md5 != null) { md5.TransformFinalBlock(new byte[0], 0, 0); mMD5SumOfPcm = md5.Hash; md5.Dispose(); md5 = null; mMD5TmpBuffer = null; } return(0); }
/// <returns>負の値: FLACのエラー FlacErrorCode</returns> public int LoadAddStart(ContentList.AudioFile af) { mFlac = new WWFlacRWCS.FlacRW(); int ercd = mFlac.DecodeStreamStart(af.Path); if (ercd < 0) { return(ercd); } int hr = SetSampleDataToWasapiStart(af.Idx, mFlac); if (hr < 0) { ercd = (int)WWFlacRWCS.FlacErrorCode.Other; } return(ercd); }
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 CreatePcmData(string path, WWFlacRWCS.FlacRW flacRW, out PcmDataLib.PcmData pcmData_return) { pcmData_return = new PcmDataLib.PcmData(); WWFlacRWCS.Metadata m; flacRW.GetDecodedMetadata(out m); pcmData_return.SetFormat(m.channels, m.bitsPerSample, m.bitsPerSample, m.sampleRate, PcmDataLib.PcmData.ValueRepresentationType.SInt, m.totalSamples); pcmData_return.SampleDataType = PcmDataLib.PcmData.DataType.PCM; pcmData_return.DisplayName = m.titleStr; pcmData_return.AlbumTitle = m.albumStr; pcmData_return.ArtistName = m.artistStr; pcmData_return.ComposerName = m.composerStr; pcmData_return.FullPath = path; mMD5SumInMetadata = new byte[MD5_BYTES]; Array.Copy(m.md5sum, mMD5SumInMetadata, MD5_BYTES); bool allZero = true; for (int i = 0; i < MD5_BYTES; ++i) { if (m.md5sum[i] != 0) { allZero = false; break; } } md5MetaAvailable = !allZero; if (0 < m.pictureBytes) { byte[] picture; flacRW.GetDecodedPicture(out picture, m.pictureBytes); pcmData_return.SetPicture(picture.Length, picture); } }
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 InspectOneFile(string path, int numFiles) { var flacrw = new WWFlacRWCS.FlacRW(); var result = flacrw.CheckIntegrity(path); int ercd = result.rv; lock (mBw) { if (ercd < 0) { ++mBackgroundResult.corrupted; } else { ++mBackgroundResult.ok; } ++mFinished; if (result.totalSamplesUnknown) { mSbLog.AppendLine(string.Format("FLAC Metadata total_samples field is Unknown : {0}", path)); } if (ercd < 0) { mSbLog.AppendLine(string.Format("({0}/{1}) {2} : {3}\n", mFinished, numFiles, WWFlacRWCS.FlacRW.ErrorCodeToStr(ercd), path)); } if (UPDATE_INTERVAL_MILLISEC < (mStopwatch.ElapsedMilliseconds - mLastUpdateMillisec)) { mLastUpdateMillisec = mStopwatch.ElapsedMilliseconds; mBw.ReportProgress((int)(1000000L * mFinished / numFiles), new ReportProgressArgs("", 0, true)); } } }
private static int WriteFlacFile(ref AudioData ad, string path) { int rv; var flac = new WWFlacRWCS.FlacRW(); rv = flac.EncodeInit(ad.meta); if (rv < 0) { return(rv); } rv = flac.EncodeSetPicture(ad.picture); if (rv < 0) { flac.EncodeEnd(); return(rv); } for (int ch = 0; ch < ad.meta.channels; ++ch) { long lrv = flac.EncodeAddPcm(ch, ad.pcm[ch].data); if (lrv < 0) { flac.EncodeEnd(); return((int)lrv); } } rv = flac.EncodeRun(path); if (rv < 0) { flac.EncodeEnd(); return(rv); } flac.EncodeEnd(); return(0); }
/// <summary> /// この後ReadEndを呼んで終了して下さい。 /// </summary> public int ReadHeader(string flacFilePath, out PcmDataLib.PcmData pcmData_return, out List <WWFlacRWCS.FlacCuesheetTrack> cueSheet_return) { pcmData_return = new PcmDataLib.PcmData(); cueSheet_return = new List <WWFlacRWCS.FlacCuesheetTrack>(); mFlacRW = new WWFlacRWCS.FlacRW(); int ercd = mFlacRW.DecodeHeader(flacFilePath); if (ercd < 0) { return(ercd); } mFlacRW.GetDecodedCuesheet(out cueSheet_return); CreatePcmData(flacFilePath, mFlacRW, out pcmData_return); mBytesPerFrame = pcmData_return.BitsPerFrame / 8; mNumFrames = pcmData_return.NumFrames; return(0); }
// 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); }
private static int WriteFlacFile(ref AudioData ad, string path) { int rv; var flac = new WWFlacRWCS.FlacRW(); rv = flac.EncodeInit(ad.meta); if (rv < 0) { return rv; } rv = flac.EncodeSetPicture(ad.picture); if (rv < 0) { flac.EncodeEnd(); return rv; } for (int ch=0; ch < ad.meta.channels; ++ch) { long lrv = flac.EncodeAddPcm(ch, ad.pcm[ch].data); if (lrv < 0) { flac.EncodeEnd(); return (int)lrv; } } rv = flac.EncodeRun(path); if (rv < 0) { flac.EncodeEnd(); return rv; } flac.EncodeEnd(); return 0; }
private static int ReadFlacFile(string path, out AudioData ad) { ad = new AudioData(); ad.fileFormat = FileFormatType.FLAC; var flac = new WWFlacRWCS.FlacRW(); int rv = flac.DecodeAll(path); if (rv < 0) { return rv; } rv = flac.GetDecodedMetadata(out ad.meta); if (rv < 0) { return rv; } rv = flac.GetDecodedPicture(out ad.picture, ad.meta.pictureBytes); if (rv < 0) { return rv; } ad.pcm = new List<AudioDataPerChannel>(); for (int ch=0; ch < ad.meta.channels; ++ch) { byte [] data; long lrv = flac.GetDecodedPcmBytes(ch, 0, out data, ad.meta.totalSamples * (ad.meta.bitsPerSample / 8)); if (lrv < 0) { return (int)lrv; } var adp = new AudioDataPerChannel(); adp.data = data; adp.offsBytes = 0; adp.bitsPerSample = ad.meta.bitsPerSample; adp.totalSamples = ad.meta.totalSamples; ad.pcm.Add(adp); } flac.DecodeEnd(); return 0; }
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); }
private void SetSampleDataToWasapiEnd(int idx, WWFlacRWCS.FlacRW flac) { mFromFormat = null; mDecodedPcmOffs = 0; }
private void LoadPcm_DoWork(object sender, DoWorkEventArgs e) { string path = (string)e.Argument; var r = new LoadPcmResult(); r.path = path; r.result = false; r.pcmData = null; mPlayPcmData = null; try { using (var br = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))) { var reader = new WavRWLib2.WavReader(); if (reader.ReadHeaderAndSamples(br, 0, -1) && reader.NumChannels == NUM_CHANNELS) { var b = reader.GetSampleLargeArray(); r.pcmData = new PcmDataLib.PcmData(); r.pcmData.SetFormat(NUM_CHANNELS, reader.BitsPerSample, reader.ValidBitsPerSample, reader.SampleRate, reader.SampleValueRepresentationType, reader.NumFrames); r.pcmData.SetSampleLargeArray(b); } } } catch (Exception ex) { Console.WriteLine(ex); r.pcmData = null; } if (r.pcmData == null) { try { var flacRW = new WWFlacRWCS.FlacRW(); int rv = flacRW.DecodeAll(r.path); if (0 <= rv) { WWFlacRWCS.Metadata metaData; flacRW.GetDecodedMetadata(out metaData); if (metaData.channels == NUM_CHANNELS) { var pcmBytes = new LargeArray <byte>(metaData.PcmBytes); int bytesPerSample = metaData.bitsPerSample / 8; var fragment = new byte[bytesPerSample]; for (long pos = 0; pos < metaData.totalSamples; ++pos) { for (int ch = 0; ch < NUM_CHANNELS; ++ch) { flacRW.GetDecodedPcmBytes(ch, pos * bytesPerSample, out fragment, bytesPerSample); pcmBytes.CopyFrom(fragment, 0, (long)bytesPerSample * (NUM_CHANNELS * pos + ch), bytesPerSample); } } r.pcmData = new PcmDataLib.PcmData(); r.pcmData.SetFormat(NUM_CHANNELS, metaData.bitsPerSample, metaData.bitsPerSample, metaData.sampleRate, PcmDataLib.PcmData.ValueRepresentationType.SInt, metaData.totalSamples); r.pcmData.SetSampleLargeArray(pcmBytes); } } flacRW.DecodeEnd(); } catch (Exception ex) { Console.WriteLine(ex); r.pcmData = null; } } if (r.pcmData != null) { r.result = true; } else { r.result = false; } e.Result = r; }
private static int ReadFlacFile(string path, out AudioData ad) { ad = new AudioData(); var flac = new WWFlacRWCS.FlacRW(); int rv = flac.DecodeAll(path); if (rv < 0) { return rv; } rv = flac.GetDecodedMetadata(out ad.meta); if (rv < 0) { return rv; } rv = flac.GetDecodedPicture(out ad.picture, ad.meta.pictureBytes); if (rv < 0) { return rv; } ad.pcm = new List<AudioDataPerChannel>(); for (int ch = 0; ch < ad.meta.channels; ++ch) { byte[] pcm; long lrv = flac.GetDecodedPcmBytes(ch, 0, out pcm, ad.meta.totalSamples * (ad.meta.bitsPerSample / 8)); if (lrv < 0) { return (int)lrv; } var pcm24 = PcmDataLib.Util.ConvertTo24bit(ad.meta.bitsPerSample, ad.meta.totalSamples, PcmDataLib.PcmData.ValueRepresentationType.SInt, pcm); var adp = new AudioDataPerChannel(); adp.data = pcm24; adp.offsBytes = 0; adp.bitsPerSample = 24; adp.totalSamples = ad.meta.totalSamples; ad.pcm.Add(adp); } // converted to 24bit ad.meta.bitsPerSample = 24; ad.preferredSaveFormat = FileFormatType.FLAC; flac.DecodeEnd(); return 0; }
public static int ReadFlacFile(string path, out AudioData ad) { ad = new AudioData(); var flac = new WWFlacRWCS.FlacRW(); int rv = flac.DecodeAll(path); if (rv < 0) { MessageBox.Show( string.Format("Error: Failed to read FLAC file: {0}", path)); return(rv); } rv = flac.GetDecodedMetadata(out ad.meta); if (rv < 0) { return(rv); } rv = flac.GetDecodedPicture(out ad.picture, ad.meta.pictureBytes); if (rv < 0) { return(rv); } // ad.pcmにPCMデータを入れる。 int bpf = ad.meta.BytesPerFrame; int bps = ad.meta.BytesPerSample; int fragmentSamples = 4096; int fragmentBytes = fragmentSamples * bps; var fragment = new byte[fragmentBytes]; ad.pcm = new List <AudioDataPerChannel>(); for (int ch = 0; ch < ad.meta.channels; ++ch) { // ■■■ 1チャンネル分のpcmを取り出す。■■■ long oneChannelPcmBytes = ad.meta.totalSamples * bps; var pcm = new WWUtil.LargeArray <byte>(oneChannelPcmBytes); for (long posS = 0; posS < ad.meta.totalSamples;) { // copySamples : コピーするサンプル数を決定する。 int copySamples = fragmentSamples; if (ad.meta.totalSamples < posS + fragmentSamples) { copySamples = (int)(ad.meta.totalSamples - posS); } copySamples = flac.GetPcmOfChannel(ch, posS, ref fragment, copySamples); if (copySamples < 0) { return(copySamples); } // fragmentに入っているPCMデータのサイズはcopySamples * bpsバイト。 pcm.CopyFrom(fragment, 0, posS * bps, copySamples * bps); posS += copySamples; } var pcm24 = PcmDataLib.PcmDataUtil.ConvertTo24bit(ad.meta.bitsPerSample, ad.meta.totalSamples, PcmDataLib.PcmData.ValueRepresentationType.SInt, pcm); var adp = new AudioDataPerChannel(); adp.mDataFormat = AudioDataPerChannel.DataFormat.Pcm; adp.mData = pcm24; adp.mOffsBytes = 0; adp.mBitsPerSample = 24; adp.mValueRepresentationType = PcmDataLib.PcmData.ValueRepresentationType.SInt; adp.mTotalSamples = ad.meta.totalSamples; ad.pcm.Add(adp); } // converted to 24bit ad.meta.bitsPerSample = 24; ad.preferredSaveFormat = WWAFUtil.FileFormatType.FLAC; flac.DecodeEnd(); 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