skip to Main Content

I am trying to create an app with the electron-react boilerplate where i can create audio files.

I found Tone.js, which allows me to play sounds but loading the sample files seems close to impossible. Is there a way to give the audio data to Tone?

I am using Sampler but i dont know how to create the URLs to transmit the data

2

Answers


  1. Chosen as BEST ANSWER

    I ended up using a mix of the above answer and what i saw in the documentation:

    let fileDataA4 = fs.readFileSync('path/to/A4.mp3');
    
    // create a Tone.js Player connected to the audio output
    const player = new Tone.Player().toDestination();
    
    let arrayBufferA4 = await new Blob([fileDataA4]).arrayBuffer();
    
    // create a ToneAudioBuffer from the ArrayBuffer with loaded buffer
    const bufferA4 = await player.context.decodeAudioData(arrayBufferA4);
                    
    
    let fileDataA5 = fs.readFileSync("path/to/A5.mp3");
    
    let arrayBufferA5 = await new Blob([fileDataA5]).arrayBuffer();
    
    const bufferA5 = await player.context.decodeAudioData(arrayBufferA5);
                    
    let sampler = new Tone.Sampler({
            urls: {
                "A4" : bufferA4,
                "A5" : bufferA5
            }
    }).toDestination();
                    
    Tone.loaded().then(() => {
        sampler.triggerAttackRelease("C4", "1n")
    })
    

    This way, you only need to load 2 mp3 files, the sampler does the rest for you


  2. Looking at the implementation of Player.load it can handle ArrayBuffers and luckily, using an <input type="file"> can be used to get an ArrayBuffer with a FileReader

    Here is some sample code that assumes that there’s a file input with id "local-file" in your HTML and you have Tone.js loaded at this point:

    document.querySelector('#local-file').addEventListener('change', async function() {
      await Tone.start();
      // create a FileReader to process the chosen file
      const fileReader = new FileReader();
      // when it's read into an ArrayBuffer, we can access that in the result property of the event target
      fileReader.onload = async (event) => {
        // create a Tone.js Player connected to the audio output
        const player = new Tone.Player().toDestination();
        // create a ToneAudioBuffer from the ArrayBuffer with file contents. event.target.result is the ArrayBuffer with the file content
        const buffer = await player.context.decodeAudioData(event.target.result); 
        // add the buffer to our player    
        player.buffer = buffer;
        // once we're ready, start the player.
        Tone.loaded().then(() => {
          player.start();
        });
      }
      // read the selected file into an ArrayBuffer
      fileReader.readAsArrayBuffer(this.files[0]);  
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search