
App作为一种工具应用程序,具有语音提示功能. 语音是通过调用云服务来合成的,该服务更加灵活,并且无需为新的提醒准备相应的语音文件. 云服务合成音频并以流方式将其返回到末尾,然后使用音频队列在末尾播放. 流可以抽象为生产者-消费者问题. 云是我们的生产者,麦克风是我们的消费者. Audio Queue解决了一半的问题,它创建了一个Buffer,提供了挂钩来告诉我们Buffer可用占用内存较小的ios音乐播放器,并提供了一个接口供我们调用以告诉它“ Buffer wefull”. 生产者-消费者问题需要协调生产者和消费者对缓存的访问. 经典的解决方案是使用信号量. 借助GCD,我使用队列来实现. 产生音频数据时占用内存较小的ios音乐播放器,如果有Buffer,则填充Buffer,Flush. 否则,将音频文件添加到producerBuffer并再次缓冲. 麦克风消耗音频文件并腾出缓冲区. 如果producerBuffer中有数据,则填充Buffer和Flush;否则,将缓冲区放入可用的缓冲区列表(consumerBuffer). 在这里,producerBuffer和consumerBuffer可以在不同的线程中修改,这需要确保线程安全. 我的方法是将修改操作添加到队列中以进行序列化,或者使用锁或类似于compareAndSwap的无锁机制. 我遇到的内存问题是播放器将在外部保留,在内部保留,并由CoreFoundataion Audio Queue保留. 除了异步问题之外,有时在需要访问它时也将其回收. SIGABRT和BAD_ACCESS都出现了. 主要原因是Audio Queue保留的balance操作错误,即调用CFRelease为时过早. 再次调用BufferCallback时,播放器已被释放.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-240467-1.html
看
现在打我们是鱼