annotate snes_spc/spc.h @ 0:e38dacceb958

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Oct 2011 05:53:11 -0700
parents
children
rev   line source
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