Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/helpers/cue_creator.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "StdAfx.h" | |
| 2 #include "cue_creator.h" | |
| 3 #include "../SDK/chapterizer.h" | |
| 4 | |
| 5 static pfc::string8 format_meta(const file_info& p_source, const char* p_name, bool p_allow_space = true) { | |
| 6 pfc::string8 temp, ret; | |
| 7 p_source.meta_format(p_name, temp); | |
| 8 temp.replace_byte('\"', '\''); | |
| 9 uReplaceString(ret, temp, pfc_infinite, "\x0d\x0a", 2, "\\", 1, false); | |
| 10 if (!p_allow_space) ret.replace_byte(' ', '_'); | |
| 11 ret.replace_nontext_chars(); | |
| 12 return ret; | |
| 13 } | |
| 14 | |
| 15 static bool is_meta_same_everywhere(const cue_creator::t_entry_list & p_list,const char * p_meta) | |
| 16 { | |
| 17 pfc::string8_fastalloc reference,temp; | |
| 18 | |
| 19 bool first = true; | |
| 20 for(auto & iter : p_list) { | |
| 21 if ( ! iter.isTrackAudio() ) continue; | |
| 22 | |
| 23 if ( first ) { | |
| 24 first = false; | |
| 25 if (!iter.m_infos.meta_format(p_meta,reference)) return false; | |
| 26 } else { | |
| 27 if (!iter.m_infos.meta_format(p_meta,temp)) return false; | |
| 28 if (strcmp(temp,reference)!=0) return false; | |
| 29 } | |
| 30 } | |
| 31 | |
| 32 return true; | |
| 33 } | |
| 34 | |
| 35 #define g_eol "\r\n" | |
| 36 | |
| 37 namespace cue_creator | |
| 38 { | |
| 39 pfc::string_formatter create(const t_entry_list& p_list) { | |
| 40 pfc::string_formatter ret; create(ret, p_list); return ret; | |
| 41 } | |
| 42 void create(pfc::string_formatter & p_out,const t_entry_list & p_data) | |
| 43 { | |
| 44 if (p_data.get_count() == 0) return; | |
| 45 bool album_artist_global = is_meta_same_everywhere(p_data,"album artist"), | |
| 46 artist_global = is_meta_same_everywhere(p_data,"artist"), | |
| 47 album_global = is_meta_same_everywhere(p_data,"album"), | |
| 48 genre_global = is_meta_same_everywhere(p_data,"genre"), | |
| 49 date_global = is_meta_same_everywhere(p_data,"date"), | |
| 50 discid_global = is_meta_same_everywhere(p_data,"discid"), | |
| 51 comment_global = is_meta_same_everywhere(p_data,"comment"), | |
| 52 catalog_global = is_meta_same_everywhere(p_data,"catalog"), | |
| 53 songwriter_global = is_meta_same_everywhere(p_data,"songwriter"); | |
| 54 | |
| 55 { | |
| 56 auto firstTrack = p_data.first(); | |
| 57 while( firstTrack.is_valid() && ! firstTrack->isTrackAudio() ) ++ firstTrack; | |
| 58 if ( firstTrack.is_valid() ) { | |
| 59 if (genre_global) { | |
| 60 p_out << "REM GENRE " << format_meta(firstTrack->m_infos,"genre") << g_eol; | |
| 61 } | |
| 62 if (date_global) { | |
| 63 p_out << "REM DATE " << format_meta(firstTrack->m_infos,"date") << g_eol; | |
| 64 } | |
| 65 if (discid_global) { | |
| 66 p_out << "REM DISCID " << format_meta(firstTrack->m_infos,"discid") << g_eol; | |
| 67 } | |
| 68 if (comment_global) { | |
| 69 p_out << "REM COMMENT " << format_meta(firstTrack->m_infos,"comment") << g_eol; | |
| 70 } | |
| 71 if (is_meta_same_everywhere(p_data, "discnumber")) { | |
| 72 p_out << "REM DISCNUMBER " << format_meta(firstTrack->m_infos, "discnumber") << g_eol; | |
| 73 } | |
| 74 if (is_meta_same_everywhere(p_data, "totaldiscs")) { | |
| 75 p_out << "REM TOTALDISCS " << format_meta(firstTrack->m_infos, "totaldiscs") << g_eol; | |
| 76 } | |
| 77 if (catalog_global) { | |
| 78 p_out << "CATALOG " << format_meta(firstTrack->m_infos,"catalog") << g_eol; | |
| 79 } | |
| 80 if (songwriter_global) { | |
| 81 p_out << "SONGWRITER \"" << format_meta(firstTrack->m_infos,"songwriter") << "\"" << g_eol; | |
| 82 } | |
| 83 | |
| 84 if (album_artist_global) | |
| 85 { | |
| 86 p_out << "PERFORMER \"" << format_meta(firstTrack->m_infos,"album artist") << "\"" << g_eol; | |
| 87 artist_global = false; | |
| 88 } | |
| 89 else if (artist_global) | |
| 90 { | |
| 91 p_out << "PERFORMER \"" << format_meta(firstTrack->m_infos,"artist") << "\"" << g_eol; | |
| 92 } | |
| 93 if (album_global) | |
| 94 { | |
| 95 p_out << "TITLE \"" << format_meta(firstTrack->m_infos,"album") << "\"" << g_eol; | |
| 96 } | |
| 97 | |
| 98 { | |
| 99 replaygain_info::t_text_buffer rgbuffer; | |
| 100 replaygain_info rg = firstTrack->m_infos.get_replaygain(); | |
| 101 if (rg.format_album_gain(rgbuffer)) | |
| 102 p_out << "REM REPLAYGAIN_ALBUM_GAIN " << rgbuffer << g_eol; | |
| 103 if (rg.format_album_peak(rgbuffer)) | |
| 104 p_out << "REM REPLAYGAIN_ALBUM_PEAK " << rgbuffer << g_eol; | |
| 105 } | |
| 106 | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 pfc::string8 last_file; | |
| 111 | |
| 112 for(t_entry_list::const_iterator iter = p_data.first();iter.is_valid();++iter) | |
| 113 { | |
| 114 if (strcmp(last_file,iter->m_file) != 0) | |
| 115 { | |
| 116 auto fileType = iter->m_fileType; | |
| 117 if ( fileType.length() == 0 ) fileType = "WAVE"; | |
| 118 p_out << "FILE \"" << iter->m_file << "\" " << fileType << g_eol; | |
| 119 last_file = iter->m_file; | |
| 120 } | |
| 121 | |
| 122 { | |
| 123 auto trackType = iter->m_trackType; | |
| 124 if (trackType.length() == 0) trackType = "AUDIO"; | |
| 125 p_out << " TRACK " << pfc::format_int(iter->m_track_number,2) << " " << trackType << g_eol; | |
| 126 } | |
| 127 | |
| 128 | |
| 129 | |
| 130 if (iter->m_infos.meta_find("title") != pfc_infinite) | |
| 131 p_out << " TITLE \"" << format_meta(iter->m_infos,"title") << "\"" << g_eol; | |
| 132 | |
| 133 const bool bHaveArtist = iter->m_infos.meta_exists("artist"); | |
| 134 if (!artist_global && bHaveArtist) { | |
| 135 p_out << " PERFORMER \"" << format_meta(iter->m_infos,"artist") << "\"" << g_eol; | |
| 136 } else if (album_artist_global && !bHaveArtist) { | |
| 137 // special case: album artist set, track artist not set | |
| 138 p_out << " PERFORMER \"\"" << g_eol; | |
| 139 } | |
| 140 | |
| 141 if (!songwriter_global && iter->m_infos.meta_find("songwriter") != pfc_infinite) { | |
| 142 p_out << " SONGWRITER \"" << format_meta(iter->m_infos,"songwriter") << "\"" << g_eol; | |
| 143 } | |
| 144 | |
| 145 if (iter->m_infos.meta_find("isrc") != pfc_infinite) { | |
| 146 p_out << " ISRC " << format_meta(iter->m_infos,"isrc") << g_eol; | |
| 147 } | |
| 148 | |
| 149 if (!date_global && iter->m_infos.meta_find("date") != pfc_infinite) { | |
| 150 p_out << " REM DATE " << format_meta(iter->m_infos,"date") << g_eol; | |
| 151 } | |
| 152 if (!comment_global && iter->m_infos.meta_exists("comment")) { | |
| 153 p_out << " REM COMMENT " << format_meta(iter->m_infos, "comment") << g_eol; | |
| 154 } | |
| 155 | |
| 156 | |
| 157 { | |
| 158 replaygain_info::t_text_buffer rgbuffer; | |
| 159 replaygain_info rg = iter->m_infos.get_replaygain(); | |
| 160 if (rg.format_track_gain(rgbuffer)) | |
| 161 p_out << " REM REPLAYGAIN_TRACK_GAIN " << rgbuffer << g_eol; | |
| 162 if (rg.format_track_peak(rgbuffer)) | |
| 163 p_out << " REM REPLAYGAIN_TRACK_PEAK " << rgbuffer << g_eol; | |
| 164 } | |
| 165 | |
| 166 if (!iter->m_flags.is_empty()) { | |
| 167 p_out << " FLAGS " << iter->m_flags << g_eol; | |
| 168 } | |
| 169 | |
| 170 if (iter->m_index_list.m_positions[0] < iter->m_index_list.m_positions[1]) | |
| 171 { | |
| 172 if (iter->m_index_list.m_positions[0] < 0) | |
| 173 p_out << " PREGAP " << cuesheet_format_index_time(iter->m_index_list.m_positions[1] - iter->m_index_list.m_positions[0]) << g_eol; | |
| 174 else | |
| 175 p_out << " INDEX 00 " << cuesheet_format_index_time(iter->m_index_list.m_positions[0]) << g_eol; | |
| 176 } | |
| 177 | |
| 178 p_out << " INDEX 01 " << cuesheet_format_index_time(iter->m_index_list.m_positions[1]) << g_eol; | |
| 179 | |
| 180 for(unsigned n=2;n<t_cuesheet_index_list::count && iter->m_index_list.m_positions[n] > 0;n++) | |
| 181 { | |
| 182 p_out << " INDEX " << pfc::format_uint(n,2) << " " << cuesheet_format_index_time(iter->m_index_list.m_positions[n]) << g_eol; | |
| 183 } | |
| 184 | |
| 185 // p_out << " INDEX 01 " << cuesheet_format_index_time(iter->m_offset) << g_eol; | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 | |
| 190 void t_entry::set_simple_index(double p_time) | |
| 191 { | |
| 192 m_index_list.reset(); | |
| 193 m_index_list.m_positions[0] = m_index_list.m_positions[1] = p_time; | |
| 194 } | |
| 195 void t_entry::set_index01(double index0, double index1) { | |
| 196 PFC_ASSERT( index0 <= index1 ); | |
| 197 m_index_list.reset(); | |
| 198 m_index_list.m_positions[0] = index0; | |
| 199 m_index_list.m_positions[1] = index1; | |
| 200 } | |
| 201 | |
| 202 bool t_entry::isTrackAudio() const { | |
| 203 PFC_ASSERT( m_trackType.length() > 0 ); | |
| 204 return pfc::stringEqualsI_ascii( m_trackType, "AUDIO" ); | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 | |
| 209 |
