DEADSOFTWARE

AL: add GME music loader
[d2df-sdl.git] / src / lib / gme / gme.pas
1 unit GME;
3 {$IFDEF FPC}
4 {$PACKRECORDS C}
5 {$MODE OBJFPC}
6 {$ENDIF}
8 interface
10 uses ctypes;
12 {$IF DEFINED(WINDOWS)}
13 {$IFDEF LIBGME_WINDOZE_STATIC}
14 {$ERROR libgme won't static-link on Windows until we switch to FPC 3.2.0}
15 // {$LINKLIB libgme.a}
16 {$ELSE}
17 {$DEFINE GME_DYNAMIC}
18 const gmelib = 'libgme.dll';
19 {$ENDIF}
20 {$ELSEIF DEFINED(UNIX)}
21 {$DEFINE GME_DYNAMIC}
22 const gmelib = 'libgme.so';
23 {$ELSE}
24 {$ERROR libgme not supported on this platform. Fix it!}
25 {$ENDIF}
27 type
28 // first parameter of most gme_ functions is a pointer to the Music_Emu
29 pgme_music_emu = pointer;
30 ppgme_music_emu = ^pgme_music_emu;
32 // track information
33 gme_info_t = record
34 // times in milliseconds, -1 if unknown
35 length: longint; // total length, if file specifies it
36 intro_length: longint; // length of song up to looping section
37 loop_length: longint; // length of looping section
38 play_length: longint; // length if available, otherwise intro_length+loop_length*2 if available,
39 // otherwise a default of 150000 (2.5 minutes).
40 i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15: longint; // reserved (jesus christ)
41 // various metadata (empty string if not available)
42 system: pchar;
43 game: pchar;
44 song: pchar;
45 author: pchar;
46 copyright: pchar;
47 comment: pchar;
48 dump: pchar;
49 // reserved (holy fuck)
50 s7,s8,s9,s10,s11,s12,s13,s14,s15: pchar;
51 end;
52 pgme_info_t = ^gme_info_t;
53 ppgme_info_t = ^pgme_info_t;
55 // frequency equalizer parameters
56 gme_equalizer_t = record
57 treble: double;
58 bass: double;
59 d2,d3,d4,d5,d6,d7,d8,d9: double; // reserved (please stop)
60 end;
61 pgme_equalizer_t = ^gme_equalizer_t;
63 // music file type identifier; can also hold NULL
64 gme_type_t = pointer;
65 pgme_type_t = ^gme_type_t;
67 // all errors are just const char* msg, NULL === success
68 gme_err_t = pchar;
70 const
71 gme_info_only = -1;
73 var
74 // emulator type constants for each supported file type
75 gme_ay_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
76 gme_gbs_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
77 gme_gym_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
78 gme_hes_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
79 gme_kss_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
80 gme_nsf_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
81 gme_nsfe_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
82 gme_sap_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
83 gme_spc_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
84 gme_vgm_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
85 gme_vgz_type: gme_type_t; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
87 // error returned if GME encounters an invalid file type
88 gme_wrong_file_type: pchar; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
90 { basic API }
92 // create emulator and load game music file/data into it. Sets *out to new emulator.
93 function gme_open_file(const path: pchar; eout: ppgme_music_emu; sample_rate: longint): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
95 // same as gme_open_file(), but uses file data already in memory; makes copy of data;
96 // the resulting Music_Emu object will be set to single channel mode
97 function gme_open_data(const data: pointer; size: clong; eout: ppgme_music_emu; sample_rate: longint): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
99 // number of tracks available
100 function gme_track_count(const emu: pgme_music_emu): longint; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
102 // start a track, where 0 is the first track
103 function gme_start_track(emu: pgme_music_emu; track: longint): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
105 // generate 'count' 16-bit signed samples into 'out'; output is in stereo
106 function gme_play(emu: pgme_music_emu; count: longint; buf: pword): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
108 // finish using emulator and free memory
109 procedure gme_delete(emu: pgme_music_emu); cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
111 { track positioning }
113 // Set time to start fading track out. Once fade ends track_ended() returns true.
114 // Fade time can be changed while track is playing.
115 procedure gme_set_fade(emu: pgme_music_emu; start_msec: longint); cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
117 // true if a track has reached its end
118 function gme_track_ended(const emu: pgme_music_emu): longint; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
120 // number of milliseconds (1000 = one second) played since beginning of track
121 function gme_tell(const emu: pgme_music_emu): longint; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
123 // number of samples generated since beginning of track
124 function gme_tell_samples(const emu: pgme_music_emu): longint; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
126 // seek to new time in track; seeking backwards or far forward can take a while
127 function gme_seek(emu: pgme_music_emu; msec: longint): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
129 // equivalent to restarting track then skipping n samples
130 function gme_seek_samples(emu: pgme_music_emu; n: longint): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
132 // If do_autoload_limit is nonzero, then automatically load track length
133 // metadata (if present) and terminate playback once the track length has been
134 // reached. Otherwise playback will continue for an arbitrary period of time
135 // until a prolonged period of silence is detected.
136 // By default, playback limits are loaded and applied.
137 procedure gme_set_autoload_playback_limit(emu: pgme_music_emu; do_autoload_limit: longint); cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
139 { informational }
141 // most recent warning string, or NULL if none; clears current warning after returning
142 function gme_warning(emu: pgme_music_emu): pchar; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
144 // gets information for a particular track (length, name, author, etc.); must be freed after use
145 function gme_track_info(const emu: pgme_music_emu; iout: ppgme_info_t; track: longint): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
147 // frees track information
148 procedure gme_free_info(info: pgme_info_t); cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
150 { advanced playback }
152 // Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum.
153 // Has no effect for GYM, SPC, and Sega Genesis VGM music
154 procedure gme_set_stereo_depth(emu: pgme_music_emu; depth: double); cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
156 // enables/disables most accurate sound emulation options
157 procedure gme_enable_accuracy(emu: pgme_music_emu; enable: longint); cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
159 { music type ident }
161 // Type of this emulator
162 function gme_type(const emu: pgme_music_emu): gme_type_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
164 // Pointer to array of all music types, with NULL entry at end. Allows a player linked
165 // to this library to support new music types without having to be updated.
166 function gme_type_list(): pgme_type_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
168 // Determine likely game music type based on first four bytes of file. Returns
169 // string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
170 // file header is not recognized.
171 function gme_identify_header(const header: pointer): pchar; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
173 // Get corresponding music type for file path or extension passed in.
174 function gme_identify_extension(const path_or_extension: pchar): gme_type_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
176 // Create new emulator and set sample rate. Returns NULL if out of memory.
177 // If you only need track information, pass gme_info_only for sample_rate.
178 function gme_new_emu(stype: gme_type_t; sample_rate: longint): pgme_music_emu; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
180 // Load music file into emulator
181 function gme_load_file(emu: pgme_music_emu; const path: pchar): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
183 // Load music file from memory into emulator. Makes a copy of data passed.
184 function gme_load_data(emu: pgme_music_emu; const data: pointer; len: clong): gme_err_t; cdecl; external {$IFDEF GME_DYNAMIC}gmelib{$ENDIF};
187 implementation
190 end.