How to properly stop a sequence of notes using WebAudio in an asynchronous manner?

Utilizing WebAudio for playing a sequence of musical notes has been quite successful. I have a playNote function that takes note frequency, start times, and stop times for each note as input. The parameters for generating the sequence are set prior to the actual audio playback, which can be a bit confusing. Essentially, this function creates an oscillator for each note - I've tried other methods, but this one is the most efficient.

However, I am facing an issue with stopping the sequence asynchronously (for example, when an external event occurs). I attempted to implement a master Gain node to control the output gating, but it seems like it needs to be placed "inside" the function in order to manipulate it later on. If I try to deactivate my gain object within the function itself, it's too late because the start and stop times have already been passed to the function.

Below is the code snippet for my function:

function playNote(audioContext,frequency, startTime, endTime, last) {
  gainNode = audioContext.createGain(); //to achieve smooth rise/fall
  oscillator = audioContext.createOscillator();
  oscillator.frequency.value=frequency;
  oscillator.connect(gainNode);
  gainNode.connect(analyserScale); //analyser is a global variable
  analyserScale.connect(audioContext.destination);
  gainNode.gain.exponentialRampToValueAtTime(toneOn,  startTime + trf);
  gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
  oscillator.start(startTime);
  oscillator.stop(endTime);
}

Any assistance would be greatly appreciated!

Answer №1

Here is the solution you're looking for: Stopping all scheduled sounds from playing using Web Audio API. By maintaining an array to keep track of scheduled oscillators, the issue can be resolved.

The revised function looks like this: var oscs = []; //array to store oscillators

function playSound(audioContext, frequency, startTime, endTime, last, index) {
  gainNode = audioContext.createGain(); //ensures smooth volume changes

  oscillator = audioContext.createOscillator();
  oscillator.frequency.value=frequency;
  oscillator.connect(gainNode);
  //keeping track of oscillators in an array
    oscs[index] = oscillator;

  gainNode.connect(analyserScale); //global analyser
  analyserScale.connect(audioContext.destination);
  gainNode.gain.exponentialRampToValueAtTime(toneOn,  startTime + trf);
  gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
  oscillator.start(startTime);
  oscillator.stop(endTime);
}

Code snippet to stop all oscillators:

