【问题标题】:Reusing a function for buttons that work independently of each other?为彼此独立工作的按钮重用功能?
【发布时间】:2021-04-19 03:03:27
【问题描述】:

我正在尝试使用 P5.js 创建类似于音频循环播放器的东西——也就是说,您录制一段 sn-p 音频,它作为循环播放给您,然后您可以录制其他 sn-ps音频一起播放以创作一首歌曲。

我想出了如何录制音频、将其作为循环播放并停止循环,但我不确定重复该功能的最佳方式,以便它可以用于相互独立运行的按钮并录制单独的音频文件,因为我想录制多个循环。

我对 P5.js 还是很陌生,所以可能有一种简单的方法可以做到这一点——任何想法都会有所帮助!一般来说,如果您对如何实现这个项目作为一个整体(音频循环器)有任何想法,我很乐意听到。

这是我的代码:

let mic, recorder, soundFile, button;

let state = 0;

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(200);
  mic = new p5.AudioIn();
  mic.start();
  recorder = new p5.SoundRecorder();
  recorder.setInput(mic);
  soundFile = new p5.SoundFile();

  button = createButton("record");

  button.size(200, 100);
  button.style("font-family", "Bodoni");
  button.style("font-size", "48px");

  button.position(10, 10, 10);
  button.mouseClicked(loopRecord);
}


// this is the looper
function loopRecord() {
  if (state === 0 && mic.enabled) {
    recorder.record(soundFile);

    background(255, 0, 0);
    state++;
  } else if (state === 1) {
    recorder.stop();

    background(0, 255, 0);
    state++;
  } else if (state === 2) {
    soundFile.loop();
    state++;
  } else if (state === 3) {
    soundFile.stop();
    state++;
  } else if (state === 4) {
    state === 0;
  }
} 

【问题讨论】:

    标签: audio p5.js


    【解决方案1】:

    您应该以某种方式构建数据,以便每个按钮都有自己的状态(以及其他不应该是全局的,而是每个循环唯一的参数)。

    这里是一个使用轨道对象数组的示例: https://editor.p5js.org/RemyDekor/sketches/gM75vBYmk

    这里的代码我也复制一下

    let mic
    
    // this array will be filled afterwards
    let tracksArray = [];
    
    function setup() {
      createCanvas(400, 400);
      background(200);
      
      // we need only one mic (it is still global)
      mic = new p5.AudioIn();
      mic.start();
      
      // we call a function that creates a custom "track" object and puts it in the tracksArray (which you could use for some other things, but is currently un-used)
      createTrack();
      
      // we create a button that call the same function when we click on it
      const addTrackButton = createButton("add track");
      addTrackButton.mouseClicked(createTrack)
      addTrackButton.position(10, 10)
    }
    
    // We now use names (strings) instead of abstract numbers to set the state of the track
    function handleTrackButtonClick(trackObject) {
      if (trackObject.state === "idle" && mic.enabled) {
        trackObject.recorder.record(trackObject.soundFile);
        background(255, 0, 0);
      
        trackObject.state = "recording";
        console.dir(trackObject.button.elt.innerText = "[recording..]");
        
      } else if (trackObject.state === "recording") {
        trackObject.recorder.stop();
        background(0, 255, 0);
        
        trackObject.state = "stopped";
        console.dir(trackObject.button.elt.innerText = "play");
      
      } else if (trackObject.state === "stopped") {
        trackObject.soundFile.loop();
        
        trackObject.state = "playing";
        console.dir(trackObject.button.elt.innerText = "[playing..] stop")
        
      } else if (trackObject.state === "playing") {
        trackObject.soundFile.stop();
        
        trackObject.state = "stopped";
        console.dir(trackObject.button.elt.innerText = "[stopped..] play")
      }
    }
    
    
    function createTrack() {
      const newButton = createButton("record");
      newButton.style("font-family", "Bodoni");
      newButton.style("font-size", "48px");
      // we do not position this button anymore, and use the "flow" of the html document
      newButton.style("display", "block");
      
      // this is the "track" object we create, and we attach the previously global parameters/states on it
      const newTrackObject = {
        button: newButton,
        state: "idle",
        recorder: new p5.SoundRecorder(),
        soundFile: new p5.SoundFile()
      };
      
      newButton.mouseClicked(function() {
         handleTrackButtonClick(newTrackObject)
      });
      
      newTrackObject.recorder.setInput(mic);
      
      tracksArray.push(newTrackObject);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2013-12-14
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 2021-12-17
      相关资源
      最近更新 更多