Tone.js 完全停止所有播放声音

2023-12-21

简而言之,按下按钮我想使用PolySynth and a Sequence。如果用户反复按下按钮,我希望停止正在播放的内容,然后重新开始。

问题:无论我尝试什么,我都无法完全取消/静音之前播放的音符,以防序列再次启动(再次单击按钮)。这很可能是由于包络的衰减/维持造成的。

我的合成器:

import { PolySynth } from 'tone'

const synth = new PolySynth(Synth, {
  oscillator: {
    type: 'sine4',
    volume: -6,
  },
  envelope: {
    attack: 0.01,
    decay: 0.5,
    sustain: 0.1,
    release: 1,
  },
}).toDestination()
synth.maxPolyphony = 4 // max notes playing at a time, not sure if necessary

我的顺序:

import { Sequence } from 'tone'

// Play the 2 notes individually then play them together
const notes = [
  { note: 'C4', duration: '8n' },
  { note: 'G4', duration: '8n' },
  { note: ['C4', 'G4'], duration: '4n' }
]

// The sequence that should play the notes after one another
const sequence = new Sequence({
  subdivision: '8n',
  loop: false,
  events: notes,
  callback: (time, note) => synth.triggerAttackRelease(note.note, note.duration, time),
})

按照我的方式,这是一个事件处理程序:

import { start, Transport } from 'tone'

// Event handler simply attached to a button's onClick
function onButtonClicked() {
  // Call whatever this start is, doc says it can only happen in an event handler
  start()
  
  // Try everything to kill current sound
  Transport.cancel()
  Transport.stop()

  // Start it again
  Transport.start()
  sequence.start()
}

在开始播放之前我怎样才能完全消除所有声音(如果有的话)?


简答

仔细思考一下,如果我理解正确的话,这实际上是有意的行为。 您正在 Synth(基本上是一个 AudioWorkletNode)上触发一个音符。因此,一旦音符触发合成器,该音符就会消失。阻止该音符播放的唯一方法是将合成器本身静音。

长答案

在您所说的评论中,您可能在概念上遗漏了一些东西,我认为您在这一点上是正确的。

让我们考虑一下 MIDI 是如何产生声音的。

  1. 您正在将 Synth(它获取 MIDI 音符并生成声音)连接到输出
  2. 您正在传输上安排一些 MIDI 音符
  3. 你开始运输
  4. 一旦传输达到音符的预定时间,该 MIDI 值就会发送到合成器。
  5. Since the Synth is basically an AudioWorkletNode with an Envelope Generator, the Synth takes that MIDI note and triggers the internal sound generation (via the envelope). So a MIDI note at a specific point in time triggers a specific length of sound generation (which would be the ADS part). Even if the MIDI notes duration is only 1ms long in your example, the sound generation would hold on for at least 1.001 seconds (Release plus 1 milliseconds MIDI duration). Let's break this down a bit more:
    • MIDI 音符在假想的传输时间轴上有一个起点和终点。
    • Start 触发 Envelope 的 ADS 部分。
    • End 触发包络的 R 部分。
    • 一旦您的 MIDI 音符触发了包络,就会生成声音。

那么,当你停止运输或序列本身时,会发生什么? 如果 MIDI 音符已触发包络,则包络将接收 MIDI 结束触发器并触发释放包络。

因此,您的合成器总会有拖尾声音,因为 MIDI 音符无法确定您的合成器的起点和终点,但会触发您的包络的部分内容。所以实际上你的合成器创造了声音,它既不依赖于传输,也不可能依赖于传输。

