1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "stdafx.hpp"
24
25 #include "Amiga/paula.hpp"
26 #include "Amiga/rjp1.hpp"
27
28 namespace Audio {
29
Rjp1(int rate,bool stereo)30 Rjp1::Rjp1(int rate, bool stereo)
31 : Paula(stereo, rate, rate / 50) {
32 memset(&_vars, 0, sizeof(_vars));
33 memset(_channelsTable, 0, sizeof(_channelsTable));
34 }
35
~Rjp1()36 Rjp1::~Rjp1() {
37 unload();
38 }
39
load(tSharedBuffer pSong,tSharedBuffer pInstruments)40 bool Rjp1::load(tSharedBuffer pSong, tSharedBuffer pInstruments ) {
41 uint8* songData = pSong->data();
42 uint8* instrumentsData = pInstruments->data();
43
44 if ( readBEDWord(songData) == 'RJP1' && readBEDWord(songData + 4) == 'SMOD') {
45 songData += 8;
46
47 for (int i = 0; i < 7; ++i) {
48 uint32 size = readBEDWord(songData);
49 songData += 4;
50
51 _vars.songDataSize[i] = size;
52 _vars.songData[i] = (uint8 *)malloc(size);
53 if (!_vars.songData[i])
54 return false;
55
56 memcpy( _vars.songData[i], songData, size );
57 songData += size;
58
59 switch (i) {
60 case 0:
61 _vars.instrumentsCount = size / 32;
62 break;
63 case 1:
64 break;
65 case 2:
66 // sequence index to offsets, 1 per channel
67 _vars.subsongsCount = size / 4;
68 break;
69 case 3:
70 case 4:
71 // sequence offsets
72 break;
73 case 5:
74 case 6:
75 // sequence data
76 break;
77 }
78 }
79
80 if (readBEDWord(instrumentsData) == 'RJP1') {
81 instrumentsData += 4;
82
83 size_t size = pInstruments->size() - 4;
84 _vars.instData = (int8 *)malloc(size);
85 _vars.instDataSize = (uint32)size;
86
87 if (!_vars.instData)
88 return false;
89
90 memcpy( _vars.instData, instrumentsData, size );
91 instrumentsData += size;
92 }
93 }
94
95 return true;
96 }
97
unload()98 void Rjp1::unload() {
99 for (int i = 0; i < 7; ++i) {
100 free(_vars.songData[i]);
101 }
102 free(_vars.instData);
103 memset(&_vars, 0, sizeof(_vars));
104 memset(_channelsTable, 0, sizeof(_channelsTable));
105 }
106
startPattern(int ch,int pat)107 void Rjp1::startPattern(int ch, int pat) {
108 Rjp1Channel *channel = &_channelsTable[ch];
109 _vars.activeChannelsMask |= 1 << ch;
110 channel->sequenceData = readBEDWord(_vars.songData[4] + pat * 4) + _vars.songData[6];
111 channel->loopSeqCount = 6;
112 channel->loopSeqCur = channel->loopSeq2Cur = 1;
113 channel->active = true;
114 channel->isSfx = true;
115 // "start" Paula audiostream
116 startPaula();
117 }
118
startSong(int song)119 void Rjp1::startSong(int song) {
120 if (song == 0 || song >= _vars.subsongsCount) {
121 //warning("Invalid subsong number %d, defaulting to 1", song);
122 //song = 1;
123 }
124 const uint8 *p = _vars.songData[2] + (song & 0x3F) * 4;
125 for (int i = 0; i < 4; ++i) {
126 uint8 seq = *p++;
127 if (seq) {
128 startSequence(i, seq);
129 }
130 }
131 // "start" Paula audiostream
132 startPaula();
133 }
134
startSequence(uint8 channelNum,uint8 seqNum)135 void Rjp1::startSequence(uint8 channelNum, uint8 seqNum) {
136 Rjp1Channel *channel = &_channelsTable[channelNum];
137 _vars.activeChannelsMask |= 1 << channelNum;
138 if (seqNum != 0) {
139 const uint8 *p = readBEDWord(_vars.songData[3] + seqNum * 4) + _vars.songData[5];
140 uint8 seq = *p++;
141 channel->sequenceOffsets = p;
142 channel->sequenceData = readBEDWord(_vars.songData[4] + seq * 4) + _vars.songData[6];
143 channel->loopSeqCount = 6;
144 channel->loopSeqCur = channel->loopSeq2Cur = 1;
145 channel->active = true;
146 } else {
147 channel->active = false;
148 turnOffChannel(channel);
149 }
150 }
151
turnOffChannel(Rjp1Channel * channel)152 void Rjp1::turnOffChannel(Rjp1Channel *channel) {
153 stopPaulaChannel(channel - _channelsTable);
154 }
155
playChannel(Rjp1Channel * channel)156 void Rjp1::playChannel(Rjp1Channel *channel) {
157 if (channel->active && channel->sequenceData) {
158 turnOnChannel(channel);
159 if (channel->sequenceData) {
160 playSongSequence(channel);
161 }
162 modulateVolume(channel);
163 modulatePeriod(channel);
164 }
165 }
166
turnOnChannel(Rjp1Channel * channel)167 void Rjp1::turnOnChannel(Rjp1Channel *channel) {
168 if (channel->setupNewNote) {
169 channel->setupNewNote = false;
170 setupPaulaChannel(channel - _channelsTable, channel->data, channel->pos, channel->len, channel->repeatPos, channel->repeatLen);
171 }
172 }
173
executeSfxSequenceOp(Rjp1Channel * channel,uint8 code,const uint8 * & p)174 bool Rjp1::executeSfxSequenceOp(Rjp1Channel *channel, uint8 code, const uint8 *&p) {
175 bool loop = true;
176 switch (code & 7) {
177 case 0:
178 _vars.activeChannelsMask &= ~(1 << _vars.currentChannel);
179 loop = false;
180 stopPaula();
181 break;
182 case 1:
183 setRelease(channel);
184 loop = false;
185 break;
186 case 2:
187 channel->loopSeqCount = *p++;
188 break;
189 case 3:
190 channel->loopSeq2Count = *p++;
191 break;
192 case 4:
193 code = *p++;
194 if (code != 0) {
195 setupInstrument(channel, code);
196 }
197 break;
198 case 7:
199 loop = false;
200 break;
201 }
202 return loop;
203 }
204
executeSongSequenceOp(Rjp1Channel * channel,uint8 code,const uint8 * & p)205 bool Rjp1::executeSongSequenceOp(Rjp1Channel *channel, uint8 code, const uint8 *&p) {
206 bool loop = true;
207 const uint8 *offs;
208 switch (code & 7) {
209 case 0:
210 offs = channel->sequenceOffsets;
211 channel->loopSeq2Count = 1;
212 while (1) {
213 code = *offs++;
214 if (code != 0) {
215 channel->sequenceOffsets = offs;
216 p = readBEDWord(_vars.songData[4] + code * 4) + _vars.songData[6];
217 break;
218 } else {
219 code = offs[0];
220 if (code == 0) {
221 p = 0;
222 channel->active = false;
223 _vars.activeChannelsMask &= ~(1 << _vars.currentChannel);
224 loop = false;
225 break;
226 } else if (code & 0x80) {
227 code = offs[1];
228 offs = readBEDWord(_vars.songData[3] + code * 4) + _vars.songData[5];
229 } else {
230 offs -= code;
231 }
232 }
233 }
234 break;
235 case 1:
236 setRelease(channel);
237 loop = false;
238 break;
239 case 2:
240 channel->loopSeqCount = *p++;
241 break;
242 case 3:
243 channel->loopSeq2Count = *p++;
244 break;
245 case 4:
246 code = *p++;
247 if (code != 0) {
248 if (code >= _vars.instrumentsCount)
249 code = 0;
250
251 setupInstrument(channel, code);
252 }
253 break;
254 case 5:
255 channel->volumeScale = *p++;
256 break;
257 case 6:
258 channel->freqStep = *p++;
259 channel->freqInc = readBEDWord(p); p += 4;
260 channel->freqInit = 0;
261 break;
262 case 7:
263 loop = false;
264 break;
265 }
266 return loop;
267 }
268
playSongSequence(Rjp1Channel * channel)269 void Rjp1::playSongSequence(Rjp1Channel *channel) {
270 const uint8 *p = channel->sequenceData;
271 --channel->loopSeqCur;
272 if (channel->loopSeqCur == 0) {
273 --channel->loopSeq2Cur;
274 if (channel->loopSeq2Cur == 0) {
275 bool loop = true;
276 do {
277 uint8 code = *p++;
278 if (code & 0x80) {
279 if (channel->isSfx) {
280 loop = executeSfxSequenceOp(channel, code, p);
281 } else {
282 loop = executeSongSequenceOp(channel, code, p);
283 }
284 } else {
285 code >>= 1;
286 if (code < _periodsCount) {
287 setupNote(channel, _periodsTable[code]);
288 }
289 loop = false;
290 }
291 } while (loop);
292 channel->sequenceData = p;
293 channel->loopSeq2Cur = channel->loopSeq2Count;
294 }
295 channel->loopSeqCur = channel->loopSeqCount;
296 }
297 }
298
modulateVolume(Rjp1Channel * channel)299 void Rjp1::modulateVolume(Rjp1Channel *channel) {
300 modulateVolumeEnvelope(channel);
301 modulateVolumeWaveform(channel);
302 setVolume(channel);
303 }
304
modulatePeriod(Rjp1Channel * channel)305 void Rjp1::modulatePeriod(Rjp1Channel *channel) {
306 if (channel->modulatePeriodData) {
307 uint32 per = channel->modulatePeriodIndex;
308 int period = (channel->modulatePeriodData[per] * channel->modulatePeriodInit) / 128;
309 period = -period;
310 if (period < 0) {
311 period /= 2;
312 }
313 channel->modulatePeriodNext = period + channel->modulatePeriodInit;
314 ++per;
315 if (per == channel->modulatePeriodLimit) {
316 per = channel->modulatePeriodBase * 2;
317 }
318 channel->modulatePeriodIndex = per;
319 }
320 if (channel->freqStep != 0) {
321 channel->freqInit += channel->freqInc;
322 --channel->freqStep;
323 }
324 setChannelPeriod(channel - _channelsTable, channel->freqInit + channel->modulatePeriodNext);
325 }
326
setupNote(Rjp1Channel * channel,int16 period)327 void Rjp1::setupNote(Rjp1Channel *channel, int16 period) {
328 const uint8 *note = channel->noteData;
329 if (note) {
330 channel->modulatePeriodInit = channel->modulatePeriodNext = period;
331 channel->freqInit = 0;
332 const int8 *e = (const int8 *)_vars.songData[1] + readBEWord(note + 12);
333 channel->envelopeData = e;
334 channel->envelopeStart = e[1];
335 channel->envelopeScale = e[1] - e[0];
336 channel->envelopeEnd2 = e[2];
337 channel->envelopeEnd1 = e[2];
338 channel->envelopeMode = 4;
339 channel->data = channel->waveData;
340 channel->pos = readBEWord(note + 16);
341 channel->len = channel->pos + readBEWord(note + 18);
342 channel->setupNewNote = true;
343 }
344 }
345
setupInstrument(Rjp1Channel * channel,uint8 num)346 void Rjp1::setupInstrument(Rjp1Channel *channel, uint8 num) {
347 if (channel->currentInstrument != num) {
348 channel->currentInstrument = num;
349 const uint8 *p = _vars.songData[0] + num * 32;
350 channel->noteData = p;
351 channel->repeatPos = readBEWord(p + 20);
352 channel->repeatLen = readBEWord(p + 22);
353 channel->volumeScale = readBEWord(p + 14);
354 channel->modulatePeriodBase = readBEWord(p + 24);
355 channel->modulatePeriodIndex = 0;
356 channel->modulatePeriodLimit = readBEWord(p + 26) * 2;
357 channel->modulateVolumeBase = readBEWord(p + 28);
358 channel->modulateVolumeIndex = 0;
359 channel->modulateVolumeLimit = readBEWord(p + 30) * 2;
360 channel->waveData = _vars.instData + readBEDWord(p);
361 uint32 off = readBEDWord(p + 4);
362 channel->modulatePeriodData = _vars.instData + off;
363 off = readBEDWord(p + 8);
364 channel->modulateVolumeData = _vars.instData + off;
365 }
366 }
367
setRelease(Rjp1Channel * channel)368 void Rjp1::setRelease(Rjp1Channel *channel) {
369 const int8 *e = channel->envelopeData;
370 if (e) {
371 channel->envelopeStart = 0;
372 channel->envelopeScale = -channel->envelopeVolume;
373 channel->envelopeEnd2 = e[5];
374 channel->envelopeEnd1 = e[5];
375 channel->envelopeMode = -1;
376 }
377 }
378
modulateVolumeEnvelope(Rjp1Channel * channel)379 void Rjp1::modulateVolumeEnvelope(Rjp1Channel *channel) {
380 if (channel->envelopeMode) {
381 int16 es = channel->envelopeScale;
382 if (es) {
383 int8 m = channel->envelopeEnd1;
384 if (m == 0) {
385 es = 0;
386 } else {
387 es *= m;
388 m = channel->envelopeEnd2;
389 if (m == 0) {
390 es = 0;
391 } else {
392 es /= m;
393 }
394 }
395 }
396 channel->envelopeVolume = channel->envelopeStart - es;
397 --channel->envelopeEnd1;
398 if (channel->envelopeEnd1 == -1) {
399 switch (channel->envelopeMode) {
400 case 0:
401 break;
402 case 2:
403 setSustain(channel);
404 break;
405 case 4:
406 setDecay(channel);
407 break;
408 case -1:
409 setSustain(channel);
410 break;
411 default:
412 //error("Unhandled envelope mode %d", channel->envelopeMode);
413 break;
414 }
415 return;
416 }
417 }
418 channel->volume = channel->envelopeVolume;
419 }
420
setSustain(Rjp1Channel * channel)421 void Rjp1::setSustain(Rjp1Channel *channel) {
422 channel->envelopeMode = 0;
423 }
424
setDecay(Rjp1Channel * channel)425 void Rjp1::setDecay(Rjp1Channel *channel) {
426 const int8 *e = channel->envelopeData;
427 if (e) {
428 channel->envelopeStart = e[3];
429 channel->envelopeScale = e[3] - e[1];
430 channel->envelopeEnd2 = e[4];
431 channel->envelopeEnd1 = e[4];
432 channel->envelopeMode = 2;
433 }
434 }
435
modulateVolumeWaveform(Rjp1Channel * channel)436 void Rjp1::modulateVolumeWaveform(Rjp1Channel *channel) {
437 if (channel->modulateVolumeData) {
438 uint32 i = channel->modulateVolumeIndex;
439 channel->volume += channel->modulateVolumeData[i] * channel->volume / 128;
440 ++i;
441 if (i == channel->modulateVolumeLimit) {
442 i = channel->modulateVolumeBase * 2;
443 }
444 channel->modulateVolumeIndex = i;
445 }
446 }
447
CLIP(T v,T amin,T amax)448 template<typename T> inline T CLIP(T v, T amin, T amax) {
449 if (v < amin) return amin; else if (v > amax) return amax; else return v;
450 }
451
setVolume(Rjp1Channel * channel)452 void Rjp1::setVolume(Rjp1Channel *channel) {
453 channel->volume = (channel->volume * channel->volumeScale) / 64;
454 //channel->volume = CLIP<uint8>(channel->volume, 0, 64);
455 setChannelVolume(channel - _channelsTable, (uint8) channel->volume);
456 }
457
stopPaulaChannel(size_t channel)458 void Rjp1::stopPaulaChannel(size_t channel) {
459 clearVoice((uint8) channel);
460 }
461
setupPaulaChannel(size_t channel,const int8 * waveData,uint16 offset,uint16 len,uint16 repeatPos,uint16 repeatLen)462 void Rjp1::setupPaulaChannel(size_t channel, const int8 *waveData, uint16 offset, uint16 len, uint16 repeatPos, uint16 repeatLen) {
463 if (waveData) {
464 setChannelData(channel, waveData, waveData + repeatPos * 2, len * 2, repeatLen * 2, offset * 2);
465 }
466 }
467
interrupt()468 void Rjp1::interrupt() {
469 for (int i = 0; i < 4; ++i) {
470 _vars.currentChannel = i;
471 if(_channelsTable[i].sequenceData)
472 playChannel(&_channelsTable[i]);
473 }
474 }
475
476 const int16 Rjp1::_periodsTable[] = {
477 0x01C5, 0x01E0, 0x01FC, 0x021A, 0x023A, 0x025C, 0x0280, 0x02A6, 0x02D0,
478 0x02FA, 0x0328, 0x0358, 0x00E2, 0x00F0, 0x00FE, 0x010D, 0x011D, 0x012E,
479 0x0140, 0x0153, 0x0168, 0x017D, 0x0194, 0x01AC, 0x0071, 0x0078, 0x007F,
480 0x0087, 0x008F, 0x0097, 0x00A0, 0x00AA, 0x00B4, 0x00BE, 0x00CA, 0x00D6
481 };
482
483 const int Rjp1::_periodsCount = (sizeof( _periodsTable ) / sizeof( *_periodsTable ));
484
makeRjp1Stream(tSharedBuffer songData,tSharedBuffer instrumentsData,int num,int rate,bool stereo)485 Rjp1 *makeRjp1Stream(tSharedBuffer songData, tSharedBuffer instrumentsData, int num, int rate, bool stereo) {
486 Rjp1 *stream = new Rjp1(rate, stereo);
487 if (stream->load(songData, instrumentsData)) {
488 if (num < 0) {
489 stream->startPattern(3, -num);
490 } else {
491 stream->startSong(num);
492 }
493 return stream;
494 }
495 delete stream;
496 return 0;
497 }
498
499 } // End of namespace Audio
500