【问题标题】:FMOD surround sound openframeworksFMOD 环绕声开放框架
【发布时间】:2012-06-11 16:37:03
【问题描述】:

好的,我希望我不要搞砸了,我已经寻找了一些答案,但找不到任何东西。我正在尝试在 3D 模式下使用 FMOD 声音播放器在 openframeworks 中制作一个简单的采样器。我可以让单个实例正常工作(使用 libsndfilerecorder 录制一个新文件,然后播放它并在环绕声中移动它。

但是,我希望有 8 层循环音频,我可以在现场表演中一次录制和替换一层。一旦我有超过 1 层,我就会遇到很多问题。

我的问题的第一部分与 FMOD 3D 模式有关,它是相对于听者的,所以我必须为每个声音定义听者的位置(我更喜欢头部相对模式,但我无法在全部。当我使用单个播放器但使用多个播放器时,这再次正常工作,但只有我更新的最后一个侦听器实际工作。

我遇到的主要问题是,当我使用多个播放器时,我会在新录音中出现失真,并且通常会混合其他当前正在播放的声音(即使麦克风听不到它们)。是否与 libsndfilerecorder 和 FMOD 不兼容?

我在这里初始化播放器

for (int i=0; i<CHANNEL_COUNT; i++) {  
    lvelocity[i].set(1, 1, 1);  
    lup[i].set(0, 1, 0);  
    lforward[i].set(0, 0, 1);  
    lposition[i].set(0, 0, 0);  
    sposition[i].set(3, 3, 2);  
    svelocity[i].set(1, 1, 1);  
    //player[1].initializeFmod();  
    //player[i].loadSound( "1.wav" );  
    player[i].setVolume(0.75);  
    player[i].setMultiPlay(true);  
    player[i].play();  
    setupHold[i]==false;  
    recording[i]=false;  
    channelHasFile[i]=false;  
    settingOsc[i]=false;  
} 

在录制时,我会卸载文件并确保未加载的播放器的位置不会更新。

void fmodApp::recordingStart(int recordingId){

if (recording[recordingId]==false) {  
    setupHold[recordingId]=true; //this stops the position updating  
    cout<<"Start recording Channel " + ofToString(recordingId+1)+"  setup hold is true \n";  
    pt=getDateName() +".wav";  
    player[recordingId].stop();  
    player[recordingId].unloadSound();  
    audioRecorder.setup(pt);  
    audioRecorder.setFormat(SF_FORMAT_WAV | SF_FORMAT_PCM_16);  
    recording[recordingId]=true; //this starts the libSndFIleRecorder  

}  
else {  
    cout<<"Channel" + ofToString(recordingId+1)+" is already recording \n";  
}  

}

然后我就这样停止录制。

void fmodApp::recordingEnd( int recordingId ){  
if (recording[recordingId]=true) {  
    recording[recordingId]=false;  
    cout<<"Stop recording" + ofToString(recordingId+1)+" \n";  
    audioRecorder.finalize();  
    audioRecorder.close();  
    player[recordingId].loadSound(pt);  
    setupHold[recordingId]=false;  
    channelHasFile[recordingId]=true;  
    cout<< "File recorded channel " + ofToString(recordingId+1) + " file is called " + pt + "\n";  
}  
else {  
    cout << "Sorry track" + ofToString(recordingId+1) + "is not recording";  
}  

}

我注意不要中断更新过程,但我看不出哪里出错了。

非常感谢

【问题讨论】:

    标签: audio openframeworks fmod surround


    【解决方案1】:

    为了处理失真,我认为您需要在播放时降低每个通道的音量,尝试将音量设置为最大音量的 1/8。没有任何削波,所以如果声音的总和 > 1.0f 你会削波,它会听起来很糟糕。

    在录制时处理串扰:我猜你在输出上有某种反馈,即输出声音被反馈到输入通道,可能是由操作系统。如果您运行另一个发出声音的应用程序,您是否也会在录音中得到它?如果是这样,那可能是你的问题。

    如果它适用于一个通道,请尝试仅使用 2 个通道,而不是直接跳到 8 个通道。

    一般来说,我会尝试将播放/录制逻辑和 soundPlayer/recorder 抽象到一个单独的类中。你有几个布尔值,使用 >1 布尔值很容易出错。有什么方法可以用枚举或整数状态变量替换布尔值?

    【讨论】:

      【解决方案2】:

      编辑:我没有看到您的问题的日期:D 假设您现在设法做到了。也许它可以帮助其他人..

      我不确定我是否可以回答您的所有问题,但我可以分享我如何在 FMOD 中使用 3D 声音。不过我还没做过录音。

      对于我自己的应用程序,用户可以在自己周围的 3D 空间中放置声音。为此,我只有一个 Listener 和多个 Sounds。在您的代码中,您正在为每个声音制作一个监听器,您确定这是必要的吗?我想这会导致多个听众拾取多个声音并将其输出到您的声卡。那么从第二个声音+听者,两个听者都拾取两个声音?我不是 100% 肯定,但对我来说这听起来很合理。

      我创建了一个类来创建声音对象(和一个听众)。然后我使用向量来存储对象并通过它们移动来渲染它们。

      我的类 SoundBox 基本上拥有 FMOD 所需的所有东西

      制作一个“SoundBox”对象并将其添加到我的 soundboxes 向量中:

      SoundBox * box = new SoundBox(box_loc, box_rotation, box_color);
      box->loadVideo(ofToDataPath(video_files[soundboxes.size()]));
      box->loadSound(ofToDataPath(sound_files[soundboxes.size()]));
      box->setVolume(1);
      box->setMultiPlay(true);
      box->updateSound(box_loc, box_vel);"
      box->play();
      soundboxes.push_back(box);
      

      SoundBox 的构造函数。我在同一个类中为侦听器使用了类似的构造函数,但是由于侦听器对我来说始终位于原点,因此它不接受任何参数,只是将所有侦听器位置设置为 0。侦听器的构造函数只获取调用一次,而当我想制作一个新的时,就会调用 Sound 的那个。 (不要介意 box_color。在这种情况下,我正在绘制物理框..):

      SoundBox::SoundBox(ofVec3f box_location, ofVec3f box_rotation, ofColor box_color) {
      
      _box_location = box_location; 
      _box_rotation = box_rotation;
      _box_color = box_color;
      
      sound_position.x = _box_location.x;
      sound_position.y = _box_location.y;
      sound_position.z = _box_location.z;
      sound_velocity.x = 0;
      sound_velocity.y = 0;
      sound_velocity.z = 0;
      

      然后我只使用一个 for 循环来循环它们并在它们不播放时播放它们。我也有一些类似的代码来选择它们然后移动。

      for(auto box = soundboxes.begin(); box != soundboxes.end(); box++){
          if(!(*box)->getIsPlaying())
              (*box)->play();
      }
      

      我真的希望这会有所帮助。我不是一个非常有经验的程序员,但这就是我在 OpenFrameworks 中获得具有多种声音的 FMOD 的方法,希望您可以使用其中的一些。我只是尽可能多地倾倒了我的代码:D

      我的主要建议是让一个听众而不是更多。例如,如果您想在初始放置后重新定位声音,那么创建声音的类也很有用。

      希望对你有帮助,祝你好运:)

      【讨论】:

      • 谢谢,很长一段时间,但我最终以与您的建议非常相似的方式解决了它,并且头脑清醒。干杯
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多