首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何播放从AVAudioPCMBuffer转换而来的NSData音频

如何播放从AVAudioPCMBuffer转换而来的NSData音频
EN

Stack Overflow用户
提问于 2015-07-15 07:14:57
回答 1查看 3.8K关注 0票数 3

我从udp数据包获得音频PCM 16位Mono数据,如下所示:

代码语言:javascript
复制
(void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
                                               fromAddress:(NSData *)address
                                         withFilterContext:(id)filterContext
{
...
}

我将通过调用data函数将数据转换为PCM缓冲区,如下所示:

代码语言:javascript
复制
func toPCMBuffer(data: NSData) -> AVAudioPCMBuffer {
    let audioFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.PCMFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false)  // given NSData audio format
    var PCMBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity:1024*10)
    PCMBuffer.frameLength = PCMBuffer.frameCapacity

    let channels = UnsafeBufferPointer(start: PCMBuffer.floatChannelData, count: Int(PCMBuffer.format.channelCount))

    data.getBytes(UnsafeMutablePointer<Void>(channels[0]) , length: data.length)

    return PCMBuffer
}

数据被转换为PCM缓冲区,我可以在日志中看到它的长度。但是当我试着演奏缓冲器时,我没有听到任何声音。以下是接收代码:

代码语言:javascript
复制
func toPCMBuffer(data: NSData) -> AVAudioPCMBuffer {
        let audioFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.PCMFormatFloat32, sampleRate: 8000, channels: 1, interleaved: false)  // given NSData audio format
        var PCMBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity:1024*10)
        PCMBuffer.frameLength = PCMBuffer.frameCapacity

        let channels = UnsafeBufferPointer(start: PCMBuffer.floatChannelData, count: Int(PCMBuffer.format.channelCount))

        data.getBytes(UnsafeMutablePointer<Void>(channels[0]) , length: data.length)
        var mainMixer = audioEngine.mainMixerNode
        audioEngine.attachNode(audioFilePlayer)
        audioEngine.connect(audioFilePlayer, to:mainMixer, format: PCMBuffer.format)
        audioEngine.startAndReturnError(nil)

        audioFilePlayer.play()
        audioFilePlayer.scheduleBuffer(PCMBuffer, atTime: nil, options: nil, completionHandler: nil)
        return PCMBuffer
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-23 17:33:51

最后使用了一个目标-c函数:数据转换得很好。

代码语言:javascript
复制
-(AudioBufferList *) getBufferListFromData: (NSData *) data
{
    if (data.length > 0)
    {
        NSUInteger len = [data length];
        //NSData *d2 = [data subdataWithRange:NSMakeRange(4, 1028)];
        //I guess you can use Byte*, void* or Float32*. I am not sure if that makes any difference.
        Byte* byteData = (Byte*) malloc (len);
        memcpy (byteData, [data bytes], len);
        if (byteData)
        {
            AudioBufferList * theDataBuffer =(AudioBufferList*)malloc(sizeof(AudioBufferList) * 1);
            theDataBuffer->mNumberBuffers = 1;
            theDataBuffer->mBuffers[0].mDataByteSize =(UInt32) len;
            theDataBuffer->mBuffers[0].mNumberChannels = 1;
            theDataBuffer->mBuffers[0].mData = byteData;
            // Read the data into an AudioBufferList
            return theDataBuffer;
        }
    }
    return nil;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31423790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档