1 module main;
2 
3 import std.stdio;
4 import std.file;
5 
6 import audioformats;
7 import core.stdc.stdlib;
8 
9 // Currently it can take a MOD and dump patterns in the wrong order...
10 // Is or seek function conceptually correct?
11 
12 void main(string[] args)
13 {
14     if (args.length != 3)
15         throw new Exception("usage: dump-patterns input.{mod|xm} doubled.wav");
16 
17     string inputPath = args[1];
18     string outputPath = args[2];
19 
20     try
21     {
22 
23         AudioStream input, output;
24 
25         input.openFromFile(args[1]);
26         float sampleRate = input.getSamplerate();
27         int channels = input.getNumChannels();
28         long lengthFrames = input.getLengthInFrames();
29 
30         if (!input.isModule)
31             throw new Exception("Must be a module");
32         if (!input.canSeek)
33             throw new Exception("Must be seekable");
34 
35         float[] buf;
36         output.openToFile(outputPath, AudioFileFormat.wav, sampleRate, channels);
37 
38 
39         int patternCount = input.getModuleLength();
40 
41         for (int pattern = 0; pattern < patternCount; ++pattern) // Note: that iterated patterns in order, but that's not the right order in the MOD
42         {
43             input.seekPosition(pattern, 0);
44 
45             // how many remaining frames in this pattern?
46             int remain = cast(int) input.framesRemainingInPattern();
47             buf.length = remain * channels;
48             int framesRead = input.readSamplesFloat(buf); // this should read the whole pattern
49             assert( (framesRead == remain) );
50 
51             output.writeSamplesFloat(buf[0..framesRead*channels]);
52         }
53 
54         output.destroy();
55         
56         writefln("=> %s patterns decoded and encoded to %s", patternCount, outputPath);
57     }
58     catch(AudioFormatsException e)
59     {
60         writeln(e.msg);
61         destroyAudioFormatException(e);
62     }
63     catch(Exception e)
64     {
65         writeln(e.msg);
66     }
67 }