1 #ifndef __ZMUSIC_H_
2 #define __ZMUSIC_H_
3 
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <stdarg.h>
7 
8 struct SoundDecoder;	// Anonymous to the client.
9 
10 typedef unsigned char zmusic_bool;
11 
12 // These constants must match the corresponding values of the Windows headers
13 // to avoid readjustment in the native Windows device's playback functions
14 // and should not be changed.
15 typedef enum EMidiDeviceClass_
16 {
17 	MIDIDEV_MIDIPORT = 1,
18 	MIDIDEV_SYNTH,
19 	MIDIDEV_SQSYNTH,
20 	MIDIDEV_FMSYNTH,
21 	MIDIDEV_MAPPER,
22 	MIDIDEV_WAVETABLE,
23 	MIDIDEV_SWSYNTH
24 } EMidiDeviceClass;
25 
26 typedef enum EMIDIType_
27 {
28 	MIDI_NOTMIDI,
29 	MIDI_MIDI,
30 	MIDI_HMI,
31 	MIDI_XMI,
32 	MIDI_MUS,
33 	MIDI_MIDS
34 } EMIDIType;
35 
36 typedef enum EMidiDevice_
37 {
38 	MDEV_DEFAULT = -1,
39 	MDEV_STANDARD = 0,
40 	MDEV_OPL = 1,
41 	MDEV_SNDSYS = 2,
42 	MDEV_TIMIDITY = 3,
43 	MDEV_FLUIDSYNTH = 4,
44 	MDEV_GUS = 5,
45 	MDEV_WILDMIDI = 6,
46 	MDEV_ADL = 7,
47 	MDEV_OPN = 8,
48 
49 	MDEV_COUNT
50 } EMidiDevice;
51 
52 typedef enum ESoundFontTypes_
53 {
54 	SF_SF2 = 1,
55 	SF_GUS = 2,
56 	SF_WOPL = 4,
57 	SF_WOPN = 8
58 } ESoundFontTypes;
59 
60 typedef struct SoundStreamInfo_
61 {
62 	int mBufferSize;	// If mBufferSize is 0, the song doesn't use streaming but plays through a different interface.
63 	int mSampleRate;
64 	int mNumChannels;	// If mNumChannels is negative, 16 bit integer format is used instead of floating point.
65 } SoundStreamInfo;
66 
67 typedef enum SampleType_
68 {
69 	SampleType_UInt8,
70 	SampleType_Int16
71 } SampleType;
72 
73 typedef enum ChannelConfig_
74 {
75 	ChannelConfig_Mono,
76 	ChannelConfig_Stereo
77 } ChannelConfig;
78 
79 typedef enum EIntConfigKey_
80 {
81 	zmusic_adl_chips_count,
82 	zmusic_adl_emulator_id,
83 	zmusic_adl_run_at_pcm_rate,
84 	zmusic_adl_fullpan,
85 	zmusic_adl_bank,
86 	zmusic_adl_use_custom_bank,
87 	zmusic_adl_volume_model,
88 
89 	zmusic_fluid_reverb,
90 	zmusic_fluid_chorus,
91 	zmusic_fluid_voices,
92 	zmusic_fluid_interp,
93 	zmusic_fluid_samplerate,
94 	zmusic_fluid_threads,
95 	zmusic_fluid_chorus_voices,
96 	zmusic_fluid_chorus_type,
97 
98 	zmusic_opl_numchips,
99 	zmusic_opl_core,
100 	zmusic_opl_fullpan,
101 
102 	zmusic_opn_chips_count,
103 	zmusic_opn_emulator_id,
104 	zmusic_opn_run_at_pcm_rate,
105 	zmusic_opn_fullpan,
106 	zmusic_opn_use_custom_bank,
107 
108 	zmusic_gus_dmxgus,
109 	zmusic_gus_midi_voices,
110 	zmusic_gus_memsize,
111 
112 	zmusic_timidity_modulation_wheel,
113 	zmusic_timidity_portamento,
114 	zmusic_timidity_reverb,
115 	zmusic_timidity_reverb_level,
116 	zmusic_timidity_chorus,
117 	zmusic_timidity_surround_chorus,
118 	zmusic_timidity_channel_pressure,
119 	zmusic_timidity_lpf_def,
120 	zmusic_timidity_temper_control,
121 	zmusic_timidity_modulation_envelope,
122 	zmusic_timidity_overlap_voice_allow,
123 	zmusic_timidity_drum_effect,
124 	zmusic_timidity_pan_delay,
125 	zmusic_timidity_key_adjust,
126 
127 	zmusic_wildmidi_reverb,
128 	zmusic_wildmidi_enhanced_resampling,
129 
130 	zmusic_snd_midiprecache,
131 
132 	zmusic_mod_samplerate,
133 	zmusic_mod_volramp,
134 	zmusic_mod_interp,
135 	zmusic_mod_autochip,
136 	zmusic_mod_autochip_size_force,
137 	zmusic_mod_autochip_size_scan,
138 	zmusic_mod_autochip_scan_threshold,
139 
140 	zmusic_snd_streambuffersize,
141 
142 	zmusic_snd_mididevice,
143 	zmusic_snd_outputrate,
144 
145 	NUM_ZMUSIC_INT_CONFIGS
146 } EIntConfigKey;
147 
148 typedef enum EFloatConfigKey_
149 {
150 	zmusic_fluid_gain = 1000,
151 	zmusic_fluid_reverb_roomsize,
152 	zmusic_fluid_reverb_damping,
153 	zmusic_fluid_reverb_width,
154 	zmusic_fluid_reverb_level,
155 	zmusic_fluid_chorus_level,
156 	zmusic_fluid_chorus_speed,
157 	zmusic_fluid_chorus_depth,
158 
159 	zmusic_timidity_drum_power,
160 	zmusic_timidity_tempo_adjust,
161 	zmusic_timidity_min_sustain_time,
162 
163 	zmusic_gme_stereodepth,
164 	zmusic_mod_dumb_mastervolume,
165 
166 	zmusic_snd_musicvolume,
167 	zmusic_relative_volume,
168 	zmusic_snd_mastervolume,
169 
170 	NUM_FLOAT_CONFIGS
171 } EFloatConfigKey;
172 
173 typedef enum EStringConfigKey_
174 {
175 	zmusic_adl_custom_bank = 2000,
176 	zmusic_fluid_lib,
177 	zmusic_fluid_patchset,
178 	zmusic_opn_custom_bank,
179 	zmusic_gus_config,
180 	zmusic_gus_patchdir,
181 	zmusic_timidity_config,
182 	zmusic_wildmidi_config,
183 
184 	NUM_STRING_CONFIGS
185 } EStringConfigKey;
186 
187 
188 typedef struct ZMusicCustomReader_
189 {
190 	void* handle;
191 	char* (*gets)(struct ZMusicCustomReader_* handle, char* buff, int n);
192 	long (*read)(struct ZMusicCustomReader_* handle, void* buff, int32_t size);
193 	long (*seek)(struct ZMusicCustomReader_* handle, long offset, int whence);
194 	long (*tell)(struct ZMusicCustomReader_* handle);
195 	void (*close)(struct ZMusicCustomReader_* handle);
196 } ZMusicCustomReader;
197 
198 typedef struct ZMusicMidiOutDevice_
199 {
200 	char *Name;
201 	int ID;
202 	int Technology;
203 } ZMusicMidiOutDevice;
204 
205 typedef enum EZMusicMessageSeverity_
206 {
207 	ZMUSIC_MSG_VERBOSE = 1,
208 	ZMUSIC_MSG_DEBUG = 5,
209 	ZMUSIC_MSG_NOTIFY = 10,
210 	ZMUSIC_MSG_WARNING = 50,
211 	ZMUSIC_MSG_ERROR = 100,
212 	ZMUSIC_MSG_FATAL = 666,
213 } EZMusicMessageSeverity;
214 
215 typedef struct ZMusicCallbacks_
216 {
217 	// Callbacks the client can install to capture messages from the backends
218 	// or to provide sound font data.
219 
220 	void (*MessageFunc)(int severity, const char* msg);
221 	// The message callbacks are optional, without them the output goes to stdout.
222 
223 	// Retrieves the path to a soundfont identified by an identifier. Only needed if the client virtualizes the sound font names
224 	const char *(*PathForSoundfont)(const char *name, int type);
225 
226 	// The sound font callbacks are for allowing the client to customize sound font management and they are optional.
227 	// They only need to be defined if the client virtualizes the sound font management and doesn't pass real paths to the music code.
228 	// Without them only paths to real files can be used. If one of these gets set, all must be set.
229 
230 	// This opens a sound font. Must return a handle with which the sound font's content can be read.
231 	void *(*OpenSoundFont)(const char* name, int type);
232 
233 	// Opens a file in the sound font. For GUS patch sets this will try to open each patch with this function.
234 	// For other formats only the sound font's actual name can be requested.
235 	// When passed NULL this must open the Timidity config file, if this is requested for an SF2 sound font it should be synthesized.
236 	ZMusicCustomReader* (*SF_OpenFile)(void* handle, const char* fn);
237 
238 	//Adds a path to the list of directories in which files must be looked for.
239 	void (*SF_AddToSearchPath)(void* handle, const char* path);
240 
241 	// Closes the sound font reader.
242 	void (*SF_Close)(void* handle);
243 
244 	// Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion.
245 	const char *(*NicePath)(const char* path);
246 } ZMusicCallbacks;
247 
248 typedef enum ZMusicVariableType_
249 {
250 	ZMUSIC_VAR_INT,
251 	ZMUSIC_VAR_BOOL,
252 	ZMUSIC_VAR_FLOAT,
253 	ZMUSIC_VAR_STRING,
254 } ZMusicVariableType;
255 
256 typedef struct ZMusicConfigurationSetting_
257 {
258 	const char* name;
259 	int identifier;
260 	ZMusicVariableType type;
261 	float defaultVal;
262 	const char* defaultString;
263 } ZMusicConfigurationSetting;
264 
265 
266 #ifndef ZMUSIC_INTERNAL
267 #ifdef _MSC_VER
268 #define DLL_IMPORT _declspec(dllimport)
269 #else // !_MSC_VER
270 #define DLL_IMPORT
271 #endif // _MSC_VER
272 // Note that the internal 'class' definitions are not C compatible!
273 typedef struct { int zm1; } *ZMusic_MidiSource;
274 typedef struct { int zm2; } *ZMusic_MusicStream;
275 struct SoundDecoder;
276 #endif
277 
278 #ifndef ZMUSIC_NO_PROTOTYPES
279 #ifdef __cplusplus
280 extern "C"
281 {
282 #endif
283 	DLL_IMPORT const char* ZMusic_GetLastError();
284 
285 	// Sets callbacks for functionality that the client needs to provide.
286 	DLL_IMPORT void ZMusic_SetCallbacks(const ZMusicCallbacks* callbacks);
287 	// Sets GenMidi data for OPL playback. If this isn't provided the OPL synth will not work.
288 	DLL_IMPORT void ZMusic_SetGenMidi(const uint8_t* data);
289 	// Set default bank for OPN. Without this OPN only works with custom banks.
290 	DLL_IMPORT void ZMusic_SetWgOpn(const void* data, unsigned len);
291 	// Set DMXGUS data for running the GUS synth in actual GUS mode.
292 	DLL_IMPORT void ZMusic_SetDmxGus(const void* data, unsigned len);
293 
294 	// Returns an array with all available configuration options - terminated with an empty entry where all elements are 0.
295 	DLL_IMPORT const ZMusicConfigurationSetting* ZMusic_GetConfiguration();
296 
297 	// These exports are needed by the MIDI dumpers which need to remain on the client side because the need access to the client's file system.
298 	DLL_IMPORT EMIDIType ZMusic_IdentifyMIDIType(uint32_t* id, int size);
299 	DLL_IMPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t* data, size_t length, EMIDIType miditype);
300 	DLL_IMPORT zmusic_bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
301 
302 	DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args);
303 	DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char *filename, EMidiDevice device, const char* Args);
304 	DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void *mem, size_t size, EMidiDevice device, const char* Args);
305 	DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid);
306 
307 	DLL_IMPORT zmusic_bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len);
308 	DLL_IMPORT zmusic_bool ZMusic_Start(ZMusic_MusicStream song, int subsong, zmusic_bool loop);
309 	DLL_IMPORT void ZMusic_Pause(ZMusic_MusicStream song);
310 	DLL_IMPORT void ZMusic_Resume(ZMusic_MusicStream song);
311 	DLL_IMPORT void ZMusic_Update(ZMusic_MusicStream song);
312 	DLL_IMPORT zmusic_bool ZMusic_IsPlaying(ZMusic_MusicStream song);
313 	DLL_IMPORT void ZMusic_Stop(ZMusic_MusicStream song);
314 	DLL_IMPORT void ZMusic_Close(ZMusic_MusicStream song);
315 	DLL_IMPORT zmusic_bool ZMusic_SetSubsong(ZMusic_MusicStream song, int subsong);
316 	DLL_IMPORT zmusic_bool ZMusic_IsLooping(ZMusic_MusicStream song);
317 	DLL_IMPORT int ZMusic_GetDeviceType(ZMusic_MusicStream song);
318 	DLL_IMPORT zmusic_bool ZMusic_IsMIDI(ZMusic_MusicStream song);
319 	DLL_IMPORT void ZMusic_VolumeChanged(ZMusic_MusicStream song);
320 	DLL_IMPORT zmusic_bool ZMusic_WriteSMF(ZMusic_MidiSource source, const char* fn, int looplimit);
321 	DLL_IMPORT void ZMusic_GetStreamInfo(ZMusic_MusicStream song, SoundStreamInfo *info);
322 	// Configuration interface. The return value specifies if a music restart is needed.
323 	// RealValue should be written back to the CVAR or whatever other method the client uses to store configuration state.
324 	DLL_IMPORT zmusic_bool ChangeMusicSettingInt(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
325 	DLL_IMPORT zmusic_bool ChangeMusicSettingFloat(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue);
326 	DLL_IMPORT zmusic_bool ChangeMusicSettingString(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
327 	DLL_IMPORT const char *ZMusic_GetStats(ZMusic_MusicStream song);
328 
329 
330 	DLL_IMPORT struct SoundDecoder* CreateDecoder(const uint8_t* data, size_t size, zmusic_bool isstatic);
331 	DLL_IMPORT void SoundDecoder_GetInfo(struct SoundDecoder* decoder, int* samplerate, ChannelConfig* chans, SampleType* type);
332 	DLL_IMPORT size_t SoundDecoder_Read(struct SoundDecoder* decoder, void* buffer, size_t length);
333 	DLL_IMPORT void SoundDecoder_Close(struct SoundDecoder* decoder);
334 	DLL_IMPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, zmusic_bool* startass, uint32_t* end, zmusic_bool* endass);
335 	// The rest of the decoder interface is only useful for streaming music.
336 
337 	DLL_IMPORT const ZMusicMidiOutDevice *ZMusic_GetMidiDevices(int *pAmount);
338 	DLL_IMPORT int ZMusic_GetADLBanks(const char* const** pNames);
339 
340 	// Direct access to the CD drive.
341 	// Stops playing the CD
342 	DLL_IMPORT void CD_Stop();
343 
344 	// Pauses CD playing
345 	DLL_IMPORT void CD_Pause();
346 
347 	// Resumes CD playback after pausing
348 	DLL_IMPORT zmusic_bool CD_Resume();
349 
350 	// Eject the CD tray
351 	DLL_IMPORT void CD_Eject();
352 
353 	// Close the CD tray
354 	DLL_IMPORT zmusic_bool CD_UnEject();
355 
356 	// Closes a CD device previously opened with CD_Init
357 	DLL_IMPORT void CD_Close();
358 
359 	DLL_IMPORT zmusic_bool CD_Enable(const char* drive);
360 
361 
362 #ifdef __cplusplus
363 }
364 
365 inline bool ChangeMusicSetting(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue = NULL)
366 {
367 	return ChangeMusicSettingInt(key, song, value, pRealValue);
368 }
369 inline bool ChangeMusicSetting(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue = NULL)
370 {
371 	return ChangeMusicSettingFloat(key, song, value, pRealValue);
372 }
ChangeMusicSetting(EStringConfigKey key,ZMusic_MusicStream song,const char * value)373 inline bool ChangeMusicSetting(EStringConfigKey key, ZMusic_MusicStream song, const char* value)
374 {
375 	return ChangeMusicSettingString(key, song, value);
376 }
377 
378 #endif
379 #endif
380 
381 // Function typedefs for run-time linking
382 typedef const char* (*pfn_ZMusic_GetLastError)();
383 typedef void (*pfn_ZMusic_SetCallbacks)(const ZMusicCallbacks* callbacks);
384 typedef void (*pfn_ZMusic_SetGenMidi)(const uint8_t* data);
385 typedef void (*pfn_ZMusic_SetWgOpn)(const void* data, unsigned len);
386 typedef void (*pfn_ZMusic_SetDmxGus)(const void* data, unsigned len);
387 typedef const ZMusicConfigurationSetting* (*pfn_ZMusic_GetConfiguration)();
388 typedef EMIDIType (*pfn_ZMusic_IdentifyMIDIType)(uint32_t* id, int size);
389 typedef ZMusic_MidiSource (*pfn_ZMusic_CreateMIDISource)(const uint8_t* data, size_t length, EMIDIType miditype);
390 typedef zmusic_bool (*pfn_ZMusic_MIDIDumpWave)(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
391 typedef ZMusic_MusicStream (*pfn_ZMusic_OpenSong)(ZMusicCustomReader* reader, EMidiDevice device, const char* Args);
392 typedef ZMusic_MusicStream (*pfn_ZMusic_OpenSongFile)(const char *filename, EMidiDevice device, const char* Args);
393 typedef ZMusic_MusicStream (*pfn_ZMusic_OpenSongMem)(const void *mem, size_t size, EMidiDevice device, const char* Args);
394 typedef ZMusic_MusicStream (*pfn_ZMusic_OpenCDSong)(int track, int cdid);
395 typedef zmusic_bool (*pfn_ZMusic_FillStream)(ZMusic_MusicStream stream, void* buff, int len);
396 typedef zmusic_bool (*pfn_ZMusic_Start)(ZMusic_MusicStream song, int subsong, zmusic_bool loop);
397 typedef void (*pfn_ZMusic_Pause)(ZMusic_MusicStream song);
398 typedef void (*pfn_ZMusic_Resume)(ZMusic_MusicStream song);
399 typedef void (*pfn_ZMusic_Update)(ZMusic_MusicStream song);
400 typedef zmusic_bool (*pfn_ZMusic_IsPlaying)(ZMusic_MusicStream song);
401 typedef void (*pfn_ZMusic_Stop)(ZMusic_MusicStream song);
402 typedef void (*pfn_ZMusic_Close)(ZMusic_MusicStream song);
403 typedef zmusic_bool (*pfn_ZMusic_SetSubsong)(ZMusic_MusicStream song, int subsong);
404 typedef zmusic_bool (*pfn_ZMusic_IsLooping)(ZMusic_MusicStream song);
405 typedef zmusic_bool (*pfn_ZMusic_IsMIDI)(ZMusic_MusicStream song);
406 typedef void (*pfn_ZMusic_VolumeChanged)(ZMusic_MusicStream song);
407 typedef zmusic_bool (*pfn_ZMusic_WriteSMF)(ZMusic_MidiSource source, const char* fn, int looplimit);
408 typedef void (*pfn_ZMusic_GetStreamInfo)(ZMusic_MusicStream song, SoundStreamInfo *info);
409 typedef zmusic_bool (*pfn_ChangeMusicSettingInt)(EIntConfigKey key, ZMusic_MusicStream song, int value, int* pRealValue);
410 typedef zmusic_bool (*pfn_ChangeMusicSettingFloat)(EFloatConfigKey key, ZMusic_MusicStream song, float value, float* pRealValue);
411 typedef zmusic_bool (*pfn_ChangeMusicSettingString)(EStringConfigKey key, ZMusic_MusicStream song, const char* value);
412 typedef const char *(*pfn_ZMusic_GetStats)(ZMusic_MusicStream song);
413 typedef struct SoundDecoder* (*pfn_CreateDecoder)(const uint8_t* data, size_t size, zmusic_bool isstatic);
414 typedef void (*pfn_SoundDecoder_GetInfo)(struct SoundDecoder* decoder, int* samplerate, ChannelConfig* chans, SampleType* type);
415 typedef size_t (*pfn_SoundDecoder_Read)(struct SoundDecoder* decoder, void* buffer, size_t length);
416 typedef void (*pfn_SoundDecoder_Close)(struct SoundDecoder* decoder);
417 typedef void (*pfn_FindLoopTags)(const uint8_t* data, size_t size, uint32_t* start, zmusic_bool* startass, uint32_t* end, zmusic_bool* endass);
418 typedef const ZMusicMidiOutDevice *(*pfn_ZMusic_GetMidiDevices)(int *pAmount);
419 
420 
421 
422 #endif