希望这个解释对你有一点帮助。如果我误解了你的意思,我很乐意纠正。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tone.js 完全停止所有播放声音 的相关文章

  • 在移动浏览器或 PhoneGap 应用程序之间进行检测

    是否可以使用 JavaScript 检测用户是否通过浏览器或应用程序进行访问 我正在通过网页和 PhoneGap 应用程序开发适用于多个移动操作系统的混合应用程序 目标是 独立于部署目标使用相同的代码 仅当用户代理是应用程序时添加 Phon
  • 带有 nextjs 的 Material-ui 选项卡?

    我有一个 Material ui nextjs 和 typescript 项目 我正在尝试让我的导航栏与 nextjs 一起使用 import as React from react import AppBar from material
  • 获取语​​音通道的用户数

    我正在重写我的音乐部分朋友不和谐机器人 https top gg bot 629799045954797609 我试图弄清楚如何获取执行命令的人的语音通道中的用户数量 我到处都找过 但似乎找不到它或它的用法 现在我正在使用以下内容 modu
  • 如何使用 Javascript 将 HTML 表单数据输出到 XML 文件?

    我目前正在尝试弄清楚如何将 HTML 表单数据输出到 XML 文件 这是我过去几天一直在研究的一个想法 目的是创建一个用于 Windows 7 安装的 autounattended xml 文件 目前我的 HTML 如下
  • LeafletJs只显示一个国家

    我使用 Leafletjs 和 D3 来显示地图 我只想在地图上显示英国 Leaflet和D3是否可以只显示英国 这当然是可能的 现在的解决方案取决于您是想使用 D3 绘制英国 还是想从 Tile Server 获取它 在后一种情况下 有一
  • d3 树 - 有相同孩子的父母

    我一直在将代码从 JIT 转换为 D3 并使用树布局 我已经复制了代码http mbostock github com d3 talk 20111018 tree html http mbostock github com d3 talk
  • 在生产中使用 css / javascript 源映射对性能有何影响?

    生产环境中应该使用源映射吗 除了调试之外 它们还有什么好处吗 由于额外的服务器往返 它们是否会影响应用程序加载时间 浏览器是否足够智能来加载 map应用程序加载和渲染后的资产 如果浏览器找不到 map asset 404错误 会对性能产生影
  • 添加数组的总和。显示1个输出

    更新 这个问题的答案如下 感谢在不同线程上进行的 dougtesting 将数组相加 显示总和 https stackoverflow com questions 45724641 add array together display su
  • HTML5 Audio Element 无法在 IOS 11 设备上的 safari 中播放 mp3 直播

    我是一家广播公司的网络开发人员 自 iOS 11 发布以来 我们收到了一些用户投诉 称我们的音频直播流无法再在 IOS 11 设备上播放 为了将流嵌入我们的网站 我们使用 HTML5 AudioElement 在 iOS 11 的 iPho
  • 如何按日期升序对对象进行排序?

    如果我有一个对象列表 var objectList LIST OF OBJECT each object列表中包含三个属性 name date gender 如何按 对列表中的对象进行排序date 属性升序 the date 属性包含字符串
  • 使用 AngularJS $resource 进行 jsonp 请求

    我在 AngularJS 中定义了以下 2 个服务 两者都应该返回 JSONP 因为我正在进行跨域请求 服务A angular module ServiceA ngResource factory A function resource r
  • 如何查明在 Chrome 控制台中按下按钮时会调用哪些函数?

    我正在尝试自学 Google Closure javascript 库 我正在检查 TreeControl UI 小部件 如何使用Chrome控制台分析当我点击下面演示中的 剪切 按钮时运行了哪些功能 例如 我可以为此设置一个断点吗 我尝试
  • d3 序数尺度的映射

    我正在使用 D3 的序数比例将数字映射到颜色 我用过这个 color d3 scale ordinal range 1f77b4 ff7f0e 2ca02c d62728 9467bd 8c564b e377c2 domain 0 6 co
  • jQuery 删除函数真的删除 Dom 元素吗?

    我真的想知道 jQuery 是否remove http api jquery com remove 函数确实从 DOM 中删除元素 首先 我看了here https stackoverflow com questions 2185760 j
  • 如何控制谷歌地图标记的不透明度

    我需要根据时间使一些标记半透明 有什么方法可以控制标记的 CSS 不透明度吗 或者是否可以可靠地找出标记的 DOM 元素 我使用 Google 地图 API v3 标记的不透明度可以设置为marker setOptions opacity
  • Chrome 和 IE 上的滚动/延迟事件

    我试图让用户始终看到一个内容块 即使他向下滚动页面也是如此 他还应该能够上下滚动内容块 这是一个精简版本的小提琴 向您展示我的意思 http jsfiddle net 9ehfV 2 http jsfiddle net 9ehfV 2 人们
  • ExtJS:简单表单忽略 formBind

    我有一个小问题让我发疯了好几天 我有一个表单面板 Ext define EC view PasswordPanel extend Ext form Panel alias widget pwdpanel bodyPadding 15 ini
  • 如何选中表格中输入文本焦点上的复选框

    我试图在输入文本焦点上检查表 DOM 中的复选框 但无法访问复选框元素 但我的焦点正在工作 这是我的 jsfiddle 链接https jsfiddle net 9qha9vft https jsfiddle net 9qha9vft 这是
  • 如何使用 jquery 生成并附加随机字符串

    一般性 我想使用 jQuery 或 javascript 将随机字符串附加到元素的属性 规格 我需要引用 CDN 上的 CSS 文件 不幸的是 每次更新该 CSS 文件时 CDN 都会更改该文件的 URL 所以我不能简单地引用静态 URL
  • 在 Angular 中导入和使用 lodash 的正确方法

    我曾经能够通过如下所示的 import 语句在 Angular 中使用 lodash 方法 import debounce as debounce from lodash 我现在在使用该语句时收到以下错误 node modules type

随机推荐