void print_breaks(Cd *cd, int gaps) { int i; long b; long pg; Track *track; for (i = 1; i <= cd_get_ntrack(cd); i++) { track = cd_get_track(cd, i); /* * When breakpoint is at: * index 0: gap is prepended to track * index 1: gap is appended to previous track */ b = track_get_start(track); pg = track_get_index(track, 1) - track_get_zero_pre(track); if (gaps == PREPEND || gaps == SPLIT) { print_breakpoint(b); /* * There is no previous track to append the first track's * pregap to. */ } else if (gaps == APPEND && 1 < i) { print_breakpoint(b + pg); } /* If pregap exists, print breakpoints (in split mode). */ if (gaps == SPLIT && 0 < pg) { print_breakpoint(b + pg); } } }
long cue_container_track_times(const char* pathname,const unsigned int tnum, int flag) { struct Cd *cd=NULL; unsigned int n_tracks=0; long time_ms=0; char *cue_filename=g_strdup(pathname); remove_suffix(cue_filename,'/'); // check that filename ends in .cue // check that cue file actually exists // check that we succesfuly parse the cue file if ( !g_str_has_suffix(cue_filename,".cue") || 0 != access (cue_filename, R_OK) || (( cd = cue_get_cd(cue_filename) ) == NULL)) { g_free(cue_filename); return 0; } g_free(cue_filename); n_tracks=(unsigned) cd_get_ntrack(cd); if ( tnum <= n_tracks && flag == 0 ) { // return start time of track struct Track * tr = cd_get_track(cd, tnum); time_ms = (track_get_start(tr) ); time_ms*= 1000.0 /75.0; free(tr); } else if ( tnum < n_tracks && flag == 1 ) { // return end time of track, for all but the last track struct Track * tr = cd_get_track(cd, tnum); time_ms = track_get_start(tr); time_ms+=track_get_length(tr); time_ms =time_ms*1000.0 /75.0; free(tr); } return time_ms; }
QMap<QString, QString> CueFile::getMetadata(int trackno) { QMap<QString, QString> metadata; auto set = genSet(metadata); Track* track = cd_get_track(cd_, trackno); if (track) { // metadata["track"] = QString::number(trackno); metadata["_cue_offset"] = QString::number(cueLengthToMs(track_get_start(track))); Cdtext* cdtext = track_get_cdtext(track); if (cdtext) { set("artist", cdtext_get(PTI_PERFORMER, cdtext)); set("title", cdtext_get(PTI_TITLE, cdtext)); if (metadata["artist"].isEmpty()) metadata["artist"] = getMetadata().value("album artist"); } } return metadata; }
/* prints cd in cue format */ void cue_print (FILE *fp, Cd *cd) { Cdtext *cdtext = cd_get_cdtext(cd); int i; /* track */ Track *track = NULL; /* print global information */ if (NULL != cd_get_catalog(cd)) fprintf(fp, "CATALOG %s\n", cd_get_catalog(cd)); cue_print_cdtext(cdtext, fp, 0); /* print track information */ for (i = 1; i <= cd_get_ntrack(cd); i++) { track = cd_get_track(cd, i); fprintf(fp, "\n"); cue_print_track(fp, track, i); } }
char * cue_file_get_filename(const char *filename,unsigned tnum) { struct Cd *cd; FILE *cue_file = fopen(filename, "rt"); if (cue_file == NULL) return NULL; cd = cue_parse_file(cue_file); fclose (cue_file); if ( cd == NULL) return NULL; // no container directory if there is only one track int ntrack =cd_get_ntrack(cd); if (ntrack == 1) return NULL; return track_get_filename( cd_get_track( cd,tnum)); }
void toc_print (FILE *fp, Cd *cd) { Cdtext *cdtext = cd_get_cdtext(cd); int i; /* track */ Track *track; switch(cd_get_mode(cd)) { case MODE_CD_DA: fprintf(fp, "CD_DA\n"); break; case MODE_CD_ROM: fprintf(fp, "CD_ROM\n"); break; case MODE_CD_ROM_XA: fprintf(fp, "CD_ROM_XA\n"); break; } if (NULL != cd_get_catalog(cd)) { fprintf(fp, "CATALOG \"%s\"\n", cd_get_catalog(cd)); } if(0 != cdtext_is_empty(cdtext)) { fprintf(fp, "CD_TEXT {\n"); fprintf(fp, "\tLANGUAGE_MAP { 0:9 }\n"); fprintf(fp, "\tLANGUAGE 0 {\n"); toc_print_cdtext(cdtext, fp, 0); fprintf(fp, "\t}\n"); fprintf(fp, "}\n"); } for (i = 1; i <= cd_get_ntrack(cd); i++) { track = cd_get_track(cd, i); fprintf(fp, "\n"); toc_print_track(fp, track); } }
static bool_t playlist_load_cue (const char * cue_filename, VFSFile * file, char * * title, Index * filenames, Index * tuples) { void * buffer = NULL; vfs_file_read_all (file, & buffer, NULL); if (! buffer) return FALSE; * title = NULL; Cd * cd = cue_parse_string (buffer); g_free (buffer); if (cd == NULL) return FALSE; int tracks = cd_get_ntrack (cd); if (tracks == 0) return FALSE; Track * current = cd_get_track (cd, 1); if (current == NULL) return FALSE; char * track_filename = track_get_filename (current); if (track_filename == NULL) return FALSE; char * filename = uri_construct (track_filename, cue_filename); Tuple * base_tuple = NULL; bool_t base_tuple_scanned = FALSE; for (int track = 1; track <= tracks; track ++) { if (current == NULL || filename == NULL) return FALSE; if (base_tuple == NULL && ! base_tuple_scanned) { base_tuple_scanned = TRUE; PluginHandle * decoder = aud_file_find_decoder (filename, FALSE); if (decoder != NULL) base_tuple = aud_file_read_tuple (filename, decoder); } Track * next = (track + 1 <= tracks) ? cd_get_track (cd, track + 1) : NULL; char * next_filename = (next != NULL) ? uri_construct (track_get_filename (next), cue_filename) : NULL; bool_t last_track = (next_filename == NULL || strcmp (next_filename, filename)); Tuple * tuple = (base_tuple != NULL) ? tuple_copy (base_tuple) : tuple_new_from_filename (filename); tuple_set_int (tuple, FIELD_TRACK_NUMBER, track); int begin = (int64_t) track_get_start (current) * 1000 / 75; tuple_set_int (tuple, FIELD_SEGMENT_START, begin); if (last_track) { if (base_tuple != NULL && tuple_get_value_type (base_tuple, FIELD_LENGTH) == TUPLE_INT) tuple_set_int (tuple, FIELD_LENGTH, tuple_get_int (base_tuple, FIELD_LENGTH) - begin); } else { int length = (int64_t) track_get_length (current) * 1000 / 75; tuple_set_int (tuple, FIELD_LENGTH, length); tuple_set_int (tuple, FIELD_SEGMENT_END, begin + length); } for (int i = 0; i < ARRAY_LEN (pti_map); i ++) tuple_attach_cdtext (tuple, current, pti_map[i].tuple_type, pti_map[i].pti); index_insert (filenames, -1, str_get (filename)); index_insert (tuples, -1, tuple); current = next; str_unref (filename); filename = next_filename; if (last_track && base_tuple != NULL) { tuple_unref (base_tuple); base_tuple = NULL; base_tuple_scanned = FALSE; } } return TRUE; }
QString CueFile::getLocation(int trackno) { Track* track = cd_get_track(cd_, trackno); return QString(track_get_filename(track)); }
int CueFile::getLength(int trackno) { Track* track = cd_get_track(cd_, trackno); return cueLengthToMs(track_get_length(track)); }
static char* cue_test() { Cd *cd = cue_parse_string (cue); mu_assert ("error parsing CUE", cd != NULL); Rem *rem = cd_get_rem (cd); mu_assert ("error getting REM", rem != NULL); Cdtext *cdtext = cd_get_cdtext (cd); mu_assert ("error getting CDTEXT", cdtext != NULL); const char *val; val = cdtext_get (PTI_PERFORMER, cdtext); mu_assert ("error getting CD performer", val != NULL); mu_assert ("error validating CD performer", strcmp (val, "Bloc Party") == 0); val = cdtext_get (PTI_TITLE, cdtext); mu_assert ("error getting CD title", val != NULL); mu_assert ("error validating CD title", strcmp (val, "Silent Alarm") == 0); int ival = cd_get_ntrack (cd); mu_assert ("invalid number of tracks", ival == 2); Track *track; /* Track 1 */ track = cd_get_track (cd, 1); mu_assert ("error getting track", track != NULL); val = track_get_filename (track); mu_assert ("error getting track filename", val != NULL); mu_assert ("error validating track filename", strcmp (val, "Bloc Party - Silent Alarm.flac") == 0); cdtext = track_get_cdtext (track); mu_assert ("error getting track CDTEXT", cdtext != NULL); val = cdtext_get (PTI_PERFORMER, cdtext); mu_assert ("error getting track performer", val != NULL); mu_assert ("error validating track performer", strcmp (val, "Bloc Party") == 0); val = cdtext_get (PTI_TITLE, cdtext); mu_assert ("error getting track title", val != NULL); mu_assert ("error validating track title", strcmp (val, "Like Eating Glass") == 0); ival = track_get_zero_pre (track); mu_assert ("invalid track pre-gap", ival == MSF_TO_F(3,22,70)); ival = track_get_start (track); mu_assert ("invalid track start", ival == MSF_TO_F(3,22,70)); ival = track_get_length (track); mu_assert ("invalid track length", ival == MSF_TO_F(4,19,74)); ival = track_get_index (track, 0); mu_assert ("invalid index", ival == 0); ival = track_get_index (track, 1); mu_assert ("invalid index", ival == MSF_TO_F(3,22,70)); /* Track 2 */ track = cd_get_track (cd, 2); mu_assert ("error getting track", track != NULL); val = track_get_filename (track); mu_assert ("error getting track filename", val != NULL); mu_assert ("error validating track filename", strcmp (val, "Bloc Party - Silent Alarm.flac") == 0); cdtext = track_get_cdtext (track); mu_assert ("error getting track CDTEXT", cdtext != NULL); val = cdtext_get (PTI_PERFORMER, cdtext); mu_assert ("error getting track performer", val != NULL); mu_assert ("error validating track performer", strcmp (val, "Bloc Party") == 0); val = cdtext_get (PTI_TITLE, cdtext); mu_assert ("error getting track title", val != NULL); mu_assert ("error validating track title", strcmp (val, "Helicopter") == 0); ival = track_get_zero_pre (track); mu_assert ("invalid track pre-gap", ival == MSF_TO_F(0,2,0)); ival = track_get_start (track); mu_assert ("invalid track start", ival == MSF_TO_F(7,44,69)); ival = track_get_length (track); mu_assert ("invalid track length", ival == -1); ival = track_get_index (track, 0); mu_assert ("invalid index", ival == MSF_TO_F(7,42,69)); ival = track_get_index (track, 1); mu_assert ("invalid index", ival == MSF_TO_F(7,44,69)); cd_delete (cd); return NULL; }
/* Parse playlist and handle its contents */ plp_status_t cue_for_each_item( char *pl_name, void *ctx, plp_func_t f ) { /* Load cue sheet */ FILE *fd = fopen(pl_name, "rt"); if (!fd) { logger_error(cue_log, 0, _("cue: failed to load cue sheet %s"), pl_name); return PLP_STATUS_FAILED; } Cd *cd = cue_parse_file(fd, pl_name); if (!cd) { logger_error(cue_log, 0, _("cue: failed to load cue sheet %s"), pl_name); fclose(fd); return PLP_STATUS_FAILED; } fclose(fd); /* Handle tracks */ int num_tracks = cd_get_ntrack(cd); plp_status_t res = PLP_STATUS_OK; for ( int i = 1; i <= num_tracks; ++i ) { Track *track = cd_get_track(cd, i); char *filename = track_get_filename(track); if (!filename) continue; song_metadata_t metadata = SONG_METADATA_EMPTY; /* Set bounds */ long start = cue_get_track_begin(track); long end = -1; if (i < num_tracks) { Track *next_track = cd_get_track(cd, i + 1); char *next_name = track_get_filename(next_track); if (next_name && !strcmp(filename, next_name)) end = cue_get_track_begin(next_track); } metadata.m_start_time = SECONDS_TO_TIME(start) / 75; metadata.m_end_time = (end < 0 ? -1 : SECONDS_TO_TIME(end) / 75); /* Set song info */ song_info_t *si = si_new(); si_set_album(si, cdtext_get(PTI_TITLE, cd_get_cdtext(cd))); si_set_year(si, rem_get(REM_DATE, cd_get_rem(cd))); si_set_artist(si, cdtext_get(PTI_PERFORMER, cd_get_cdtext(cd))); si_set_name(si, cdtext_get(PTI_TITLE, track_get_cdtext(track))); si_set_genre(si, cue_get_genre(cd, track)); si_set_comments(si, cue_get_comment(cd, track)); char track_num_str[10]; snprintf(track_num_str, sizeof(track_num_str), "%02d", i); si_set_track(si, track_num_str); metadata.m_song_info = si; plp_status_t st = f(ctx, filename, &metadata); if (st != PLP_STATUS_OK) { res = st; break; } } /* Free memory */ cd_delete(cd); return res; } /* End of 'cue_for_each_item' function */
static char* cue_pregap_test() { Cd *cd = cue_parse_string (cue_pregap); mu_assert ("error parsing CUE", cd != NULL); Rem *rem = cd_get_rem (cd); mu_assert ("error getting REM", rem != NULL); Cdtext *cdtext = cd_get_cdtext (cd); mu_assert ("error getting CDTEXT", cdtext != NULL); const char *val; val = cdtext_get (PTI_PERFORMER, cdtext); mu_assert ("error validating CD performer", val == NULL); val = cdtext_get (PTI_TITLE, cdtext); mu_assert ("error validating CD title", val == NULL); int ival = cd_get_ntrack (cd); mu_assert ("invalid number of tracks", ival == 2); Track *track; /* Track 1 */ track = cd_get_track (cd, 1); mu_assert ("error getting track", track != NULL); val = track_get_filename (track); mu_assert ("error getting track filename", val != NULL); mu_assert ("error validating track filename", strcmp (val, "The Specials - Singles - 01 - Gangsters.wav") == 0); cdtext = track_get_cdtext (track); mu_assert ("error getting track CDTEXT", cdtext != NULL); val = cdtext_get (PTI_PERFORMER, cdtext); mu_assert ("error getting track performer", val != NULL); mu_assert ("error validating track performer", strcmp (val, "The Specials") == 0); val = cdtext_get (PTI_TITLE, cdtext); mu_assert ("error getting track title", val != NULL); mu_assert ("error validating track title", strcmp (val, "Gangsters") == 0); ival = track_get_start (track); mu_assert ("invalid track start", ival == 0); ival = track_get_length (track); mu_assert ("invalid track length", ival == -1); ival = track_get_index (track, 1); mu_assert ("invalid index", ival == 0); /* Track 2 */ track = cd_get_track (cd, 2); mu_assert ("error getting track", track != NULL); val = track_get_filename (track); mu_assert ("error getting track filename", val != NULL); mu_assert ("error validating track filename", strcmp (val, "The Specials - Singles - 02 - Rudi, A Message To You.wav") == 0); cdtext = track_get_cdtext (track); mu_assert ("error getting track CDTEXT", cdtext != NULL); val = cdtext_get (PTI_PERFORMER, cdtext); mu_assert ("error getting track performer", val != NULL); mu_assert ("error validating track performer", strcmp (val, "The Specials") == 0); val = cdtext_get (PTI_TITLE, cdtext); mu_assert ("error getting track title", val != NULL); mu_assert ("error validating track title", strcmp (val, "Rudi, A Message To You") == 0); ival = track_get_zero_pre (track); mu_assert ("invalid track pre-gap", ival == 28); ival = track_get_start (track); mu_assert ("invalid track start", ival == 0); ival = track_get_length (track); mu_assert ("invalid track length", ival == -1); ival = track_get_index (track, 1); mu_assert ("invalid index", ival == 0); cd_delete (cd); return NULL; }
void track_field(char *conv, int length, Cd *cd, int trackno, Value *value) { char *c; /* pointer to conversion character */ Track *track = NULL; Cdtext *cdtext = NULL; track = cd_get_track(cd, trackno); cdtext = track_get_cdtext(track); c = conv + length - 1; switch (*c) { case 'a': value->sval = cdtext_get(PTI_ARRANGER, cdtext); *c = 's'; break; case 'c': value->sval = cdtext_get(PTI_COMPOSER, cdtext); *c = 's'; break; case 'f': value->sval = track_get_filename(track); *c = 's'; break; case 'g': value->sval = cdtext_get(PTI_GENRE, cdtext); *c = 's'; break; case 'i': value->sval = track_get_isrc(track); *c = 's'; break; case 'm': value->sval = cdtext_get(PTI_MESSAGE, cdtext); *c = 's'; break; case 'n': value->ival = trackno; *c = 'd'; break; case 'p': value->sval = cdtext_get(PTI_PERFORMER, cdtext); *c = 's'; break; case 's': value->sval = cdtext_get(PTI_SONGWRITER, cdtext); *c = 's'; break; case 't': value->sval = cdtext_get(PTI_TITLE, cdtext); *c = 's'; break; case 'u': value->sval = cdtext_get(PTI_UPC_ISRC, cdtext); *c = 's'; break; default: disc_field(conv, length, cd, value); break; } }