我正在尝试制作一个简单的游戏,当你击中某物时,它的音高会有所不同。我以为这很简单,但结果却有很多东西(其中大部分是我完全从别人那里复制的):
func hitSound(value: Float) {
let audioPlayerNode = AVAudioPlayerNode()
audioPlayerNode.stop()
engine.stop() // This is an AVAudioEngine defined previously
engine.reset()
engine.attach(audioPlayerNode)
let changeAudioUnitTime = AVAudioUnitTimePitch()
changeAudioUnitTime.pitch = value
engine.attach(changeAudioUnitTime)
engine.connect(audioPlayerNode, to: changeAudioUnitTime, format: nil)
engine.connect(changeAudioUnitTime, to: engine.outputNode, format: nil)
audioPlayerNode.scheduleFile(file, at: nil, completionHandler: nil) // File is an AVAudioFile defined previously
try? engine.start()
audioPlayerNode.play()
}
由于此代码似乎停止播放当前正在播放的任何声音以播放新声音,是否有办法改变此行为,使其不会停止播放任何内容?我尝试删除 engine.stop 和 engine.reset 位,但这只会使应用程序崩溃。此外,这段代码在频繁调用时速度非常慢。我可以做些什么来加快速度吗?经常需要这种击中声音。
最佳答案
每次播放声音时都在重置引擎!而且您正在创建额外的播放器节点 - 如果您只想同时播放一个音高变化的声音实例,它实际上比这要简单得多:
// instance variables
let engine = AVAudioEngine()
let audioPlayerNode = AVAudioPlayerNode()
let changeAudioUnitTime = AVAudioUnitTimePitch()
调用setupAudioEngine()一次:
func setupAudioEngine() {
engine.attach(self.audioPlayerNode)
engine.attach(changeAudioUnitTime)
engine.connect(audioPlayerNode, to: changeAudioUnitTime, format: nil)
engine.connect(changeAudioUnitTime, to: engine.outputNode, format: nil)
try? engine.start()
audioPlayerNode.play()
}
并根据需要多次调用 hitSound():
func hitSound(value: Float) {
changeAudioUnitTime.pitch = value
audioPlayerNode.scheduleFile(file, at: nil, completionHandler: nil) // File is an AVAudioFile defined previously
}
附注音高可以向上或向下移动两个 Octave ,范围为 4 个 Octave ,并且位于 [-2400, 2400] 的数值范围内,单位为“音分”。
p.p.s AVAudioUnitTimePitch 是一项非常酷的技术。我们小时候肯定没有这样的东西。
更新
如果您想要多 channel ,您可以轻松设置多个播放器和音调节点,但是您必须在启动引擎之前选择 channel 数。下面是两个方法(很容易扩展到 n 个实例,并且您可能想要选择自己的方法来选择在所有播放时中断哪个 channel ):
// instance variables
let engine = AVAudioEngine()
var nextPlayerIndex = 0
let audioPlayers = [AVAudioPlayerNode(), AVAudioPlayerNode()]
let pitchUnits = [AVAudioUnitTimePitch(), AVAudioUnitTimePitch()]
func setupAudioEngine() {
var i = 0
for playerNode in audioPlayers {
let pitchUnit = pitchUnits[i]
engine.attach(playerNode)
engine.attach(pitchUnit)
engine.connect(playerNode, to: pitchUnit, format: nil)
engine.connect(pitchUnit, to:engine.mainMixerNode, format: nil)
i += 1
}
try? engine.start()
for playerNode in audioPlayers {
playerNode.play()
}
}
func hitSound(value: Float) {
let playerNode = audioPlayers[nextPlayerIndex]
let pitchUnit = pitchUnits[nextPlayerIndex]
pitchUnit.pitch = value
// interrupt playing sound if you have to
if playerNode.isPlaying {
playerNode.stop()
playerNode.play()
}
playerNode.scheduleFile(file, at: nil, completionHandler: nil) // File is an AVAudioFile defined previously
nextPlayerIndex = (nextPlayerIndex + 1) % audioPlayers.count
}
关于swift - Xcode 8 Swift 3 改变音调的声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39893997/
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
我有以下内容:text.gsub(/(lower)(upper)/,'\1\2')我可以将\2替换为大写吗?类似于:sed-e's/\(abc\)/\U\1/'这在Ruby中可行吗? 最佳答案 查看gsub文档:str.gsub(模式){|匹配|block}→new_str在block形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量将被适当设置。block返回的值将替换为每次调用的匹配项。"alowerupperb".gsub(/(lower)(upper)/){|s|$1+""+$2.upcase}
我找遍了所有我能找到的地方,但似乎找不到解决这个问题的办法。我在Lion10.8.2上使用Xcode4.5.1,并尝试为Rails项目运行bundle,但它一直卡在这上面。我正在为Heroku使用Thingem。Bolanos@Jeremys-Mac-mini⦿-1.9.3fishfarm$sudogeminstalleventmachinePassword:Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingeventmachine:ERROR:Failedtobuildgemnativeextens
为什么我可以这样改变“self”:self.map!{|x|x*2}或者这样:self.replace(self.map{|x|x*2})但不是这样:self=self.map{|x|x*2}为什么Ruby不允许我更改“self”变量指向的对象,但允许我更改对象的属性? 最佳答案 不是答案,只是一个线索。a=[1,2]=>[1,2]a.object_id=>2938a.map!{|x|x*2}=>[2,4]a.object_id#differentdatabutstillthesameobject=>2938a.replace(a.
为什么下面的表达式会这样解析?括号的优先级应该高于换行符,不是吗?3-(1+1)#=>13-(1+1)#=>2省略加号也会让表达式计算为2:3-(11)#=>2如果我声明为连续的换行符(转义)或将加号移动到第一行,则会实现所需的行为:3-(1\+1)#=>13-(1+1)#=>1 最佳答案 这是因为Ruby将新行识别为表达式的结尾,除非表达式不完整。例如,(1+1)与相同(1;+1)这与+1相同,因为返回了括号内的最后一个表达式。这进一步与1相同。如果行尾有+,则表达式不完整,因此会继续到下一行。这使得:3-(1+1)被解释为3-(
这个问题在这里已经有了答案:differentlayoutforsign_inactionindevise(8个答案)关闭7年前。如何更改设计Controller中的布局?
我最近想开始使用MacRuby。我已经安装了Xcode4.2和MacRuby,但显然我遗漏了一些东西。到目前为止,在我发现的每个教程中都说,我必须从Xcode模板中选择“MacRuby应用程序”……但是没有这样的条目可用。我试过0.10和几天前发布的每晚版本。我查看了MacRuby的安装位置,我找到了Xcode3.0的模板……我必须使用这些模板吗?如何将它们导入Xcode4.2?在开始之前,我还想知道,从MacRuby开始是否安全?乍一看,我认为"is",因为有新的MacRuby书籍可用——但MacRuby网站上似乎没有太多事件(去年3月的最后一篇博客文章?)……根据我的经验,这可能是
在Xcode之外,我使用特定版本的Ruby,使用RVM管理多个Ruby安装。Apple的命令行开发工具将Ruby安装在/usr/bin/ruby并且版本为1.8.7。我通过RVM使用1.9.3。有没有办法强制Xcode在运行其运行脚本构建阶段时使用我的1.9.3安装?我已经尝试将Shell路径设置为我的特定Ruby的完整路径,但这似乎没有什么不同,我的意思是我在1.9.3中安装的特定Gems不可用/在Xcode中运行时对脚本可见。如果我在命令行上通过xcodebuild运行我的项目,运行脚本阶段会使用我的特定Ruby,因为它是从我的shell环境中运行的(即使项目文件中的Shell路径
我最近注意到ActiveRecord对象上的方法changed?在Rails3.2.13和Rails4.0.1之间发生了变化。问题在于连接到数据库中整数字段的字段。假设我的模型Model带有number整数字段:#Rails3.2.13m=Model.lastm.number#=>5m.number='5hello'm.number#=>5m.number_changed?#=>truem.changed?#=>truem.changes#=>{:number=>[5,5]}#Rails4.0.1m=Model.lastm.number#=>5m.number='5hello'm.nu
Xcode的语法着色充其量只是很差,而textmate看起来不错,但我喜欢Xcode,因为我也用C++编程。我想将所有内容都放在一个地方并利用其他Xcode功能。有没有人已经这样做过或者有没有简单的方法来做到这一点? 最佳答案 你可以去Editor>SyntaxColoring>CheckHTMLanddoitagainforRuby 关于ruby-on-rails-是否有针对Rails、Ruby、Erb的Xcode语法着色?如果没有,我怎么能自己写一个?,我们在StackOverflo