【问题标题】:What is the best way to play sound quickly upon fast button presses Xcode?在快速按下 Xcode 按钮时快速播放声音的最佳方法是什么?
【发布时间】:2011-03-08 21:10:51
【问题描述】:

我有一个音板 它只是一个带有大约 8 个按钮的屏幕。 每个单独的按钮都有自己的声音,在按钮按下时播放 有几种方法可以播放声音,例如使用 SystemSound 或 AVAudioPlayer 到目前为止,系统声音似乎具有最快的响应时间,avaudioplayer 很慢,如果用户真的快速点击按钮,它就跟不上,我为每个声音都创建了一个音频播放器,这很混乱。 这就是我现在播放声音的方式 .h 文件

@interface MainScreenViewController : UIViewController <AVAudioPlayerDelegate, UITabBarControllerDelegate> {
 AVAudioPlayer *player;
 CFURLRef  keNURL;
 SystemSoundID    keNObject;
 //KE LOUD
 CFURLRef  keLURL;
 SystemSoundID    keLObject;
 //GE NORMAL
 CFURLRef  geNURL;
 SystemSoundID    geNObject;
 //GE LOUD
 CFURLRef  geLURL;
 SystemSoundID    geLObject;
 //NA NORMAL
 CFURLRef  naNURL;
 SystemSoundID    naNObject;
 //NA LOUD
 CFURLRef  naLURL;
 SystemSoundID    naLObject;
 //RA
 CFURLRef  raURL;
 SystemSoundID    raObject;
 //DAGGA CLICK
 CFURLRef  daCURL;
 SystemSoundID    daCObject;
 //TILLI CLICK
 CFURLRef  tiCURL;
 SystemSoundID    tiCObject;
}
@property (nonatomic, retain) AVAudioPlayer *player;
@property (readwrite)    CFURLRef        keNURL;
@property (readonly)    SystemSoundID    keNObject;
@property (readwrite)    CFURLRef        keLURL;
@property (readonly)    SystemSoundID    keLObject;
@property (readwrite)    CFURLRef        geNURL;
@property (readonly)    SystemSoundID    geNObject;
@property (readwrite)    CFURLRef        geLURL;
@property (readonly)    SystemSoundID    geLObject;
@property (readwrite)    CFURLRef        naNURL;
@property (readonly)    SystemSoundID    naNObject;
@property (readwrite)    CFURLRef        naLURL;
@property (readonly)    SystemSoundID    naLObject;
@property (readwrite)    CFURLRef        raURL;
@property (readonly)    SystemSoundID    raObject;
@property (readwrite)    CFURLRef        daCURL;
@property (readonly)    SystemSoundID    daCObject;
@property (readwrite)    CFURLRef        tiCURL;
@property (readonly)    SystemSoundID    tiCObject;
}

然后播放个人声音的动作

然后是.m文件,在导入.h文件和正确的框架工作并综合所有变量后,编写动作代码 这就是个人行动中的内容。

-(IBAction)geSound{
 AudioServicesPlaySystemSound (self.geNObject);
}

我只是想知道 systemsound 是否是我创建音板的前进方向。 尤其是当用户在节拍之间快速交替敲击板时。 . 如果不是,播放响应非常好的声音的最佳方式是什么?

【问题讨论】:

  • Xcode 只是一个 IDE - 你大概在谈论 Mac OS X (Cocoa) 或 iPhone (CocoaTouch)?
  • 我回答了我自己的问题。往下看。

标签: iphone objective-c ios audio uibutton


【解决方案1】:

根据经验,AVAudioPlayer 可以很好地同时播放多个声音,或者一个接一个地快速播放。使用它的最佳方法是只创建一个方法,将其输入 NSString 以播放带有 NSString 中的名称的声音...这样,您将为每个声音文件创建一个新播放器你玩。除非你知道你已经完成了他们,否则在释放分配的球员时要小心。

除非你有非常大的声音文件,可能需要很短的时间来缓冲(你必须自己弄清楚你是否可以忍受任何延迟),我从来没有遇到过它变慢的问题.如果速度很慢,您可能违反了 Apple 关于解码某些文件的建议(即一次针对多个声音,Apple 建议使用 CAF 格式,因为它是硬件解码而不是软件解码):http://developer.apple.com/iphone/library/documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html

更新

这是我使用 shell 脚本对文件进行编码的方法。把它放在一个名为batchit.sh 的文件中,放在它自己的目录中。然后将要编码为 .CAF 文件的任何 .WAV 文件放在该目录中。在您的 Mac 上打开 Terminalcd 到该目录并输入 sh batchit.sh 并让它做这件事。它将批量转换所有文件...这是代码:

for f in *; do
if  [ "$f" != "batchit.sh" ]
then
    /usr/bin/afconvert -f caff -d ima4 $f 
    echo "$f converted"
