Source: effects/audealize.js

  1. /*
  2. audealize.js: implements a high-level audio effect node in Web Audio API. To use it, simply instantiate the Web Audio Node in your Web Audio graph, and give a reverb word or an eq word.
  3. Depends: reverb.js, equalizer.js, data.js, descriptor.js
  4. */
  5. /**
  6. * <b>The Audealize AudioNode </b>(See {@tutorial gettingstarted}) <br>
  7. *
  8. * Enables semantic control of EQ and reverb effects <br><br>
  9. *
  10. * To use, instantiate the node in your web audio graph, then set
  11. * {@link Audealize~eq_descriptor} or {@link Audealize~reverb_descriptor} <br>
  12. * <br>
  13. *
  14. * This node can optionally look for synonyms if an unkown descriptor is given.
  15. * <br>
  16. * <i>To utilize this functionality, get an API key from
  17. * <a
  18. * href="http://words.bighugelabs.com/api.php">http://words.bighugelabs.com/api.php</a>
  19. * and pass as an argument to the
  20. * constructor.
  21. *
  22. *
  23. * @class
  24. * @name Audealize
  25. * @param {AudioContext} context - The Web Audio context
  26. * @param {string} api_key - (optional) API key for Thesaurus service provided
  27. * by
  28. * <a href="http://words.bighugelabs.com/api.php">words.bighugelabs.com</a>
  29. * (See {@tutorial synonyms})
  30. * @param {Object} opts - (optional) Initial vlaues for
  31. * eq_descriptor, reverb_descriptor, eq_amount, reverb_amount, eq_on, reverb_on
  32. */
  33. function Audealize (context, api_key = '', opts = {}) {
  34. this.input = context.createGain();
  35. this.output = context.createGain();
  36. var curve = new Array(40).fill(0.0);
  37. this.eq = new Equalizer(context, { 'curve': curve });
  38. this.reverb = new Reverb(context);
  39. this.api_key = api_key || null;
  40. this.parameters = new Object();
  41. this.parameters.eq_descriptor = opts.eq_descriptor || 'bright';
  42. this.parameters.reverb_descriptor = opts.reverb_descriptor || 'crisp';
  43. this.parameters.eq_amount = opts.eq_amount || 1;
  44. this.parameters.reverb_amount = opts.reverb_amount || 0.7;
  45. this.parameters.eq_on = opts.eq_on || true;
  46. this.parameters.reverb_on = opts.reverb_on || true;
  47. // start out dry
  48. this.reverb.wetdry = 0;
  49. this.input.connect(this.eq.input);
  50. this.eq.connect(this.reverb.input);
  51. this.reverb.connect(this.output);
  52. }
  53. Audealize.prototype = Object.create(null, {
  54. /**
  55. * Connect output of this node to the input of another AudioNode
  56. * @function
  57. * @name Audealize~connect
  58. * @param {AudioNode} dest - The node to connect to
  59. */
  60. connect: {
  61. value: function(dest) {
  62. this.output.connect(dest.input ? dest.input : dest);
  63. }
  64. },
  65. /**
  66. * Disconnect the output of this node
  67. * @function
  68. * @name Audealize~disconnect
  69. */
  70. disconnect: {value: function() { this.output.disconnect(); }},
  71. /**
  72. * The EQ {@link Descriptor}. <br>
  73. * Set with a string or {@link Descriptor}. Changes to this paramter will
  74. * cause the effect settings to be changed immediately to match. <br>
  75. * If set with a descriptor not present in the EQ dictionary, the node
  76. * will attempt to find synonyms in the dictionary. (See {@tutorial synonyms})
  77. * <br>
  78. * If none are found, the descriptor will revert to its previous value.
  79. * @member
  80. * @name Audealize~eq_descriptor
  81. * @type Descriptor
  82. */
  83. eq_descriptor: {
  84. get: function() {
  85. return new Descriptor(this.parameters.eq_descriptor, 'eq');
  86. },
  87. set: function(word) {
  88. word = word.word ? word.word : word.toLowerCase();
  89. if (word in descriptors['eq']) {
  90. console.log('(Audealize) Changed eq setting to ' + word);
  91. this.eq.curve = descriptors['eq'][word]['settings'];
  92. this.parameters.eq_descriptor = word;
  93. } else {
  94. var synonyms = this.get_synonyms(word);
  95. if (synonyms.length > 0) {
  96. for (var i in synonyms) {
  97. var syn = synonyms[i];
  98. if (syn in descriptors['eq']) {
  99. this.parameters.eq_descriptor = syn;
  100. this.eq.curve =
  101. descriptors['eq'][syn]['settings'];
  102. console.log('(Audealize) Found EQ synonym ' + syn);
  103. return;
  104. }
  105. }
  106. }
  107. console.log('(Audealize) Descriptor not found');
  108. }
  109. }
  110. },
  111. /**
  112. * The reverb {@link Descriptor}. <br>
  113. * Set with a string or {@link Descriptor}. Changes to this paramter will
  114. * cause the effect settings to be changed immediately to match. <br>
  115. * If set with a descriptor not present in the reverb dictionary, the node
  116. * will attempt to find synonyms in the dictionary.
  117. * (See {@tutorial synonyms}) <br>
  118. * If none are found, the descriptor will revert to its previous value.
  119. * @member
  120. * @name Audealize~reverb_descriptor
  121. * @type Descriptor
  122. */
  123. reverb_descriptor: {
  124. get: function() {
  125. return new Descriptor(this.parameters.reverb_descriptor, 'reverb');
  126. },
  127. set: function(word) {
  128. word = word.word ? word.word : word.toLowerCase();
  129. if (word in descriptors['reverb']) {
  130. this.reverb.settings = descriptors['reverb'][word]['settings'];
  131. this.reverb.wetdry = this.parameters.reverb_amount;
  132. this.parameters.reverb_descriptor = word;
  133. console.log('(Audealize) Changed reverb setting to ' + word);
  134. } else {
  135. var synonyms = this.get_synonyms(word);
  136. if (synonyms.length > 0) {
  137. for (var i in synonyms) {
  138. var syn = synonyms[i];
  139. if (syn in descriptors['reverb']) {
  140. this.parameters.eq_descriptor = syn;
  141. this.eq.curve = descriptors['reverb'][syn]['settings'];
  142. console.log('(Audealize) Found reverb synonym ' + syn);
  143. return;
  144. }
  145. }
  146. }
  147. console.log('(Audealize) Descriptor not found');
  148. }
  149. }
  150. },
  151. /**
  152. * The intensity of the EQ effect. <br>
  153. * Scales the gain values of each filter in the equalizer. <br>
  154. * Default = 1.0. A value of 0.0 means the EQ curve will be flat at 0dB. <br>
  155. * Negative values can be used to achieve the inverse effect of the
  156. * descriptor. (e.g. If eq_descriptor = 'bright' and eq_amount = -1, the sound
  157. * will the opposite of bright)
  158. * @member
  159. * @name Audealize~eq_amount
  160. * @type number
  161. */
  162. eq_amount: {
  163. get: function() { return this.parameters.eq_amount; },
  164. set: function(amount) {
  165. this.parameters.eq_amount = amount;
  166. this.eq.range = amount;
  167. }
  168. },
  169. /**
  170. * The ratio of reverb to dry signal. <br>
  171. * 1 = reverb only. 0 = dry signal only. <br>
  172. * Set with a number [0,1]
  173. * @member
  174. * @name Audealize~reverb_amount
  175. * @type number
  176. */
  177. reverb_amount: {
  178. get: function() { return this.parameters.reverb_amount; },
  179. set: function(amount) {
  180. amount = Math.max(amount, 1);
  181. amount = Math.min(amount, 0);
  182. this.parameters.reverb_amount = amount;
  183. this.reverb.wetdry = amount;
  184. }
  185. },
  186. /**
  187. * The on/off state of the eq effect. <br>
  188. * If true, EQ is enabled.
  189. * @member
  190. * @name Audealize~eq_on
  191. * @type boolean
  192. */
  193. eq_on: {
  194. get: function() { return this.parameters.eq_on; },
  195. set: function(on) {
  196. this.parameters.eq_on = on;
  197. if (on) {
  198. this.eq.range = this.parameters.eq_amount;
  199. } else {
  200. this.eq.range = 0;
  201. }
  202. }
  203. },
  204. /**
  205. * The on/off state of the reverb effect. <br>
  206. * If true, reverb is enabled.
  207. * @member
  208. * @name Audealize~reverb_on
  209. * @type boolean
  210. */
  211. reverb_on: {
  212. get: function() { return this.parameters.reverb_on; },
  213. set: function(on) {
  214. this.parameters.reverb_on = on;
  215. if (on) {
  216. this.reverb.wetdry = this.parameters.reverb_amount;
  217. } else {
  218. this.reverb.wetdry = 0;
  219. }
  220. }
  221. },
  222. // For internal use only
  223. get_synonyms: {
  224. value: function(word) {
  225. if (this.api_key == null) {
  226. return [];
  227. }
  228. console.log('(Audealize) Looking for synonyms of ' + word);
  229. // Thesaurus service provided by words.bighugelabs.com
  230. var url = 'http://words.bighugelabs.com/api/2/' + this.api_key + '/';
  231. word = word.replace(/' '/g, '%20');
  232. var fullurl = url + word + '/json';
  233. var response = '';
  234. $.ajax({
  235. url: fullurl,
  236. success: function (repl, status) {
  237. response = repl;
  238. },
  239. type: 'POST',
  240. dataType: 'json',
  241. async: false
  242. }); // .fail(function (x) { console.log(x) })
  243. var synonyms = [];
  244. for (var mainkey in response) { // part of speech
  245. for (var subkey in response[mainkey]) { // syn, sim, ant, etc..
  246. if (subkey !== 'ant') { // don't want to include antonyms
  247. for (var syn in response[mainkey][subkey]) {
  248. synonyms.push(response[mainkey][subkey][syn]);
  249. }
  250. }
  251. }
  252. }
  253. if (synonyms.length == 0) {
  254. console.log('(Audealize) No synonyms found');
  255. }
  256. return synonyms;
  257. }
  258. }
  259. });