精准网站seo诊断报告免费网站空间哪个好

diannao/2026/1/22 8:05:51/文章来源:
精准网站seo诊断报告,免费网站空间哪个好,网站建设的现状与趋势论文,wordpress背景图片尺寸如果你想先看看最终效果再决定看不看文章 - bilibili示例代码下载 第二篇#xff1a;一步一步教你实现iOS音频频谱动画#xff08;二#xff09; 基于篇幅考虑#xff0c;本次教程分为两篇文章#xff0c;本篇文章主要讲述音频播放和频谱数据的获取#xff0c;下篇将… 如果你想先看看最终效果再决定看不看文章 - bilibili示例代码下载 第二篇一步一步教你实现iOS音频频谱动画二 基于篇幅考虑本次教程分为两篇文章本篇文章主要讲述音频播放和频谱数据的获取下篇将讲述数据处理和动画绘制。 前言 很久以前在电脑上听音乐的时候经常会调出播放器的一个小工具里面的柱状图会随着音乐节奏而跳动就感觉自己好专业尽管后来才知道这个是音频信号在频域下的表现。 热身知识 动手写代码之前让我们先了解几个基础概念吧 音频数字化 采样 总所周知声音是一种压力波是连续的然而在计算机中无法表示连续的数据所以只能通过间隔采样的方式进行离散化其中采集的频率称为采样率。根据奈奎斯特采样定理 当采样率大于信号最高频率的2倍时信号频率不会失真。人类能听到的声音频率范围是20hz到20khz所以CD等采用了44.1khz采样率能满足大部分需要。 量化 每次采样的信号强度也会有精度的损失如果用16位的Int(位深度)来表示它的范围是[-32768,32767]因此位深度越高可表示的范围就越大音频质量越好。 声道数 为了更好的效果声音一般采集左右双声道的信号如何编排呢一种是采用交错排列(Interleaved) LRLRLRLR 另一种采用各自排列(non-Interleaved): LLL RRR。 以上将模拟信号数字化的方法称为脉冲编码调制PCM而本文中我们就需要对这类数据进行加工处理。 傅里叶变换 现在我们的音频数据是时域的也就是说横轴是时间纵轴是信号的强度而动画展现要求的横轴是频率。将信号从时域转换成频域可以使用傅里叶变换实现信号经过傅里叶变换分解成了不同频率的正弦波这些信号的频率和振幅就是我们需要实现动画的数据。 图1 (from nti-audio) 傅里叶变换将信号从时域转换成频域 实际上计算机中处理的都是离散傅里叶变换(DFT)而快速傅里叶变换(FFT)是快速计算离散傅里叶变换DFT或其逆变换的方法它将DFT的复杂度从O(n²)降低到O(nlogn)。 如果你刚才点开前面链接看过其中介绍的FFT算法那么可能会觉得这FFT代码该怎么写不用担心苹果为此提供了Accelerate框架其中vDSP部分提供了数字信号处理的函数实现包含FFT。有了vDSP我们只需几个步骤即可实现FFT简单便捷而且性能高效。 iOS中的音频框架 现在开始让我们看一下iOS系统中的音频框架 AudioToolbox功能强大不过提供的API都是基于C语言的其大多数功能已经可以通过AVFoundation实现它利用Objective-C/Swift对于底层接口进行了封装。我们本次需求比较简单只需要播放音频文件并进行实时处理所以AVFoundation中的AVAudioEngine就能满足本次音频播放和处理的需要。 图2 (from WWDC16) iOS/MAC OS X 音频技术栈 AVAudioEngine AVAudioEngine 从iOS8加入到AVFoundation框架它提供了以前需要深入到底层AudioToolbox才实现的功能比如实时音频处理。它把音频处理的各环节抽象成AVAudioNode并通过AVAudioEngine进行管理最后将它们连接构成完整的节点图。以下就是本次教程的AVAudioEngine与其节点的连接方式。 图3 AVAudioEngine和AVAudioNode连接图 mainMixerNode和outputNode都是在被访问的时候默认由AVAudioEngine对象创建并连接的单例对象也就是说我们只需要手动创建engine和player节点并将他们连接就可以了最后在mainMixerNode的输出总线上安装分接头将定量输出的AVAudioPCMBuffer数据进行转换和FFT。 代码实现 了解了以上相关知识后我们就可以开始编写代码了。打开项目AudioSpectrum01-starter首先要实现的是音频播放功能。 如果你只是想浏览实现代码打开项目AudioSpectrum01-final即可已经完成本篇文章的所有代码 音频播放 在AudioSpectrumPlayer类中创建AVAudioEngine和AVAudioPlayerNode两个实例变量 private let engine AVAudioEngine() private let player AVAudioPlayerNode() 复制代码 接下来在init()方法中添加如下代码 //1 engine.attach(player) engine.connect(player, to: engine.mainMixerNode, format: nil) //2 engine.prepare() try! engine.start() 复制代码 //1这里将player挂载到engine上再把player与engine的mainMixerNode连接起来就完成了AVAudioEngine的整个节点图创建详见图3。//2在调用engine的strat()方法开始启动engine之前需要通过prepare()方法提前分配相关资源 继续完善play(withFileName fileName: String)和stop()方法 //1 func play(withFileName fileName: String) { guard let audioFileURL Bundle.main.url(forResource: fileName, withExtension: nil), let audioFile try? AVAudioFile(forReading: audioFileURL) else { return } player.stop() player.scheduleFile(audioFile, at: nil, completionHandler: nil) player.play() } //2 func stop() { player.stop() } 复制代码 //1首先需要确保文件名为fileName的音频文件能正常加载然后通过stop()方法停止之前的播放再调用scheduleFile(_:at:completionHandler:)方法编排新的文件最后通过play()方法开始播放。//2停止播放调用player的stop()方法即可。 音频播放功能已经完成运行项目试试点击音乐右侧的Play按钮进行音频播放吧。 音频数据获取 前面提到我们可以在mainMixerNode上安装分接头定量获取AVAudioPCMBuffer数据现在打开AudioSpectrumPlayer文件先定义一个属性: fftSize它是每次获取到的buffer的frame数量。 private var fftSize: Int 2048 复制代码 将光标定位至init()方法中的engine.connect()语句下方调用mainMixerNode的installTap方法开始安装分接头 engine.mainMixerNode.installTap(onBus: 0, bufferSize: AVAudioFrameCount(fftSize), format: nil, block: { [weak self](buffer, when) in guard let strongSelf self else { return } if !strongSelf.player.isPlaying { return } buffer.frameLength AVAudioFrameCount(strongSelf.fftSize) //这句的作用是确保每次回调中buffer的frameLength是fftSize大小详见https://stackoverflow.com/a/27343266/6192288 let amplitudes strongSelf.fft(buffer) if strongSelf.delegate ! nil { strongSelf.delegate?.player(strongSelf, didGenerateSpectrum: amplitudes) } }) 复制代码 在分接头的回调 block 中将拿到的 2048 个 frame 的 buffer 交由fft函数进行计算最后将计算的结果通过delegate进行传递。 按照 44100hz 采样率和 1 Frame 1 Packet 来计算可以参考这里关于channel、sample、frame、packet的概念与关系那么block将会在一秒中调用44100/2048≈21.5次左右另外需要注意的是block有可能不在主线程调用。 FFT实现 终于到实现FFT的时候了根据vDSP文档首先需要定义一个FFT的权重数组(fftSetup)它可以在多次FFT中重复使用和提升FFT性能: private lazy var fftSetup vDSP_create_fftsetup(vDSP_Length(Int(round(log2(Double(fftSize))))), FFTRadix(kFFTRadix2)) 复制代码 不需要时在析构函数反初始化函数中销毁 deinit {vDSP_destroy_fftsetup(fftSetup) } 复制代码 最后新建fft函数实现代码如下 private func fft(_ buffer: AVAudioPCMBuffer) - [[Float]] { var amplitudes [[Float]]() guard let floatChannelData buffer.floatChannelData else { return amplitudes } //1抽取buffer中的样本数据 var channels: UnsafePointerUnsafeMutablePointerFloat floatChannelData let channelCount Int(buffer.format.channelCount) let isInterleaved buffer.format.isInterleaved if isInterleaved { // deinterleave let interleavedData UnsafeBufferPointer(start: floatChannelData[0], count: self.fftSize * channelCount) var channelsTemp : [UnsafeMutablePointerFloat] [] for i in 0..channelCount { var channelData stride(from: i, to: interleavedData.count, by: channelCount).map{ interleavedData[$0]} channelsTemp.append(UnsafeMutablePointer(channelData)) } channels UnsafePointer(channelsTemp) } for i in 0..channelCount { let channel channels[i] //2: 加汉宁窗 var window [Float](repeating: 0, count: Int(fftSize)) vDSP_hann_window(window, vDSP_Length(fftSize), Int32(vDSP_HANN_NORM)) vDSP_vmul(channel, 1, window, 1, channel, 1, vDSP_Length(fftSize)) //3: 将实数包装成FFT要求的复数fftInOut既是输入也是输出 var realp [Float](repeating: 0.0, count: Int(fftSize / 2)) var imagp [Float](repeating: 0.0, count: Int(fftSize / 2)) var fftInOut DSPSplitComplex(realp: realp, imagp: imagp) channel.withMemoryRebound(to: DSPComplex.self, capacity: fftSize) { (typeConvertedTransferBuffer) - Void in vDSP_ctoz(typeConvertedTransferBuffer, 2, fftInOut, 1, vDSP_Length(fftSize / 2)) } //4执行FFT vDSP_fft_zrip(fftSetup!, fftInOut, 1, vDSP_Length(round(log2(Double(fftSize)))), FFTDirection(FFT_FORWARD)); //5调整FFT结果计算振幅 fftInOut.imagp[0] 0 let fftNormFactor Float(1.0 / (Float(fftSize))) vDSP_vsmul(fftInOut.realp, 1, [fftNormFactor], fftInOut.realp, 1, vDSP_Length(fftSize / 2)); vDSP_vsmul(fftInOut.imagp, 1, [fftNormFactor], fftInOut.imagp, 1, vDSP_Length(fftSize / 2)); var channelAmplitudes [Float](repeating: 0.0, count: Int(fftSize / 2)) vDSP_zvabs(fftInOut, 1, channelAmplitudes, 1, vDSP_Length(fftSize / 2)); channelAmplitudes[0] channelAmplitudes[0] / 2 //直流分量的振幅需要再除以2 amplitudes.append(channelAmplitudes) } return amplitudes } 复制代码 通过代码中的注释应该能了解如何从buffer获取音频样本数据并进行FFT计算了不过以下两点是我在完成这一部分内容过程中比较难理解的部分 通过buffer对象的方法floatChannelData获取样本数据如果是多声道并且是interleaved我们就需要对它进行deinterleave, 通过下图就能比较清楚的知道deinterleave前后的结构不过在我试验了许多音频文件之后发现都是non-interleaved的也就是无需进行转换。┑(Д )┍ 图4 interleaved的样本数据需要进行deinterleavevDSP在进行实数FFT计算时利用一种独特的数据格式化方式以达到节省内存的目的它在FFT计算的前后通过两次转换将FFT的输入和输出的数据结构进行统一成DSPSplitComplex。第一次转换是通过vDSP_ctoz函数将样本数据的实数数组转换成DSPSplitComplex。第二次则是将FFT结果转换成DSPSplitComplex这个转换的过程是在FFT计算函数vDSP_fft_zrip中自动完成的。 第二次转换过程如下n位样本数据n/2位复数进行fft计算会得到n/21位复数结果{[DC,0],C[2],...,C[n/2],[NY,0]} (其中DC是直流分量NY是奈奎斯特频率的值,C是复数数组)其中[DC,0]和[NY,0]的虚部都是0所以可以将NY放到DC中的虚部中其结果变成{[DC,NY],C[2],C[3],...,C[n/2]}与输入位数一致。 图5 第一次转换时vDSP_ctoz函数将实数数组转换成DSPSplitComplex结构 再次运行项目现在除了听到音乐之外还可以在控制台中看到打印输出的频谱数据。 图6 将结果通过Google Sheets绘制出来的频谱图 好了本篇文章内容到这里就结束了下一篇文章将对计算好的频谱数据进行处理和动画绘制。 资料参考 [1] wikipedia脉冲编码调制 zh.wikipedia.org/wiki/%E8%84… [2] Mike Ash音频数据获取与解析, www.mikeash.com/pyblog/frid… [3] 韩 昊, 傅里叶分析之掐死教程, blog.jobbole.com/70549/ [4] raywenderlich, AVAudioEngine编程入门www.raywenderlich.com/5154-avaudi… [5] Apple, vDSP编程指南, developer.apple.com/library/arc… [6] Apple, aurioTouch案例代码developer.apple.com/library/arc… 作者potato04链接https://juejin.im/post/5c1bbec66fb9a049cb18b64c来源掘金著作权归作者所有。商业转载请联系作者获得授权非商业转载请注明出处。 转载于:https://www.cnblogs.com/Free-Thinker/p/10880118.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/89370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

