static int snd_seq_gf1_get(void *private_data, snd_seq_kinstr_t *instr, char *instr_data, long len, int atomic, int cmd) { snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data; gf1_instrument_t *ip; gf1_xinstrument_t ix; if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; if (len < sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (gf1_instrument_t *)KINSTR_DATA(instr); ix.stype = GF1_STRU_INSTR; ix.exclusion = cpu_to_le16(ip->exclusion); ix.exclusion_group = cpu_to_le16(ip->exclusion_group); ix.effect1 = cpu_to_le16(ip->effect1); ix.effect1_depth = cpu_to_le16(ip->effect1_depth); ix.effect2 = ip->effect2; ix.effect2_depth = ip->effect2_depth; if (copy_to_user(instr_data, &ix, sizeof(ix))) return -EFAULT; instr_data += sizeof(ix); len -= sizeof(ix); return snd_seq_gf1_copy_wave_to_stream(ops, ip, &instr_data, &len, atomic); }
static int snd_seq_iwffff_remove(void *private_data, snd_seq_kinstr_t *instr, int atomic) { snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data; iwffff_instrument_t *ip; ip = (iwffff_instrument_t *)KINSTR_DATA(instr); snd_seq_iwffff_instr_free(ops, ip, atomic); return 0; }
static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr, char *instr_data, long len, int atomic, int cmd) { snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data; gf1_instrument_t *ip; gf1_xinstrument_t ix; int err, gfp_mask; if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) return -EINVAL; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; /* copy instrument data */ if (len < sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; if (ix.stype != GF1_STRU_INSTR) return -EINVAL; instr_data += sizeof(ix); len -= sizeof(ix); ip = (gf1_instrument_t *)KINSTR_DATA(instr); ip->exclusion = le16_to_cpu(ix.exclusion); ip->exclusion_group = le16_to_cpu(ix.exclusion_group); ip->effect1 = ix.effect1; ip->effect1_depth = ix.effect1_depth; ip->effect2 = ix.effect2; ip->effect2_depth = ix.effect2_depth; /* copy layers */ while (len > sizeof(__u32)) { __u32 stype; if (copy_from_user(&stype, instr_data, sizeof(stype))) return -EFAULT; if (stype != GF1_STRU_WAVE) { snd_seq_gf1_instr_free(ops, ip, atomic); return -EINVAL; } err = snd_seq_gf1_copy_wave_from_stream(ops, ip, &instr_data, &len, atomic); if (err < 0) { snd_seq_gf1_instr_free(ops, ip, atomic); return err; } } return 0; }
static int snd_seq_gf1_get_size(void *private_data, snd_seq_kinstr_t *instr, long *size) { long result; gf1_instrument_t *ip; gf1_wave_t *wp; *size = 0; ip = (gf1_instrument_t *)KINSTR_DATA(instr); result = sizeof(gf1_xinstrument_t); for (wp = ip->wave; wp; wp = wp->next) { result += sizeof(gf1_xwave_t); result += wp->size; } *size = result; return 0; }
static int snd_seq_iwffff_get_size(void *private_data, snd_seq_kinstr_t *instr, long *size) { long result; iwffff_instrument_t *ip; iwffff_layer_t *lp; *size = 0; ip = (iwffff_instrument_t *)KINSTR_DATA(instr); result = sizeof(iwffff_xinstrument_t); for (lp = ip->layer; lp; lp = lp->next) { result += sizeof(iwffff_xlayer_t); result += snd_seq_iwffff_env_size_in_stream(&lp->penv); result += snd_seq_iwffff_env_size_in_stream(&lp->venv); result += snd_seq_iwffff_wave_size_in_stream(lp); } *size = result; return 0; }
static int snd_seq_fm_get(void *private_data, snd_seq_kinstr_t *instr, char __user *instr_data, long len, int atomic, int cmd) { fm_instrument_t *ip; fm_xinstrument_t ix; int idx; if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; if (len < (long)sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (fm_instrument_t *)KINSTR_DATA(instr); ix.stype = FM_STRU_INSTR; ix.share_id[0] = cpu_to_le32(ip->share_id[0]); ix.share_id[1] = cpu_to_le32(ip->share_id[1]); ix.share_id[2] = cpu_to_le32(ip->share_id[2]); ix.share_id[3] = cpu_to_le32(ip->share_id[3]); ix.type = ip->type; for (idx = 0; idx < 4; idx++) { ix.op[idx].am_vib = ip->op[idx].am_vib; ix.op[idx].ksl_level = ip->op[idx].ksl_level; ix.op[idx].attack_decay = ip->op[idx].attack_decay; ix.op[idx].sustain_release = ip->op[idx].sustain_release; ix.op[idx].wave_select = ip->op[idx].wave_select; } for (idx = 0; idx < 2; idx++) { ix.feedback_connection[idx] = ip->feedback_connection[idx]; } if (copy_to_user(instr_data, &ix, sizeof(ix))) return -EFAULT; ix.echo_delay = ip->echo_delay; ix.echo_atten = ip->echo_atten; ix.chorus_spread = ip->chorus_spread; ix.trnsps = ip->trnsps; ix.fix_dur = ip->fix_dur; ix.modes = ip->modes; ix.fix_key = ip->fix_key; return 0; }
static int snd_seq_fm_put(void *private_data, struct snd_seq_kinstr *instr, char __user *instr_data, long len, int atomic, int cmd) { struct fm_instrument *ip; struct fm_xinstrument ix; int idx; if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) return -EINVAL; /* copy instrument data */ if (len < (long)sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; if (ix.stype != FM_STRU_INSTR) return -EINVAL; ip = (struct fm_instrument *)KINSTR_DATA(instr); ip->share_id[0] = le32_to_cpu(ix.share_id[0]); ip->share_id[1] = le32_to_cpu(ix.share_id[1]); ip->share_id[2] = le32_to_cpu(ix.share_id[2]); ip->share_id[3] = le32_to_cpu(ix.share_id[3]); ip->type = ix.type; for (idx = 0; idx < 4; idx++) { ip->op[idx].am_vib = ix.op[idx].am_vib; ip->op[idx].ksl_level = ix.op[idx].ksl_level; ip->op[idx].attack_decay = ix.op[idx].attack_decay; ip->op[idx].sustain_release = ix.op[idx].sustain_release; ip->op[idx].wave_select = ix.op[idx].wave_select; } for (idx = 0; idx < 2; idx++) { ip->feedback_connection[idx] = ix.feedback_connection[idx]; } ip->echo_delay = ix.echo_delay; ip->echo_atten = ix.echo_atten; ip->chorus_spread = ix.chorus_spread; ip->trnsps = ix.trnsps; ip->fix_dur = ix.fix_dur; ip->modes = ix.modes; ip->fix_key = ix.fix_key; return 0; }
static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position) { simple_instrument_t *simple; snd_seq_kinstr_t *instr; unsigned long flags; unsigned int loop_start, loop_end, sample_start, sample_end, start_offset; unsigned int value; unsigned int shift = 0; instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1); if (instr == NULL) return; voice->instr = instr->instr; /* copy ID to speedup aliases */ simple = KINSTR_DATA(instr); spin_lock_irqsave(&trident->reg_lock, flags); if (trident->device == TRIDENT_DEVICE_ID_SI7018) voice->GVSel = 1; /* route to Wave volume */ voice->CTRL = 0; voice->Alpha = 0; voice->FMS = 0; loop_start = simple->loop_start >> 4; loop_end = simple->loop_end >> 4; sample_start = (simple->start + position) >> 4; if( sample_start >= simple->size ) sample_start = simple->start >> 4; sample_end = simple->size; start_offset = position >> 4; if (simple->format & SIMPLE_WAVE_16BIT) { voice->CTRL |= 8; shift++; } if (simple->format & SIMPLE_WAVE_STEREO) { voice->CTRL |= 4; shift++; } if (!(simple->format & SIMPLE_WAVE_UNSIGNED)) voice->CTRL |= 2; voice->LBA = simple->address.memory; if (simple->format & SIMPLE_WAVE_LOOP) { voice->CTRL |= 1; voice->LBA += loop_start << shift; if( start_offset >= loop_start ) { voice->CSO = start_offset - loop_start; voice->negCSO = 0; } else { voice->CSO = loop_start - start_offset; voice->negCSO = 1; } voice->ESO = loop_end - loop_start - 1; } else { voice->LBA += start_offset << shift; voice->CSO = sample_start; voice->ESO = sample_end - 1; voice->negCSO = 0; } if (voice->flags & SNDRV_TRIDENT_VFLG_RUNNING) { snd_trident_stop_voice(trident, voice->number); voice->flags &= ~SNDRV_TRIDENT_VFLG_RUNNING; } /* set CSO sign */ value = inl(TRID_REG(trident, T4D_SIGN_CSO_A)); if( voice->negCSO ) { value |= 1 << (voice->number&31); } else { value &= ~(1 << (voice->number&31)); } outl(value,TRID_REG(trident, T4D_SIGN_CSO_A)); voice->Attribute = 0; snd_trident_write_voice_regs(trident, voice); snd_trident_start_voice(trident, voice->number); voice->flags |= SNDRV_TRIDENT_VFLG_RUNNING; spin_unlock_irqrestore(&trident->reg_lock, flags); snd_seq_instr_free_use(trident->synth.ilist, instr); }
static int snd_seq_iwffff_get(void *private_data, snd_seq_kinstr_t *instr, char __user *instr_data, long len, int atomic, int cmd) { snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data; iwffff_instrument_t *ip; iwffff_xinstrument_t ix; iwffff_layer_t *lp; iwffff_xlayer_t lx; char __user *layer_instr_data; int err; if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; if (len < (long)sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (iwffff_instrument_t *)KINSTR_DATA(instr); ix.stype = IWFFFF_STRU_INSTR; ix.exclusion = cpu_to_le16(ip->exclusion); ix.layer_type = cpu_to_le16(ip->layer_type); ix.exclusion_group = cpu_to_le16(ip->exclusion_group); ix.effect1 = cpu_to_le16(ip->effect1); ix.effect1_depth = cpu_to_le16(ip->effect1_depth); ix.effect2 = ip->effect2; ix.effect2_depth = ip->effect2_depth; if (copy_to_user(instr_data, &ix, sizeof(ix))) return -EFAULT; instr_data += sizeof(ix); len -= sizeof(ix); for (lp = ip->layer; lp; lp = lp->next) { if (len < (long)sizeof(lx)) return -ENOMEM; memset(&lx, 0, sizeof(lx)); lx.stype = IWFFFF_STRU_LAYER; lx.flags = lp->flags; lx.velocity_mode = lp->velocity_mode; lx.layer_event = lp->layer_event; lx.low_range = lp->low_range; lx.high_range = lp->high_range; lx.pan = lp->pan; lx.pan_freq_scale = lp->pan_freq_scale; lx.attenuation = lp->attenuation; snd_seq_iwffff_copy_lfo_to_stream(&lx.tremolo, &lp->tremolo); snd_seq_iwffff_copy_lfo_to_stream(&lx.vibrato, &lp->vibrato); layer_instr_data = instr_data; instr_data += sizeof(lx); len -= sizeof(lx); err = snd_seq_iwffff_copy_env_to_stream(IWFFFF_STRU_ENV_RECP, lp, &lx.penv, &lp->penv, &instr_data, &len); if (err < 0) return err; err = snd_seq_iwffff_copy_env_to_stream(IWFFFF_STRU_ENV_RECV, lp, &lx.venv, &lp->venv, &instr_data, &len); if (err < 0) return err; /* layer structure updating is now finished */ if (copy_to_user(layer_instr_data, &lx, sizeof(lx))) return -EFAULT; err = snd_seq_iwffff_copy_wave_to_stream(ops, lp, &instr_data, &len, atomic); if (err < 0) return err; } return 0; }
static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr, char __user *instr_data, long len, int atomic, int cmd) { snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data; iwffff_instrument_t *ip; iwffff_xinstrument_t ix; iwffff_layer_t *lp, *prev_lp; iwffff_xlayer_t lx; int err, gfp_mask; if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) return -EINVAL; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; /* copy instrument data */ if (len < (long)sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; if (ix.stype != IWFFFF_STRU_INSTR) return -EINVAL; instr_data += sizeof(ix); len -= sizeof(ix); ip = (iwffff_instrument_t *)KINSTR_DATA(instr); ip->exclusion = le16_to_cpu(ix.exclusion); ip->layer_type = le16_to_cpu(ix.layer_type); ip->exclusion_group = le16_to_cpu(ix.exclusion_group); ip->effect1 = ix.effect1; ip->effect1_depth = ix.effect1_depth; ip->effect2 = ix.effect2; ip->effect2_depth = ix.effect2_depth; /* copy layers */ prev_lp = NULL; while (len > 0) { if (len < (long)sizeof(iwffff_xlayer_t)) { snd_seq_iwffff_instr_free(ops, ip, atomic); return -EINVAL; } if (copy_from_user(&lx, instr_data, sizeof(lx))) return -EFAULT; instr_data += sizeof(lx); len -= sizeof(lx); if (lx.stype != IWFFFF_STRU_LAYER) { snd_seq_iwffff_instr_free(ops, ip, atomic); return -EINVAL; } lp = kcalloc(1, sizeof(*lp), gfp_mask); if (lp == NULL) { snd_seq_iwffff_instr_free(ops, ip, atomic); return -ENOMEM; } if (prev_lp) { prev_lp->next = lp; } else { ip->layer = lp; } prev_lp = lp; lp->flags = lx.flags; lp->velocity_mode = lx.velocity_mode; lp->layer_event = lx.layer_event; lp->low_range = lx.low_range; lp->high_range = lx.high_range; lp->pan = lx.pan; lp->pan_freq_scale = lx.pan_freq_scale; lp->attenuation = lx.attenuation; snd_seq_iwffff_copy_lfo_from_stream(&lp->tremolo, &lx.tremolo); snd_seq_iwffff_copy_lfo_from_stream(&lp->vibrato, &lx.vibrato); lp->freq_scale = le16_to_cpu(lx.freq_scale); lp->freq_center = lx.freq_center; err = snd_seq_iwffff_copy_env_from_stream(IWFFFF_STRU_ENV_RECP, lp, &lp->penv, &lx.penv, &instr_data, &len, gfp_mask); if (err < 0) { snd_seq_iwffff_instr_free(ops, ip, atomic); return err; } err = snd_seq_iwffff_copy_env_from_stream(IWFFFF_STRU_ENV_RECV, lp, &lp->venv, &lx.venv, &instr_data, &len, gfp_mask); if (err < 0) { snd_seq_iwffff_instr_free(ops, ip, atomic); return err; } while (len > (long)sizeof(__u32)) { __u32 stype; if (copy_from_user(&stype, instr_data, sizeof(stype))) return -EFAULT; if (stype != IWFFFF_STRU_WAVE) break; err = snd_seq_iwffff_copy_wave_from_stream(ops, lp, &instr_data, &len, atomic); if (err < 0) { snd_seq_iwffff_instr_free(ops, ip, atomic); return err; } } } return 0; }