CUEParser.h 3.5 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;
  51. // Track number and mode in CD format
  52. int track_number;
  53. CUETrackMode track_mode;
  54. // Sector length for this track in bytes in the file, or 0 for audio files
  55. uint32_t sector_length;
  56. // Unstored pregap length, in CD frames, or 0
  57. uint32_t unstored_pregap_length;
  58. // LBA start position of the pregap of this track (in CD frames)
  59. uint32_t pregap_start;
  60. // LBA start position of the data area of this track (in CD frames)
  61. uint32_t data_start;
  62. // Track start, either pregap_start or if no pregap, data_start.
  63. uint32_t track_start;
  64. };
  65. class CUEParser
  66. {
  67. public:
  68. CUEParser();
  69. // Initialize the class to parse data from string.
  70. // The string must remain valid for the lifetime of this object.
  71. CUEParser(const char *cue_sheet);
  72. // Restart parsing from beginning of file
  73. void restart();
  74. // Get information for next track.
  75. // Returns nullptr when there are no more tracks.
  76. // The returned pointer remains valid until next call to next_track()
  77. // or destruction of this object.
  78. const CUETrackInfo *next_track();
  79. protected:
  80. const char *m_cue_sheet;
  81. const char *m_parse_pos;
  82. CUETrackInfo m_track_info;
  83. // Skip any whitespace at beginning of line.
  84. // Returns false if at end of string.
  85. bool start_line();
  86. // Advance parser to next line
  87. void next_line();
  88. // Skip spaces in string, return pointer to first non-space character
  89. const char *skip_space(const char *p) const;
  90. // Read text starting with " and ending with next "
  91. // Returns pointer to character after ending quote.
  92. const char *read_quoted(const char *src, char *dest, int dest_size);
  93. // Parse time from MM:SS:FF format to frame number
  94. uint32_t parse_time(const char *src);
  95. // Parse file mode into enum
  96. CUEFileMode parse_file_mode(const char *src);
  97. // Parse track mode into enum
  98. CUETrackMode parse_track_mode(const char *src);
  99. // Get sector length in file from track mode
  100. uint32_t get_sector_length(CUEFileMode filemode, CUETrackMode trackmode);
  101. };