aboutsummaryrefslogtreecommitdiff
path: root/audio/decoders/3do.h
blob: 75243585433c249734096376aae984a96d075878 (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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

/**
 * @file
 * Sound decoder used in engines:
 *  - sherlock (3DO version of Serrated Scalpel)
 */

#ifndef AUDIO_3DO_SDX2_H
#define AUDIO_3DO_SDX2_H

#include "common/scummsys.h"
#include "common/types.h"
#include "common/substream.h"

#include "audio/audiostream.h"
#include "audio/decoders/raw.h"

namespace Common {
class SeekableReadStream;
}

namespace Audio {

class SeekableAudioStream;

// amount of bytes to be used within the decoder classes as buffers
#define AUDIO_3DO_CACHE_SIZE 1024

// persistent spaces
struct audio_3DO_ADP4_PersistentSpace {
	int16 lastSample;
	int16 stepIndex;
};

struct audio_3DO_SDX2_PersistentSpace {
	int16 lastSample1;
	int16 lastSample2;
};

class Audio3DO_ADP4_Stream : public RewindableAudioStream {
public:
	Audio3DO_ADP4_Stream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_ADP4_PersistentSpace *persistentSpace);

protected:
	const uint16 _sampleRate;
	const bool _stereo;

	Common::DisposablePtr<Common::SeekableReadStream> _stream;
	int32 _streamBytesLeft;

	void reset();
	bool rewind();
	bool endOfData() const { return (_stream->pos() >= _stream->size()); }
	bool isStereo() const { return _stereo; }
	int getRate() const { return _sampleRate; }

	int readBuffer(int16 *buffer, const int numSamples);

	bool _initialRead;
	audio_3DO_ADP4_PersistentSpace *_callerDecoderData;
	audio_3DO_ADP4_PersistentSpace _initialDecoderData;
	audio_3DO_ADP4_PersistentSpace _curDecoderData;

private:
	int16 decodeSample(byte compressedNibble);
};

class Audio3DO_SDX2_Stream : public RewindableAudioStream {
public:
	Audio3DO_SDX2_Stream(Common::SeekableReadStream *stream, uint16 sampleRate, bool stereo, DisposeAfterUse::Flag disposeAfterUse, audio_3DO_SDX2_PersistentSpace *persistentSpacePtr);

protected:
	const uint16 _sampleRate;
	const bool _stereo;

	Common::DisposablePtr<Common::SeekableReadStream> _stream;
	int32 _streamBytesLeft;

	void reset();
	bool rewind();
	bool endOfData() const { return (_stream->pos() >= _stream->size()); }
	bool isStereo() const { return _stereo; }
	int getRate() const { return _sampleRate; }

	int readBuffer(int16 *buffer, const int numSamples);

	bool _initialRead;
	audio_3DO_SDX2_PersistentSpace *_callerDecoderData;
	audio_3DO_SDX2_PersistentSpace _initialDecoderData;
	audio_3DO_SDX2_PersistentSpace _curDecoderData;
};

/**
 * Try to decode 3DO ADP4 data from the given seekable stream and create a SeekableAudioStream
 * from that data.
 *
 * @param stream			the SeekableReadStream from which to read the 3DO SDX2 data
 * @sampleRate				sample rate
 * @stereo					if it's stereo or mono
 * @audioLengthMSecsPtr		pointer to a uint32 variable, that is supposed to get the length of the audio in milliseconds
 * @disposeAfterUse			disposeAfterUse	whether to delete the stream after use
 * @persistentSpacePtr		pointer to the persistent space structure
 * @return					a new SeekableAudioStream, or NULL, if an error occurred
 */
RewindableAudioStream *make3DO_ADP4AudioStream(
	Common::SeekableReadStream *stream,
	uint16 sampleRate,
	bool stereo,
	uint32 *audioLengthMSecsPtr = NULL, // returns the audio length in milliseconds
	DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES,
	audio_3DO_ADP4_PersistentSpace *persistentSpacePtr = NULL
);

/**
 * Try to decode 3DO SDX2 data from the given seekable stream and create a SeekableAudioStream
 * from that data.
 *
 * @param stream			the SeekableReadStream from which to read the 3DO SDX2 data
 * @sampleRate				sample rate
 * @stereo					if it's stereo or mono
 * @audioLengthMSecsPtr		pointer to a uint32 variable, that is supposed to get the length of the audio in milliseconds
 * @disposeAfterUse			disposeAfterUse	whether to delete the stream after use
 * @persistentSpacePtr		pointer to the persistent space structure
 * @return					a new SeekableAudioStream, or NULL, if an error occurred
 */
RewindableAudioStream *make3DO_SDX2AudioStream(
	Common::SeekableReadStream *stream,
	uint16 sampleRate,
	bool stereo,
	uint32 *audioLengthMSecsPtr = NULL, // returns the audio length in milliseconds
	DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES,
	audio_3DO_SDX2_PersistentSpace *persistentSpacePtr = NULL
);

} // End of namespace Audio

#endif