使用音频队列或音频单元的 VoIP 功能

Posted

技术标签:

【中文标题】使用音频队列或音频单元的 VoIP 功能【英文标题】:VoIP functionality using Audio Queue or Audio Unit 【发布时间】:2012-12-04 19:31:10 【问题描述】:

你能告诉我这是怎么做到的吗?在一台设备上录制音频并在另一台设备上播放(VoIP)?

我被困在这里:我在此功能中的一台设备上获取输入语音数据

void AQRecorder::MyInputBufferHandler(  void *                              inUserData,
                                        AudioQueueRef                       inAQ,
                                        AudioQueueBufferRef                 inBuffer,
                                        const AudioTimeStamp *              inStartTime,
                                        UInt32                              inNumPackets,
                                        const AudiostreamPacketDescription* inPacketDesc)

    AQRecorder *aqr = (AQRecorder *)inUserData;
    try 
        if (inNumPackets > 0) 
            // write packets to file
            XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize,
                                             inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData),
                       "AudioFileWritePackets failed");
            //inData = inBuffer->mAudioData;
            aqr->mRecordPacket += inNumPackets;
            aqr->updateIndata(inBuffer);
        

        // if we're not stopping, re-enqueue the buffe so that it gets filled again
        if (aqr->IsRunning())
            XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
     catch (CAXException e) 
        char buf[256];
        fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
    

我将数据包发送到 UDP:

void AQRecorder::updateIndata(AudioQueueBufferRef inBuffer)

    SpeakHereAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSData *audioBytes = [NSData dataWithBytes:inBuffer->mAudioData 
                                        length:inBuffer->mAudioDataByteSize];
    NSLog(@"bytes: %d", [audioBytes length]);
    [appDelegate.udpSocket sendData:audioBytes 
                             toHost:appDelegate.host
                               port:appDelegate.port
                        withTimeout:-1
                                tag:1];

& 我正在以 NSData 的形式接收另一端的数据,但不知道如何播放,请您帮忙

【问题讨论】:

【参考方案1】:

你需要一个像 CARingBuffer 这样的环形缓冲区来存储接收到的音频数据,并像 Audio Unit Render Callback 方法一样从缓冲区中读取数据。因为读写操作是异步的,而且速度不同,所以很难确定环形缓冲区应该多长。 所以你也可以使用临时文件来存储接收到的数据,总是把日期写到文件的末尾,然后从头部读取。

【讨论】:

以上是关于使用音频队列或音频单元的 VoIP 功能的主要内容,如果未能解决你的问题,请参考以下文章

ios 使用音频/voip 模式在后台永远运行应用程序

Core Audio:用于提升信号电平的音频单元

Core Audio(音频单元)音频会话和 MPVolumeView

当我需要自定义音频效果时,我是不是需要处理音频单元,或者我可以依赖音频队列服务?

用于 voip 的音频比特流上的 ios 回声消除

UWP 后台 VoIP 通话