summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_mod.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/demuxers/demux_mod.c b/src/demuxers/demux_mod.c
index 185ef5c97..7e0d99556 100644
--- a/src/demuxers/demux_mod.c
+++ b/src/demuxers/demux_mod.c
@@ -50,6 +50,7 @@
#include "demux.h"
#include "group_audio.h"
#include "modplug.h"
+#include "bswap.h"
#define MOD_SAMPLERATE 44100
#define MOD_BITS 16
@@ -89,6 +90,43 @@ typedef struct {
demux_class_t demux_class;
} demux_mod_class_t;
+#define FOURCC_32(a, b, c, d) (d + (c<<8) + (b<<16) + (a<<24))
+
+/**
+ * @brief Probes if the given file can be demuxed using modplug or not
+ * @retval 0 The file is not a valid modplug file (or the probe isn't complete yet)
+ * @retval 1 The file has been identified as a valid modplug file
+ * @todo Just Protracker files are detected right now.
+ */
+static int probe_mod_file(demux_mod_t *this) {
+ /* We need the value present at offset 1080, of size 4 */
+ union {
+ uint8_t buffer[1080+4]; /* The raw buffer */
+ uint32_t values[(1080+4)/sizeof(uint32_t)];
+ } header;
+
+ if (_x_demux_read_header(this->input, header.buffer, 1080+4) != 1080+4)
+ return 0;
+
+ /* Magic numbers taken from GNU file's magic description */
+ switch( ABE_32(header.values + (1080/sizeof(uint32_t))) ) {
+ case FOURCC_32('M', '.', 'K', '.'): /* 4-channel Protracker module sound data */
+ case FOURCC_32('M', '!', 'K', '!'): /* 4-channel Protracker module sound data */
+ case FOURCC_32('F', 'L', 'T', '4'): /* 4-channel Startracker module sound data */
+ case FOURCC_32('F', 'L', 'T', '8'): /* 8-channel Startracker module sound data */
+ case FOURCC_32('4', 'C', 'H', 'N'): /* 4-channel Fasttracker module sound data */
+ case FOURCC_32('6', 'C', 'H', 'N'): /* 6-channel Fasttracker module sound data */
+ case FOURCC_32('8', 'C', 'H', 'N'): /* 8-channel Fasttracker module sound data */
+ case FOURCC_32('C', 'D', '8', '1'): /* 8-channel Octalyser module sound data */
+ case FOURCC_32('O', 'K', 'T', 'A'): /* 8-channel Oktalyzer module sound data */
+ case FOURCC_32('1', '6', 'C', 'N'): /* 16-channel Taketracker module sound data */
+ case FOURCC_32('3', '2', 'C', 'N'): /* 32-channel Taketracker module sound data */
+ return 1;
+ }
+
+ return 0;
+}
+
/* returns 1 if the MOD file was opened successfully, 0 otherwise */
static int open_mod_file(demux_mod_t *this) {
int total_read;
@@ -306,6 +344,9 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str
break;
case METHOD_BY_CONTENT:
+ if (probe_mod_file(this) && open_mod_file(this))
+ break;
+
default:
free (this);
return NULL;