⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtbl_aweunits.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
字号:
/*================================================================== * wtbl_aweunits.c - OSS AWE driver unit conversion functions * Based on the awesfx utility Copyright (C) 1996-1999 Takashi Iwai * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include "config.h"#ifdef AWE_SUPPORT#include <stdio.h>#include <stdlib.h>#include <math.h>#include "wtbl_aweunits.h"/*================================================================ * unit conversion *================================================================*//* * Sample pitch offset for the specified sample rate * rate=44100 is no offset, each 4096 is 1 octave (twice). * eg, when rate is 22050, this offset becomes -4096. */gintawe_calc_rate_offset (guint16 Hz){  if (Hz == 44100)    return 0;  return (short) (log ((double) Hz / 44100) / log (2.0) * 4096.0);}/*================================================================ * Emu8000 parameters conversion *================================================================*//* * Delay time * sf: timecents * parm: 0x8000 - msec * 0.725 */gintawe_calc_delay (gint16 amount){  /* completely lost here! */  gint delay, temp;  if (amount <= -12000)    return 0x8000;		/* minimum delay */  delay = (amount + 0x30E4) << 16;  delay /= 1200;  temp = 0x10000 | (delay & 0xffff);	/* SI:BX */  delay >>= 16;  temp >>= 16 - (delay & 0xff);  delay = 0x8000 - temp;  if (delay < -32768)    delay = -32768;  return delay;}/* * Attack and Hold time * This parameter is difficult... * * ADIP says: * bit15 = always 0 * upper byte = 0x7f - hold time / 92, max 11.68sec at 0, no hold at 0x7f. * bit7 = always 0 * lower byte = encoded attack time, 0 = never attack, *      1 = max 11.68sec, 0x7f = min 6msec. * * In VVSG,  *        if AttackTime_ms >= 360ms: *          RegisterValue = 11878/AttackTime_ms - 1 *        if AttackTime_ms < 360ms and AttackTime != 0: *          RegisterValue = 32 + [16/log(2)] * log(360_ms/AttackTime_ms) *        if AttackTime_ms == 0 *          RegisterValue = 0x7F *//* attack & decay/release time table (msec) */gintawe_calc_attack (gint16 amount){  gint attack, temp1, temp2;  if (amount >= 4300)    return 1;  if (amount > -600)    {      attack = (amount + 500) / 150;      temp1 = ((~attack) & 7) | 8;      temp2 = attack >> 16;      attack += temp2 & 7;      attack >>= 3;      temp1 >>= attack;      if (temp1 < 1)	temp1 = 1;      return temp1;    }  attack = (37 - amount) / 75 + 8;  if (attack >= 128)    attack = 127;		/* 128 */  return attack;}gintawe_calc_hold (gint16 amount){  gint hold, temp;  if (amount < -5368)    return 127;			/* maximum hold */  hold = (amount + 4130) << 16;  hold /= 1200;  temp = 0x10000 | (hold & 0xffff);	/* SI:BX */  hold >>= 16;  temp >>= 16 - (hold & 0xff);  hold = 127 - temp;  if (hold < 0)    hold = 0;  return hold;}/* * Sustain level * sf: centibels * parm: 0x7f - sustain_level(dB) * 0.75 */gintawe_calc_sustain (gint16 amount){  gint val = 127 - (amount * 127) / 1000;  if (val < 0)    return 0;  else if (val > 127)    return 127;  else    return val;}/* * Modulation sustain level * sf: 0.1% * parm: 0x7f - sustain_level(dB) * 0.75 */gintawe_calc_mod_sustain (gint16 amount){  gint val = 127 - (amount * 127) / 1000;  if (val < 0)    return 0;  else if (val > 127)    return 127;  else    return val;}/* * This parameter is also difficult to understand... * * ADIP says the value means decay rate, 0x7f minimum time is of 240usec/dB, * 0x01 being the max time of 470msec/dB, and 0 begin no decay. * * In VVSG, 2 * log(0.5) * log(23756/[ms]) (0x7F...0ms), but this is * obviously incorrect. But, the max time 23756 seems to be correct. * (actually, in NRPN control, decay time is within 0.023 and 23.7 secs.) *  */gintawe_calc_decay (gint16 amount){  gint decay, temp1, temp2;  if (amount > 1800)    {      decay = (amount - 1800) / 150;      temp1 = ((~decay) & 7) | 8;      /* here, ASM code has high part of decay & 0x7 too, but we know that         this is always clear since amount is between 1800 & 32767,         therefore decay is 0..206       */      temp2 = decay >> 3;      temp1 >>= temp2;      decay = temp1;      if (decay < 1)	decay = 1;      return decay;    }  /* here, amount < 1800 */  decay = (37 - amount) / 75 + 39;  if (decay >= 128)    decay = 127;  return decay;}/* * Cutoff frequency; return (0-255) * sf: abs cents (cents above 8.176Hz) * parm: quarter semitone; 0 = 125Hz, 0xff=8kHz? * (in VVS, cutoff(Hz) = value * 31.25 + 100) */gintawe_calc_cutoff (gint16 amount){  gint cutoff = (amount + 0xf) / 0x1d - 0x99;  if (cutoff < 0)    return 0;  else if (cutoff > 255)    return 255;  else    return cutoff;}/* * Initial filter Q; return (0-15) * sf: centibels above DC gain. * parm: 0 = no attenuation, 15 = 24dB */gintawe_calc_filterQ (gint16 amount){  gint Q = amount / 12;  if (Q < 0)    return 0;  else if (Q > 15)    return 15;  else    return Q;}/* * Pitch modulation height (0-255) * sf: cents, 100 = 1 semitone * parm: signed char, 0x80 = 1 octave */gintawe_calc_pitch_shift (gint16 amount){  gint val = (amount * 0x1b4f) >> 16;  if (val < -128)    val = -128;  else if (val > 127)    val = 127;  if (val < 0)    return 0x100 + val;  else    return val;}/* * Filter cutoff for modulation envelope (0-255) * sf: 1200 = +1 octave * par: 0x80 = +6(modenv) octave */gintawe_calc_modenv_cutoff (gint16 amount){  gint val;  val = (amount * 0x048D) >> 16;  if (val < -128)    val = -128;  if (val > 127)    val = 127;  if (val < 0)    return (guint8) (0x100 + val);  else    return (guint8) val;}/* * Filter cutoff for modulation LFO (0-255) * sf: 1200 = +1 octave * par: 0x80 = +3(lfo1) octave */gintawe_calc_modlfo_cutoff (gint16 amount){  gint val;  val = (amount * 0x0919) >> 16;  if (val < -128)    val = -128;  if (val > 127)    val = 127;  if (val < 0)    return (guint8) (0x100 + val);  else    return (guint8) val;}/* * Tremolo volume (0-255) * sf: cB, 10 = 1dB * parm: 0x7f = +/-12dB, 0x80 = -/+12dB */gintawe_calc_tremolo (gint16 amount){  gint val = (amount << 7) / 0x78;  if (val < -128)    val = -128;  if (val > 127)    val = 127;  if (val < 0)    val = 0x100 + val;  return (guint8) val;}/* * Envelope/LFO frequency (0-255) * sf: cents  * parm: mHz / 42 (42mHz step; 0xff=10.72Hz) */gintawe_calc_freq (gint16 amount){  gint freq, temp;  if (amount <= -16000)    return 0;			/* minimum freq. shift */  freq = (amount + 0x23A6) << 16;  freq /= 1200;  temp = 0x10000 | (freq & 0xffff);	/* DX:AX */  freq >>= 16;			/* SI:BX */  temp >>= 16 - (freq & 0xff);  if (temp > 255)    temp = 255;  return temp;}/* * Panning position (0-127) * sf: (left) -500 - 500 (right) (0=center) * parm: (left) 0 - 127 (right), as same as MIDI parameter. * * NOTE: *   The value above is converted in the driver to the actual emu8000 *   parameter, 8bit, 0 (right) - 0xff (left). */gintawe_calc_pan (gint16 val){  if (val < -500)    return 0;  else if (val > 500)    return 127;  return (gint8) ((val + 500) * 127 / 1000);}/* * Value in 0.1% units * sf: 0 - 1000 (max) * parm: 0 - 255 (max) */gintawe_calc_tenthpercent (gint16 val){  if (val < 0)    return 0;  else if (val > 1000)    val = 255;  return (guint8) (val * 255 / 1000);}/* * Initial volume attenuation (0-255) * sf: centibels, eg. 60 = 6dB below from full scale * parm: dB * 8 / 3 */gintawe_calc_attenuation (gint16 amount){  gint atten;  atten = (amount + 12) / 24;  atten = (atten * 8) / 3;  if (atten > 255)    atten = 255;  if (atten < 0)    atten = 0;  return atten;}#endif /* #ifdef AWE_SUPPORT */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -