private Stream GetDataStreamFromCueInfo(AcbCueRecord cue, string fileNameForErrorInfo) { if (!cue.IsWaveformIdentified) { throw new InvalidOperationException($"File '{fileNameForErrorInfo}' is not identified."); } Stream result; if (cue.IsStreaming) { var externalAwb = ExternalAwb; if (externalAwb == null) { throw new InvalidOperationException($"External AWB does not exist for streaming file '{fileNameForErrorInfo}'."); } if (!externalAwb.Files.ContainsKey(cue.WaveformId)) { throw new InvalidOperationException($"Waveform ID {cue.WaveformId} is not found in AWB file {externalAwb.FileName}."); } var targetExternalFile = externalAwb.Files[cue.WaveformId]; using (var fs = File.Open(externalAwb.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { result = AcbHelper.ExtractToNewStream(fs, targetExternalFile.FileOffsetAligned, (int)targetExternalFile.FileLength); } } else { var internalAwb = InternalAwb; if (internalAwb == null) { throw new InvalidOperationException($"Internal AWB is not found for memory file '{fileNameForErrorInfo}' in '{AcbFileName}'."); } if (!internalAwb.Files.ContainsKey(cue.WaveformId)) { throw new InvalidOperationException($"Waveform ID {cue.WaveformId} is not found in internal AWB in {AcbFileName}."); } var targetInternalFile = internalAwb.Files[cue.WaveformId]; result = AcbHelper.ExtractToNewStream(Stream, targetInternalFile.FileOffsetAligned, (int)targetInternalFile.FileLength); } return(result); }
private void InitializeAcbTables() { var stream = Stream; long refItemOffset = 0, refItemSize = 0, refCorrection = 0; var tables = new Dictionary <string, UtfTable>(); _tables = tables; var cueTable = GetTable("CueTable"); var waveformTable = GetTable("WaveformTable"); var synthTable = GetTable("SynthTable"); var cues = new AcbCueRecord[cueTable.Rows.Length]; _cues = cues; for (var i = 0; i < cues.Length; ++i) { var cue = new AcbCueRecord(); cue.IsWaveformIdentified = false; cue.CueId = cueTable.GetFieldValueAsNumber <uint>(i, "CueId").Value; cue.ReferenceType = cueTable.GetFieldValueAsNumber <byte>(i, "ReferenceType").Value; cue.ReferenceIndex = cueTable.GetFieldValueAsNumber <ushort>(i, "ReferenceIndex").Value; cues[i] = cue; switch (cue.ReferenceType) { case 2: refItemOffset = synthTable.GetFieldOffset(cue.ReferenceIndex, "ReferenceItems").Value; refItemSize = synthTable.GetFieldSize(cue.ReferenceIndex, "ReferenceItems").Value; refCorrection = refItemSize + 2; break; case 3: case 8: if (i == 0) { var refItemOffsetNullable = synthTable.GetFieldOffset(0, "ReferenceItems"); if (refItemOffsetNullable == null) { throw new AcbFieldMissingException("ReferenceItems"); } refItemOffset = refItemOffsetNullable.Value; var refItemSizeNullable = synthTable.GetFieldSize(0, "ReferenceItems"); if (refItemSizeNullable == null) { throw new AcbFieldMissingException("ReferenceItems"); } refItemSize = refItemSizeNullable.Value; refCorrection = refItemSize - 2; } else { refCorrection += 4; } break; default: throw new FormatException($"Unexpected ReferenceType '{cues[i].ReferenceType}' for CueIndex: '{i}.'"); } if (refItemSize != 0) { cue.WaveformIndex = stream.PeekUInt16BE(refItemOffset + refCorrection); var isStreamingNullable = waveformTable.GetFieldValueAsNumber <byte>(cue.WaveformIndex, "Streaming"); if (isStreamingNullable != null) { cue.IsStreaming = isStreamingNullable.Value != 0; var waveformIdNullable = waveformTable.GetFieldValueAsNumber <ushort>(cue.WaveformIndex, "Id"); if (waveformIdNullable != null) { cue.WaveformId = waveformIdNullable.Value; } else if (cue.IsStreaming) { waveformIdNullable = waveformTable.GetFieldValueAsNumber <ushort>(cue.WaveformIndex, "StreamAwbId"); if (waveformIdNullable == null) { throw new AcbFieldMissingException("StreamAwbId"); } cue.WaveformId = waveformIdNullable.Value; } else { // MemoryAwbId is for ADX2LE encoder. waveformIdNullable = waveformTable.GetFieldValueAsNumber <ushort>(cue.WaveformIndex, "MemoryAwbId"); if (waveformIdNullable == null) { throw new AcbFieldMissingException("MemoryAwbId"); } cue.WaveformId = waveformIdNullable.Value; } var encTypeNullable = waveformTable.GetFieldValueAsNumber <byte>(cue.WaveformIndex, "EncodeType"); if (encTypeNullable == null) { throw new AcbFieldMissingException("EncodeType"); } cue.EncodeType = encTypeNullable.Value; cue.IsWaveformIdentified = true; } } } }