📄 wtbl_awepatch.c
字号:
/* allocate and initialize patch IDs to unset state */ patchids = g_chunk_new (AwePatchIDs, chunk_patchids); sam->datainfo->patchid = patchids; patchids->locked_id = -1; patchids->unlocked_id = -1; } else patchids = sam->datainfo->patchid; newid = awe_patch_id_counter++; /* get new patch ID */ /* assign patch ID depending on current sample locking mode */ if (awe_lock_samples) patchids->locked_id = newid; else patchids->unlocked_id = newid; return (newid);}/* resets AWE patch IDs in sample data info structures, if cacheonly is TRUE then only cache samples are cleared, otherwise all patches are */static voidawe_clear_patch_ids (gboolean cacheonly){ GSList *p; SFSamDataInfo *datanfo; AwePatchIDs *patchids; /* clear patch IDs in cached sample datainfo structures */ p = sam_datainfo_list; while (p) { datanfo = (SFSamDataInfo *)(p->data); patchids = datanfo->patchid; if (patchids) { /* reset unlocked_id despite value of "cacheonly" */ patchids->unlocked_id = -1; /* reset locked_id only if clearing all IDs */ if (!cacheonly) patchids->locked_id = -1; /* if no more set IDs then free AwePatchIDs structure */ if (patchids->locked_id == -1) { g_mem_chunk_free (chunk_patchids, patchids); datanfo->patchid = NULL; } } p = g_slist_next (p); } /* reset patch counter if clearing all patch ids */ if (!cacheonly) awe_patch_id_counter = 0;}voidawe_clear_sample_patch_id (SFSample *sam, gboolean locked){ AwePatchIDs *patchids = sam->datainfo->patchid; if (!patchids) return; if (locked) patchids->locked_id = -1; else patchids->unlocked_id = -1; /* if no more set IDs then free AwePatchIDs structure */ if (patchids->locked_id == -1 && patchids->unlocked_id == -1) { g_mem_chunk_free (chunk_patchids, patchids); sam->datainfo->patchid = NULL; }}/* amount of sample memory available */gintawe_mem_avail (void){ gint mem_avail; mem_avail = seq_oss_dev; ioctl (seq_oss_fd, SNDCTL_SYNTH_MEMAVL, &mem_avail); return (mem_avail);}/* amount of sample memory required to load a sample usecache: whether to use sample cache (returns 0 if sample already loaded) locked: if "usecache" then "locked" indicates which cache to check */gintawe_samdata_mem_required (SFSample *sam, SFData *sf, gboolean usecache, gboolean locked){ AwePatchIDs *patchids; /* if not using cache or patch not loaded for the sample locking mode requested by "locked", return memory required */ if (!usecache || !(patchids = sam->datainfo->patchid) || ((locked ? patchids->locked_id : patchids->unlocked_id) == -1)) return ((sam->datainfo->size + BLANK_LOOPSIZE) * 2); else return (0); /* sample already loaded, nothing required */}/*---------------------------------------------------------------- * load awe patch data block *----------------------------------------------------------------*/static gintload_patch (void *patch, gint len){ awe_patch_info *p; p = (awe_patch_info *) patch; p->key = AWE_PATCH; p->device_no = seq_oss_dev; p->sf_id = 0; p->reserved = 0; if (write (seq_oss_fd, patch, len) == -1) return (FAIL); return (OK);}static voidawe_stuff_voicenfo (SFData * sf, SFSample * sp, awe_voice_info * vp, SFGenAmount * garr){ set_sample_info (sf, sp, vp, garr); set_init_info (vp, garr); set_rootkey (sf, sp, vp, garr); set_modenv (vp, garr); set_volenv (vp, garr); set_lfo1 (vp, garr); set_lfo2 (vp, garr); memset (vp->parm.reserved, 0, sizeof (vp->parm.reserved));}/* set sample info from generators */static voidset_sample_info (SFData * sf, SFSample * sp, awe_voice_info * vp, SFGenAmount * garr){ AwePatchIDs *patchids; vp->sf_id = 0; /* not used */ /* assign sample ID */ patchids = sp->datainfo->patchid; vp->sample = awe_lock_samples ? patchids->locked_id : patchids->unlocked_id; vp->start = ((gint) (garr[Gen_StartAddrCoarseOfs].sword) << 15) + (gint) (garr[Gen_StartAddrOfs].sword); vp->end = ((gint) (garr[Gen_EndAddrCoarseOfs].sword) << 15) + (gint) (garr[Gen_EndAddrOfs].sword); vp->mode = 0; /* sample mode */ if (sp->sampletype & 0x8000) /* rom sample? */ vp->mode |= AWE_MODE_ROMSOUND; if (garr[Gen_SampleModes].sword & 1) { /* voice loops? */ vp->mode |= AWE_MODE_LOOPING; /* calculate loop offsets */ vp->loopstart = ((gint) (garr[Gen_StartLoopAddrCoarseOfs].sword) << 15) + (gint) (garr[Gen_StartLoopAddrOfs].sword); vp->loopend = ((gint) (garr[Gen_EndLoopAddrCoarseOfs].sword) << 15) + (gint) (garr[Gen_EndLoopAddrOfs].sword); } else if (!(vp->mode & AWE_MODE_ROMSOUND)) { /* single shot voice */ /* set loop offset start and end pointers to blank loop */ vp->loopstart = sp->end + 1 - sp->loopstart + BLANK_LOOPSTART; vp->loopend = sp->end + 1 - sp->loopend + BLANK_LOOPEND; } else vp->loopstart = vp->loopend = 0; vp->rate_offset = awe_calc_rate_offset (sp->samplerate);}/*----------------------------------------------------------------*//* set global information */static voidset_init_info (awe_voice_info * vp, SFGenAmount * garr){ /* key range */ vp->low = garr[Gen_KeyRange].range.lo; vp->high = garr[Gen_KeyRange].range.hi; /* velocity range */ vp->vellow = garr[Gen_VelRange].range.lo; vp->velhigh = garr[Gen_VelRange].range.hi; /* fixed key & velocity */ vp->fixkey = garr[Gen_Keynum].sword; vp->fixvel = garr[Gen_Velocity].sword; /* panning position */ vp->pan = awe_calc_pan (garr[Gen_Pan].sword); vp->fixpan = -1; /* initial volume */ vp->amplitude = 89; /* should we do something else with this? */ vp->attenuation = awe_calc_attenuation (garr[Gen_Attenuation].sword); /* chorus & reverb effects */ vp->parm.chorus = awe_calc_tenthpercent (garr[Gen_ChorusSend].sword); vp->parm.reverb = awe_calc_tenthpercent (garr[Gen_ReverbSend].sword); /* initial cutoff & resonance */ vp->parm.cutoff = awe_calc_cutoff (garr[Gen_FilterFc].sword); vp->parm.filterQ = awe_calc_filterQ (garr[Gen_FilterQ].sword); /* exclusive class key */ vp->exclusiveClass = garr[Gen_ExclusiveClass].sword;}/*----------------------------------------------------------------*//* calculate root key & fine tune */static voidset_rootkey (SFData * sf, SFSample * sp, awe_voice_info * vp, SFGenAmount * garr){ /* scale tuning */ vp->scaleTuning = garr[Gen_ScaleTune].sword; /* set initial root key & fine tune */ vp->root = sp->origpitch; vp->tune = sp->pitchadj; /* orverride root key if specified in instrument generators */ if ((garr[Gen_OverrideRootKey].sword >= 0) && (garr[Gen_OverrideRootKey].sword <= 127)) vp->root = garr[Gen_OverrideRootKey].sword; /* tuning */ vp->tune += garr[Gen_CoarseTune].sword * 100 + garr[Gen_FineTune].sword; /* correct too high pitch */ if (vp->root >= vp->high + 60) vp->root -= 60;}/*----------------------------------------------------------------*/#define TO_WORD(hi,lo) (((unsigned short)(hi) << 8) | (unsigned short)(lo))/* modulation envelope parameters */static voidset_modenv (awe_voice_info * vp, SFGenAmount * garr){ /* delay */ vp->parm.moddelay = awe_calc_delay (garr[Gen_ModEnvDelay].sword); /* attack & hold */ vp->parm.modatkhld = TO_WORD (awe_calc_hold (garr[Gen_ModEnvHold].sword), awe_calc_attack (garr[Gen_ModEnvAttack].sword)); /* decay & sustain */ vp->parm.moddcysus = TO_WORD (awe_calc_mod_sustain (garr[Gen_ModEnvSustain].sword), awe_calc_decay (garr[Gen_ModEnvDecay].sword)); /* release */ vp->parm.modrelease = TO_WORD (0x80, awe_calc_decay (garr[Gen_ModEnvRelease].sword)); /* key hold/decay */ vp->parm.modkeyhold = garr[Gen_Key2ModEnvHold].sword; vp->parm.modkeydecay = garr[Gen_Key2ModEnvDecay].sword; /* pitch / cutoff shift */ vp->parm.pefe = TO_WORD (awe_calc_pitch_shift (garr[Gen_ModEnv2Pitch].sword), awe_calc_modenv_cutoff (garr[Gen_ModEnv2FilterFc].sword));}/* volume envelope parameters */static voidset_volenv (awe_voice_info * vp, SFGenAmount * garr){ /* delay */ vp->parm.voldelay = awe_calc_delay (garr[Gen_VolEnvDelay].sword); /* attack & hold */ vp->parm.volatkhld = TO_WORD (awe_calc_hold (garr[Gen_VolEnvHold].sword), awe_calc_attack (garr[Gen_VolEnvAttack].sword)); /* decay & sustain */ vp->parm.voldcysus = TO_WORD (awe_calc_sustain (garr[Gen_VolEnvSustain].sword), awe_calc_decay (garr[Gen_VolEnvDecay].sword)); /* release */ vp->parm.volrelease = TO_WORD (0x80, awe_calc_decay (garr[Gen_VolEnvRelease].sword)); /* key hold/decay */ vp->parm.volkeyhold = garr[Gen_Key2VolEnvHold].sword; vp->parm.volkeydecay = garr[Gen_Key2VolEnvDecay].sword;}/* Modulation LFO parameters (tremolo & vibrato) */static voidset_lfo1 (awe_voice_info * vp, SFGenAmount * garr){ vp->parm.lfo1delay = awe_calc_delay (garr[Gen_ModLFODelay].sword); vp->parm.fmmod = TO_WORD (awe_calc_pitch_shift (garr[Gen_ModLFO2Pitch].sword), awe_calc_modlfo_cutoff (garr[Gen_ModLFO2FilterFc].sword)); vp->parm.tremfrq = TO_WORD (awe_calc_tremolo (garr[Gen_ModLFO2Vol].sword), awe_calc_freq (garr[Gen_ModLFOFreq].sword));}/* Vibrato LFO parameters (vibrato only) */static voidset_lfo2 (awe_voice_info * vp, SFGenAmount * garr){ vp->parm.lfo2delay = awe_calc_delay (garr[Gen_VibLFODelay].sword); vp->parm.fm2frq2 = TO_WORD (awe_calc_pitch_shift (garr[Gen_VibLFO2Pitch].sword), awe_calc_freq (garr[Gen_VibLFOFreq].sword));}#endif /* #ifdef AWE_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -