envelope.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // ---------------------------------------------------------------------------
  2. // This file is part of reSID, a MOS6581 SID emulator engine.
  3. // Copyright (C) 2004 Dag Lem <resid@nimrod.no>
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. // ---------------------------------------------------------------------------
  19. #ifndef __ENVELOPE_H__
  20. #define __ENVELOPE_H__
  21. #include "siddefs.h"
  22. // ----------------------------------------------------------------------------
  23. // A 15 bit counter is used to implement the envelope rates, in effect
  24. // dividing the clock to the envelope counter by the currently selected rate
  25. // period.
  26. // In addition, another counter is used to implement the exponential envelope
  27. // decay, in effect further dividing the clock to the envelope counter.
  28. // The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope
  29. // counter values 255, 93, 54, 26, 14, 6, respectively.
  30. // ----------------------------------------------------------------------------
  31. class EnvelopeGenerator
  32. {
  33. public:
  34. EnvelopeGenerator();
  35. enum State { ATTACK, DECAY_SUSTAIN, RELEASE };
  36. RESID_INLINE void clock();
  37. RESID_INLINE void clock(cycle_count delta_t);
  38. void reset();
  39. void writeCONTROL_REG(reg8);
  40. void writeATTACK_DECAY(reg8);
  41. void writeSUSTAIN_RELEASE(reg8);
  42. reg8 readENV();
  43. // 8-bit envelope output.
  44. RESID_INLINE reg8 output();
  45. protected:
  46. reg16 rate_counter;
  47. reg16 rate_period;
  48. reg8 exponential_counter;
  49. reg8 exponential_counter_period;
  50. reg8 envelope_counter;
  51. bool hold_zero;
  52. reg4 attack;
  53. reg4 decay;
  54. reg4 sustain;
  55. reg4 release;
  56. reg8 gate;
  57. State state;
  58. // Lookup table to convert from attack, decay, or release value to rate
  59. // counter period.
  60. static reg16 rate_counter_period[];
  61. // The 16 selectable sustain levels.
  62. static reg8 sustain_level[];
  63. friend class cSID;
  64. };
  65. // ----------------------------------------------------------------------------
  66. // Inline functions.
  67. // The following functions are defined inline because they are called every
  68. // time a sample is calculated.
  69. // ----------------------------------------------------------------------------
  70. #if RESID_INLINING || defined(__ENVELOPE_CC__)
  71. // ----------------------------------------------------------------------------
  72. // SID clocking - 1 cycle.
  73. // ----------------------------------------------------------------------------
  74. RESID_INLINE
  75. void EnvelopeGenerator::clock()
  76. {
  77. // Check for ADSR delay bug.
  78. // If the rate counter comparison value is set below the current value of the
  79. // rate counter, the counter will continue counting up until it wraps around
  80. // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
  81. // envelope can finally be stepped.
  82. // This has been verified by sampling ENV3.
  83. //
  84. if (++rate_counter & 0x8000) {
  85. ++rate_counter &= 0x7fff;
  86. }
  87. if (rate_counter != rate_period) {
  88. return;
  89. }
  90. rate_counter = 0;
  91. // The first envelope step in the attack state also resets the exponential
  92. // counter. This has been verified by sampling ENV3.
  93. //
  94. if (state == ATTACK || ++exponential_counter == exponential_counter_period)
  95. {
  96. exponential_counter = 0;
  97. // Check whether the envelope counter is frozen at zero.
  98. if (hold_zero) {
  99. return;
  100. }
  101. switch (state) {
  102. case ATTACK:
  103. // The envelope counter can flip from 0xff to 0x00 by changing state to
  104. // release, then to attack. The envelope counter is then frozen at
  105. // zero; to unlock this situation the state must be changed to release,
  106. // then to attack. This has been verified by sampling ENV3.
  107. //
  108. ++envelope_counter &= 0xff;
  109. if (envelope_counter == 0xff) {
  110. state = DECAY_SUSTAIN;
  111. rate_period = rate_counter_period[decay];
  112. }
  113. break;
  114. case DECAY_SUSTAIN:
  115. if (envelope_counter != sustain_level[sustain]) {
  116. --envelope_counter;
  117. }
  118. break;
  119. case RELEASE:
  120. // The envelope counter can flip from 0x00 to 0xff by changing state to
  121. // attack, then to release. The envelope counter will then continue
  122. // counting down in the release state.
  123. // This has been verified by sampling ENV3.
  124. // NB! The operation below requires two's complement integer.
  125. //
  126. --envelope_counter &= 0xff;
  127. break;
  128. }
  129. // Check for change of exponential counter period.
  130. switch (envelope_counter) {
  131. case 0xff:
  132. exponential_counter_period = 1;
  133. break;
  134. case 0x5d:
  135. exponential_counter_period = 2;
  136. break;
  137. case 0x36:
  138. exponential_counter_period = 4;
  139. break;
  140. case 0x1a:
  141. exponential_counter_period = 8;
  142. break;
  143. case 0x0e:
  144. exponential_counter_period = 16;
  145. break;
  146. case 0x06:
  147. exponential_counter_period = 30;
  148. break;
  149. case 0x00:
  150. exponential_counter_period = 1;
  151. // When the envelope counter is changed to zero, it is frozen at zero.
  152. // This has been verified by sampling ENV3.
  153. hold_zero = true;
  154. break;
  155. }
  156. }
  157. }
  158. // ----------------------------------------------------------------------------
  159. // SID clocking - delta_t cycles.
  160. // ----------------------------------------------------------------------------
  161. RESID_INLINE
  162. void EnvelopeGenerator::clock(cycle_count delta_t)
  163. {
  164. // Check for ADSR delay bug.
  165. // If the rate counter comparison value is set below the current value of the
  166. // rate counter, the counter will continue counting up until it wraps around
  167. // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the
  168. // envelope can finally be stepped.
  169. // This has been verified by sampling ENV3.
  170. //
  171. // NB! This requires two's complement integer.
  172. int rate_step = rate_period - rate_counter;
  173. if (rate_step <= 0) {
  174. rate_step += 0x7fff;
  175. }
  176. while (delta_t) {
  177. if (delta_t < rate_step) {
  178. rate_counter += delta_t;
  179. if (rate_counter & 0x8000) {
  180. ++rate_counter &= 0x7fff;
  181. }
  182. return;
  183. }
  184. rate_counter = 0;
  185. delta_t -= rate_step;
  186. // The first envelope step in the attack state also resets the exponential
  187. // counter. This has been verified by sampling ENV3.
  188. //
  189. if (state == ATTACK || ++exponential_counter == exponential_counter_period)
  190. {
  191. exponential_counter = 0;
  192. // Check whether the envelope counter is frozen at zero.
  193. if (hold_zero) {
  194. rate_step = rate_period;
  195. continue;
  196. }
  197. switch (state) {
  198. case ATTACK:
  199. // The envelope counter can flip from 0xff to 0x00 by changing state to
  200. // release, then to attack. The envelope counter is then frozen at
  201. // zero; to unlock this situation the state must be changed to release,
  202. // then to attack. This has been verified by sampling ENV3.
  203. //
  204. ++envelope_counter &= 0xff;
  205. if (envelope_counter == 0xff) {
  206. state = DECAY_SUSTAIN;
  207. rate_period = rate_counter_period[decay];
  208. }
  209. break;
  210. case DECAY_SUSTAIN:
  211. if (envelope_counter != sustain_level[sustain]) {
  212. --envelope_counter;
  213. }
  214. break;
  215. case RELEASE:
  216. // The envelope counter can flip from 0x00 to 0xff by changing state to
  217. // attack, then to release. The envelope counter will then continue
  218. // counting down in the release state.
  219. // This has been verified by sampling ENV3.
  220. // NB! The operation below requires two's complement integer.
  221. //
  222. --envelope_counter &= 0xff;
  223. break;
  224. }
  225. // Check for change of exponential counter period.
  226. switch (envelope_counter) {
  227. case 0xff:
  228. exponential_counter_period = 1;
  229. break;
  230. case 0x5d:
  231. exponential_counter_period = 2;
  232. break;
  233. case 0x36:
  234. exponential_counter_period = 4;
  235. break;
  236. case 0x1a:
  237. exponential_counter_period = 8;
  238. break;
  239. case 0x0e:
  240. exponential_counter_period = 16;
  241. break;
  242. case 0x06:
  243. exponential_counter_period = 30;
  244. break;
  245. case 0x00:
  246. exponential_counter_period = 1;
  247. // When the envelope counter is changed to zero, it is frozen at zero.
  248. // This has been verified by sampling ENV3.
  249. hold_zero = true;
  250. break;
  251. }
  252. }
  253. rate_step = rate_period;
  254. }
  255. }
  256. // ----------------------------------------------------------------------------
  257. // Read the envelope generator output.
  258. // ----------------------------------------------------------------------------
  259. RESID_INLINE
  260. reg8 EnvelopeGenerator::output()
  261. {
  262. return envelope_counter;
  263. }
  264. #endif // RESID_INLINING || defined(__ENVELOPE_CC__)
  265. #endif // not __ENVELOPE_H__