- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您好!
我正在使用 GCD 构建一个计时器,目的是在特定时间间隔播放声音,更准确地说,它是节拍器声音。几天来我一直在努力解决我的问题,但一无所获。一切都很好,但是当我将节奏设置为更大的值时,比如说 150 bpm 或 200 bpm,当声音第一次开始时,它会非常快速地触发(几乎就像同时发出两个声音,这意味着它没有预期间隔),然后进行校准。我第二次启动声音,一切都很好......所以这只发生在我第一次恢复我的调度源时所以我猜它与从磁盘加载声音有关,就像这篇文章中的那样:Slow start for AVAudioPlayer the first time a sound is played .对于我的声音,我首先使用了 AVAudioPlayer
的实例,带有 prepareToPlay
和 play
并且还在 AppDelegate 类中创建了它,但它没有用...我什至尝试过@NickLockwood 开发的 SoundManager 类,同样的问题。目前,我正在使用 SystemSoundID
。至于计时器,这是我的第一个 GCD 计时器,我已经尝试过经典的 NSTimer
、CADisplayLink
和其他在 git 上找到的计时器......都是徒劳的。
另一个有趣的问题是,对于其他计时器,模拟器上的一切都很完美,但在设备上却出现了同样的故障。
这是代码,我希望有人能告诉我。
-(void)playButtonAction //
{
if (_metronomeIsAnimatingAndPLaying == NO)
{
[self startAnimatingArm]; // I start my animation and create my timer
metronomeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
dispatch_source_set_timer(metronomeTimer,dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC),duration * NSEC_PER_SEC,duration *NSEC_PER_SEC);
dispatch_source_set_event_handler(metronomeTimer, ^{[self playTick];});
dispatch_resume(metronomeTimer);
_metronomeIsAnimatingAndPLaying = YES;
}
}
-(void)playTick
{
AudioServicesPlaySystemSound(appDeleg.soundID); // soundID is created in appDelegate
}
在我的应用程序中 didFinishLaunching
NSString *path = [[NSBundle mainBundle] pathForResource:@"tick"
ofType:@"caf"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
, &_soundID);
以及 BPM setter 和 getter :
- (NSUInteger)bpm
{
return round(60.0 / duration);
}
- (void)setBpm:(NSUInteger)bpm
{
if (bpm >= MaxBPM) {
bpm = MaxBPM;
} else if (bpm <= MinBPM) {
bpm = MinBPM;
}
duration = (60.0 / bpm);
}
最佳答案
这种安排根本行不通。
GCD 是一个线程池,旨在促进任务级并行性。它通常是异步和非实时的。这些特性几乎与音频应用程序所需的特性完全相反。
为 GCD 队列提供服务的每个线程都在与系统中的其他线程竞争执行机会。此外,队列可能在请求的时间忙于处理其他事情。如果那个其他是长时间运行的——而长时间运行的任务正是 GCD 的目标——调度程序可能会在操作完成之前抢占线程并惩罚队列;它可能会等待很长时间才能获得服务。
Manpage对于 GCD,关于 GCD 队列上的计时器的声明如下:
尽最大努力在指定时间将事件处理程序 block 提交到目标队列;但是,实际调用可能会在稍后发生。
NSTimer
不会更好。它的文档声明计时器不是实时机制。由于您可能会在应用程序的主运行循环中运行它,因此它也将是非常不可预测的。
此问题的解决方案是使用较低级别的音频 API - 特别是音频单元。这样做的好处是 soft-syth 单元有一个事件队列,由单元的渲染处理程序提供服务。这在实时线程上运行,并提供极其强大和可预测的服务。由于您可以在未来对大量带有时间戳的事件进行排队,因此您的时间要求现在非常宽松。您可以安全地为此使用 GCD 或 NSTimer
。
关于ios - 使用 GCD 计时器间隔播放声音不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17285212/
我们如何让 SwiftUI 对象,尤其是 Image,符合 Hashable 协议(protocol)? 我知道它们符合 Equatable 协议(protocol),所以主要问题是如何获取哈希值,或
我遇到了一些符合 AVAudioPlayerDelegate 的奇怪问题。以下正是我在一个全新的 Xcode 项目中所拥有的: import UIKit import AVFoundation cla
我一辈子都弄不明白为什么我会收到此类不符合 NSCoding 协议(protocol)的错误。也许另一双眼睛会有所帮助。我试图添加注释以明确每个函数在做什么。 import Foundation im
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
所有现代浏览器都理解 HTML,所以除了在键盘最右侧编写更多字符之外,兼容 XHTML 的意义何在。 最佳答案 没有一点我能想到的。 W3C 已经取消了 XHTML 2.0,尽管应该有一个 XHTML
我正在设计一个订单系统,状态设计模式似乎很合适,因为订单可以更改其状态,从而更改订单允许的功能。下面是我的基本类图: 我不喜欢这种方法,因为客户端无法查看某个方法是否受支持并且违反了里氏原则。我在下面
我正在考虑使用图形数据库来存储 IFC数据。理想情况下,数据库应该提供一种方法来定义 IFC 架构中定义的所有规则类型。但是,我不认为有任何这样的数据库,因为 IFC 中的某些规则类型非常复杂并且需要
我所在的组织必须满足 FISMA 对启用 FIPS 的系统的要求。我正在尝试做的一件事是为我们的密码实现哈希算法。我对此有很多选择:SHA-2、MD5、bcrypt(使用 Blowfish)、RIPE
我正在尝试实现我的自定义 CoreData Carpark 实体以符合 MKAnnotation,就像我们如何使 class 对象符合 >MKAnnotation. 我根据以下帖子调整了我的实现:th
我在 project-Swift.h 文件中收到名为“CBCentralManagerDelegate”的 No 类型或协议(protocol)。不知道我在这里哪里出错了。我认为这与 swift.h
我正在尝试读取之前写入 NVM 闪存的变量的值。 我的代码是: uintptr_t address = getAddress(); //[MISRA C++ Rule 5-2-8] cast from
所以我有这个练习要解决。我必须创建第一个。一个名为 Printable 的接口(interface),它有一个 put() 方法,该方法将接受实现 Comparable 的对象。 完成 interfa
我的问题涉及 IEEE 754 单精度数字。假设我有一个结构: typedef struct __ieee754 { int sign; int exponent; int mant
我需要使用 map,键为 uint32_t,值为 Meshes。我希望将网格布局在连续的内存中以 boost 性能,因为它们将经常被连续访问。 我想知道有哪些内存分配器库可以提供以下内容; 分配给连续
在处理小对象时,有哪些分配器可用于 STL。我已经尝试过使用 Boost 的池分配器,但没有得到任何性能提升(实际上,在某些情况下性能下降相当大)。 最佳答案 你没有说你使用的是什么编译器,但它可能带
我想做什么 我有一种划分事物的方法。此方法不会对数组进行完全排序;它只是简单地对数组进行分区,以便一侧的所有元素(某些预先确定的“中心”或“中点值”——但它不必导致均匀拆分)小于“中心”和另一侧的所有
假设我需要开发一个 REST 银行应用程序允许创建/销毁银行账户以及对帐户进行以下操作:withdraw/credit/getBalance。 创建帐户 PUT/银行/约翰 这里我使用 PUT 而不是
假设我有一个 struct 符合我的模型的 Equatable,如下所示: struct Model: Equatable { var a: Int = 0 var b: String
我目前正在研究 Decodable、Encodable 和 friend ,试图理解它背后的“魔法”。 以下是我发现不寻常的一件事: class Person: Decodable { var n
在 Swift 书中,枚举的例子很好用 enum CompassPoint: String { case north, south, east, west } var northCom = C
我是一名优秀的程序员,十分优秀!