soundsurgeon HTML5合成器
JS-11-16单声道:由Web Audio API创建的电子乐器,它生活在soundsurgeon .com上。
它始于我在2016 – 17年参加的大会JavaScript开发课程的最后一个项目。
此应用中使用的JavaScript库:
JS-11-16 Monosynth是一种乐器,可让用户使用Qwerty键盘的主排或通过屏幕上的按钮弹奏八度音符。
该HTML5应用程序使用Web音频API在浏览器中生成声音而无需使用音频文件。 Web音频API允许以1960年代和70年代的模拟模块化合成器的方式进行减法合成: Moog , Buchla等。
在Web音频API中, AudioContext对象是一个音频处理接口,由相互连接的音频模块组成,例如模块化合成器。这些模块(称为节点)是使用构造方法方法创建的,而其他AudioContext方法连接并操纵节点。
// create AudioContext var a = new AudioContext ( ) ; // create GainNode var g = a . createGain ( ) ; // create OscillatorNode var o = a . createOscillator ( ) ; // set OscillatorNode.type to \'sine\' o . type = \'sine\' ; // OscillatorNode.frequency.value in Hertz o . frequency . value = \'1000\' ; // connect OscillatorNode to GainNode o . connect ( g ) ; // connect GainNode to AudioDestinationNode g . connect ( a . destination ) ; // GainNode gain value range: 0 = 0%, 1 = 100% g . gain . value = 0 ; // start OscillatorNode instantly o . start ( 0 ) ;
Tone.js是一个将Web音频API AudioContext和节点抽象到Tone对象中的框架,其中包含诸如Instrument和Effect的对象类型,在音乐环境中更易于使用。例如,您可以使用科学音调符号选择音符来选择频率,也可以像分数一样定义音符持续时间:
// Tone.js \"Hello World\" // create a synth and connect it to the destination (your speakers) var synth = new Tone . Synth ( ) . toDestination ( ) ; // play a middle \'C\' for the duration of an 8th note synth . triggerAttackRelease ( \"C4\" , \"8n\" ) ;
在App.init中, App.synthObj被分配了一个Tone.MonoSynth仪器的实例。
- 一个振荡器
- 连接到振幅信封
- 连接到由自己的信封控制的过滤器
- 连接到
Tone.Destination输出对象。
Tone.js API描述了可用于Tone组件的各种方法和参数。主要Tone.MonoSynth单一声音参数是:
- 振荡器
- 静音按钮
- 音量滑块
- 波形:
- 正弦
- 正方形(默认)
- 三角形
- 锯齿
- 解剖
- 滑音
- 振幅信封
- 攻击
- 衰变
- 维持
- 发布
- 过滤信封
- 攻击
- 衰变
- 维持
- 发布
- “问”
用户界面用于生活在index.html中,但现在通过App.view中的模板字符串生成。 HTML5 <input>元素用于控制以下参数:
- 静音按钮的
checkbox -
radio选择 - 所有其他参数的
range滑块
App.init中调用的App.initControls方法。INIT接受tone.js Synth对象作为参数,获取合成器的声音参数,并调整UI以使用jQuery方法来表示这些值:
initControls: function ( synth ) { var initWaveform = \'input[value=\"\' + synth . oscillator . type + \'\"]\' ; $ ( initWaveform ) . attr ( \'checked\' , \'checked\' ) ; $ ( \'.envelope .attack\' ) . val ( synth . envelope . attack ) ; $ ( \'.envelope .sustain\' ) . val ( synth . envelope . sustain ) ; $ ( \'.envelope .decay\' ) . val ( synth . envelope . decay ) ; $ ( \'.envelope .release\' ) . val ( synth . envelope . release ) ; $ ( \'.portamento\' ) . val ( synth . portamento ) ; $ ( \'.detune\' ) . val ( synth . detune . value ) ; $ ( \'.filter .q\' ) . val ( synth . filter . Q . value ) ; $ ( \'.filter-envelope .attack\' ) . val ( synth . filterEnvelope . attack ) ; $ ( \'.filter-envelope .sustain\' ) . val ( synth . filterEnvelope . sustain ) ; $ ( \'.filter-envelope .decay\' ) . val ( synth . filterEnvelope . decay ) ; $ ( \'.filter-envelope .release\' ) . val ( synth . filterEnvelope . release ) ; }
App.init中调用的App.bindEvents方法也接受tone.js synth对象作为参数,并包含在UI元素更改时处理事件侦听器的代码:
$ ( \'.mute\' ) . change ( function ( e ) { if ( $ ( this ) . is ( \':checked\' ) ) { Tone . Destination . mute = true ; } else { Tone . Destination . mute = false ; } } ) ; $ ( \'.volume\' ) . change ( function ( e ) { Tone . Destination . volume . value = $ ( this ) . val ( ) ; } ) ; $ ( \'.waveforms input\' ) . change ( function ( e ) { var waveform = $ ( this ) . val ( ) ; synth . oscillator . type = waveform ; } ) ; $ ( \'.envelope input\' ) . change ( function ( e ) { var controlName = this . name ; var controlValue = $ ( this ) . val ( ) ; var currentEnv = synth . envelope ; currentEnv [ controlName ] = controlValue ; } ) ; $ ( \'.portamento\' ) . change ( function ( e ) { synth . portamento = $ ( this ) . val ( ) ; } ) ; $ ( \'.detune\' ) . change ( function ( e ) { synth . detune . value = $ ( this ) . val ( ) ; } ) ; $ ( \'.filter .q\' ) . change ( function ( e ) { synth . filter . Q . value = $ ( this ) . val ( ) ; } ) ; $ ( \'.filter-envelope input\' ) . change ( function ( e ) { var controlName = this . name ; var controlValue = $ ( this ) . val ( ) ; var currentEnv = synth . filterEnvelope ; currentEnv [ controlName ] = controlValue ; } ) ;
App.bindEvents还使用键盘键,这是一个键绑定库,最重要的是允许.preventRepeat()方法在按键下键时禁用密钥重复。主排键的名称保存在CONSTANTS对象中的变量中,而音调触发器都附加到键绑定和<button> ui元素的<label>元素。
CONSTANTS . HOME_ROW . forEach ( function ( elem , i ) { keyboardJS . bind ( elem , function ( e ) { e . preventRepeat ( ) ; synth . triggerAttack ( App . currentScale [ i ] ) ; $ ( keybtns ) . removeClass ( \'active\' ) ; $ ( keybtns [ i ] ) . addClass ( \'active\' ) ; } , function ( event ) { $ ( keybtns [ i ] ) . removeClass ( \'active\' ) ; synth . triggerRelease ( ) ; } ) ; } ) ; document . querySelectorAll ( \'.keyboard label\' ) . forEach ( function ( elem , i ) { elem . addEventListener ( \'mousedown\' , function ( e ) { synth . triggerAttack ( App . currentScale [ i ] ) ; } ) ; elem . addEventListener ( \'mouseup\' , function ( e ) { synth . triggerRelease ( ) ; } ) ; } ) ;
teoria.js是一个图书馆,允许在西方音乐理论背景下进行编程。在开发的早期, CONSTANTS.DEFAULT_SCALE数组为该应用提供了Tone对象所需的注释来创建完整的比例。 teoria.js允许对象表示尺度,注释和间隔,并且可以像jQuery一样将对象链接在一起。 App.generateScale方法现在返回用于创建注释的数组,以便将来,用户可以选择他们想要控制键盘的补品音符,八度和比例尺。
generateScale: function ( tonic , scaleType ) { var tonicObj = teoria . note ( tonic ) ; var scaleObj = tonicObj . scale ( scaleType ) ; var notesArr = scaleObj . notes ( ) ; var noteNamesArr = [ ] ; notesArr . forEach ( function ( e , i ) { noteNamesArr . push ( e . scientific ( ) ) ; } ) ; noteNamesArr . push ( teoria . interval ( tonicObj , \'P8\' ) . scientific ( ) ) ; return noteNamesArr ; }
该应用程序可能会有许多不同的方向:
- 通过JS生成UI
- 添加效果和复音
- 允许保存和回忆补丁
- 添加和弦Arpeggator或Suequencer
- 添加Web MIDI API支持,以便可以使用MIDI键盘播放合成器
上次更新:2023-12-23 07:25 UTC
