#include #include #include #include #include const char *self; static MirageContext *mirage = NULL; static MirageDisc *disc = NULL; static MirageSession *session = NULL; static int output_track_number = 0; // static int tracks; void die(char *msg) { fprintf(stderr, "%s: %s\n", self, msg); exit(1); } void extract_audio(MirageTrack *track) { } void extract_track(int t) { MirageTrack *track; MirageSector *sector; int sector_type, sec = 0; gint len; const guint8 *buf; char *ext; char outfile[4096]; FILE *out; SNDFILE *sfout; struct SF_INFO sfi; double quality = 0.7l; output_track_number++; if(!(track = mirage_session_get_track_by_index(session, t, NULL))) die("can't read track"); sector_type = mirage_track_get_sector_type(track); switch(sector_type) { case MIRAGE_SECTOR_MODE1: case MIRAGE_SECTOR_MODE2_FORM1: // printf("Track %d is data, extracting\n", output_track_number); ext = "iso"; break; case MIRAGE_SECTOR_AUDIO: // printf("Track %d is audio, extracting\n", output_track_number); ext = "ogg"; break; default: // printf("Track %d is unsupported type, dumping raw\n", output_track_number); ext = "raw"; break; } sector = mirage_track_get_sector(track, 0, 0, NULL); /* mirage_sector_get_data(sector, &buf, &len, NULL); printf("got %d bytes per sector\n", len); */ sprintf(outfile, "track%02d.%s", output_track_number, ext); if(sector_type == MIRAGE_SECTOR_AUDIO) { sfi.samplerate = 44100; sfi.channels = 2; sfi.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS; if(!(sfout = sf_open(outfile, SFM_WRITE, &sfi))) die("can't open output audio file"); sf_command(sfout, SFC_SET_VBR_ENCODING_QUALITY, &quality, sizeof(double)); } else { if(!(out = fopen(outfile, "wb"))) { die("can't open output file"); } } sec = mirage_track_get_track_start(track); while((sector = mirage_track_get_sector(track, sec++, 0, NULL))) { mirage_sector_get_data(sector, &buf, &len, NULL); if(sector_type == MIRAGE_SECTOR_AUDIO) { /* TODO: find out what happens on big-endian platform! */ sf_write_short(sfout, (const short *)buf, len / 2); } else { fwrite(buf, len, 1, out); } g_object_unref(sector); } if(sector_type == MIRAGE_SECTOR_AUDIO) { sf_close(sfout); } else { fclose(out); } printf("read %d sectors\n", sec); return; } int main(int argc, char **argv) { self = argv[0]; gchar *fn[2]; int s, t; if(!((mirage = g_object_new(MIRAGE_TYPE_CONTEXT, NULL)))) die("couldn't get mirage context"); if(!mirage_initialize(NULL)) die("couldn't initialize libmirage"); fn[0] = "test.cue"; fn[1] = NULL; if(!(disc = mirage_context_load_image(mirage, fn, NULL))) die("couldn't load image"); for(s = 0; s < mirage_disc_get_number_of_sessions(disc); s++) { if(!(session = mirage_disc_get_session_by_index(disc, s, NULL))) die("couldn't read session"); for(t = 0; t < mirage_session_get_number_of_tracks(session); t++) { printf("session %d, track %d\n", s, t); extract_track(t); } } mirage_shutdown(NULL); return 0; }