建设主题网站的顺序是什么意思上海免费网站建设模板推荐

1.every()方法的定义与用法 every()方法用于检测数组中的所有元素是否都满足指定条件every()方法会遍历数组中的每一项,如果有一项不满足条件,则表达式返回false,剩余的项将不会进行检测;如果遍历完数组后,每一项都符…

个人网站开发西安seo王

目录 1、Value注解的作用 2、Value 注解的写法 3、用法示例 3.1 resources 目录新增 book.properties 配置文件 3.2 新增实体 Book.java 3.3 新增 TestValueConfig.java 3.4 新增 TestValue.java 测试文件 4、使用场景 今天给大家分享Spring属性赋值注解Value 用法&#xff0c…

建网站无锡网站建设主流开发语言

Java中的WeakHashMap是中高级Java开发人员中非常流行的数据结构。 WeakHashMap类位于java.util包中。 这是一个Map实现,其中存储了对其键的弱引用。 当关联密钥丢失其所有活动的强引用和软引用时, WeakHashMap中的条目将自动删除。 在本文中&#xff0…

换网站了吗网站平台维护

ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。 说明: 从API version 9开始,该接口支持在ArkTS卡片中使用。 使用规则 支持if、else和else if语句。 if、else if后跟随的条件语句…

html5个人网站源码有专门做市场分析的网站么

