1 #ifndef CYD_H 2 #define CYD_H 3 4 /* 5 Copyright (c) 2009-2010 Tero Lindeman (kometbomb) 6 7 Permission is hereby granted, free of charge, to any person 8 obtaining a copy of this software and associated documentation 9 files (the "Software"), to deal in the Software without 10 restriction, including without limitation the rights to use, 11 copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the 13 Software is furnished to do so, subject to the following 14 conditions: 15 16 The above copyright notice and this permission notice shall be 17 included in all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 OTHER DEALINGS IN THE SOFTWARE. 27 */ 28 29 #include <signal.h> 30 #include "cydtypes.h" 31 #include "cydflt.h" 32 #include "cydfx.h" 33 #include "cydentry.h" 34 #include "cyddefs.h" 35 #include "cydadsr.h" 36 #include "cydfm.h" 37 #include "cydwave.h" 38 39 typedef struct 40 { 41 Uint32 frequency; 42 Uint32 accumulator; 43 Uint32 random; // random lfsr 44 Uint32 lfsr, lfsr_period, lfsr_ctr, lfsr_acc; // lfsr state 45 Uint32 reg4, reg5, reg9; // "pokey" lfsr registers 46 CydWaveState wave; 47 } CydOscState; 48 49 typedef struct 50 { 51 // ---- interface 52 Uint32 flags; 53 Uint16 pw; // 0-2047 54 Uint8 sync_source, ring_mod; // channel 55 Uint8 flttype; 56 CydAdsr adsr; 57 Uint8 ym_env_shape; 58 #ifdef STEREOOUTPUT 59 Uint8 panning; // 0-128, 64 = center 60 Sint32 gain_left, gain_right; 61 #endif 62 // ---- internal 63 Uint32 sync_bit; 64 Uint32 lfsr_type; 65 const CydWavetableEntry *wave_entry; 66 CydOscState subosc[CYD_SUB_OSCS]; 67 CydFilter flt; 68 int fx_bus; 69 #ifndef CYD_DISABLE_FM 70 CydFm fm; 71 #endif 72 } CydChannel; 73 74 enum 75 { 76 FLT_LP, 77 FLT_HP, 78 FLT_BP, 79 FLT_TYPES 80 }; 81 82 enum 83 { 84 CYD_CHN_ENABLE_NOISE = 1, 85 CYD_CHN_ENABLE_PULSE = 2, 86 CYD_CHN_ENABLE_TRIANGLE = 4, 87 CYD_CHN_ENABLE_SAW = 8, 88 CYD_CHN_ENABLE_SYNC = 16, 89 CYD_CHN_ENABLE_GATE = 32, 90 CYD_CHN_ENABLE_KEY_SYNC = 64, 91 CYD_CHN_ENABLE_METAL = 128, 92 CYD_CHN_ENABLE_RING_MODULATION = 256, 93 CYD_CHN_ENABLE_FILTER = 512, 94 CYD_CHN_ENABLE_FX = 1024, 95 CYD_CHN_ENABLE_YM_ENV = 2048, 96 CYD_CHN_ENABLE_WAVE = 4096, 97 CYD_CHN_WAVE_OVERRIDE_ENV = 8192, 98 CYD_CHN_ENABLE_LFSR = 16384, 99 CYD_CHN_ENABLE_FM = 32768 100 }; 101 102 enum 103 { 104 CYD_FM_ENABLE_WAVE = CYD_CHN_ENABLE_WAVE, 105 CYD_FM_ENABLE_TRIANGLE = CYD_CHN_ENABLE_TRIANGLE, 106 CYD_FM_ENABLE_PULSE = CYD_CHN_ENABLE_PULSE, 107 CYD_FM_ENABLE_SAW = CYD_CHN_ENABLE_SAW 108 }; 109 110 enum { 111 ATTACK, 112 DECAY, 113 SUSTAIN, 114 RELEASE, 115 DONE 116 }; 117 118 enum 119 { 120 CYD_LOCK_REQUEST=1, 121 CYD_LOCK_LOCKED=2, 122 CYD_LOCK_CALLBACK=4 123 124 }; 125 126 #define WAVEFORMS (CYD_CHN_ENABLE_NOISE|CYD_CHN_ENABLE_PULSE|CYD_CHN_ENABLE_TRIANGLE|CYD_CHN_ENABLE_SAW|CYD_CHN_ENABLE_WAVE|CYD_CHN_ENABLE_LFSR) 127 128 #define LUT_SIZE 1024 129 #define YM_LUT_SIZE 16 130 131 #define CYD_NUM_WO_BUFFER_SIZE 2000 132 #define CYD_NUM_WO_BUFFERS 4 133 134 #define CYD_NUM_LFSR 16 135 136 typedef struct CydEngine_t 137 { 138 CydChannel *channel; 139 int n_channels; 140 Uint32 sample_rate; 141 // ----- internal 142 volatile Uint32 flags; 143 int (*callback)(void*); 144 void *callback_parameter; 145 volatile Uint32 callback_period, callback_counter; 146 Uint16 *lookup_table, *lookup_table_ym; 147 CydFx fx[CYD_MAX_FX_CHANNELS]; 148 #ifdef USESDLMUTEXES 149 CydMutex mutex; 150 #else 151 volatile sig_atomic_t lock_request; 152 volatile sig_atomic_t lock_locked; 153 #endif 154 size_t samples_output; // bytes in last cyd_output_buffer 155 CydWavetableEntry *wavetable_entries; 156 #ifdef USENATIVEAPIS 157 # ifdef WIN32 158 BOOL thread_running; 159 DWORD thread_handle, cb_handle; 160 CRITICAL_SECTION thread_lock; 161 int buffers_available; 162 int waveout_hdr_idx; 163 HWAVEOUT hWaveOut; 164 WAVEHDR waveout_hdr[CYD_NUM_WO_BUFFERS]; 165 # endif 166 #endif 167 Uint64 samples_played; 168 int oversample; 169 } CydEngine; 170 171 enum 172 { 173 CYD_PAUSED = 1, 174 CYD_CLIPPING = 2, 175 CYD_SINGLE_THREAD = 8, 176 }; 177 178 // YM2149 envelope shape flags, CONT is assumed to be always set 179 180 enum { CYD_YM_ENV_ATT = 1, CYD_YM_ENV_ALT = 2}; 181 182 /////////////////777 183 184 void cyd_init(CydEngine *cyd, Uint16 sample_rate, int initial_channels); 185 void cyd_set_oversampling(CydEngine *cyd, int oversampling); 186 void cyd_reserve_channels(CydEngine *cyd, int channels); 187 void cyd_deinit(CydEngine *cyd); 188 void cyd_reset(CydEngine *cyd); 189 void cyd_set_frequency(CydEngine *cyd, CydChannel *chn, int subosc, Uint16 frequency); 190 void cyd_set_wavetable_frequency(CydEngine *cyd, CydChannel *chn, int subosc, Uint16 frequency); 191 void cyd_reset_wavetable(CydEngine *cyd); 192 void cyd_set_wavetable_offset(CydChannel *chn, Uint16 offset /* 0..0x1000 = 0-100% */); 193 void cyd_set_env_frequency(CydEngine *cyd, CydChannel *chn, Uint16 frequency); 194 void cyd_set_env_shape(CydChannel *chn, Uint8 shape); 195 void cyd_enable_gate(CydEngine *cyd, CydChannel *chn, Uint8 enable); 196 void cyd_set_waveform(CydChannel *chn, Uint32 wave); 197 void cyd_set_wave_entry(CydChannel *chn, const CydWavetableEntry * entry); 198 void cyd_set_filter_coeffs(CydEngine * cyd, CydChannel *chn, Uint16 cutoff, Uint8 resonance); 199 void cyd_pause(CydEngine *cyd, Uint8 enable); 200 void cyd_set_callback(CydEngine *cyd, int (*callback)(void*), void*param, Uint16 period); 201 void cyd_set_callback_rate(CydEngine *cyd, Uint16 period); 202 #ifdef NOSDL_MIXER 203 int cyd_register(CydEngine * cyd, int buffer_length); 204 #else 205 int cyd_register(CydEngine * cyd); 206 #endif 207 int cyd_unregister(CydEngine * cyd); 208 void cyd_lock(CydEngine *cyd, Uint8 enable); 209 #ifdef ENABLEAUDIODUMP 210 void cyd_enable_audio_dump(CydEngine *cyd); 211 void cyd_disable_audio_dump(CydEngine *cyd); 212 #endif 213 #ifdef STEREOOUTPUT 214 void cyd_set_panning(CydEngine *cyd, CydChannel *chn, Uint8 panning); 215 #endif 216 217 #ifdef NOSDL_MIXER 218 void cyd_output_buffer_stereo(void *udata, Uint8 *_stream, int len); 219 #else 220 void cyd_output_buffer_stereo(int chan, void *_stream, int len, void *udata); 221 #endif 222 223 Sint32 cyd_env_output(const CydEngine *cyd, Uint32 channel_flags, const CydAdsr *adsr, Sint32 input); 224 Uint32 cyd_cycle_adsr(const CydEngine *eng, Uint32 flags, Uint32 ym_env_shape, CydAdsr *adsr); 225 226 #endif 227