草庐IT

ios - 波形绘制性能优化

coder 2023-09-06 原文

我正在构建一个绘制输入音频数据波形的应用程序。

这是它的外观的直观表示:

它的行为方式类似于 Apple 的原生 VoiceMemos 应用程序。但它缺乏性能。 Waveform 本身是一个 UIScrollView 子类,我在其中绘制 CALayer 的实例来表示紫色“条形”并将它们添加为子层。一开始波形是空的,当声音输入开始时,我用这个函数更新波形:

class ScrollingWaveformPlot: UIScrollView {

  var offset: CGFloat = 0
  var normalColor: UIColor?
  var waveforms: [CALayer] = []
  var lastBarRect: CGRect?
  var kBarWidth: Int = 5

  func updateGraph(with value: Float) {

    //Create instance
    self.lastBarRect = CGRect(x: self.offset,
                              y:   self.frame.height / 2,
                              width: CGFloat(self.barWidth),
                              height: -(CGFloat)(value * 2))


    let barLayer = CALayer()
    barLayer.bounds = self.lastBarRect!
    barLayer.position = CGPoint(x: self.offset + CGFloat(self.barWidth) / 2,
                                y: self.frame.height / 2)
    barLayer.backgroundColor = self.normalColor?.cgColor

    self.layer.addSublayer(barLayer)
    self.waveforms.append(barLayer)

    self.offset += 7

  }

...

}

当紫色条的最后一个矩形到达屏幕中间时,我开始增加波形的 contentOffset.x 以使其像 Apple 的 VoiceMemos 应用程序一样运行。

问题是:当柱数达到 ~500...1000 时,在 setContentOffset 期间开始出现一些明显的波形滞后。

self.inputAudioPlot.setContentOffset(CGPoint(x: CGFloat(self.offset) - CGFloat(self.view.frame.width/2 - 7),y: 0), animated: false)

这里可以优化什么?任何帮助表示赞赏。

最佳答案

只需将滚动到屏幕外的条从其上层移除即可。如果您想变得更有趣,您可以将它们放入队列中以在添加新样本时重复使用,但这可能不值得付出努力。

如果您不让用户在该 View 内滚动,则根本不使用 ScrollView ,而是在添加新 View 时将可见栏移到左侧甚至可能是值得的。

当然,如果您确实需要让用户滚动,您还有更多工作要做。然后你首先必须存储你在某个地方显示的所有值,这样你就可以取回它们。有了这个,您可以覆盖 layoutSubviews 以在滚动期间添加所有缺失的栏。

这基本上就是 UITableViewUICollectionView 的工作方式,因此您可以使用 Collection View 和自定义布局来实现它。手动执行可能更容易,而且性能也更好。

关于ios - 波形绘制性能优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44226017/

有关ios - 波形绘制性能优化的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. ruby - Ruby 中的波形可视化 - 2

    我即将开始一个将录制和编辑音频文件的项目,我正在寻找一个好的库(最好是Ruby,但会考虑Java或.NET以外的任何库)以进行实时可视化波形。有人知道我应该从哪里开始搜索吗? 最佳答案 要流入浏览器的数据量很大。Flash或Flex图表可能是唯一能提高内存效率的解决方案。Javascript图表往往会因大型数据集而崩溃。 关于ruby-Ruby中的波形可视化,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  6. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  7. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  8. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

  9. ruby - 如何找到我的 Ruby 应用程序中的性能瓶颈? - 2

    我编写了一个Ruby应用程序,它可以解析来自不同格式html、xml和csv文件的源中的大量数据。我如何找出代码的哪些区域花费的时间最长?有没有关于如何提高Ruby应用程序性能的好资源?或者您是否有任何始终遵循的性能编码标准?例如,你总是用加入你的字符串吗?output=String.newoutput或者你会使用output="#{part_one}#{part_two}\n" 最佳答案 好吧,有一些众所周知的做法,例如字符串连接比“#{value}”慢得多,但是为了找出您的脚本在哪里消耗了大部分时间或比所需时间更多,您需要进行分

  10. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

随机推荐