public static string GetTrackLength(CueSheetTrack currentTrack, CueSheetTrack nextTrack) { var currentTrackPosition = CueSheetIndex.ToTimeSpan(currentTrack.Index.Time); var nextTrackPosition = CueSheetIndex.ToTimeSpan(nextTrack.Index.Time); var trackLength = nextTrackPosition - currentTrackPosition; return(CueSheetIndex.FromTimeSpan(trackLength)); }
protected virtual MetaDataItem[] GetMetaData(CueSheet cueSheet, CueSheetTrack cueSheetTrack, IEnumerable <MetaDataItem> fileMetaData) { var metaDataItems = new Dictionary <string, MetaDataItem>(StringComparer.OrdinalIgnoreCase); if (fileMetaData != null) { foreach (var metaDataItem in fileMetaData) { metaDataItems[metaDataItem.Name] = metaDataItem; } } foreach (var tag in cueSheet.Tags) { var name = default(string); if (!FILE_NAMES.TryGetValue(tag.Name, out name)) { if (!CommonMetaData.Lookup.TryGetValue(tag.Name, out name)) { name = tag.Name; } } metaDataItems[name] = new MetaDataItem(name, MetaDataItemType.Tag) { Value = tag.Value }; } foreach (var tag in cueSheetTrack.Tags) { var name = default(string); if (!TRACK_NAMES.TryGetValue(tag.Name, out name)) { if (!CommonMetaData.Lookup.TryGetValue(tag.Name, out name)) { name = tag.Name; } } metaDataItems[name] = new MetaDataItem(name, MetaDataItemType.Tag) { Value = tag.Value }; } metaDataItems[CommonMetaData.Track] = new MetaDataItem(CommonMetaData.Track, MetaDataItemType.Tag) { Value = cueSheetTrack.Number }; //TODO: We could create the CommonProperties.Duration for all but the last track in each file. //TODO: Without understanding the file format we can't determine the length of the last track. //TODO: Just don't provide any duration for now. metaDataItems.Remove(CommonProperties.Duration); return(metaDataItems.Values.ToArray()); }
private void OnParseFile(string[] lines, ref int position, IList <CueSheetFile> files, IList <CueSheetTag> tags) { var line = lines[position].Trim(); var path = line.Substring( line.IndexOf(' '), line.LastIndexOf(' ') - line.IndexOf(' ') ).Trim(new[] { '"', ' ' }); var format = line.Substring( line.LastIndexOf(' ') ).Trim(); var tracks = new List <CueSheetTrack>(); var trackNumber = default(string); var trackType = default(string); var trackIndexes = new List <CueSheetIndex>(); var trackTags = new List <CueSheetTag>(); for (position = position + 1; position < lines.Length; position++) { line = lines[position].Trim(); var parts = line.Split(new[] { ' ' }, 3); if (parts.Length < 2) { continue; } switch (parts[0].ToUpper()) { case REM: this.OnParseTag(lines, ref position, files, trackTags); break; case TITLE: case PERFORMER: case SONGWRITER: this.OnParseTag(lines, ref position, files, trackTags); break; case ISRC: //TODO: Should we do something with this? International Standard Recording Code. break; case FLAGS: //TODO: Should we do something with this? Copy protection, multi channel... break; case TRACK: if (!string.IsNullOrEmpty(trackNumber) && !string.IsNullOrEmpty(trackType) && trackIndexes.Count > 0) { var track = new CueSheetTrack( trackNumber, trackType, trackIndexes, trackTags ); tracks.Add(track); } trackNumber = default(string); trackType = default(string); trackIndexes = new List <CueSheetIndex>(); trackTags = new List <CueSheetTag>(); if (parts.Length == 3) { trackNumber = parts[1]; trackType = parts[2]; } break; case INDEX: if (parts.Length == 3) { var indexPosition = parts[1]; var indexTime = parts[2]; var index = new CueSheetIndex( indexPosition, indexTime ); trackIndexes.Add(index); } break; default: position--; goto done; } } done: if (!string.IsNullOrEmpty(trackNumber) && !string.IsNullOrEmpty(trackType) && trackIndexes.Count > 0) { var track = new CueSheetTrack( trackNumber, trackType, trackIndexes, trackTags ); tracks.Add(track); } var file = new CueSheetFile(path, format, tracks); files.Add(file); }