21 static const unsigned BAUDRATE = 3744;
22 static const unsigned OUTPUT_FREQUENCY = 4 * BAUDRATE;
33 static const unsigned AUDIO_OVERSAMPLE = 4;
36 static const unsigned SHORT_SILENCE = OUTPUT_FREQUENCY * 1;
37 static const unsigned LONG_SILENCE = OUTPUT_FREQUENCY * 2;
40 static const unsigned LONG_HEADER = 16000 / 2;
41 static const unsigned SHORT_HEADER = 4000 / 2;
44 static const byte CAS_HEADER [ 8] = { 0x1F,0xA6,0xDE,0xBA,0xCC,0x13,0x7D,0x74 };
45 static const byte ASCII_HEADER [10] = { 0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA,0xEA };
46 static const byte BINARY_HEADER[10] = { 0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0,0xD0 };
47 static const byte BASIC_HEADER [10] = { 0xD3,0xD3,0xD3,0xD3,0xD3,0xD3,0xD3,0xD3,0xD3,0xD3 };
53 convert(filename, filePool, cliComm);
60 return pos < output.size() ? output[pos] * 256 : 0;
66 clk += unsigned(output.size());
72 return OUTPUT_FREQUENCY * AUDIO_OVERSAMPLE;
77 size_t nbSamples = output.size();
78 if ((pos / AUDIO_OVERSAMPLE) < nbSamples) {
79 for (
auto i :
xrange(num)) {
80 bufs[0][i] = ((pos / AUDIO_OVERSAMPLE) < nbSamples)
81 ? output[pos / AUDIO_OVERSAMPLE] * 256
90 void CasImage::write0()
92 output.push_back( 127);
93 output.push_back( 127);
94 output.push_back(-127);
95 output.push_back(-127);
97 void CasImage::write1()
99 output.push_back( 127);
100 output.push_back(-127);
101 output.push_back( 127);
102 output.push_back(-127);
106 void CasImage::writeHeader(
int s)
108 for (
int i = 0; i < s; ++i) {
114 void CasImage::writeSilence(
int s)
116 output.insert(output.end(), s, 0);
120 void CasImage::writeByte(
byte b)
125 for (
auto i :
xrange(8)) {
138 bool CasImage::writeData(
const byte* buf,
size_t size,
size_t& pos)
141 while ((pos + 8) <= size) {
142 if (!memcmp(&buf[pos], CAS_HEADER, 8)) {
146 if (buf[pos] == 0x1A) {
152 writeByte(buf[pos++]);
157 void CasImage::convert(
const Filename& filename, FilePool& filePool, CliComm& cliComm)
161 const byte* buf = file.mmap(size);
164 bool issueWarning =
false;
165 bool headerFound =
false;
166 bool firstFile =
true;
168 while ((pos + 8) <= size) {
169 if (!memcmp(&buf[pos], CAS_HEADER, 8)) {
175 writeSilence(LONG_SILENCE);
176 writeHeader(LONG_HEADER);
177 if ((pos + 10) <= size) {
180 if (!memcmp(&buf[pos], ASCII_HEADER, 10)) {
182 }
else if (!memcmp(&buf[pos], BINARY_HEADER, 10)) {
184 }
else if (!memcmp(&buf[pos], BASIC_HEADER, 10)) {
190 writeData(buf, size, pos);
194 writeSilence(SHORT_SILENCE);
195 writeHeader(SHORT_HEADER);
196 eof = writeData(buf, size, pos);
197 }
while (!eof && ((pos + 8) <= size));
201 writeData(buf, size, pos);
202 writeSilence(SHORT_SILENCE);
203 writeHeader(SHORT_HEADER);
205 writeData(buf, size, pos);
209 writeData(buf, size, pos);
214 writeData(buf, size, pos);
219 PRT_DEBUG(
"CAS2WAV: skipping unhandled data");
225 throw MSXException(filename.getOriginal() +
226 ": not a valid CAS image");
229 cliComm.printWarning(
"Skipped unhandled data in " +
230 filename.getOriginal());
234 file.setFilePool(filePool);