/// <summary> /// サウンドデータチャンクのヘッダ情報を読む /// </summary> /// <param name="mode">ReadStopBeforeSoundData サウンドデータチャンクのサウンドデータの手前で読み込みを止める。 /// AllHeadersWithID3 サウンドデータチャンクの終わりまで読み進む。</param> private ResultType ReadSoundDataChunk(BinaryReader br, ReadHeaderMode mode) { if (!SkipToChunk(br, "SSND")) { return(ResultType.NotFoundSsndHeader); } long ckSize = Util.ReadBigU32(br); long offset = Util.ReadBigU32(br); long blockSize = Util.ReadBigU32(br); if (blockSize != 0) { return(ResultType.NotSupportBlockSizeNonzero); } if (mode == ReadHeaderMode.ReadStopBeforeSoundData) { // SSNDのsound data直前まで移動。 // offset == unused bytes。 読み飛ばす ReadStreamSkip(br, offset); } else { // SoundDataチャンクの最後まで移動。 // sizeof offset + blockSize == 8 PcmDataLib.Util.BinaryReaderSkip(br, PcmDataLib.Util.ChunkSizeWithPad(ckSize) - 8); } return(ResultType.Success); }
/// <summary> /// pathのファイルまたはディレクトリの音声ファイルを読む。 /// </summary> /// <returns>エラーの発生回数。0の時正常終了。</returns> public int ReadFileHeader(string path, ReadHeaderMode mode, PlaylistTrackInfo plti) { int nError = 0; if (System.IO.Directory.Exists(path)) { // pathはディレクトリである。直下のファイル一覧を作って足す。再帰的にはたぐらない。 var files = System.IO.Directory.GetFiles(path); if (mSortFolderItem) { files = (from s in files orderby s select s).ToArray(); } foreach (var file in files) { nError += ReadFileHeader1(file, mode, plti, null); } } else { // pathはファイル。 nError += ReadFileHeader1(path, mode, plti, null); } return(nError); }
/// <summary> /// pathのファイルまたはディレクトリの音声ファイルを読む。 /// </summary> /// <returns>エラーの発生回数。0の時正常終了。</returns> public int ReadFileHeader(string path, ReadHeaderMode mode, PlaylistTrackInfo plti) { int nError = 0; if (System.IO.Directory.Exists(path)) { // pathはディレクトリである。直下のファイル一覧を作って足す。再帰的にはたぐらない。 var files = System.IO.Directory.GetFiles(path); if (mSortFolderItem) { files = (from s in files orderby s select s).ToArray(); } foreach (var file in files) { nError += ReadFileHeader1(file, mode, plti, null); } } else { // pathはファイル。 nError += ReadFileHeader1(path, mode, plti, null); } return nError; }
private ResultType ReadSoundDataChunkHeader(BinaryReader br, ReadHeaderMode mode) { ulong chunkBytes = Util.ReadBigU64(br); if (chunkBytes == 0 || 0x7fffffff < chunkBytes) { return(ResultType.NotSupportFileTooLarge); } mDataFrames = (long)chunkBytes / 2 / NumChannels; switch (mode) { case ReadHeaderMode.AllHeadersWithID3: // skip dsd data PcmDataLib.PcmDataUtil.BinaryReaderSkip(br, (long)chunkBytes); break; case ReadHeaderMode.ReadStopBeforeSoundData: break; } return(ResultType.Success); }
private ResultType ReadHeader1(BinaryReader br, out PcmDataLib.PcmData pcmData, ReadHeaderMode mode) { pcmData = new PcmDataLib.PcmData(); ResultType result = ReadDsfChunk(br); if (result != ResultType.Success) { return(result); } result = ReadFmtChunk(br); if (ResultType.Success != result) { return(result); } result = ReadDataChunkHeader(br); if (ResultType.Success != result) { return(result); } // 読み込めるデータのフレーム数DataFramesと出力するデータのフレーム数OutputFrames。 // PCMデータのフレーム数OutputFramesは偶数個にする。 OutputFrames = mDataFrames; if (0 != (1 & OutputFrames)) { // OutputFrames must be even number ++OutputFrames; } pcmData.SetFormat( NumChannels, 24, 24, SampleRate / 16, PcmDataLib.PcmData.ValueRepresentationType.SInt, OutputFrames); pcmData.SampleDataType = PcmDataLib.PcmData.DataType.DoP; if (mode == ReadHeaderMode.AllHeadersWithID3 && mMetadataOffset != 0) { PcmDataLib.PcmDataUtil.BinaryReaderSkip(br, (long)mMetadataOffset - STREAM_DATA_OFFSET); result = ReadID3Chunk(br); if (ResultType.Success == result) { // ID3読み込み成功 pcmData.DisplayName = TitleName; pcmData.AlbumTitle = AlbumName; pcmData.ArtistName = ArtistName; if (0 < PictureBytes) { pcmData.SetPicture(PictureBytes, PictureData); } } } return(0); }
private ResultType ReadHeader1(BinaryReader br, ReadHeaderMode mode, out PcmDataLib.PcmData pcmData) { pcmData = new PcmDataLib.PcmData(); bool done = false; try { while (!done) { ResultType rt = ResultType.Success; uint fourCC = br.ReadUInt32(); switch (fourCC) { case FOURCC_FRM8: rt = ReadDsdChunk(br); break; case FOURCC_FVER: rt = ReadFormVersionChunk(br); break; case FOURCC_PROP: rt = ReadPropertyChunk(br); break; case FOURCC_FS: rt = ReadSampleRateChunk(br); break; case FOURCC_CHNL: rt = ReadChannelsChunk(br); break; case FOURCC_CMPR: rt = ReadCompressionTypeChunk(br); break; case FOURCC_DSD: rt = ReadSoundDataChunkHeader(br, mode); switch (mode) { case ReadHeaderMode.ReadStopBeforeSoundData: done = true; break; case ReadHeaderMode.AllHeadersWithID3: break; } break; case FOURCC_ID3: rt = ReadID3Chunk(br); break; default: rt = SkipUnknownChunk(br); break; } if (rt != ResultType.Success) { return(rt); } } } catch (EndOfStreamException ex) { // this is only way to exit from the while loop above System.Console.WriteLine(ex); } if (0 == SampleRate || // SampleRateChunkが存在しないとき。 0 == mDataFrames) { return(ResultType.ReadError); } if (NumChannels < 1) { return(ResultType.NotSupportNumChannels); } // 読み込めるデータのフレーム数DataFramesと出力するデータのフレーム数OutputFrames。 // PCMデータのフレーム数OutputFramesは偶数個にする。 OutputFrames = mDataFrames; if (0 != (1 & OutputFrames)) { // OutputFrames must be even number ++OutputFrames; } pcmData.SampleDataType = PcmDataLib.PcmData.DataType.DoP; pcmData.SetFormat( NumChannels, 24, 24, SampleRate / 16, PcmDataLib.PcmData.ValueRepresentationType.SInt, OutputFrames); if (null != TitleName) { pcmData.DisplayName = TitleName; } if (null != AlbumName) { pcmData.AlbumTitle = AlbumName; } if (null != ArtistName) { pcmData.ArtistName = ArtistName; } if (0 < PictureBytes) { pcmData.SetPicture(PictureBytes, PictureData); } return(0); }
private ResultType ReadHeader1(BinaryReader br, out PcmDataLib.PcmData pcmData, ReadHeaderMode mode) { pcmData = new PcmDataLib.PcmData(); ResultType result = ReadFormChunkHeader(br); if (result != ResultType.Success) { return(result); } if (mIsAIFC) { // AIFCの場合、FVERチャンクが来る(required) result = ReadFverChunk(br); if (ResultType.Success != result) { return(result); } } result = ReadCommonChunk(br); if (ResultType.Success != result) { return(result); } result = ReadSoundDataChunk(br, mode); if (ResultType.Success != result) { return(result); } if (16 != BitsPerSample && 24 != BitsPerSample) { return(ResultType.NotSupportBitsPerSample); } pcmData.SetFormat( NumChannels, BitsPerSample, BitsPerSample, SampleRate, PcmDataLib.PcmData.ValueRepresentationType.SInt, NumFrames); if (mode == ReadHeaderMode.AllHeadersWithID3) { result = ReadID3Chunk(br); if (ResultType.Success == result) { // ID3読み込み成功 pcmData.DisplayName = TitleName; pcmData.AlbumTitle = AlbumName; pcmData.ArtistName = ArtistName; pcmData.ComposerName = ComposerName; if (0 < PictureBytes) { pcmData.SetPicture(PictureBytes, PictureData); } } } return(0); }
private ResultType ReadHeader1(BinaryReader br, out PcmDataLib.PcmData pcmData, ReadHeaderMode mode) { pcmData = new PcmDataLib.PcmData(); ResultType result = ReadDsfChunk(br); if (result != ResultType.Success) { return result; } result = ReadFmtChunk(br); if (ResultType.Success != result) { return result; } result = ReadDataChunkHeader(br); if (ResultType.Success != result) { return result; } // 読み込めるデータのフレーム数DataFramesと出力するデータのフレーム数OutputFrames。 // PCMデータのフレーム数OutputFramesは偶数個にする。 OutputFrames = mDataFrames; if (0 != (1 & OutputFrames)) { // OutputFrames must be even number ++OutputFrames; } pcmData.SetFormat( NumChannels, 24, 24, SampleRate/16, PcmDataLib.PcmData.ValueRepresentationType.SInt, OutputFrames); pcmData.SampleDataType = PcmDataLib.PcmData.DataType.DoP; if (mode == ReadHeaderMode.AllHeadersWithID3 && mMetadataOffset != 0) { PcmDataLib.Util.BinaryReaderSkip(br, (long)mMetadataOffset - STREAM_DATA_OFFSET); result = ReadID3Chunk(br); if (ResultType.Success == result) { // ID3読み込み成功 pcmData.DisplayName = TitleName; pcmData.AlbumTitle = AlbumName; pcmData.ArtistName = ArtistName; if (0 < PictureBytes) { pcmData.SetPicture(PictureBytes, PictureData); } } } return 0; }
/// <summary> /// N.B. PcmReader.StreamBeginも参照(へぼい)。 /// MenuItemFileOpen_Clickも参照。 /// </summary> /// <returns>エラーの発生回数を戻す</returns> private int ReadFileHeader1(string path, ReadHeaderMode mode, PlaylistTrackInfo plti, PlaylistItemSave3 plis) { mPlaylistTrackMeta = plti; mPlis = plis; int errCount = 0; var ext = System.IO.Path.GetExtension(path).ToUpperInvariant(); try { switch (ext) { case ".PPWPL": if (mode != ReadHeaderMode.OnlyConcreteFile) { // PPWプレイリストを読み込み errCount += ReadPpwPlaylist(path); } break; case ".CUE": case ".M3U": case ".M3U8": if (mode != ReadHeaderMode.OnlyConcreteFile) { // CUEシートかM3U8再生リストを読み込み。 errCount += ReadCueSheet(path); } break; case ".FLAC": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadFlacFileHeader(path, mode) ? 1 : 0; } break; case ".MP3": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadMp3FileHeader(path) ? 1 : 0; } break; case ".AIF": case ".AIFF": case ".AIFC": case ".AIFFC": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadAiffFileHeader(path) ? 1 : 0; } break; case ".WAV": case ".WAVE": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadWavFileHeader(path) ? 1 : 0; } break; case ".DSF": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadDsfFileHeader(path) ? 1 : 0; } break; case ".DFF": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadDsdiffFileHeader(path) ? 1 : 0; } break; case ".JPG": case ".JPEG": case ".PNG": case ".BMP": // 読まないで無視する。 break; default: LoadErrorMessageAdd(string.Format(CultureInfo.InvariantCulture, "{0}: {1}{2}", Properties.Resources.NotSupportedFileFormat, path, Environment.NewLine)); ++errCount; break; } } catch (IOException ex) { HandleFileReadException(path, ex); ++errCount; } catch (ArgumentException ex) { HandleFileReadException(path, ex); ++errCount; } catch (UnauthorizedAccessException ex) { HandleFileReadException(path, ex); ++errCount; } catch (Exception ex) { // 未知のエラー。 HandleFileReadException(path, ex); ++errCount; } return(errCount); }
/// <summary> /// FLACファイルのヘッダ部分を読み込む。 /// </summary> /// <returns>読めたらtrue、失敗false</returns> private bool ReadFlacFileHeader(string path, ReadHeaderMode mode) { PcmDataLib.PcmData pcmData; List <WWFlacRWCS.FlacCuesheetTrack> ctiList; var fdif = new FlacDecodeIF(); int flacErcd = 0; flacErcd = fdif.ReadHeader(path, out pcmData, out ctiList); if (flacErcd != 0) { // FLACヘッダ部分読み込み失敗。 LoadErrorMessageAdd(string.Format(CultureInfo.InvariantCulture, Properties.Resources.ReadFileFailed + " {2}: {1}{3}", "FLAC", path, FlacDecodeIF.ErrorCodeToStr(flacErcd), Environment.NewLine)); return(false); } // FLACヘッダ部分読み込み成功。 // PCMデータにDoPマーカーが付いているか調べ、pcmData.SampleDataTypeを確定する。 pcmData = FlacScanDopMarker(pcmData, fdif); fdif.ReadEnd(); if (ctiList.Count == 0 || mode == ReadHeaderMode.OnlyConcreteFile) { // FLAC埋め込みCUEシート情報を読まない。 CheckAddPcmData(path, pcmData, true); } else { // FLAC埋め込みCUEシート情報を読む。 PcmData pcmTrack = null; for (int trackId = 0; trackId < ctiList.Count; ++trackId) { var cti = ctiList[trackId]; if (cti.indices.Count == 0) { // インデックスが1つもないトラック。lead-outトラックの場合等。 if (pcmTrack != null) { pcmTrack.EndTick = (int)((cti.offsetSamples * 75) / pcmTrack.SampleRate); CheckAddPcmData(path, pcmTrack, false); pcmTrack = null; } } else { for (int indexId = 0; indexId < cti.indices.Count; ++indexId) { var indexInfo = cti.indices[indexId]; if (pcmTrack != null) { pcmTrack.EndTick = (int)(((cti.offsetSamples + indexInfo.offsetSamples) * 75) / pcmTrack.SampleRate); CheckAddPcmData(path, pcmTrack, false); pcmTrack = null; } pcmTrack = new PcmData(); pcmTrack.CopyFrom(pcmData); if (pcmTrack.DisplayName.Length == 0) { pcmTrack.DisplayName = System.IO.Path.GetFileName(path); } pcmTrack.DisplayName = string.Format(CultureInfo.InvariantCulture, "{0} (Track {1}, Index {2})", pcmTrack.DisplayName, cti.trackNr, indexInfo.indexNr); pcmTrack.CueSheetIndex = indexInfo.indexNr; pcmTrack.StartTick = (int)(((cti.offsetSamples + indexInfo.offsetSamples) * 75) / pcmTrack.SampleRate); } } } } return(true); }
/// <summary> /// サウンドデータチャンクのヘッダ情報を読む /// </summary> /// <param name="mode">ReadStopBeforeSoundData サウンドデータチャンクのサウンドデータの手前で読み込みを止める。 /// AllHeadersWithID3 サウンドデータチャンクの終わりまで読み進む。</param> private ResultType ReadSoundDataChunk(BinaryReader br, ReadHeaderMode mode) { if (!SkipToChunk(br, "SSND")) { return ResultType.NotFoundSsndHeader; } long ckSize = Util.ReadBigU32(br); long offset = Util.ReadBigU32(br); long blockSize = Util.ReadBigU32(br); if (blockSize != 0) { return ResultType.NotSupportBlockSizeNonzero; } if (mode == ReadHeaderMode.ReadStopBeforeSoundData) { // SSNDのsound data直前まで移動。 // offset == unused bytes。 読み飛ばす ReadStreamSkip(br, offset); } else { // SoundDataチャンクの最後まで移動。 // sizeof offset + blockSize == 8 PcmDataLib.Util.BinaryReaderSkip(br, PcmDataLib.Util.ChunkSizeWithPad(ckSize) - 8); } return ResultType.Success; }
private ResultType ReadHeader1(BinaryReader br, out PcmDataLib.PcmData pcmData, ReadHeaderMode mode) { pcmData = new PcmDataLib.PcmData(); ResultType result = ReadFormChunkHeader(br); if (result != ResultType.Success) { return result; } if (mIsAIFC) { // AIFCの場合、FVERチャンクが来る(required) result = ReadFverChunk(br); if (ResultType.Success != result) { return result; } } result = ReadCommonChunk(br); if (ResultType.Success != result) { return result; } result = ReadSoundDataChunk(br, mode); if (ResultType.Success != result) { return result; } if (16 != BitsPerSample && 24 != BitsPerSample) { return ResultType.NotSupportBitsPerSample; } pcmData.SetFormat( NumChannels, BitsPerSample, BitsPerSample, SampleRate, PcmDataLib.PcmData.ValueRepresentationType.SInt, NumFrames); if (mode == ReadHeaderMode.AllHeadersWithID3) { result = ReadID3Chunk(br); if (ResultType.Success == result) { // ID3読み込み成功 pcmData.DisplayName = TitleName; pcmData.AlbumTitle = AlbumName; pcmData.ArtistName = ArtistName; if (0 < PictureBytes) { pcmData.SetPicture(PictureBytes, PictureData); } } } return 0; }
/// <summary> /// FLACファイルのヘッダ部分を読み込む。 /// </summary> /// <returns>読めたらtrue、失敗false</returns> private bool ReadFlacFileHeader(string path, ReadHeaderMode mode) { PcmDataLib.PcmData pcmData; List<FlacDecodeIF.FlacCuesheetTrackInfo> ctiList; var fdif = new FlacDecodeIF(); int flacErcd = 0; flacErcd = fdif.ReadHeader(path, out pcmData, out ctiList); if (flacErcd != 0) { // FLACヘッダ部分読み込み失敗。 LoadErrorMessageAdd(string.Format(CultureInfo.InvariantCulture, Properties.Resources.ReadFileFailed + " {2}: {1}{3}", "FLAC", path, FlacDecodeIF.ErrorCodeToStr(flacErcd), Environment.NewLine)); return false; } // FLACヘッダ部分読み込み成功。 if (ctiList.Count == 0 || mode == ReadHeaderMode.OnlyConcreteFile) { // FLAC埋め込みCUEシート情報を読まない。 CheckAddPcmData(path, pcmData, true); } else { // FLAC埋め込みCUEシート情報を読む。 PcmData pcmTrack = null; for (int trackId=0; trackId < ctiList.Count; ++trackId) { var cti = ctiList[trackId]; if (cti.indices.Count == 0) { // インデックスが1つもないトラック。lead-outトラックの場合等。 if (pcmTrack != null) { pcmTrack.EndTick = (int)((cti.offsetSamples * 75) / pcmTrack.SampleRate); CheckAddPcmData(path, pcmTrack, false); pcmTrack = null; } } else { for (int indexId=0; indexId < cti.indices.Count; ++indexId) { var indexInfo = cti.indices[indexId]; if (pcmTrack != null) { pcmTrack.EndTick = (int)(((cti.offsetSamples + indexInfo.offsetSamples) * 75) / pcmTrack.SampleRate); CheckAddPcmData(path, pcmTrack, false); pcmTrack = null; } pcmTrack = new PcmData(); pcmTrack.CopyFrom(pcmData); if (pcmTrack.DisplayName.Length == 0) { pcmTrack.DisplayName = System.IO.Path.GetFileName(path); } pcmTrack.DisplayName = string.Format(CultureInfo.InvariantCulture, "{0} (Track {1}, Index {2})", pcmTrack.DisplayName, cti.trackNr, indexInfo.indexNr); pcmTrack.CueSheetIndex = indexInfo.indexNr; pcmTrack.StartTick = (int)(((cti.offsetSamples + indexInfo.offsetSamples) * 75) / pcmTrack.SampleRate); } } } } return true; }
/// <summary> /// N.B. PcmReader.StreamBeginも参照(へぼい)。 /// MenuItemFileOpen_Clickも参照。 /// </summary> /// <returns>エラーの発生回数を戻す</returns> private int ReadFileHeader1(string path, ReadHeaderMode mode, PlaylistTrackInfo plti, PlaylistItemSave plis) { mPlaylistTrackMeta = plti; mPlis = plis; int errCount = 0; var ext = System.IO.Path.GetExtension(path).ToUpperInvariant(); try { switch (ext) { case ".PPWPL": if (mode != ReadHeaderMode.OnlyConcreteFile) { // PPWプレイリストを読み込み errCount += ReadPpwPlaylist(path); } break; case ".CUE": case ".M3U": case ".M3U8": if (mode != ReadHeaderMode.OnlyConcreteFile) { // CUEシートかM3U8再生リストを読み込み。 errCount += ReadCueSheet(path); } break; case ".FLAC": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadFlacFileHeader(path, mode) ? 1 : 0; } break; case ".AIF": case ".AIFF": case ".AIFC": case ".AIFFC": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadAiffFileHeader(path) ? 1 : 0; } break; case ".WAV": case ".WAVE": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadWavFileHeader(path) ? 1 : 0; } break; case ".DSF": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadDsfFileHeader(path) ? 1 : 0; } break; case ".DFF": if (mode != ReadHeaderMode.OnlyMetaFile) { errCount += !ReadDsdiffFileHeader(path) ? 1 : 0; } break; case ".JPG": case ".JPEG": case ".PNG": case ".BMP": // 読まないで無視する。 break; default: LoadErrorMessageAdd(string.Format(CultureInfo.InvariantCulture, "{0}: {1}{2}", Properties.Resources.NotSupportedFileFormat, path, Environment.NewLine)); ++errCount; break; } } catch (IOException ex) { HandleFileReadException(path, ex); ++errCount; } catch (ArgumentException ex) { HandleFileReadException(path, ex); ++errCount; } catch (UnauthorizedAccessException ex) { HandleFileReadException(path, ex); ++errCount; } catch (Exception ex) { // 未知のエラー。 HandleFileReadException(path, ex); ++errCount; } return errCount; }
private ResultType ReadSoundDataChunkHeader(BinaryReader br, ReadHeaderMode mode) { ulong chunkBytes = Util.ReadBigU64(br); if (chunkBytes == 0 || 0x7fffffff < chunkBytes) { return ResultType.NotSupportFileTooLarge; } mDataFrames = (long)chunkBytes / 2 / NumChannels; switch (mode) { case ReadHeaderMode.AllHeadersWithID3: // skip dsd data PcmDataLib.Util.BinaryReaderSkip(br, (long)chunkBytes); break; case ReadHeaderMode.ReadStopBeforeSoundData: break; } return ResultType.Success; }
private ResultType ReadHeader1(BinaryReader br, ReadHeaderMode mode, out PcmDataLib.PcmData pcmData) { pcmData = new PcmDataLib.PcmData(); bool done = false; try { while (!done) { ResultType rt = ResultType.Success; uint fourCC = br.ReadUInt32(); switch (fourCC) { case FOURCC_FRM8: rt = ReadDsdChunk(br); break; case FOURCC_FVER: rt = ReadFormVersionChunk(br); break; case FOURCC_PROP: rt = ReadPropertyChunk(br); break; case FOURCC_FS: rt = ReadSampleRateChunk(br); break; case FOURCC_CHNL: rt = ReadChannelsChunk(br); break; case FOURCC_CMPR: rt = ReadCompressionTypeChunk(br); break; case FOURCC_DSD: rt = ReadSoundDataChunkHeader(br, mode); switch (mode) { case ReadHeaderMode.ReadStopBeforeSoundData: done = true; break; case ReadHeaderMode.AllHeadersWithID3: break; } break; case FOURCC_ID3: rt = ReadID3Chunk(br); break; default: rt = SkipUnknownChunk(br); break; } if (rt != ResultType.Success) { return rt; } } } catch (EndOfStreamException ex) { // this is only way to exit from the while loop above System.Console.WriteLine(ex); } if (0 == SampleRate || // SampleRateChunkが存在しないとき。 2 != NumChannels || 0 == mDataFrames) { return ResultType.ReadError; } // 読み込めるデータのフレーム数DataFramesと出力するデータのフレーム数OutputFrames。 // PCMデータのフレーム数OutputFramesは偶数個にする。 OutputFrames = mDataFrames; if (0 != (1 & OutputFrames)) { // OutputFrames must be even number ++OutputFrames; } pcmData.SetFormat( NumChannels, 24, 24, SampleRate/16, PcmDataLib.PcmData.ValueRepresentationType.SInt, OutputFrames); pcmData.SampleDataType = PcmDataLib.PcmData.DataType.DoP; if (null != TitleName) { pcmData.DisplayName = TitleName; } if (null != AlbumName) { pcmData.AlbumTitle = AlbumName; } if (null != ArtistName) { pcmData.ArtistName = ArtistName; } if (0 < PictureBytes) { pcmData.SetPicture(PictureBytes, PictureData); } return 0; }