/* GETWS.C * This file implements the 'Get Wavesample Parameters' message. * * Copyright (C) 1991 by Andrew Arensburger. Permission is granted to * use, copy and/or distribute this file freely for non-commercial purposes, * as long as this notice remains intact. Any commercial use is prohibited * without express permission from the author. * * If you make any changes, fix bugs, etc., please send them to me that I * might coordinate fixes and improvements. */ #include #include "eps.h" /* GET_WS * Get wavesample parameters for the instrument/layer/wavesample described * in 'inst'. The parameters are returned by filling in the fields in 'out'. * Returns 0 on no error, or a negative error code on error. */ int get_ws(chan,inst,out) int chan; /* MIDI channel */ edit_spec *inst; /* Which wavesample? */ ws_par *out; /* Description will be put here */ { int i; int waiting; /* Are we waiting for the EPS to do things? */ /* Send request for wavesample parameters */ send_head(chan); /* Send SysEx head */ mpu_sbyte(GET_WS); /* Request wavesample parameters */ send12(inst->inst_num); /* Instrument number */ send12(inst->layer_num);/* Layer number */ send12(inst->ws_num); /* Wavesample number */ send_tail(); /* Send SysEx tail */ if (timeout(SHORT_TIMEOUT)) return(-1); /* Short timeout occurred */ /* This loop is a bit tricky. The basic idea is that the EPS can * send out one of three responses at this point: ACK, WAIT, or * something else. * If it sends an ACK, then all is well, and we can go on to * receive the data. If it sends a something else, then there's * clearly an error, and we can abort with a clean conscience. * If it sends a WAIT, however, then we have to wait for up to * 30 seconds, during which time any of the above can happen, * including a second, third, etc. WAIT message. * If the EPS has sent a WAIT, it will send an ACK before * sending the data (but this was implied by the above para- * graphs). */ waiting = 1; while (waiting) { /* See which response the EPS sends, and react * accordingly. */ switch(recv_response(NULL)) { case ACK: /* Acknowledgement */ waiting = 0; /* Stop waiting */ break; case WAIT: /* Wait for up to 30 seconds */ send_response(chan, ACK); /* Okay, I'll wait */ /* Wait for a timeout */ if (timeout(LONG_TIMEOUT)) return(-3); /* 30-sec timeout * has occurred */ break; default: /* Something's wrong */ wait(BREATHER); return(-4); } } /* Receive the wavesample parameters, part 1 */ recv_head(NULL); /* Read the head of the incoming message */ mpu_rbyte(); /* Should return 0x0e */ recv12(); /* Should return instrument number */ recv12(); /* Should return layer number */ recv12(); /* Should return wavesample number */ recv_tail(); /* Read the tail */ /* Send ACK to receive wavesample parameters Part 2 */ send_response(chan, ACK); /* Ask for next part */ /* Receive the wavesample parameters (Part 2: the revenge) */ recv_head(NULL); for (i = 0; i < 12; i++) /* Receive instrument name */ out->name[i] = recv16() >> 8; out->cp_num = recv16() >> 8; /* Receive ws copy number */ out->cp_lay = recv16() >> 8; /* Receive ws copy layer */ /* Receive pitch envelope */ out->pitch_env.env_type = recv16() >> 8; for (i = 0; i < 5; i++) { /* Soft levels, hard levels, and times */ out->pitch_env.soft_lev[i] = recv16() >> 8; out->pitch_env.hard_lev[i] = recv16() >> 8; out->pitch_env.times[i] = recv16() >> 8; } out->pitch_env.vel_switch = recv16() >> 8; out->pitch_env.rel_bkpt = recv16() >> 8; out->pitch_env.times[5] = recv16() >> 8; /* 2nd release time */ out->pitch_env.vel_sens = recv16() >> 8; out->pitch_env.time_scal = recv16() >> 8; out->pitch_env.mode = recv16() >> 8; /* Receive filter envelope */ out->filter_env.env_type = recv16() >> 8; for (i = 0; i < 5; i++) { /* Soft levels, hard levels, and times */ out->filter_env.soft_lev[i] = recv16() >> 8; out->filter_env.hard_lev[i] = recv16() >> 8; out->filter_env.times[i] = recv16() >> 8; } out->filter_env.vel_switch = recv16() >> 8; out->filter_env.rel_bkpt = recv16() >> 8; out->filter_env.times[5] = recv16() >> 8; /* 2nd release time */ out->filter_env.vel_sens = recv16() >> 8; out->filter_env.time_scal = recv16() >> 8; out->filter_env.mode = recv16() >> 8; /* Receive amplitude envelope */ out->amp_env.env_type = recv16() >> 8; for (i = 0; i < 5; i++) { /* Soft levels, hard levels, and times */ out->amp_env.soft_lev[i] = recv16() >> 8; out->amp_env.hard_lev[i] = recv16() >> 8; out->amp_env.times[i] = recv16() >> 8; } out->amp_env.vel_switch = recv16() >> 8; out->amp_env.rel_bkpt = recv16() >> 8; out->amp_env.times[5] = recv16() >> 8; /* 2nd release time */ out->amp_env.vel_sens = recv16() >> 8; out->amp_env.time_scal = recv16() >> 8; out->amp_env.mode = recv16() >> 8; out->root = recv16() >> 8; out->penv_amt = recv16() >> 8; out->lfo_amt = recv16() >> 8; out->randmod_amt = recv16() >> 8; out->bend_rng = recv16() >> 8; out->mod_src = recv16() >> 8; out->finetune = recv16() >> 8; out->mod_amt = recv16() >> 8; out->filter_mode = recv16() >> 8; out->fc1_cut = recv16() >> 8; out->fc2_cut = recv16() >> 8; out->fc1_kbd = recv16() >> 8; out->fc2_kbd = recv16() >> 8; out->fc1_filter = recv16() >> 8; out->fc2_filter = recv16() >> 8; out->fc1_modsrc = recv16() >> 8; out->fc2_modsrc = recv16() >> 8; out->fc1_modamt = recv16() >> 8; out->fc2_modamt = recv16() >> 8; out->volume = recv16() >> 8; out->amod_src = recv16() >> 8; out->acc_a = recv16() >> 8; out->acc_b = recv16() >> 8; out->acc_c = recv16() >> 8; out->acc_d = recv16() >> 8; out->pan_pos = recv16() >> 8; out->amod_amt = recv16() >> 8; out->lfo_wave = recv16() >> 8; out->lfo_speed = recv16() >> 8; out->lfo_depth = recv16() >> 8; out->lfo_delay = recv16() >> 8; out->lfo_modsrc = recv16() >> 8; out->lfo_mode = recv16() >> 8; out->randmod_freq = recv16() >> 8; out->loopmode = recv16() >> 8; /* Get sample start offset (see 'EPS External Command Specification', * p. 35, my notes. */ out->sstart_off = recv16() >> 8; out->sstart_off <<= 8; out->sstart_off |= (recv16() >> 8); out->sstart_off <<= 8; out->sstart_off |= (recv16() >> 8); out->sstart_off <<= 8; out->sstart_off |= (recv16() >> 8); /* Get sample end offset */ out->send_off = recv16() >> 8; out->send_off <<= 8; out->send_off |= (recv16() >> 8); out->send_off <<= 8; out->send_off |= (recv16() >> 8); out->send_off <<= 8; out->send_off |= (recv16() >> 8); /* Get loop start offset */ out->lstart_off = recv16() >> 8; out->lstart_off <<= 8; out->lstart_off |= (recv16() >> 8); out->lstart_off <<= 8; out->lstart_off |= (recv16() >> 8); out->lstart_off <<= 8; out->lstart_off |= (recv16() >> 8); /* Get loop end offset */ out->lend_off = recv16() >> 8; out->lend_off <<= 8; out->lend_off |= (recv16() >> 8); out->lend_off <<= 8; out->lend_off |= (recv16() >> 8); out->lend_off <<= 8; out->lend_off |= (recv16() >> 8); out->rate = recv16() >> 8; out->low_range = recv16() >> 8; out->high_range = recv16() >> 8; out->sl_modsrc = recv16() >> 8; out->sl_modamt = recv16() >> 8; out->sl_modrng = recv16() >> 8; out->mod_type = recv16() >> 8; recv16(); /* Unused */ recv_tail(); /* Receive end of SysEx */ /* Send ACK to EPS to say that everything has been received * successfully. */ send_response(chan, ACK); wait(BREATHER); return(0); }