for(let i=0; i<oscs.length; i++) {
    if(oscs[i]){
      oscs[i].stop(0);
    }
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to access and manipulate data stored in a Firestore map using React?

In my Firestore database, I have a field with map-like data: coordinates:{_01:"copper",_02:"gold",_03:"iron"} When viewing this database in the Firestore admin panel, it appears like this: pic However, when attempting to list items using the following c ...

The table element fails to display in IE11 due to a rendering issue, displaying the error message: "Render error - TypeError: Object does not support the property or method 'entries'"

As someone new to web app development, I am currently working on a project that involves using Vue cli and antd components, with the additional challenge of ensuring compatibility with IE11. However, I have encountered an issue where IE11 does not render ...

Troubleshooting problems with background-image in CSS using Javascript

My latest project involves coding to assign background images to various classes using jQuery. The image files are named in a numerical order, such as 0bg.jpg, 1bg.jpg, 2bg.jpg, and so on. for (i=0; i < 8; i++) { $('.hpCarousel:eq('+i+' ...

Determine whether either of these elements has the mouse hovering over it using jQuery

In my DOM, I have two separate elements that need to change when either one is hovered over. If the link is hovered over, not only does the image src need to change (which is easy), but also the link color needs to change. Similarly, if the image is hovere ...

Error encountered: The use of 'import' and 'export' is limited to 'sourceType: module' when attempting to install Tweakpane

I am currently learning JavaScript and have been following a course on Domestika that requires me to install the Tweakpane package. I usually use Git Bash for installing packages, and I have successfully installed others this way before. Here is the proces ...

center text above images in flexbox when page is resized

When resizing the page, I'm facing an issue where the links overlap with the images in a flexbox layout. It seems like the padding and margin between the images and links are not working due to them not being "related" or connected. I believe I need t ...

Retrieve the CSS class definition using the console in the Chrome Developer Tools

Is there a way to automatedly extract CSS class definitions from Chrome Developer Tools? I want to retrieve the styles defined in a specific class name, similar to how it is displayed in the Styles tab on the right-hand side. I know about the getComputedS ...

Invoke OnSelectedIndexChanged from GridView prior to any other function execution

In my scenario, there are two GridViews available. The first GridView allows the user to select a row, based on which a corresponding list will be displayed according to the selected GridView ID. First Grid: https://i.stack.imgur.com/d0OKq.png Second Gri ...

Component not refreshing when state changes occur

I have a unique react application that resembles the one showcased in this codesandbox link https://codesandbox.io/s/eatery-v1691 By clicking on the Menu located at the bottom center of the page, it triggers the display of the MenuFilter component. The M ...

I am trying to display an element upon hovering using Jquery, but unfortunately, despite recognizing the event, it refuses to function as expected

I've been searching for a solution to show a submenu on hover by removing the hidden class that is hiding it. Despite trying various approaches, including using CSS and JavaScript, I haven't been able to make it work. Here is the code snippet I h ...

The JSON syntax contains an unexpected token

I am encountering an issue with a JavaScript variable named "text" that contains the following value: text={"text":"@RT #Olle_Carly Nuevas filtraciones del iPhone 6: así sería comparado con el Samsung Galaxy S5 y el iPhone 5S: Des... http://t.co/eRuXLS6 ...

Navigating with jQuery Scrollbars

Looking to incorporate a bit of animation in jQuery, trying out the following line: window.parent.scroll(coord[0], coord[1]); The next block of code doesn't seem to be achieving what I had in mind. Do you have any suggestions? $(window.parent).anim ...

Issues with my transpiled and typed TypeScript npm module: How can I effectively use it in a TypeScript project?

I'm trying to experiment with TypeScript. Recently, I created a simple "hello world" TypeScript module and shared it on npm. It's very basic, just has a default export: export default function hello(target: string = 'World'): void { ...

Develop a unique method for loading AngularJS templates

When working with AngularJS, there are various ways to provide an external template, such as using a script tag or a separate HTML file on the web server. However, I am faced with a situation where I need to implement a custom logic for retrieving these ...

What is the best method to trigger a bootstrap modal window from a separate component in Angular 8?

I have successfully implemented a bootstrap modal window that opens on a button click. However, I am now facing difficulty in opening the same modal window from a different component. Below is the code I have tried: <section> <button type=&quo ...

Issue with Electron application encountered during relocation of build directory

Currently, I am developing an Electron-App using NPM that functions as an installer by unzipping a file to a specified directory. While everything works smoothly when I build the application and run it from the win-unpacked folder, moving the folder to a d ...

The promise catch method does not handle JSON parsing correctly

Utilizing Angular's Http to interact with my API has been successful for handling responses with a status of 200. The data is parsed correctly and outputted as expected within the first .then() block. However, when encountering an error with a status ...

What is the best way to incorporate AngularJS data into JavaScript for use in Google Chart?

How can I leverage my AngularJS scope data in a Google Chart or JavaScript? Below is my AngularJS file: angular.module('reports').controller('ReportInfoCtrl', ['$scope', 'reports', '$rootScope','$loca ...

What is the method for implementing a timeout in axios when utilizing the proxy option?

When using Axios with the proxy option, I wanted to verify bad proxies by setting a timeout on my GET request. Here is the code snippet: let res = await axios.get(`http://somedomain.com`, { timeout: 1500, proxy: { ...

Experiment with catching an exception on variable `v`

In my code, I am using a v-if statement to display an error message in HTML. <div id="error" v-if="showError">Error User or Password</div> data() { return { showError: false, };} When I change the value of showError ...