1 module tinysid
/*is aliced*/;
8 import iv
.follin
.resampler
;
9 import iv
.follin
.utils
;
17 // ////////////////////////////////////////////////////////////////////////// //
18 enum BUF_SIZE
= 882; // Audio Buffer size, in samples
20 __gshared
short[BUF_SIZE
*16] soundbuffer
; // the soundbuffer
21 __gshared SpeexResampler
rsm;
24 // ////////////////////////////////////////////////////////////////////////// //
25 void main (string
[] args
) {
26 if (args
.length
< 2) {
27 conwriteln("TinySID v0.94");
28 conwriteln("(c)Copyright 1999-2006 T. Hinrichs and R. Sinsch.");
29 conwriteln("All rights reserved.");
33 if (ttyIsRedirected
) assert(0, "no redirects, please!");
35 concmd("exec tinysid.rc tan");
36 conProcessQueue(); // load config
37 conProcessArgs
!true(args
);
40 scope(exit
) ttySetNormal();
43 alsaDevice
= "plug:default";
45 float[] rsfbufi
, rsfbufo
;
48 mainloop
: while (idx
< args
.length
) {
49 string fname
= args
[idx
];
51 auto fl
= VFile(fname
);
52 ubyte speed
= c64SidGetSpeed(fl
);
54 c64Init(/*speed == 1*/);
56 if (!alsaInit(44100, 1)) assert(0, "error initializing ALSA");
57 scope(exit
) alsaShutdown(true);
59 conwriteln("ALSA initialized; real sampling rate is ", alsaRealRate
, "Hz");
61 conwriteln("Loading '", args
[1], "'...");
65 conwriteln("TITLE : ", song
.name
);
66 conwriteln("AUTHOR : ", song
.author
);
67 conwriteln("COPYRIGHT: ", song
.copyright
);
68 conwriteln("SPEED : ", speed
);
70 cpuJSR(song
.init_addr
, song
.sub_song_start
);
71 //conwriteln("Playing... Hit ^C to quit.");
73 ushort play_addr
= song
.play_addr
;
74 ubyte play_speed
= song
.speed
;
76 //conwriteln("SPEED : ", play_speed);
78 auto stt
= MonoTime
.currTime
;
79 auto stu
= MonoTime
.zero
;
86 rsm.setup(1, 44100*2, 44100, 8);
91 if (play_speed
== 0) {
92 // Single Speed (50Hz); render 16*50Hz buffer
93 foreach (immutable j
; 0..8) {
95 synth_render(&soundbuffer
[BUF_SIZE
*j
], BUF_SIZE
);
97 } else if (play_speed
== 1) {
98 // Double Speed (100Hz); render 16*50Hz buffer
99 foreach (immutable j
; 0..16) {
100 cpuJSR(play_addr
, 0);
101 synth_render(&soundbuffer
[BUF_SIZE
/2*j
], BUF_SIZE
/2);
104 assert(0, "invalid playing speed");
106 alsaWriteShort(soundbuffer
[0..BUF_SIZE
*8]); // mono
108 foreach (immutable j; 0..8) {
109 cpuJSR(play_addr, 0);
110 synth_render(&soundbuffer[BUF_SIZE*j], BUF_SIZE);
113 // oops, must resample
114 SpeexResampler.Data srbdata;
115 if (rsfbufi.length < BUF_SIZE*8) rsfbufi.length = BUF_SIZE*8;
116 if (rsfbufo.length < BUF_SIZE*8) rsfbufo.length = BUF_SIZE*8;
117 tflShort2Float(soundbuffer[0..BUF_SIZE*8], rsfbufi[0..BUF_SIZE*8]);
120 srbdata = srbdata.init; // just in case
121 srbdata.dataIn = rsfbufi[inpos..BUF_SIZE*8];
122 srbdata.dataOut = rsfbufo[];
123 if (rsm.process(srbdata) != 0) assert(0, "resampling error");
124 if (srbdata.outputSamplesUsed) {
125 tflFloat2Short(rsfbufo[0..srbdata.outputSamplesUsed], soundbuffer[0..srbdata.outputSamplesUsed]);
126 //outSoundFlushX(b, srbdata.outputSamplesUsed*2);
127 //conwriteln("RSM: ", srbdata.outputSamplesUsed);
128 alsaWriteShort(soundbuffer[0..srbdata.outputSamplesUsed]); // mono
130 // no data consumed, no data produced, so we're done
131 if (inpos >= BUF_SIZE*8) break;
133 inpos += cast(uint)srbdata.inputSamplesUsed;
136 alsaWriteShort(soundbuffer[0..BUF_SIZE*8]); // mono
140 soundbuffer
[0..BUF_SIZE
*8] = 0;
141 alsaWriteShort(soundbuffer
[0..BUF_SIZE
*8]); // mono
144 while (ttyIsKeyHit
) {
145 auto key
= ttyReadKey(0, 20);
146 if (!ttyconEvent(key
)) {
148 case TtyEvent
.Key
.Char
:
149 if (key
.ch
== '<') { if (idx
> 1) { ttyRawWrite("\n"); --idx
; continue mainloop
; } }
150 if (key
.ch
== '>') { ttyRawWrite("\n"); ++idx
; continue mainloop
; }
151 if (key
.ch
== 'q') { ttyRawWrite("\n"); break mainloop
; }
154 auto ctt
= MonoTime
.currTime
;
156 auto cms
= (ctt
-stt
).total
!"msecs"+msecs
;
157 msecs
= cast(uint)cms
;
168 auto ctt
= MonoTime
.currTime
;
169 auto cms
= (ctt
-stt
).total
!"msecs"+msecs
;
170 if (cms
>= 2*60*1000) break;
171 if ((ctt
-stu
).total
!"seconds" >= 1) {
172 import core
.stdc
.stdio
: snprintf
;
175 auto len
= snprintf(tmp
.ptr
, tmp
.length
, "\r%02u:%02u", cast(uint)(cms
/1000/60), cast(uint)(cms
/1000%60));
176 ttyRawWrite(tmp
[0..len
]);