1 // This program is free software; you can redistribute it and/or
2 // modify it under the terms of the GNU General Public License
3 // as published by the Free Software Foundation; either version 2
4 // of the License, or (at your option) any later version.
6 // This program is distributed in the hope that it will be useful,
7 // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // GNU General Public License for more details.
18 ////////////////////////////////////////////////////////////////////////////////
19 __gshared OPLPlayer player
;
20 __gshared
short[4096] smpbuf
;
21 __gshared
uint smpbufpos
;
23 __gshared
float amp
= 1.0f;
27 if (smpbufpos
== 0) return;
28 foreach (ref short v
; smpbuf
[0..smpbufpos
]) {
29 int n
= cast(int)(v
*amp
);
30 if (n
< short.min
) n
= short.min
;
31 if (n
> short.max
) n
= short.max
;
34 alsaWriteX(smpbuf
.ptr
, smpbufpos
/2);
39 void main (string
[] args
) {
41 string filename
= null;
43 string outwavname
= null;
44 bool nextIsWav
= false;
45 foreach (string a
; args
[1..$]) {
47 if (outwavname
!is null) assert(0, "too many output .wav filenames");
53 if (filename
!is null) assert(0, "too many file names");
57 if (a
== "--") { nomore
= true; continue; }
58 if (a
.length
== 0) continue;
59 if (a
== "-opl2" || a
== "--opl2") useOPL3
= false;
60 else if (a
== "-opl3" || a
== "--opl3") useOPL3
= true;
61 else if (a
== "--wav" || a
== "-w") nextIsWav
= true;
62 else if (a
.length
> 2 && a
[0..2] == "-w") {
63 if (outwavname
!is null) assert(0, "too many output .wav filenames");
65 } else if (a
.length
> 2 && a
[0..2] == "-a") {
67 amp
= a
[2..$].to
!float;
68 } else if (a
[0] == '-') assert(0, "invalid option: '"~a
~"'");
70 if (filename
!is null) assert(0, "too many file names");
75 player
= new OPLPlayer(48000, useOPL3
);
76 version(genmidi_dumper
) {
77 player
.dumpGenMidi(stdout
);
79 if (filename
.length
== 0) assert(0, "file?");
80 auto fl
= VFile(filename
);
81 uint flen
= cast(uint)fl
.size
;
83 if (outwavname
.length
== 0) alsaOpen(2);
84 scope(exit
) alsaClose();
86 conwriteln("OPL", (useOPL3 ?
"3" : "2"), " (amp:", amp
, "): ", (outwavname
.length ?
"writing .wav from" : "playing"), " '", filename
, "'...");
87 ubyte[] fdata
= new ubyte[](flen
);
88 fl
.rawReadExact(fdata
);
89 if (!player
.load(fdata
)) assert(0, "cannot load song");
95 if (outwavname
.length
) {
96 of
= VFile(outwavname
, "w");
97 // write RIFF/WAV header
98 of
.rawWriteExact("RIFF");
99 of
.writeNum
!uint(0); // will be filled later
100 of
.rawWriteExact("WAVE");
101 of
.rawWriteExact("fmt ");
102 of
.writeNum
!uint(16);
103 of
.writeNum
!ushort(1); // pcm
104 of
.writeNum
!ushort(2); // stereo
105 of
.writeNum
!uint(48000);
106 of
.writeNum
!uint(48000*2*2);
107 of
.writeNum
!ushort(2); // block align
108 of
.writeNum
!ushort(16); // bits per sample
109 of
.rawWriteExact("data");
110 of
.writeNum
!uint(0); // will be filled later
114 while (player
.playing
) {
115 smpbufpos
= player
.generate(smpbuf
[])*2;
116 if (smpbufpos
== 0) break;
118 of
.rawWriteExact(smpbuf
[0..smpbufpos
]);
125 auto fsize
= cast(uint)of
.size
;
127 of
.writeNum
!uint(fsize
-8);
129 of
.writeNum
!uint(cast(uint)(fsize
-datapos
));