aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/players/player_mac.h
blob: 713d72c2ce34a3d1e26802b42cf9eeb13afe03af (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
/* 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.
 *
 */

#ifndef SCUMM_PLAYERS_PLAYER_MAC_H
#define SCUMM_PLAYERS_PLAYER_MAC_H

#include "common/scummsys.h"
#include "common/util.h"
#include "common/mutex.h"
#include "scumm/music.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"

#define RES_SND MKTAG('s', 'n', 'd', ' ')

class Mixer;

namespace Scumm {

class ScummEngine;

/**
 * Scumm Macintosh music driver, base class.
 */
class Player_Mac : public Audio::AudioStream, public MusicEngine {
public:
	Player_Mac(ScummEngine *scumm, Audio::Mixer *mixer, int numberOfChannels, int channelMask, bool fadeNoteEnds);
	virtual ~Player_Mac();

	void init();

	// MusicEngine API
	virtual void setMusicVolume(int vol);
	virtual void startSound(int sound);
	virtual void stopSound(int sound);
	virtual void stopAllSounds();
	virtual int  getMusicTimer();
	virtual int  getSoundStatus(int sound) const;

	// AudioStream API
	virtual int readBuffer(int16 *buffer, const int numSamples);
	virtual bool isStereo() const { return false; }
	virtual bool endOfData() const { return false; }
	virtual int getRate() const { return _sampleRate; }

	virtual void saveLoadWithSerializer(Common::Serializer &ser);

private:
	Common::Mutex _mutex;
	Audio::Mixer *const _mixer;
	Audio::SoundHandle _soundHandle;
	uint32 _sampleRate;
	int _soundPlaying;

	void stopAllSounds_Internal();

	struct Instrument {
		byte *_data;
		uint32 _size;
		uint32 _rate;
		uint32 _loopStart;
		uint32 _loopEnd;
		byte _baseFreq;

		uint _pos;
		uint _subPos;

		void newNote() {
			_pos = 0;
			_subPos = 0;
		}

		void generateSamples(int16 *data, int pitchModifier, int volume, int numSamples, int remainingSamplesOnNote, bool fadeNoteEnds);
	};
	friend void syncWithSerializer(Common::Serializer &, Instrument &);

	int _pitchTable[128];
	int _numberOfChannels;
	int _channelMask;
	bool _fadeNoteEnds;

	virtual bool checkMusicAvailable() { return false; }
	virtual bool loadMusic(const byte *ptr) { return false; }
	virtual bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) { return false; }

protected:
	struct Channel {
		virtual ~Channel() {}

		Instrument _instrument;
		bool _looped;
		uint32 _length;
		const byte *_data;

		uint _pos;
		int _pitchModifier;
		byte _velocity;
		uint32 _remaining;

		bool _notesLeft;

		bool loadInstrument(Common::SeekableReadStream *stream);
 	};
	friend void syncWithSerializer(Common::Serializer &, Channel &);

	ScummEngine *const _vm;
	Channel *_channel;

	uint32 durationToSamples(uint16 duration);
	int noteToPitchModifier(byte note, Instrument *instrument);
};

} // End of namespace Scumm

#endif