diff --git a/NAudio.Core/Wave/WaveOutputs/CueWaveFileWriter.cs b/NAudio.Core/Wave/WaveOutputs/CueWaveFileWriter.cs
index b866d01b..52434ab0 100644
--- a/NAudio.Core/Wave/WaveOutputs/CueWaveFileWriter.cs
+++ b/NAudio.Core/Wave/WaveOutputs/CueWaveFileWriter.cs
@@ -31,7 +31,7 @@ public void AddCue(int position, string label)
{
cues = new CueList();
}
- cues.Add(new Cue(position, label));
+ cues.Add(new Cue(position, null, label));
}
private void WriteCues(BinaryWriter w)
diff --git a/NAudio.Core/Wave/WaveStreams/CueList.cs b/NAudio.Core/Wave/WaveStreams/CueList.cs
index 9b2a08f4..ebbd7506 100644
--- a/NAudio.Core/Wave/WaveStreams/CueList.cs
+++ b/NAudio.Core/Wave/WaveStreams/CueList.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@@ -18,19 +19,24 @@ public class Cue
///
public int Position { get; }
///
+ /// Cue length in samples
+ ///
+ public int? Length { get; }
+ ///
/// Label of the cue
///
public string Label { get; }
///
- /// Creates a Cue based on a sample position and label
+ /// Creates a Cue based on a sample position, length and label
///
///
///
- public Cue(int position, string label)
+ public Cue(int position, int? length, string label)
{
Position = position;
- Label = label??string.Empty;
+ Length = length;
+ Label = label ?? string.Empty;
}
}
@@ -77,6 +83,19 @@ public Cue(int position, string label)
/// Int32 dwIdentifier;
/// Char[] dwText; /* Encoded with extended ASCII */
/// } LabelChunk;
+ ///
+ /// struct TextWithDataLengthChunk
+ /// {
+ /// Int32 chunkID;
+ /// Int32 chunkSize;
+ /// Int32 dwIdentifier;
+ /// Int32 dwSampleLength;
+ /// Int32 dwPurpose;
+ /// Int16 wCountry;
+ /// Int16 wLanguage;
+ /// Int16 wDialect;
+ /// Int16 wCodePage;
+ /// } TextWithDataLengthChunk;
///
public class CueList
{
@@ -115,6 +134,23 @@ public int[] CuePositions
}
}
+ ///
+ /// Gets sample length for the embedded cues
+ ///
+ /// Array containing the cue lenghts
+ public int?[] CueLengths
+ {
+ get
+ {
+ int?[] lengths = new int?[cues.Count];
+ for (int i = 0; i < cues.Count; i++)
+ {
+ lengths[i] = cues[i].Length;
+ }
+ return lengths;
+ }
+ }
+
///
/// Gets labels for the embedded cues
///
@@ -150,24 +186,50 @@ internal CueList(byte[] cueChunkData, byte[] listChunkData)
positions[cue] = BitConverter.ToInt32(cueChunkData, p + 20);
}
+ // Loop listChunkData and extract supported features
+ int listDataPosition = 4;
+
+ var lablChunkId = ChunkIdentifier.ChunkIdentifierToInt32("labl");
+ var ltxtChunkId = ChunkIdentifier.ChunkIdentifierToInt32("ltxt");
+
string[] labels = new string[cueCount];
- int labelLength = 0;
+ int?[] lenghts = new int?[cueCount];
- var labelChunkId = ChunkIdentifier.ChunkIdentifierToInt32("labl");
- for (int p = 4; listChunkData.Length - p >= 16; p += labelLength + labelLength % 2 + 12)
+ do
{
- if (BitConverter.ToInt32(listChunkData, p) == labelChunkId)
+ // Chunk Header
+ int chunkId = BitConverter.ToInt32(listChunkData, listDataPosition);
+ int chunkSize = BitConverter.ToInt32(listChunkData, listDataPosition + 4);
+
+ // Chunk Data
+ if (chunkId == lablChunkId)
{
- labelLength = BitConverter.ToInt32(listChunkData, p + 4) - 4;
- var cueId = BitConverter.ToInt32(listChunkData, p + 8);
+ // Label (labl)
+ int labelLength = BitConverter.ToInt32(listChunkData, listDataPosition + 4) - 4;
+ var cueId = BitConverter.ToInt32(listChunkData, listDataPosition + 8);
cue = cueIndex[cueId];
- labels[cue] = Encoding.UTF8.GetString(listChunkData, p + 12, labelLength - 1);
+ labels[cue] = Encoding.UTF8.GetString(listChunkData, listDataPosition + 12, labelLength - 1);
}
- }
+
+ else if (chunkId == ltxtChunkId)
+ {
+ // Text with Data Length (ltxt)
+ var cueId = BitConverter.ToInt32(listChunkData, listDataPosition + 8);
+ lenghts[cue] = BitConverter.ToInt32(listChunkData, listDataPosition + 12);
+ }
+
+ else
+ {
+ Debug.WriteLine($"Unknown chunkId: {chunkId}");
+ }
+
+ // Header + Chunk Data
+ listDataPosition += 8 + chunkSize;
+ } while (listDataPosition + 7 < listChunkData.Length); // Break when there are less than a full Chunk Header left (chunkId + chunkSize = 8 bytes)
for (int i = 0; i < cueCount; i++)
{
- cues.Add(new Cue(positions[i], labels[i]));
+ cues.Add(new Cue(positions[i], lenghts[i], labels[i]));
}
}