CUEParser.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Simple CUE sheet parser suitable for embedded systems.
  3. *
  4. * Copyright (c) 2023 Rabbit Hole Computing
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. #pragma once
  20. #include <stdint.h>
  21. #ifndef CUE_MAX_FILENAME
  22. #define CUE_MAX_FILENAME 64
  23. #endif
  24. enum CUEFileMode
  25. {
  26. CUEFile_BINARY = 0,
  27. CUEFile_MOTOROLA,
  28. CUEFile_MP3,
  29. CUEFile_WAVE,
  30. CUEFile_AIFF,
  31. };
  32. enum CUETrackMode
  33. {
  34. CUETrack_AUDIO = 0,
  35. CUETrack_CDG,
  36. CUETrack_MODE1_2048,
  37. CUETrack_MODE1_2352,
  38. CUETrack_MODE2_2048,
  39. CUETrack_MODE2_2324,
  40. CUETrack_MODE2_2336,
  41. CUETrack_MODE2_2352,
  42. CUETrack_CDI_2336,
  43. CUETrack_CDI_2352,
  44. };
  45. struct CUETrackInfo
  46. {
  47. // Source file name and file type, and offset to start of track data in bytes.
  48. char filename[CUE_MAX_FILENAME+1];
  49. CUEFileMode file_mode;
  50. uint64_t file_offset; // corresponds to data_start below
  51. // Track number and mode in CD format
  52. int track_number;
  53. CUETrackMode track_mode;
  54. // Sector length for this track in bytes, assuming BINARY or MOTOROLA file modes.
  55. uint32_t sector_length;
  56. // The CD frames of PREGAP time at the start of this track, or 0 if none are present.
  57. // These frames of silence are not stored in the underlying data file.
  58. uint32_t unstored_pregap_length;
  59. // LBA start position of the data area (INDEX 01) of this track (in CD frames)
  60. uint32_t data_start;
  61. // LBA for the beginning of the track, which will be INDEX 00 if that is present.
  62. // If there is unstored PREGAP, it's added between track_start and data_start.
  63. // Otherwise this will be INDEX 01 matching data_start above.
  64. uint32_t track_start;
  65. };
  66. class CUEParser
  67. {
  68. public:
  69. CUEParser();
  70. // Initialize the class to parse data from string.
  71. // The string must remain valid for the lifetime of this object.
  72. CUEParser(const char *cue_sheet);
  73. // Restart parsing from beginning of file
  74. void restart();
  75. // Get information for next track.
  76. // Returns nullptr when there are no more tracks.
  77. // The returned pointer remains valid until next call to next_track()
  78. // or destruction of this object.
  79. const CUETrackInfo *next_track();
  80. protected:
  81. const char *m_cue_sheet;
  82. const char *m_parse_pos;
  83. CUETrackInfo m_track_info;
  84. // Skip any whitespace at beginning of line.
  85. // Returns false if at end of string.
  86. bool start_line();
  87. // Advance parser to next line
  88. void next_line();
  89. // Skip spaces in string, return pointer to first non-space character
  90. const char *skip_space(const char *p) const;
  91. // Read text starting with " and ending with next "
  92. // Returns pointer to character after ending quote.
  93. const char *read_quoted(const char *src, char *dest, int dest_size);
  94. // Parse time from MM:SS:FF format to frame number
  95. uint32_t parse_time(const char *src);
  96. // Parse file mode into enum
  97. CUEFileMode parse_file_mode(const char *src);
  98. // Parse track mode into enum
  99. CUETrackMode parse_track_mode(const char *src);
  100. // Get sector length in file from track mode
  101. uint32_t get_sector_length(CUEFileMode filemode, CUETrackMode trackmode);
  102. };