/// <summary> /// 次のストリームを準備する /// </summary> private static bool PrepareNextStream(int index, List <KeyValuePair <string, object> > tags = null) { lock (PrepareMutex) { LastPreparedIndex = index; if (PreparedStream != null) { return(false); } if (index == -1) { PreparedStream = new StopperInputStream(); return(true); } if (index >= CurrentPlaylistRows || index < 0) { return(false); } object[] row = Controller.GetPlaylistRow(index); string filename = (string)row[Controller.GetColumnIndexByName(LibraryDBColumnTextMinimum.file_name)]; try { int tr = Util.Util.GetTrackNumberInt(row[Controller.GetColumnIndexByName("tagTracknumber")].ToString(), 1); PullSoundStreamBase nextStream = DecodeStreamFactory.CreateFileStream(filename, tr, MyCoreComponent.UsePrescan, tags); if (nextStream == null) { return(false); } if (nextStream.Chans == 1) { nextStream = new Mono2StereoFilter(nextStream); } //if (nextStream.Freq == 96000) //{ // nextStream = new FreqConvertFilter(nextStream); //} // prepareにsyncを設定 var inStream = new InputStream(nextStream, row); inStream.Ready = !OutputDeviceFactory.RebuildRequired(OutputDevice, nextStream.Freq, nextStream.Chans, true); inStream.SetEvent(on80Percent, nextStream.LengthSec * 0.80); inStream.SetEvent(onPreFinish, Math.Max(nextStream.LengthSec * 0.90, nextStream.LengthSec - 5)); PreparedStream = inStream; } catch (Exception e) { Logger.Log(e.ToString()); return(false); } } return(true); }
/// <summary> /// 単体の音楽ファイルを解析する /// </summary> /// <param name="file_name">ファイル名</param> /// <param name="threadLocalResultQueue">スレッド固有の解析結果</param> /// <param name="lastModifySTMT">modifyを取得するプリペアドステートメント</param> private void AnalyzeStreamFile(string file_name, List <LuteaAudioTrack> threadLocalResultQueue, SQLite3DB.STMT lastModifySTMT) { // 既に処理済みの場合はreturn if (AlreadyAnalyzedFiles.Contains(file_name)) { return; } // 処理済みファイルに追加 lock (AlreadyAnalyzedFiles) { AlreadyAnalyzedFiles.Add(file_name); } if (LastModifyDatetime(lastModifySTMT, file_name) > new System.IO.FileInfo(file_name).LastWriteTime&& IsFastMode) { return; } var tag = MetaTag.readTagByFilename(file_name, false); if (tag == null) { return; } var cue = tag.Find(match => match.Key.ToUpper() == "CUESHEET"); if (cue.Key != null) { var cd = InternalCUEReader.Read(file_name, true); if (cd == null) { Logger.Error("CUESHEET is embedded. But, it has error. " + file_name); return; } threadLocalResultQueue.AddRange(cd.tracks.Cast <LuteaAudioTrack>()); } else { // PERFORMERがないとき、ARTISTをPERFORMERとして扱う if (tag.Find((e) => { return(e.Key == "PERFORMER"); }).Value == null) { var artist = tag.Find((e) => { return(e.Key == "ARTIST"); }); if (artist.Value != null) { tag.Add(new KeyValuePair <string, object>("PERFORMER", artist.Value)); } } var tr = new LuteaAudioTrack() { file_name = file_name, file_size = new System.IO.FileInfo(file_name).Length }; if (tag.Exists(_ => _.Key == "__X-LUTEA-CHANS__") && tag.Exists(_ => _.Key == "__X-LUTEA-FREQ__") && tag.Exists(_ => _.Key == "__X-LUTEA-DURATION__")) { tr.duration = int.Parse(tag.Find(_ => _.Key == "__X-LUTEA-DURATION__").Value.ToString()); tr.channels = int.Parse(tag.Find(_ => _.Key == "__X-LUTEA-CHANS__").Value.ToString()); tr.freq = int.Parse(tag.Find(_ => _.Key == "__X-LUTEA-FREQ__").Value.ToString()); } else { try { using (var strm = DecodeStreamFactory.CreateFileStreamPrimitive(file_name)) { tr.duration = (int)strm.LengthSec; tr.channels = (int)strm.Chans; tr.freq = (int)strm.Freq; } } catch (ArgumentException ex) { Logger.Error("cannot open file (by BASS)" + file_name); Logger.Debug(ex); } } tr.tag = tag; if (tr.file_ext == "M4A") { if (tag.Exists(_ => (_.Key == "PURCHASE DATE") || (_.Key == "PURCHASED"))) { if ((TypesToImport & ImportableTypes.M4A_iTunes) == 0) { return; } } else if (tr.codec == H2k6Codec.ALAC) { if ((TypesToImport & ImportableTypes.M4A_ALAC) == 0) { return; } } else { if ((TypesToImport & ImportableTypes.M4A) == 0) { return; } } } threadLocalResultQueue.Add(tr); } }