程序员的圈子啊那是十分神秘,又令人着迷的。每天的工作就是对着电脑,那他们的工作是如何的呢?我们来品一品(PS:后面奉上各位大佬的桌面,别走开哦)↓↓↓最最常见的普通版:升级版&…

wordpress 不允许评论网站seo文章该怎么写

CSRF攻击是开发Web后端时需要重点解决的问题。 那么什么是CSRF攻击呢? CSRF跨站点请求伪造(Cross—Site Request Forgery),其主要利用的是Cookie的一个弱点,就是Cookie 最初被设计成了允许在第三方网站发起的请求中携带: 关于Co…

成都低价做网站合肥公司网站建设

iOS 9音频应用播放音频之音量设置与声道设置 iOS 9音频应用音量设置 音量又称响度、音强,是指人耳对所听到的声音大小强弱的主观感受,其客观评价尺度是声音的振幅大小。在iOS 9音频应用的应用中,经常会出现播放的音乐音量过大或者过小。此时i…

网站发布服务托管器wordpress后台登陆logo

每个人都习惯使用Python去完成机器学习和深度学习的工作,但是对于习惯于某种特定语言的人来说,转型不是那么容易的事。这两年我花了不少时间在Python,毕竟工作的重心也从移动开发转为机器学习和深度学习。感谢我的老板给我很大的空间去开拓新…

