rlm@0
|
1 /* SNES SPC-700 APU emulator C interface (also usable from C++) */
|
rlm@0
|
2
|
rlm@0
|
3 /* snes_spc 0.9.0 */
|
rlm@0
|
4 #ifndef SPC_H
|
rlm@0
|
5 #define SPC_H
|
rlm@0
|
6
|
rlm@0
|
7 #include <stddef.h>
|
rlm@0
|
8
|
rlm@0
|
9 #ifdef __cplusplus
|
rlm@0
|
10 extern "C" {
|
rlm@0
|
11 #endif
|
rlm@0
|
12
|
rlm@0
|
13 /* Error string return. NULL if success, otherwise error message. */
|
rlm@0
|
14 typedef const char* spc_err_t;
|
rlm@0
|
15
|
rlm@0
|
16 typedef struct SNES_SPC SNES_SPC;
|
rlm@0
|
17
|
rlm@0
|
18 /* Creates new SPC emulator. NULL if out of memory. */
|
rlm@0
|
19 SNES_SPC* spc_new( void );
|
rlm@0
|
20
|
rlm@0
|
21 /* Frees SPC emulator */
|
rlm@0
|
22 void spc_delete( SNES_SPC* );
|
rlm@0
|
23
|
rlm@0
|
24 /* Sample pairs generated per second */
|
rlm@0
|
25 enum { spc_sample_rate = 32000 };
|
rlm@0
|
26
|
rlm@0
|
27
|
rlm@0
|
28 /**** Emulator use ****/
|
rlm@0
|
29
|
rlm@0
|
30 /* Sets IPL ROM data. Library does not include ROM data. Most SPC music files
|
rlm@0
|
31 don't need ROM, but a full emulator must provide this. */
|
rlm@0
|
32 enum { spc_rom_size = 0x40 };
|
rlm@0
|
33 void spc_init_rom( SNES_SPC*, unsigned char const rom [spc_rom_size] );
|
rlm@0
|
34
|
rlm@0
|
35 /* Sets destination for output samples */
|
rlm@0
|
36 typedef short spc_sample_t;
|
rlm@0
|
37 void spc_set_output( SNES_SPC*, spc_sample_t* out, int out_size );
|
rlm@0
|
38
|
rlm@0
|
39 /* Number of samples written to output since last set */
|
rlm@0
|
40 int spc_sample_count( SNES_SPC const* );
|
rlm@0
|
41
|
rlm@0
|
42 /* Resets SPC to power-on state. This resets your output buffer, so you must
|
rlm@0
|
43 call spc_set_output() after this. */
|
rlm@0
|
44 void spc_reset( SNES_SPC* );
|
rlm@0
|
45
|
rlm@0
|
46 /* Emulates pressing reset switch on SNES. This resets your output buffer, so
|
rlm@0
|
47 you must call spc_set_output() after this. */
|
rlm@0
|
48 void spc_soft_reset( SNES_SPC* );
|
rlm@0
|
49
|
rlm@0
|
50 /* 1024000 SPC clocks per second, sample pair every 32 clocks */
|
rlm@0
|
51 typedef int spc_time_t;
|
rlm@0
|
52 enum { spc_clock_rate = 1024000 };
|
rlm@0
|
53 enum { spc_clocks_per_sample = 32 };
|
rlm@0
|
54
|
rlm@0
|
55 /* Reads/writes port at specified time */
|
rlm@0
|
56 enum { spc_port_count = 4 };
|
rlm@0
|
57 int spc_read_port ( SNES_SPC*, spc_time_t, int port );
|
rlm@0
|
58 void spc_write_port( SNES_SPC*, spc_time_t, int port, int data );
|
rlm@0
|
59
|
rlm@0
|
60 /* Runs SPC to end_time and starts a new time frame at 0 */
|
rlm@0
|
61 void spc_end_frame( SNES_SPC*, spc_time_t end_time );
|
rlm@0
|
62
|
rlm@0
|
63
|
rlm@0
|
64 /**** Sound control ****/
|
rlm@0
|
65
|
rlm@0
|
66 /*Mutes voices corresponding to non-zero bits in mask. Reduces emulation accuracy. */
|
rlm@0
|
67 enum { spc_voice_count = 8 };
|
rlm@0
|
68 void spc_mute_voices( SNES_SPC*, int mask );
|
rlm@0
|
69
|
rlm@0
|
70 /* If true, prevents channels and global volumes from being phase-negated.
|
rlm@0
|
71 Only supported by fast DSP; has no effect on accurate DSP. */
|
rlm@0
|
72 void spc_disable_surround( SNES_SPC*, int disable );
|
rlm@0
|
73
|
rlm@0
|
74 /* Sets tempo, where spc_tempo_unit = normal, spc_tempo_unit / 2 = half speed, etc. */
|
rlm@0
|
75 enum { spc_tempo_unit = 0x100 };
|
rlm@0
|
76 void spc_set_tempo( SNES_SPC*, int );
|
rlm@0
|
77
|
rlm@0
|
78
|
rlm@0
|
79 /**** SPC music playback *****/
|
rlm@0
|
80
|
rlm@0
|
81 /* Loads SPC data into emulator. Returns NULL on success, otherwise error string. */
|
rlm@0
|
82 spc_err_t spc_load_spc( SNES_SPC*, void const* spc_in, long size );
|
rlm@0
|
83
|
rlm@0
|
84 /* Clears echo region. Useful after loading an SPC as many have garbage in echo. */
|
rlm@0
|
85 void spc_clear_echo( SNES_SPC* );
|
rlm@0
|
86
|
rlm@0
|
87 /* Plays for count samples and write samples to out. Discards samples if out
|
rlm@0
|
88 is NULL. Count must be a multiple of 2 since output is stereo. */
|
rlm@0
|
89 spc_err_t spc_play( SNES_SPC*, int count, short* out );
|
rlm@0
|
90
|
rlm@0
|
91 /* Skips count samples. Several times faster than spc_play(). */
|
rlm@0
|
92 spc_err_t spc_skip( SNES_SPC*, int count );
|
rlm@0
|
93
|
rlm@0
|
94
|
rlm@0
|
95 /**** State save/load (only available with accurate DSP) ****/
|
rlm@0
|
96
|
rlm@0
|
97 /* Saves/loads exact emulator state */
|
rlm@0
|
98 enum { spc_state_size = 67 * 1024L }; /* maximum space needed when saving */
|
rlm@0
|
99 typedef void (*spc_copy_func_t)( unsigned char** io, void* state, size_t );
|
rlm@0
|
100 void spc_copy_state( SNES_SPC*, unsigned char** io, spc_copy_func_t );
|
rlm@0
|
101
|
rlm@0
|
102 /* Writes minimal SPC file header to spc_out */
|
rlm@0
|
103 void spc_init_header( void* spc_out );
|
rlm@0
|
104
|
rlm@0
|
105 /* Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out.
|
rlm@0
|
106 Does not set up SPC header; use spc_init_header() for that. */
|
rlm@0
|
107 enum { spc_file_size = 0x10200 }; /* spc_out must have this many bytes allocated */
|
rlm@0
|
108 void spc_save_spc( SNES_SPC*, void* spc_out );
|
rlm@0
|
109
|
rlm@0
|
110 /* Returns non-zero if new key-on events occurred since last check. Useful for
|
rlm@0
|
111 trimming silence while saving an SPC. */
|
rlm@0
|
112 int spc_check_kon( SNES_SPC* );
|
rlm@0
|
113
|
rlm@0
|
114
|
rlm@0
|
115 /**** SPC_Filter ****/
|
rlm@0
|
116
|
rlm@0
|
117 typedef struct SPC_Filter SPC_Filter;
|
rlm@0
|
118
|
rlm@0
|
119 /* Creates new filter. NULL if out of memory. */
|
rlm@0
|
120 SPC_Filter* spc_filter_new( void );
|
rlm@0
|
121
|
rlm@0
|
122 /* Frees filter */
|
rlm@0
|
123 void spc_filter_delete( SPC_Filter* );
|
rlm@0
|
124
|
rlm@0
|
125 /* Filters count samples of stereo sound in place. Count must be a multiple of 2. */
|
rlm@0
|
126 void spc_filter_run( SPC_Filter*, spc_sample_t* io, int count );
|
rlm@0
|
127
|
rlm@0
|
128 /* Clears filter to silence */
|
rlm@0
|
129 void spc_filter_clear( SPC_Filter* );
|
rlm@0
|
130
|
rlm@0
|
131 /* Sets gain (volume), where spc_filter_gain_unit is normal. Gains greater than
|
rlm@0
|
132 spc_filter_gain_unit are fine, since output is clamped to 16-bit sample range. */
|
rlm@0
|
133 enum { spc_filter_gain_unit = 0x100 };
|
rlm@0
|
134 void spc_filter_set_gain( SPC_Filter*, int gain );
|
rlm@0
|
135
|
rlm@0
|
136 /* Sets amount of bass (logarithmic scale) */
|
rlm@0
|
137 enum { spc_filter_bass_none = 0 };
|
rlm@0
|
138 enum { spc_filter_bass_norm = 8 }; /* normal amount */
|
rlm@0
|
139 enum { spc_filter_bass_max = 31 };
|
rlm@0
|
140 void spc_filter_set_bass( SPC_Filter*, int bass );
|
rlm@0
|
141
|
rlm@0
|
142
|
rlm@0
|
143 #ifdef __cplusplus
|
rlm@0
|
144 }
|
rlm@0
|
145 #endif
|
rlm@0
|
146
|
rlm@0
|
147 #endif
|