summaryrefslogtreecommitdiff
path: root/apps/codecs/libasap/asap.h
blob: 783d62801983085e5d0eb5d4eed1f7b75d71a54c (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
 * asap.h - public interface of the ASAP engine
 *
 * Copyright (C) 2005-2008  Piotr Fusik
 *
 * This file is part of ASAP (Another Slight Atari Player),
 * see http://asap.sourceforge.net
 *
 * ASAP 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.
 *
 * ASAP 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 ASAP; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _ASAP_H_
#define _ASAP_H_

#ifdef __cplusplus
extern "C" {
#endif

/* ASAP version. */
#define ASAP_VERSION_MAJOR   1
#define ASAP_VERSION_MINOR   2
#define ASAP_VERSION_MICRO   0
#define ASAP_VERSION         "1.2.0"

/* Short credits of the ASAP engine. */
#define ASAP_YEARS           "2005-2008"
#define ASAP_CREDITS \
	"Another Slight Atari Player (C) 2005-2008 Piotr Fusik\n" \
	"CMC, MPT, TMC players (C) 1994-2005 Marcin Lewandowski\n" \
	"RMT player (C) 2002-2005 Radek Sterba\n"

/* Short GPL notice.
   Display after the credits. */
#define ASAP_COPYRIGHT \
	"This program is free software; you can redistribute it and/or modify\n" \
	"it under the terms of the GNU General Public License as published\n" \
	"by the Free Software Foundation; either version 2 of the License,\n" \
	"or (at your option) any later version."

/* Useful type definitions. */
#ifndef FALSE
#define FALSE  0
#endif
#ifndef TRUE
#define TRUE   1
#endif
typedef int abool;
typedef unsigned char byte;

/* Information about a file. */
typedef struct {
	char author[128];    /* author's name */
	char name[128];      /* title */
	char date[128];      /* creation date */
	int channels;        /* 1 for mono or 2 for stereo */
	int songs;           /* number of subsongs */
	int default_song;    /* 0-based index of the "main" subsong */
	int durations[32];   /* lengths of songs, in milliseconds, -1 = unspecified */
	abool loops[32];     /* whether songs repeat or not */
	/* the following technical information should not be used outside ASAP. */
	char type;
	int fastplay;
	int music;
	int init;
	int player;
	int header_len;
	byte song_pos[128];
} ASAP_ModuleInfo;

/* POKEY state.
   Not for use outside the ASAP engine. */
typedef struct {
	int audctl;
	abool init;
	int poly_index;
	int div_cycles;
	int mute1;
	int mute2;
	int mute3;
	int mute4;
	int audf1;
	int audf2;
	int audf3;
	int audf4;
	int audc1;
	int audc2;
	int audc3;
	int audc4;
	int tick_cycle1;
	int tick_cycle2;
	int tick_cycle3;
	int tick_cycle4;
	int period_cycles1;
	int period_cycles2;
	int period_cycles3;
	int period_cycles4;
	int reload_cycles1;
	int reload_cycles3;
	int out1;
	int out2;
	int out3;
	int out4;
	int delta1;
	int delta2;
	int delta3;
	int delta4;
	int skctl;
	signed char delta_buffer[888];
} PokeyState;

/* Player state.
   Only module_info is meant to be read outside the ASAP engine. */
typedef struct {
	int cycle;
	int cpu_pc;
	int cpu_a;
	int cpu_x;
	int cpu_y;
	int cpu_s;
	int cpu_nz;
	int cpu_c;
	int cpu_vdi;
	int scanline_number;
	int nearest_event_cycle;
	int next_scanline_cycle;
	int timer1_cycle;
	int timer2_cycle;
	int timer4_cycle;
	int irqst;
	int extra_pokey_mask;
	PokeyState base_pokey;
	PokeyState extra_pokey;
	int sample_offset;
	int sample_index;
	int samples;
	int iir_acc_left;
	int iir_acc_right;
	ASAP_ModuleInfo module_info;
	int tmc_per_frame;
	int tmc_per_frame_counter;
	int current_song;
	int current_duration;
	int blocks_played;
	int silence_cycles;
	int silence_cycles_counter;
	byte poly9_lookup[511];
	byte poly17_lookup[16385];
	byte memory[65536];
} ASAP_State;

/* Maximum length of a "mm:ss.xxx" string including the terminator. */
#define ASAP_DURATION_CHARS  10

/* Maximum length of a supported input file.
   You can assume that files longer than this are not supported by ASAP. */
#define ASAP_MODULE_MAX      65000

/* Output sample rate. */
#define ASAP_SAMPLE_RATE     44100

/* Output formats. */
typedef enum {
	ASAP_FORMAT_U8 = 8,       /* unsigned char */
	ASAP_FORMAT_S16_LE = 16,  /* signed short, little-endian */
	ASAP_FORMAT_S16_BE = -16  /* signed short, big-endian */
} ASAP_SampleFormat;

/* Parses the string in the "mm:ss.xxx" format
   and returns the number of milliseconds or -1 if an error occurs. */
int ASAP_ParseDuration(const char *s);

/* Converts number of milliseconds to a string in the "mm:ss.xxx" format. */
void ASAP_DurationToString(char *s, int duration);

/* Checks whether the extension of the passed filename is known to ASAP. */
abool ASAP_IsOurFile(const char *filename);

/* Checks whether the filename extension is known to ASAP. */
abool ASAP_IsOurExt(const char *ext);

/* Changes the filename extension, returns true on success. */
abool ASAP_ChangeExt(char *filename, const char *ext);

/* Gets information about a module.
   "module_info" is the structure where the information is returned.
   "filename" determines file format.
   "module" is the music data (contents of the file).
   "module_len" is the number of data bytes.
   ASAP_GetModuleInfo() returns true on success. */
abool ASAP_GetModuleInfo(ASAP_ModuleInfo *module_info, const char *filename,
                         const byte module[], int module_len);

/* Loads music data.
   "as" is the destination structure.
   "filename" determines file format.
   "module" is the music data (contents of the file).
   "module_len" is the number of data bytes.
   ASAP does not make copies of the passed pointers. You can overwrite
   or free "filename" and "module" once this function returns.
   ASAP_Load() returns true on success.
   If false is returned, the structure is invalid and you cannot
   call the following functions. */
abool ASAP_Load(ASAP_State *as, const char *filename,
                const byte module[], int module_len);

/* Enables silence detection.
   Makes ASAP finish playing after the specified period of silence.
   "as" is ASAP state initialized by ASAP_Load().
   "seconds" is the minimum length of silence that ends playback. */
void ASAP_DetectSilence(ASAP_State *as, int seconds);

/* Prepares ASAP to play the specified song of the loaded module.
   "as" is ASAP state initialized by ASAP_Load().
   "song" is a zero-based index which must be less than the "songs" field
   of the ASAP_ModuleInfo structure.
   "duration" is playback time in milliseconds - use durations[song]
   unless you want to override it. -1 means indefinitely. */
void ASAP_PlaySong(ASAP_State *as, int song, int duration);

/* Mutes the selected POKEY channels.
   This is only useful for people who want to grab samples of individual
   instruments.
   "as" is ASAP state after calling ASAP_PlaySong().
   "mask" is a bit mask which selects POKEY channels to be muted.
   Bits 0-3 control the base POKEY channels,
   bits 4-7 control the extra POKEY channels. */
void ASAP_MutePokeyChannels(ASAP_State *as, int mask);

/* Rewinds the current song.
   "as" is ASAP state initialized by ASAP_PlaySong().
   "position" is the requested absolute position in milliseconds. */
void ASAP_Seek(ASAP_State *as, int position);

/* Fills the specified buffer with generated samples.
   "as" is ASAP state initialized by ASAP_PlaySong().
   "buffer" is the destination buffer.
   "buffer_len" is the length of this buffer in bytes.
   "format" is the format of samples.
   ASAP_Generate() returns number of bytes actually written
   (less than buffer_len if reached the end of the song).
   Normally you use a buffer of a few kilobytes or less,
   and call ASAP_Generate() in a loop or via a callback. */
int ASAP_Generate(ASAP_State *as, void *buffer, int buffer_len,
                  ASAP_SampleFormat format);

/* Checks whether information in the specified file can be edited. */
abool ASAP_CanSetModuleInfo(const char *filename);

/* Updates the specified module with author, name, date, stereo
   and song durations as specified in "module_info".
   "module_info" contains the new module information.
   "module" is the source file contents.
   "module_len" is the source file length.
   "out_module" is the destination buffer of size ASAP_MODULE_MAX.
   ASAP_SetModuleInfo() returns the resulting file length (number of bytes
   written to "out_module") or -1 if illegal characters were found. */
int ASAP_SetModuleInfo(const ASAP_ModuleInfo *module_info, const byte module[],
                       int module_len, byte out_module[]);

/* Checks whether the specified module can be converted to another format.
   "filename" determines the source format.
   "module_info" contains the information about the source module,
   with possibly modified public fields.
   "module" is the source file contents.
   "module_len" is the source file length.
   ASAP_CanConvert() returns the extension of the target format
   or NULL if there's no possible conversion. */
const char *ASAP_CanConvert(const char *filename, const ASAP_ModuleInfo *module_info,
                            const byte module[], int module_len);

/* Converts the specified module to the format returned by ASAP_CanConvert().
   "filename" determines the source format.
   "module_info" contains the information about the source module,
   with possibly modified public fields.
   "module" is the source file contents.
   "module_len" is the source file length.
   "out_module" is the destination buffer of size ASAP_MODULE_MAX.
   ASAP_Convert() returns the resulting file length (number of bytes
   written to "out_module") or -1 on error. */
int ASAP_Convert(const char *filename, const ASAP_ModuleInfo *module_info,
                 const byte module[], int module_len, byte out_module[]);

#ifdef __cplusplus
}
#endif

#endif