做网站需要用socket吗莱芜网站制作

所谓的冷备和热备,冷备就是不用vrrp和hsb协议同步ap和用户信息,主的断了等七十五秒后,备的capwap和ap连接上去。 双链路冷备不用vrrp和hsb 双链路热备份只用hsb同步ap和用户信息,不用vrrp,两个ac可以不用在同一个二层…

沙田镇网站建设wordpress会话已过期

在进行媒体查询的编写的时候,我们可以利用scss与与编译器,通过include混入的方式对代码进行简化,从而大大提高了代码的可维护性,也减少了代码的编写量,废话不多说,直接上代码: // 断点列表 相当…

如何设定旅游网站seo核心关键词梵高网站建设

我们听说过很多关于测试驱动开发(TDD)的内容。那么什么是ATDD? ATDD代表验收测试驱动开发,这是一种定义验收标准并创建自动化测试来验证是否满足这些标准的软件开发方法。ATDD是一种协作方法,涉及客户、开发人员和测试…

如何用网站做淘宝客滴道网站建设

一、最终效果为了不浪费大家时间,先展示最终效果,看看是不是大家需要的解决方案:标准分辨率:其他分辨率的适配情况:二、需求1.canvas的内容能全部展示在屏幕上2.尽量能保证图像不变形3.绘制的文字也能自适应三、解决方…

