微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我怎样才能让这里的代码在上一个结束时选择一个新的歌曲文件?

如何解决我怎样才能让这里的代码在上一个结束时选择一个新的歌曲文件?

我一直在努力为此开发解决方案,我真的希望这部分非常适合上交。但是,我遇到了 .isPlaying() 函数的具体问题,因为它不会看到它已经结束。另外,如果我没有 noLoop() ,它会“堆叠”声音。一个功能无法正常工作和一个功能必须正确播放歌曲的这种组合使得很难弄清楚如何让计算机重新选择一首歌曲然后播放它。我知道必须有一个解决方案,但我自己找不到,尤其是在我时间紧迫的情况下。老实说,如果没有人及时回复,我可能会离开它,因为我对它现在的工作方式有点酷并且会“适应”它,但我仍然想找到一个不涉及安装另一个解决方案图书馆。

        import processing.sound.*;
        
        SoundFile dd1;
        SoundFile dd2;
        SoundFile dd3;
        SoundFile dd4;
        SoundFile dd5;
        SoundFile dd6;
        int s = int(random(1,6));
    
        int bs=0;
        int PT=0;
    
    void setup() {
    size(20,20);
    
    dd1 = new SoundFile(this,"daydream-1.wav");
    dd2 = new SoundFile(this,"daydream-2.wav");
    dd3 = new SoundFile(this,"daydream-3.wav");
    dd4 = new SoundFile(this,"daydream-4.wav");
    dd5 = new SoundFile(this,"daydream-5.wav");
    dd6 = new SoundFile(this,"daydream-6.wav");
    
    void draw(){
        if (second()-PT>=1) {
    PT=second();
    bs +=1;
  }
  println(bs);
  if (bs>=10) {

    if (s==1) {
      noLoop();
      dd1.play();
    }
    if (dd1.isPlaying()==false) {
      s=int(random(1,6));
    }
    if (s==2) {
      noLoop();
      dd2.play();
    }
    if (dd2.isPlaying()==false) {
      s=int(random(1,6));
    }
    if (s==3) {
      noLoop();
      dd3.play();
    }
    if (dd3.isPlaying()==false) {
      s=int(random(1,6));
    }
    if (s==4) {
      noLoop();
      dd4.play();
    }

    if (dd4.isPlaying()==false) {
      s=int(random(1,6));
    }
    if (s==5) {
      noLoop();
      dd5.play();
    }
    if (dd5.isPlaying()==false) {
      s=int(random(1,6));
    }
    if (s==6) {
      noLoop();
      dd6.play();
    }
    if (dd6.isPlaying()==false) {
      s=int(random(1,6));
    }

    if (keypressed) {
      if (key=='w'||key=='a'||key=='s'||key=='d'||key== ' ') {
        loop();
        if (dd1.isPlaying()) {
          dd1.stop();
          loop();
        }
        if (dd2.isPlaying()) {
          dd2.stop();
          loop();
        }
        if (dd3.isPlaying()) {
          dd3.stop();
          loop();
        }
        if (dd4.isPlaying()) {
          dd4.stop();
          loop();
        }
        if (dd5.isPlaying()) {
          dd5.stop();
          loop();
        }
        if (dd6.isPlaying()) {
          dd6.stop();
          loop();
        }
        s=int(random(1,6));
        bs=0;
        loop();
      }
    }
  }

    void mouseMoved() {
    
    
      if (dd1.isPlaying()==true) {
        dd1.stop();
      }
      if (dd2.isPlaying()==true) {
        dd2.stop();
      }
      if (dd3.isPlaying()==true) {
        dd3.stop();
      }
      if (dd4.isPlaying()==true) {
        dd4.stop();
      }
      if (dd5.isPlaying()==true) {
        dd5.stop();
      }
      if (dd6.isPlaying()==true) {
        dd6.stop();
      }
      s=int(random(1,6));
      bs=0;
      loop();
    }

解决方法

有很多单独的问题会阻止给定的代码示例工作并阻碍您找到解决方案,其中包括:

  • 变量命名
  • 风格
  • 语法错误
  • 重复

一一解决这些问题后,您应该希望看到解决方案

语法和样式

解决语法错误和不一致的缩进为我们提供了以下代码:

import processing.sound.*;

SoundFile dd1;
SoundFile dd2;
SoundFile dd3;
SoundFile dd4;
SoundFile dd5;
SoundFile dd6;

int s = int(random(1,6));

int bs=0;
int PT=0;

void setup()
{
  size(20,20);

  dd1 = new SoundFile(this,"daydream-1.wav");
  dd2 = new SoundFile(this,"daydream-2.wav");
  dd3 = new SoundFile(this,"daydream-3.wav");
  dd4 = new SoundFile(this,"daydream-4.wav");
  dd5 = new SoundFile(this,"daydream-5.wav");
  dd6 = new SoundFile(this,"daydream-6.wav");
}

void draw()
{
  if (second()-PT>=1)
  {
    PT=second();
    bs +=1;
  }
  println(bs);
  if (bs>=10)
  {
    if (s==1)
    {
      noLoop();
      dd1.play();
    }
    if (dd1.isPlaying()==false)
    {
      s=int(random(1,6));
    }
    if (s==2)
    {
      noLoop();
      dd2.play();
    }
    if (dd2.isPlaying()==false)
    {
      s=int(random(1,6));
    }
    if (s==3)
    {
      noLoop();
      dd3.play();
    }
    if (dd3.isPlaying()==false)
    {
      s=int(random(1,6));
    }
    if (s==4)
    {
      noLoop();
      dd4.play();
    }

    if (dd4.isPlaying()==false)
    {
      s=int(random(1,6));
    }
    if (s==5)
    {
      noLoop();
      dd5.play();
    }
    if (dd5.isPlaying()==false)
    {
      s=int(random(1,6));
    }
    if (s==6)
    {
      noLoop();
      dd6.play();
    }
    if (dd6.isPlaying()==false)
    {
      s=int(random(1,6));
    }

    if (keyPressed)
    {
      if (key=='w'||key=='a'||key=='s'||key=='d'||key== ' ')
      {
        loop();
        if (dd1.isPlaying())
        {
          dd1.stop();
          loop();
        }
        if (dd2.isPlaying())
        {
          dd2.stop();
          loop();
        }
        if (dd3.isPlaying())
        {
          dd3.stop();
          loop();
        }
        if (dd4.isPlaying())
        {
          dd4.stop();
          loop();
        }
        if (dd5.isPlaying())
        {
          dd5.stop();
          loop();
        }
        if (dd6.isPlaying())
        {
          dd6.stop();
          loop();
        }
        s=int(random(1,6));
        bs=0;
        loop();
      }
    }
  }
}

void mouseMoved()
{
  if (dd1.isPlaying()==true)
  {
    dd1.stop();
  }
  if (dd2.isPlaying()==true)
  {
    dd2.stop();
  }
  if (dd3.isPlaying()==true)
  {
    dd3.stop();
  }
  if (dd4.isPlaying()==true)
  {
    dd4.stop();
  }
  if (dd5.isPlaying()==true)
  {
    dd5.stop();
  }
  if (dd6.isPlaying()==true)
  {
    dd6.stop();
  }
  s=int(random(1,6));
  bs=0;
  loop();
}

我们可以以此作为本答案其余部分的基础。

变量命名

为您的变量名称选择另一种约定是明智的

  1. 让你更容易理解编程
  2. 让其他人更容易了解正在发生的事情

以下是建议的替代方案

原创 建议
s currentSoundIndex
bs secondsSinceUserInput
PT previousTimeInSeconds
SoundFile dd# SoundFile[] daydreams

我将使用其余部分的建议使答案更清晰一些。

重复

接下来让我们解决重复问题。如果您发现自己写的变量名末尾带有数字,则表明该过程可以简化。

将单个 SoundFile 对象捆绑到单个 SoundFile[] 数组中是有意义的

设置

SoundFile dd1;
SoundFile dd2;
SoundFile dd3;
SoundFile dd4;
SoundFile dd5;
SoundFile dd6;

void setup()
{
  size(20,"daydream-6.wav");
}

变成

SoundFile[] daydreams;

void setup()
{
  size(20,20);
  daydreams = new SoundFile[6];

  for (int i = 0; i < daydreams.length; i++)
  {
    daydreams[i] = new SoundFile(this,"daydream-"+str(i+1)+".wav");
  }
}

mouseMoved 事件

if (dd1.isPlaying()==true)
{
  dd1.stop();
}
if (dd2.isPlaying()==true)
{
  dd2.stop();
}
if (dd3.isPlaying()==true)
{
  dd3.stop();
}
if (dd4.isPlaying()==true)
{
  dd4.stop();
}
if (dd5.isPlaying()==true)
{
  dd5.stop();
}
if (dd6.isPlaying()==true)
{
  dd6.stop();
}

变成

for (SoundFile daydream : daydreams)
{
  if (daydream.isPlaying())
    daydream.stop();
}

这本身就意味着这可以被包装成一个函数

void stopAllSounds()
{
  for (SoundFile daydream : daydreams)
  {
    if (daydream.isPlaying())
      daydream.stop();
  }
}

触发并产生新的随机声音

if (s==1)
{
  noLoop();
  dd1.play();
}
if (dd1.isPlaying()==false)
{
  s=int(random(1,6));
}
if (s==2)
{
  noLoop();
  dd2.play();
}
if (dd2.isPlaying()==false)
{
  s=int(random(1,6));
}
if (s==3)
{
  noLoop();
  dd3.play();
}
if (dd3.isPlaying()==false)
{
  s=int(random(1,6));
}
if (s==4)
{
  noLoop();
  dd4.play();
}

if (dd4.isPlaying()==false)
{
  s=int(random(1,6));
}
if (s==5)
{
  noLoop();
  dd5.play();
}
if (dd5.isPlaying()==false)
{
  s=int(random(1,6));
}
if (s==6)
{
  noLoop();
  dd6.play();
}
if (dd6.isPlaying()==false)
{
  s=int(random(1,6));
}

变成

for (int i = 0; i < daydreams.length; i++)
{
  if (currentSoundIndex == i)
  {
    noLoop();
    daydreams[i].play();
  }
  if(!daydreams[i].isPlaying())
  {
    currentSoundIndex = int(random(6));
  }
}

当前问题

反复使用 noLoop()loop() 会使上述行为的预测变得有点棘手,因此我建议将其完全废弃。

我所看到的是中央绘制循环中的一个固有问题,您决定播放哪个声音

for (int i = 0; i < daydreams.length; i++)
{
  if (currentSoundIndex == i)
  {
    noLoop();
    daydreams[i].play();
  }
  if(!daydreams[i].isPlaying())
  {
    currentSoundIndex = int(random(6));
  }
}

像以前那样写有点难看,但在这种形式中,我们可以确定一个潜在的问题。当上面第一次运行时,你要做的是

  1. 检查您应该播放哪种声音,然后播放
  2. 检查是否所有其他声音都没有播放
  3. 如果没有播放任何后续声音,则生成一个新的随机数以确定应该播放哪个声音。

让我们看一个例子

  • 我们从currentSoundIndex = 5

    开始
  • 对于i = 0

    • currentSoundIndex 不等于 0 所以我们不玩 daydreams[0]
    • 然后我们检查 daydreams[0] 是否正在播放,它肯定不是
    • 因此我们生成一个随机数并分配给 currentSoundIndex
    • 偶然 currentSoundIndex 现在等于 1
  • 我们对 i = 1 重复此操作

    • currentSoundIndex 1 所以我们开始玩daydreams[1]
    • 然后我们检查 daydreams[1] 是否正在播放。是的,所以我们什么都不做
  • 我们对 i = 2 重复此操作

    • currentSoundIndex 不等于 2 所以我们不玩 daydreams[2]
    • 然后我们检查 daydreams[2] 是否正在播放,它肯定不是
    • 因此我们生成一个随机数并分配给 currentSoundIndex
    • 偶然 currentSoundIndex 现在等于 3
  • 我们对 i = 3 重复此操作

    • currentSoundIndex 现在确实等于3,所以我们开始玩daydreams[3]
    • 然后我们检查 daydreams[3] 是否正在播放,它是,所以我们什么都不做
  • 我们对 i = 4 重复此操作

    • currentSoundIndex 不等于 4 所以我们不玩 daydreams[4]
    • 然后我们检查 daydreams[4] 是否正在播放,它肯定不是
    • 因此我们生成一个随机数并分配给 currentSoundIndex
    • 偶然 currentSoundIndex 现在等于 5
  • 我们对 i = 5 重复此操作

    • currentSoundIndex 现在确实等于5,所以我们开始玩daydreams[5]
    • 然后我们检查 daydreams[5] 是否正在播放,它是,所以我们什么都不做

这种情况每次都会发生一些变化。 noLoop()loop() 可能会减轻一些影响。我建议的是一种稍微不同的方法。由于文件现在排列在一个数组中,我们知道要播放的文件的索引,因此我们不再需要循环。我们需要的是什么时候生成一个新的随机 currentSoundIndex 以及什么时候播放那个文件的一些指示。为此,我建议再引入一个变量,即我将称之为 boolean 的单个 soundShouldPlay

soundShouldPlaytrue 开头,可以像下面这样使用

if (secondsSinceUserInput >= 10)
{
  if (soundShouldPlay)
  {
    daydreams[currentSoundIndex].play();
    soundShouldPlay = false;
  }

  if(!daydreams[currentSoundIndex].isPlaying())
  {
    currentSoundIndex = int(random(6));
    soundShouldPlay = false;
  }
}

如果 soundShouldPlay 为真,我们播放 daydreams[currentSoundIndex] 并将 soundShouldPlay 设置为 false。下次我们再来的时候不行,因为 soundShouldPlay 是假的,我们再也不会要求玩 daydreams[currentSoundIndex]。一旦 daydreams[currentSoundIndex] 不再播放,我们会生成一个 currentSoundIndex 并将 soundShouldPlay 设置回 true。因此,下次我们回来时,由于 soundShouldPlaytrue,我们播放新的 daydreams[currentSoundIndex]

把它放在一起

把它放在一起会让程序看起来像

import processing.sound.*;

int currentSoundIndex = int(random(6));
int secondsSinceUserInput = 0;
int previousTimeInSeconds = 0;
boolean soundShouldPlay = true;

SoundFile[] daydreams;
void setup()
{
  size(20,"daydream-"+str(i+1)+".wav");
  }
}

void draw()
{
  if ((second() - previousTimeInSeconds) >= 1)
  {
    previousTimeInSeconds = second();
    secondsSinceUserInput += 1;
  }
  println(secondsSinceUserInput);
  if (secondsSinceUserInput >= 10)
  {
    if (soundShouldPlay)
    {
      daydreams[currentSoundIndex].play();
      soundShouldPlay = false;
    }

    if(!daydreams[currentSoundIndex].isPlaying())
    {
      currentSoundIndex = int(random(6));
      soundShouldPlay = false;
    }
  }
}


void keyPressed()
{
  if (key=='w'||key=='a'||key=='s'||key=='d'||key== ' ')
  {
    stopAllSounds();
    currentSoundIndex = int(random(6));
    secondsSinceUserInput = 0;
  }
}

void mouseMoved()
{
  stopAllSounds();
  currentSoundIndex = int(random(6));
  secondsSinceUserInput = 0;
}

void stopAllSounds()
{
  for (SoundFile daydream : daydreams)
  {
    if (daydream.isPlaying())
      daydream.stop();
  }
}

在这种情况下,您处理用户输入的方式值得怀疑,但如果没有进一步表明您的意图,就很难提供任何类型的反馈。

,

@fdcpp 的回答很全面,而且解释得很好(+1)。 在我看来,这是正确的答案。

我只想提供一些更简单的片段,可能有助于熟悉处理 SoundFile

如果 isPlaying() 在声音播放完毕后没有正确报告 false,解决方法是调用 percent()

import processing.sound.*;
SoundFile file1;
SoundFile file2;

void setup() {
  // load two files
  file1 = new SoundFile(this,"daydream-1.wav");
  file2 = new SoundFile(this,"daydream-2.wav");
  // play first one
  file1.play();
}

void draw(){
  // check if the first file finished playing 
  if(file1.percent() >= 99.8){
      println("track pretty close to done: cue out / cross fade here");
      file1.stop();
      // move file 2 playhead to start
      file2.jump(0);
      // play file 2
      file2.play();
   }
   // same check for file 2
   if(file2.percent() >= 99.8){
      println("track pretty close to done: cue out / cross fade here");
      file2.stop();
      // move file 2 playhead to start
      file1.jump(0);
      // play file 2
      file1.play();
   }

   background(0);
   text("file1.percent(): " + file1.percent() + "\n" + 
        "file1.percent(): " + file2.percent(),5,15);
}

正如 fccpp 所提到的,数组非常适合避免重复自己并使代码臃肿且难以导航和编辑:

import processing.sound.*;
// total audio files
int NUM_FILES = 6;
// array of sound files
SoundFile[] playlist = new SoundFile[NUM_FILES];
// index of the currently playing sound file
int currentIndex = 0;

void setup() {
  // load files
  for(int i = 1 ; i <= NUM_FILES; i++){
    playlist[i] = new SoundFile(this,"daydream-" + i + ".wav");
  }
  // play first one
  playlist[currentIndex].play();
}

void draw(){
  // check if the first file finished playing and play next sound
  if(hasCurrentSoundFinished()){
    playNextSound();
  }

  background(0);
  text("current sound percent: " + playlist[currentIndex].percent(),15);
}

boolean hasCurrentSoundFinished(){
  return playlist[currentIndex].percent() >= 99.8;
}

void playNextSound(){
  // stop current sound
  playlist[currentIndex].stop();
  // increment the index
  currentIndex++;
  // check if it's past the last index to optionally loop to first sound
  if(currentIndex == NUM_FILES){
    currentIndex = 0;
  }
  // reset playhead position
  playlist[currentIndex].jump(0);
  // play
  playlist[currentIndex].play();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。