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