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