fi
done

注意我在audioPlayerDidFinishPlaying 方法中没有做任何事情,它是AVAudioPlayer 的委托方法。您需要添加代码以在每个播放器完成播放后正确释放播放器(嘿,我不能为您完成所有工作:) 以便正确分配所有内存。否则,如果您无限期地继续创建玩家而不释放他们,您最终会用完。由于您的一天似乎过得很艰难。请参阅下面的重要提示。

不过,这就是我能提供的所有帮助。你必须学习并赚取其余的

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {

    // do something here if you want.. you know like maybe release the old players by uncommenting the line below :)

    //[player release];

}

【讨论】:

  • 非常感谢您的回复。我之前所做的是为每个单独的 osund 文件创建一个音频播放器,然后键入 [sound1 play];单击按钮时,当我轻按按钮时,有时声音会错过播放等等,有时它们确实会播放。它们是很短的声音。它就像一个鼓音板。无论如何,所以每次我单击其中一个按钮播放声音时,您提供的代码是不是有点太多执行?特别是当用户敲击音板时?
  • 感谢您的上传。它帮助我意识到了一件事。我的声音有问题。我不知道那是什么。但是当我用我的替换你的一些声音时,只是为了比较我们在你的应用程序上的声音延迟。你的声音很好,但我的声音不行。有一些随机延迟/滞后。我不明白发生了什么事。 -_-'' 我要拍我的笔记本电脑
  • P.S.声音结束时的沉默与延迟无关。除非它当然在你的循环中,然后是的,你想确保循环听起来不错(我包括的那个不是,但它适用于这个例子)。
  • 非常感谢!就是这样。这是我的声音被转换的方式。 ima4 绝对有帮助。令人惊讶的是,现在声音如何正常播放。无论如何,我可以获取您的联系信息吗?如果你能在 kataria.pavan@gmail.com 上给我发电子邮件,那就太好了,在此先感谢 iwasrobbed。感谢您的耐心和快速回复,以及您更新的帖子。
  • 很棒的帖子!...但我是唯一一个将batchit.sh 视为batshit 的人吗?
【解决方案2】:

您可以为每个声音创建 AVAudioPlayer,然后暂停/播放它。

【讨论】:

  • 我试过了,它仍然播放声音很慢。它现在播放速度比 systemsound 慢。文件开头没有静音。它只有 1 秒的文件。谁能帮帮我?
【解决方案3】:

您是否尝试过在各自的线程中播放每个声音?你可以试试基本的NSOperation

【讨论】:

  • 他的问题在于他如何编码声音文件。框架正在做他们应该做的事情,但他只需要正确编码它们就可以了。
  • 原来如此。感谢您更新的帖子,我跟随您转换为 ima4,它就像一个魅力。你怎么知道是因为我的声音,因为它们仍然是 .caf
【解决方案4】:

22/03/2014 - 更新:删除我过于兴奋的帖子(很久以前写的)并更新以描绘更合适的答案。

我必须对音频进行精细控制,因此选择使用 OpenAL。 WOW是总结它的一种方式。我一开始自己使用 OpenAL,这需要一些额外的工作,实现所有必需的方法并设置所有内容;我发现自己几乎没有明显的延迟。我对出色的结果感到非常满意。

我能够实现良好的控制并且完全没有延迟。我记得当我让它工作的时候高兴得跳起来。

以下是我使用的资源,有助于简化首次实施 OpenAL 的工作:

  1. OpenAL on the iPhone
  2. 正是因为 this link this video tutorial,我才能够创建一个出色的声音管理器单例。这让我可以在几乎没有声音管理的情况下从任何我想要的课程中播放我需要的所有声音,单身人士为我处理了所有事情。

如果您需要对音频进行精细控制,更重要的是,如果您需要低延迟的点播音频,我谦虚地建议大家使用 OpenAL,尤其是当您需要确保在那里播放声音以及何时播放的游戏时您需要并期望它,例如基于音频的应用程序。

【讨论】:

  • “此链接”已失效。想总结一下它所说的内容吗?
  • @Gyfis 链接已更新,伙计。它是一个非常好的视频教程。我敦促您观看它,以便快速启动并运行 OpenAL。
【解决方案5】:

只是为了他人的利益而添加,即使这是发布后 2 年。

我发现如果它们是简短的声音,那么您的应用程序负载就可以了(ish)。通过运行一个准备为每个声音播放的实例(在 for 循环中)缓冲所有音轨(然后释放 - 足以让您的处理器记住文件的位置)

这会在您下次使用它时节省初始加载时间,并让声音更迅速地开始

【讨论】:

  • 您好,感谢您发布答案。如果你看看我对这个问题的回答,你会看到我是如何处理这个问题的。直到现在我仍然使用相同的方法。
猜你喜欢
  • 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
相关资源
最近更新 更多