/* PUTWS.C * The routine that implements the 'Put 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" /* PUT_WS * Set the parameters of the wavesample described in 'inst' to the * values given in 'params'. * Returns 0 on no error, or a negative error code. */ int put_ws(chan,inst,params) int chan; /* MIDI channel */ edit_spec *inst; /* Which instrument? */ ws_par *params; /* Instrument parameters */ { int i; int waiting; /* Are we waiting for the EPS to do things? */ register ushort temp_off; /* Temp. offset value */ /* Send instruction to await instrument parameters */ send_head(chan); /* Send SysEx head */ mpu_sbyte(PUT_WS); /* 'Put Wavesample Parameters' message */ 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); } } /* Send instrument parameters */ send_head(chan); for (i = 0; i < 12; i++) /* Send instrument name */ send16(params->name[i] << 8); send16(params->cp_num << 8); /* Send ws copy number */ send16(params->cp_lay << 8); /* Send ws copy layer */ /* Send pitch envelope */ send16(params->pitch_env.env_type << 8); for (i = 0; i < 5; i++) { /* Soft levels, hard levels, and times */ send16(params->pitch_env.soft_lev[i] << 8); send16(params->pitch_env.hard_lev[i] << 8); send16(params->pitch_env.times[i] << 8); } send16(params->pitch_env.vel_switch << 8); send16(params->pitch_env.rel_bkpt << 8); send16(params->pitch_env.times[5] << 8); send16(params->pitch_env.vel_sens << 8); send16(params->pitch_env.time_scal << 8); send16(params->pitch_env.mode << 8); /* Send filter envelope */ send16(params->filter_env.env_type << 8); for (i = 0; i < 5; i++) { /* Soft levels, hard levels, and times */ send16(params->filter_env.soft_lev[i] << 8); send16(params->filter_env.hard_lev[i] << 8); send16(params->filter_env.times[i] << 8); } send16(params->filter_env.vel_switch << 8); send16(params->filter_env.rel_bkpt << 8); send16(params->filter_env.times[5] << 8); send16(params->filter_env.vel_sens << 8); send16(params->filter_env.time_scal << 8); send16(params->filter_env.mode << 8); /* Send amplitude envelope */ send16(params->amp_env.env_type << 8); for (i = 0; i < 5; i++) { /* Soft levels, hard levels, and times */ send16(params->amp_env.soft_lev[i] << 8); send16(params->amp_env.hard_lev[i] << 8); send16(params->amp_env.times[i] << 8); } send16(params->amp_env.vel_switch << 8); send16(params->amp_env.rel_bkpt << 8); send16(params->amp_env.times[5] << 8); send16(params->amp_env.vel_sens << 8); send16(params->amp_env.time_scal << 8); send16(params->amp_env.mode << 8); send16(params->root << 8); send16(params->penv_amt << 8); send16(params->lfo_amt << 8); send16(params->randmod_amt << 8); send16(params->bend_rng << 8); send16(params->mod_src << 8); send16(params->finetune << 8); send16(params->mod_amt << 8); send16(params->filter_mode << 8); send16(params->fc1_cut << 8); send16(params->fc2_cut << 8); send16(params->fc1_kbd << 8); send16(params->fc2_kbd << 8); send16(params->fc1_filter << 8); send16(params->fc2_filter << 8); send16(params->fc1_modsrc << 8); send16(params->fc2_modsrc << 8); send16(params->fc1_modamt << 8); send16(params->fc2_modamt << 8); send16(params->volume << 8); send16(params->amod_src << 8); send16(params->acc_a << 8); send16(params->acc_b << 8); send16(params->acc_c << 8); send16(params->acc_d << 8); send16(params->pan_pos << 8); send16(params->amod_amt << 8); send16(params->lfo_wave << 8); send16(params->lfo_speed << 8); send16(params->lfo_depth << 8); send16(params->lfo_delay << 8); send16(params->lfo_modsrc << 8); send16(params->lfo_mode << 8); send16(params->randmod_freq << 8); send16(params->loopmode << 8); /* Send sample start offset (see 'EPS External Command Specification', * p. 35, my notes. */ temp_off = params->sstart_off; for (i = 0; i < 4; i++) { send16((ushort) ((temp_off >> 16) & 0xff00)); temp_off <<= 8; } /* Send sample end offset */ temp_off = params->send_off; for (i = 0; i < 4; i++) { send16((ushort) ((temp_off >> 16) & 0xff00)); temp_off <<= 8; } /* Send loop start offset */ temp_off = params->lstart_off; for (i = 0; i < 4; i++) { send16((ushort) ((temp_off >> 16) & 0xff00)); temp_off <<= 8; } /* Send loop end offset */ temp_off = params->lend_off; for (i = 0; i < 4; i++) { send16((ushort) ((temp_off >> 16) & 0xff00)); temp_off <<= 8; } send16(params->rate << 8); send16(params->low_range << 8); send16(params->high_range << 8); send16(params->sl_modsrc << 8); send16(params->sl_modamt << 8); send16(params->sl_modrng << 8); send16(params->mod_type << 8); send16(0x00); /* Unused */ send_tail(); /* Send end of SysEx */ /* Receive response to see if everything went well */ i = recv_response(NULL); wait(BREATHER); if (i == ACK) return(0); /* All went well */ else return(-1); /* There was some error */ }