做视频播放网站站酷网站的比赛网页谁做的

可以将 nginx 作为一个非常高效的 HTTP 负载均衡器,将流量分配到多个应用服务器上,并通过 nginx 提高 Web 应用的性能、可扩展性和可靠性。 nginx 可以通过添加一个 upstream,来实现 nginx 的负载均衡功能。 upstream myserver {server 192…

石家庄网站建立兰州网络推广范文

M/M/m排队模型 (单队列多服务台并联服务模型) 数学建模: 基于生灭过程的理论计算和基于事件推进的Matlab模拟仿真思路 原创文章,转载文章请注明出处:©️Sylvan Ding 🎉🎉🎉 摘要 本文研究M/M/m单队列多服务台并…

深圳市制作网站百度关键词多少钱一个月

第十七天课堂笔记 Java常用类 数学类★★★ math java.lang.Math , 数学类 round(x) : 四舍五入 , 把 x加0.5 后向下取整 ceil(x) : 返回大于等于x的最小整数 , 向上取整 floor(x) : 返回小于等于x的最大整数 , 向下取整 sqrt(x) : 平方根 cbrt(x): 立方根 pow(a , b)…

建筑人才网站哪个比较好绍兴网站制作建设

一、界面预览鼠标放到右边的Tab按钮上&#xff0c;文字透明度降低&#xff0c;同时一段文字高亮显示&#xff0c;效果如下&#xff1a;Demo地址&#xff1a;http://5thirtyone.com/sandbox/samples/fadefocus/很绚丽的效果幺&#xff01;二、实现原理将要高亮显示的文字加上<…

淄博网站建设淄博中国十大软件外包公司排名

1. 模型介绍&#xff1a; 生产者消费者模型是操作系统中的一种并发编程模型&#xff0c;用于解决生产者和消费者之间的数据共享和同步问题。 在该模型中&#xff0c;生产者负责生成数据&#xff0c;并将数据放入一个有限的缓冲区中&#xff0c;而消费者则从缓冲区中取出数据进…

怎么设置网站名称长荣建设深圳公司网站

问题说明前几天运维同事反馈开发同事代码在Windows 2008 R2 Datacenter服务器上跑会出现无法正常建立SSL/TLS连接的情况&#xff0c;在自己的电脑上跑是OK的&#xff0c;代码也没有变动过。于是我问他改了服务器上什么配置没有&#xff0c;他说改了注册表也不行。接过这个坑&am…

游戏网站建设多少钱企业邮箱入口163

常用命令 命令说明git submodule add <url> <本地路径>添加子模块git submodule update --init --recursive添加子模块后&#xff0c;同步子模块内容git clone <url> --recurse-submodules克隆带有子模块的项目git submodule init初始化子模块git submodule…

网约车平台app网站建设苏州工业园区社保公积金管理中心

《WEB应用测试》笔记&#xff08;六&#xff09;第三章 软件测试基础 18、软件开发阶段的常见范例&#xff08;1&#xff09;a版&#xff1a;产品主要的和达成共识的部分已经完成。产品准备投入内部使用。&#xff08;2&#xff09;B前期版本&#xff1a;提交进行B验收的构造版…