1 #ifndef MUSIC_H 2 #define MUSIC_H 3 4 /* 5 Copyright (c) 2009-2011 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 "cyd.h" 30 #include "cydfx.h" 31 #include <stdio.h> 32 33 #define MUS_PROG_LEN 32 34 #define MUS_MAX_CHANNELS CYD_MAX_CHANNELS 35 36 #define MUS_VERSION 27 37 38 #define MUS_SONG_TITLE_LEN 64 39 #define MUS_INSTRUMENT_NAME_LEN 32 40 #define MUS_WAVETABLE_NAME_LEN MUS_INSTRUMENT_NAME_LEN 41 42 typedef struct 43 { 44 Uint8 a, d, s, r; // 0-15 45 } MusAdsr; 46 47 typedef struct 48 { 49 Uint32 flags; 50 Uint32 cydflags; 51 MusAdsr adsr; 52 Uint8 sync_source, ring_mod; // 0xff == self 53 Uint16 pw; 54 Uint8 volume; 55 Uint16 program[MUS_PROG_LEN]; 56 Uint8 prog_period; 57 Uint8 vibrato_speed, vibrato_depth, slide_speed, pwm_speed, pwm_depth; 58 Uint8 base_note; 59 Uint16 cutoff; 60 Uint8 resonance; 61 Uint8 flttype; 62 Uint8 ym_env_shape; 63 Sint16 buzz_offset; 64 Uint8 fx_bus, vib_shape, vib_delay, pwm_shape; 65 char name[MUS_INSTRUMENT_NAME_LEN + 1]; 66 Uint8 wavetable_entry; 67 Uint8 lfsr_type; 68 Sint8 finetune; 69 Uint32 fm_flags; 70 Uint8 fm_modulation, fm_feedback, fm_wave, fm_harmonic; 71 MusAdsr fm_adsr; 72 Uint8 fm_attack_start; 73 } MusInstrument; 74 75 enum 76 { 77 MUS_INST_PROG_SPEED_RELATIVE = 0, // chn.current_tick / mus.tick_period * ins.prog_period 78 MUS_INST_PROG_SPEED_ABSOLUTE = 1, // absolute number of ticks 79 MUS_INST_DRUM = 2, 80 MUS_INST_INVERT_VIBRATO_BIT = 4, 81 MUS_INST_LOCK_NOTE = 8, 82 MUS_INST_SET_PW = 16, 83 MUS_INST_SET_CUTOFF = 32, 84 MUS_INST_YM_BUZZ = 64, 85 MUS_INST_RELATIVE_VOLUME = 128, 86 MUS_INST_QUARTER_FREQ = 256, 87 MUS_INST_WAVE_LOCK_NOTE = 512, 88 MUS_INST_NO_PROG_RESTART = 1024, 89 MUS_INST_MULTIOSC = 2048, 90 }; 91 92 enum 93 { 94 MUS_FX_WAVE_NOISE = 1, 95 MUS_FX_WAVE_PULSE = 2, 96 MUS_FX_WAVE_TRIANGLE = 4, 97 MUS_FX_WAVE_SAW = 8, 98 MUS_FX_WAVE_LFSR = 16, 99 MUS_FX_WAVE_WAVE = 32, 100 }; 101 102 typedef struct 103 { 104 MusInstrument *instrument; 105 Uint16 note; 106 Uint8 volume; 107 // ------ 108 Uint8 arpeggio_note; 109 Uint16 target_note, last_note, fixed_note; 110 volatile Uint32 flags; 111 Uint32 current_tick; 112 Uint8 program_counter, program_tick, program_loop, prog_period; 113 Sint16 buzz_offset; 114 } MusChannel; 115 116 typedef struct 117 { 118 Uint8 note, instrument, ctrl; 119 Uint16 command; 120 Uint8 volume; 121 } MusStep; 122 123 typedef struct 124 { 125 Uint16 position; 126 Uint16 pattern; 127 Sint8 note_offset; 128 } MusSeqPattern; 129 130 typedef struct 131 { 132 MusStep *step; 133 Uint16 num_steps; 134 Uint8 color; 135 } MusPattern; 136 137 typedef struct 138 { 139 MusInstrument *instrument; 140 Uint8 num_instruments; 141 MusPattern *pattern; 142 Uint16 num_patterns; 143 MusSeqPattern *sequence[MUS_MAX_CHANNELS]; 144 Uint16 num_sequences[MUS_MAX_CHANNELS]; 145 Uint16 song_length, loop_point; 146 Uint8 song_speed, song_speed2, song_rate; 147 Uint16 time_signature, sequence_step; 148 Uint32 flags; 149 Uint8 num_channels; 150 Uint8 multiplex_period, pitch_inaccuracy; 151 char title[MUS_SONG_TITLE_LEN + 1]; 152 CydFxSerialized fx[CYD_MAX_FX_CHANNELS]; 153 Uint8 master_volume; 154 Uint8 default_volume[MUS_MAX_CHANNELS]; 155 Sint8 default_panning[MUS_MAX_CHANNELS]; 156 char **wavetable_names; 157 int num_wavetables; 158 } MusSong; 159 160 161 typedef struct 162 { 163 MusPattern *pattern; 164 Uint8 last_ctrl; 165 Uint16 pw, pattern_step, sequence_position, slide_speed; 166 Uint16 vibrato_position, pwm_position; 167 Sint8 note_offset; 168 Uint16 filter_cutoff; 169 Uint8 filter_resonance; 170 Uint8 extarp1, extarp2; 171 Uint8 volume; 172 Uint8 vib_delay; 173 } MusTrackStatus; 174 175 typedef struct 176 { 177 MusChannel channel[MUS_MAX_CHANNELS]; 178 Uint8 tick_period; // 1 = at the rate this is polled 179 // ---- 180 MusTrackStatus song_track[MUS_MAX_CHANNELS]; 181 MusSong *song; 182 Uint8 song_counter; 183 Uint16 song_position; 184 CydEngine *cyd; 185 Uint8 current_tick; 186 Uint8 volume, play_volume; // 0..128 187 Uint8 multiplex_ctr; 188 Uint32 flags; 189 Uint32 ext_sync_ticks; 190 Uint32 pitch_mask; 191 } MusEngine; 192 193 194 enum 195 { 196 MUS_CHN_PLAYING = 1, 197 MUS_CHN_PROGRAM_RUNNING = 2, 198 MUS_CHN_DISABLED = 4 199 }; 200 201 enum 202 { 203 MUS_NOTE_NONE = 0xff, 204 MUS_NOTE_RELEASE = 0xfe 205 }; 206 207 enum 208 { 209 MUS_PAK_BIT_NOTE = 1, 210 MUS_PAK_BIT_INST = 2, 211 MUS_PAK_BIT_CTRL = 4, 212 MUS_PAK_BIT_CMD = 8, 213 /* -- these go in ctrl byte -- */ 214 MUS_PAK_BIT_VOLUME = 128 215 }; 216 217 enum 218 { 219 MUS_EXT_SYNC = 1 220 }; 221 222 #define MUS_NOTE_VOLUME_SET_PAN 0xa0 223 #define MUS_NOTE_VOLUME_PAN_LEFT 0xb0 224 #define MUS_NOTE_VOLUME_PAN_RIGHT 0xc0 225 #define MUS_NOTE_VOLUME_FADE_UP 0xe0 226 #define MUS_NOTE_VOLUME_FADE_DN 0xd0 227 #define MUS_NOTE_NO_VOLUME 0xff 228 #define MUS_NOTE_NO_INSTRUMENT 0xff 229 #define MUS_CTRL_BIT 1 230 #define MAX_VOLUME 128 231 232 enum 233 { 234 MUS_FX_ARPEGGIO = 0x0000, 235 MUS_FX_ARPEGGIO_ABS = 0x4000, 236 MUS_FX_SET_EXT_ARP = 0x1000, 237 MUS_FX_PORTA_UP = 0x0100, 238 MUS_FX_PORTA_DN = 0x0200, 239 MUS_FX_PORTA_UP_LOG = 0x0500, 240 MUS_FX_PORTA_DN_LOG = 0x0600, 241 MUS_FX_SLIDE = 0x0300, 242 MUS_FX_VIBRATO = 0x0400, 243 MUS_FX_FADE_VOLUME = 0x0a00, 244 MUS_FX_SET_VOLUME = 0x0c00, 245 MUS_FX_LOOP_PATTERN = 0x0d00, 246 MUS_FX_SKIP_PATTERN = 0x2d00, 247 MUS_FX_EXT = 0x0e00, 248 MUS_FX_EXT_PORTA_UP = 0x0e10, 249 MUS_FX_EXT_PORTA_DN = 0x0e20, 250 MUS_FX_EXT_RETRIGGER = 0x0e90, 251 MUS_FX_EXT_FADE_VOLUME_DN = 0x0ea0, 252 MUS_FX_EXT_FADE_VOLUME_UP = 0x0eb0, 253 MUS_FX_EXT_NOTE_CUT = 0x0ec0, 254 MUS_FX_EXT_NOTE_DELAY = 0x0ed0, 255 MUS_FX_SET_SPEED = 0x0f00, 256 MUS_FX_SET_RATE = 0x1f00, 257 MUS_FX_PORTA_UP_SEMI = 0x1100, 258 MUS_FX_PORTA_DN_SEMI = 0x1200, 259 MUS_FX_SET_PANNING = 0x1800, 260 MUS_FX_PAN_LEFT = 0x1700, 261 MUS_FX_PAN_RIGHT = 0x1900, 262 MUS_FX_FADE_GLOBAL_VOLUME = 0x1a00, 263 MUS_FX_SET_GLOBAL_VOLUME = 0x1d00, 264 MUS_FX_SET_CHANNEL_VOLUME = 0x1c00, 265 MUS_FX_CUTOFF_UP = 0x2100, 266 MUS_FX_CUTOFF_DN = 0x2200, 267 MUS_FX_CUTOFF_SET = 0x2900, 268 MUS_FX_RESONANCE_SET = 0x2a00, 269 MUS_FX_FILTER_TYPE = 0x2b00, 270 MUS_FX_CUTOFF_SET_COMBINED = 0x2c00, 271 MUS_FX_BUZZ_UP = 0x3100, 272 MUS_FX_BUZZ_DN = 0x3200, 273 MUS_FX_BUZZ_SHAPE = 0x3f00, 274 MUS_FX_BUZZ_SET = 0x3900, 275 MUS_FX_BUZZ_SET_SEMI = 0x3a00, 276 MUS_FX_FM_SET_MODULATION = 0x3300, 277 MUS_FX_FM_SET_FEEDBACK = 0x3400, 278 MUS_FX_FM_SET_HARMONIC = 0x3500, 279 MUS_FX_FM_SET_WAVEFORM = 0x3600, 280 MUS_FX_PW_DN = 0x0700, 281 MUS_FX_PW_UP = 0x0800, 282 MUS_FX_PW_SET = 0x0900, 283 MUS_FX_SET_WAVEFORM = 0x0b00, 284 MUS_FX_SET_FXBUS = 0x1b00, 285 MUS_FX_SET_SYNCSRC = 0x7a00, 286 MUS_FX_SET_RINGSRC = 0x7b00, 287 MUS_FX_SET_WAVETABLE_ITEM = 0x3b00, 288 MUS_FX_SET_DOWNSAMPLE = 0x1e00, 289 MUS_FX_WAVETABLE_OFFSET = 0x5000, 290 MUS_FX_CUTOFF_FINE_SET = 0x6000, 291 MUS_FX_END = 0xffff, 292 MUS_FX_JUMP = 0xff00, 293 MUS_FX_LABEL = 0xfd00, 294 MUS_FX_LOOP = 0xfe00, 295 MUS_FX_TRIGGER_RELEASE = 0x7c00, 296 MUS_FX_RESTART_PROGRAM = 0x7d00, 297 MUS_FX_NOP = 0xfffe 298 }; 299 300 enum 301 { 302 MUS_CTRL_LEGATO = MUS_CTRL_BIT, 303 MUS_CTRL_SLIDE = MUS_CTRL_BIT << 1, 304 MUS_CTRL_VIB = MUS_CTRL_BIT << 2 305 306 }; 307 308 enum 309 { 310 MUS_ENABLE_REVERB = 1, 311 MUS_ENABLE_CRUSH = 2, 312 MUS_ENABLE_MULTIPLEX = 4, 313 MUS_NO_REPEAT = 8 314 }; 315 316 enum 317 { 318 MUS_SHAPE_SINE, 319 MUS_SHAPE_RAMP_UP, 320 MUS_SHAPE_RAMP_DN, 321 MUS_SHAPE_RANDOM, 322 MUS_SHAPE_SQUARE, 323 MUS_NUM_SHAPES 324 }; 325 326 #define MUS_INST_SIG "cyd!inst" 327 #define MUS_SONG_SIG "cyd!song" 328 #define MUS_FX_SIG "cyd!efex" 329 330 #ifdef USESDL_RWOPS 331 #include "SDL_rwops.h" 332 typedef SDL_RWops RWops; 333 #else 334 335 typedef struct RWops 336 { 337 int (*read)(struct RWops *context, void *ptr, int size, int maxnum); 338 int (*close)(struct RWops *context); 339 union { 340 FILE *fp; 341 struct 342 { 343 Uint32 ptr, length; 344 void *base; 345 } mem; 346 }; 347 int close_fp; 348 } RWops; 349 350 #endif 351 352 int mus_advance_tick(void* udata); 353 int mus_trigger_instrument(MusEngine* mus, int chan, MusInstrument *ins, Uint16 note, int panning); 354 void mus_set_channel_volume(MusEngine* mus, int chan, int volume); 355 void mus_release(MusEngine* mus, int chan); 356 void mus_init_engine(MusEngine *mus, CydEngine *cyd); 357 void mus_set_song(MusEngine *mus, MusSong *song, Uint16 position); 358 int mus_poll_status(MusEngine *mus, int *song_position, int *pattern_position, MusPattern **pattern, MusChannel *channel, int *cyd_env, int *mus_note, Uint64 *time_played); 359 int mus_load_instrument_file(Uint8 version, FILE *f, MusInstrument *inst, CydWavetableEntry *wavetable_entries); 360 int mus_load_instrument_file2(FILE *f, MusInstrument *inst, CydWavetableEntry *wavetable_entries); 361 int mus_load_instrument_RW(Uint8 version, RWops *ctx, MusInstrument *inst, CydWavetableEntry *wavetable_entries); 362 int mus_load_instrument_RW2(RWops *ctx, MusInstrument *inst, CydWavetableEntry *wavetable_entries); 363 int mus_load_instrument(const char *path, MusInstrument *inst, CydWavetableEntry *wavetable_entries); 364 void mus_get_default_instrument(MusInstrument *inst); 365 int mus_load_song(const char *path, MusSong *song, CydWavetableEntry *wavetable_entries); 366 int mus_load_song_file(FILE *f, MusSong *song, CydWavetableEntry *wavetable_entries); 367 int mus_load_song_RW(RWops *rw, MusSong *song, CydWavetableEntry *wavetable_entries); 368 int mus_load_fx_RW(RWops *ctx, CydFxSerialized *fx); 369 int mus_load_fx_file(FILE *f, CydFxSerialized *fx); 370 int mus_load_fx(const char *path, CydFxSerialized *fx); 371 void mus_free_song(MusSong *song); 372 void mus_set_fx(MusEngine *mus, MusSong *song); 373 Uint32 mus_ext_sync(MusEngine *mus); 374 Uint32 mus_get_playtime_at(MusSong *song, int position); 375 376 #endif 377