aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2020-05-06 23:57:38 -0400
committerB. Watson <yalhcru@gmail.com>2020-05-06 23:57:38 -0400
commit2c70ffa4e72d678fa5653e6d014abc6cbc5b9989 (patch)
treeb5e514f8e9065016d8bd76747086f68e62036d6e
downloadmiragextract-2c70ffa4e72d678fa5653e6d014abc6cbc5b9989.tar.gz
initial commit
-rw-r--r--Makefile19
-rw-r--r--miragextract.c134
2 files changed, 153 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6e9e402
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,19 @@
+PROJ=miragextract
+
+# Packagers: override these on make command line as needed.
+OPTFLAGS=-O2
+LDEXTRA=
+
+SNDFILE_CFLAGS:=$(shell pkg-config --cflags sndfile)
+SNDFILE_LIBS:=$(shell pkg-config --libs sndfile)
+
+MIRAGE_CFLAGS:=$(shell pkg-config --cflags libmirage)
+MIRAGE_LIBS:=$(shell pkg-config --libs libmirage)
+
+CFLAGS=-Wall $(OPTFLAGS) $(MIRAGE_CFLAGS) $(SNDFILE_CFLAGS)
+LDFLAGS=$(LDEXTRA) $(MIRAGE_LIBS) $(SNDFILE_LIBS)
+
+all: $(PROJ)
+
+test: all
+ ./$(PROJ)
diff --git a/miragextract.c b/miragextract.c
new file mode 100644
index 0000000..2c16132
--- /dev/null
+++ b/miragextract.c
@@ -0,0 +1,134 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sndfile.h>
+#include <mirage/mirage.h>
+
+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;
+}