aboutsummaryrefslogtreecommitdiff
path: root/sound/mixer.h
blob: abc511ff712c86ce53491ca0adeca6e7eb5a3f8f (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
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-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 MIXER_H
#define MIXER_H

#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#ifdef USE_MAD
#include <mad.h>
#endif
#ifdef USE_VORBIS
#include <vorbis/vorbisfile.h>
#endif
#include "stdafx.h"
#include "common/scummsys.h"
#include "common/system.h"


typedef uint32 PlayingSoundHandle;

class Channel;
class File;

class SoundMixer {
public:
	typedef void PremixProc (void *param, int16 *data, uint len);

	enum {
		NUM_CHANNELS = 16
	};

private:
	OSystem *_syst;
	OSystem::MutexRef _mutex;

	void *_premixParam;
	PremixProc *_premixProc;

public:
	uint _outputRate;

	int16 *_volumeTable;
	int _musicVolume;

	bool _paused;

	Channel *_channels[NUM_CHANNELS];

public:
	SoundMixer();
	~SoundMixer();

	// start playing a raw sound
	enum {
		// Do *NOT* change any of these flags without looking at the code in mixer.cpp
		FLAG_UNSIGNED = 1 << 0,         // unsigned samples
		FLAG_STEREO = 1 << 1,           // sound is in stereo
		FLAG_16BITS = 1 << 2,           // sound is 16 bits wide
		FLAG_AUTOFREE = 1 << 3,         // sound buffer is freed automagically at the end of playing
		FLAG_REVERSE_STEREO = 1 << 4,   // sound should be reverse stereo
		FLAG_LOOP = 1 << 5              // loop the audio
	};
	int playRaw(PlayingSoundHandle *handle, void *sound, uint32 size, uint rate, byte flags, int id = -1);
#ifdef USE_MAD
	int playMP3(PlayingSoundHandle *handle, void *sound, uint32 size, byte flags);
	int playMP3CDTrack(PlayingSoundHandle *handle, File *file, mad_timer_t duration);
#endif
#ifdef USE_VORBIS
	int playVorbis(PlayingSoundHandle *handle, OggVorbis_File *ov_file, int duration, bool is_cd_track);
#endif

	/** Premix procedure, useful when using fmopl adlib */
	void setupPremix(void * param, PremixProc * proc);

	/** stop all currently playing sounds */
	void stopAll();

	/** stop playing the given channel */
	void stop(int channel);

	/** stop playing the sound with given ID  */
	void stopID(int id);

	/** stop playing the channel for the given handle */
	void stopHandle(PlayingSoundHandle handle);

	/** Start a new stream. */
	int newStream(void *sound, uint32 size, uint rate, byte flags, uint32 buffer_size);

	/** Append to an existing stream. */
	void appendStream(int index, void * sound, uint32 size);

	/** Mark a stream as finished - it will play all its remaining data, then stop. */
	void endStream(int index);

	/** Check whether any SFX channel is active.*/
	bool hasActiveSFXChannel();
	
	/** Check whether the specified channel is active. */
	bool isActiveChannel(int index);

	/** bind to the OSystem object => mixer will be
	 * invoked automatically when samples need
	 * to be generated */
	bool bindToSystem(OSystem *syst);

	/** set the global volume, 0-256 */
	void setVolume(int volume);

	/** set the music volume, 0-256 */
	void setMusicVolume(int volume);

	/** pause - unpause */
	void pause(bool paused);

private:
	int insertChannel(PlayingSoundHandle *handle, Channel *chan);

	/** mix */
	void mix(int16 * buf, uint len);

	static void onGenerateSamples(void *s, byte *samples, int len);
};

#endif