aboutsummaryrefslogtreecommitdiff
path: root/scumm/smush/channel.h
blob: 6b9390d300f061bdc506082339ef14ffa3ea82bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2002-2003 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header$
 *
 */

#ifndef SMUSH_CHANNEL_H
#define SMUSH_CHANNEL_H

#include "common/util.h"

class Chunk;
class ContChunk;
	
class SmushChannel {
public:

	virtual ~SmushChannel() {};
	virtual bool appendData(Chunk &b, int32 size) = 0;
	virtual bool setParameters(int32, int32, int32, int32) = 0;
	virtual bool checkParameters(int32, int32, int32, int32, int32) = 0;
	virtual bool isTerminated() const = 0;
	virtual int32 availableSoundData() const = 0;
	virtual void getSoundData(int16 *sound_buffer, int32 size) = 0;
	virtual void getSoundData(int8 *sound_buffer, int32 size) = 0;
	virtual int32 getRate() = 0;
	virtual bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) = 0;
	virtual int32 getTrackIdentifier() const = 0;
};

class SaudChannel : public SmushChannel {
private:
	int32 _track;
	int32 _nbframes;
	int32 _dataSize;
	int32 _frequency;
	bool _inData;
	bool _markReached;
	int32 _flags;
	int32 _volume;
	int32 _balance;
	int32 _index;
	int16 _voltable[2][256];
	byte *_tbuffer;
	int32 _tbufferSize;
	byte *_sbuffer;
	int32 _sbufferSize;

protected:
	void handleStrk(Chunk &c);
	void handleSmrk(Chunk &c);
	void handleShdr(Chunk &c);
	bool handleSubTags(int32 &offset);
	bool processBuffer();
	void recalcVolumeTable();

public:
	SaudChannel(int32 track, int32 freq);
	virtual ~SaudChannel();
	bool isTerminated() const;
	bool setParameters(int32 duration, int32 flags, int32 vol1, int32 vol2);
	bool checkParameters(int32 index, int32 duration, int32 flags, int32 vol1, int32 vol2);
	bool appendData(Chunk &b, int32 size);
	int32 availableSoundData() const;
	void getSoundData(int16 *sound_buffer, int32 size);
	void getSoundData(int8 *sound_buffer, int32 size) { error("16bit request for SAUD channel should never happen"); };
	int32 getRate() { return _frequency; }
	bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) { 
		rate = _frequency;
		stereo = true;
		is_16bit = true;
		return true;
	};
	virtual int32 getTrackIdentifier() const { return _track; };
};

class ImuseChannel : public SmushChannel {
private:
	int32 _track;				//!< the track number
	byte *_tbuffer;	//!< data temporary buffer
	int32 _tbufferSize;			//!< temporary buffer size
	byte *_sbuffer;	//!< sound buffer
	int32 _sbufferSize;			//!< sound buffer size
	int32 _srbufferSize;
	int32 _frequency;			//!< the target frequency of the ::mixer
	int32 _dataSize;			//!< remaining size of sound data in the iMUS buffer
	bool _inData;
	int32 _volume;

	int32 _bitsize;			//!< the bitsize of the original data
	int32 _rate;				//!< the sampling rate of the original data
	int32 _channels;			//!< the number of channels of the original data

protected:
	int32 decode(int32 size, int32 &ret);
	void decode();
	bool processBuffer();
	bool handleMap(Chunk &);
	bool handleFormat(Chunk &);
	bool handleText(Chunk &);
	bool handleRegion(Chunk &);
	bool handleStop(Chunk &);
	bool handleSubTags(int32 & offset);

public:
	ImuseChannel(int32 track, int32 freq);
	virtual ~ImuseChannel();
	bool isTerminated() const;
	bool setParameters(int32 nbframes, int32 size, int32 track_flags, int32 unk1);
	bool checkParameters(int32 index, int32 nbframes, int32 size, int32 track_flags, int32 unk1);
	bool appendData(Chunk &b, int32 size);
	int32 availableSoundData() const;
	void getSoundData(int16 *sound_buffer, int32 size);
	void getSoundData(int8 *sound_buffer, int32 size);
	int32 getRate() { return _rate; }
	bool getParameters(int32 &rate, bool &stereo, bool &is_16bit) {
		rate = _rate;
		stereo = (_channels == 2);
		is_16bit = (_bitsize > 8);
		return true;
	};
	virtual int32 getTrackIdentifier() const { return _track; };
};

#endif