简体   繁体   English

在AudioUnit播放回调中从AudioBuffer-> mdata播放音频

[英]Playing audio from AudioBuffer->mdata in AudioUnit playback callback

Folks i have been searching and trying to resolve following problem since a whole day. 一整天以来,我一直在寻找并尝试解决以下问题的人们。 No success yet 尚未成功

Ok, So i have been using apple sample code project name WiTap to communicate b/w two devices over wifi using NSInputStreams and NSOutputStreams I have been able to transfer data (audio data) b/w devices successfully. 好的,所以我一直在使用Apple示例代码项目名称WiTap使用NSInputStreamsNSOutputStreams通过wifi通过WiTap通信两个设备,我已经能够成功传输数据(音频数据)黑白设备。

However on the destination device i receive data and fill it in an audio buffer as follows: 但是,在目标设备上,我接收数据并将其填充到音频缓冲区中,如下所示:

bytesRead = [self.inputStream read:anAudioBuffer.mData maxLength:anAudioBuffer.mDataByteSize];

while anAudioBuffer itself is declared as follows anAudioBuffer本身声明如下

anAudioBuffer.mNumberChannels = 1;
anAudioBuffer.mDataByteSize = 512 * 2;
anAudioBuffer.mData = malloc( 512 * 2 );

Now i access this audio buffer as someObject.anAudioBuffer in the AudioUnit Callback from the Apple's sample code 现在,我从Apple的示例代码中,通过AudioUnit回调中的someObject.anAudioBuffer来访问此音频缓冲区。

which is as follows 如下

static OSStatus playbackCallback(void *inRefCon, 
                                 AudioUnitRenderActionFlags *ioActionFlags, 
                                 const AudioTimeStamp *inTimeStamp, 
                                 UInt32 inBusNumber, 
                                 UInt32 inNumberFrames, 
                                 AudioBufferList *ioData) {    
    // Notes: ioData contains buffers (may be more than one!)
    // Fill them up as much as you can. Remember to set the size value in each buffer to match how
    // much data is in the buffer.

    for (int i=0; i < ioData->mNumberBuffers; i++) { // in practice we will only ever have 1 buffer, since audio format is mono
        AudioBuffer buffer = ioData->mBuffers[i];

        // copy temporary buffer data to output buffer
        UInt32 size = min(buffer.mDataByteSize, someObject.anAudioBuffer.mDataByteSize); // dont copy more data then we have, or then fits
        memcpy(buffer.mData, someObject.anAudioBuffer.mData, size);
        buffer.mDataByteSize = size; // indicate how much data we wrote in the buffer

        // uncomment to hear random noise
        /*
        UInt16 *frameBuffer = buffer.mData;
        for (int j = 0; j < inNumberFrames; j++) {
            frameBuffer[j] = arc4random();
        }
        */

    }

    return noErr;
}

Now i want to play the bytes that i copied from someObject.anAudioBuffer into a local var buffer 现在我要播放从someObject.anAudioBuffer复制到本地var buffer的字节

I do note that the this section of the code has to do with playing the audio 我确实注意到,代码的这一部分与播放音频有关

/*
 UInt16 *frameBuffer = buffer.mData;
 for (int j = 0; j < inNumberFrames; j++) {
    frameBuffer[j] = arc4random();
 }
*/

now the arc4random is used to play static noise. 现在, arc4random用于播放静态噪声。 With best of my efforts and searching all over the internet i could not figure out how to play my own bytes and also this piece of code b/w /* */ 尽我最大的努力并在整个互联网上搜索,我无法弄清楚如何播放自己的字节以及这段代码b / w /* */

eg what is the purpose of this line? 例如,这条线的目的是什么?

UInt16 *frameBuffer = buffer.mData;

and how do i fill this frameBuffer with my own data to play. 以及如何使用自己的数据填充此frameBuffer来播放。

Can anybody please guide me. 谁能指导我。 Too much of my time is wasted on this seemingly trivial problem. 我太多的时间都浪费在这个看似微不足道的问题上。

I can provide more detail, if required. 如果需要,我可以提供更多详细信息。

Waiting in anticipation... 等待中...

You have to fill the memory (or array) pointed to by mBuffer.mData[0] with exactly inNumberFrames of audio sample frames (whether you have those samples available or not). 您必须将mBuffer.mData [0]指向的内存(或数组)完全插入音频样本帧的inNumberFrames中(无论这些样本是否可用)。 You do this in your noise generator, but not in your memcopy code. 您可以在噪声生成器中执行此操作,但不能在内存复制代码中执行此操作。

Also leave mDataByteSize unchanged, as it is an input to the callback, not an inout. 还要保留mDataByteSize不变,因为它是回调的输入,而不是inout。 An audio callback is a demand, not an optional request. 音频回调是需求,而不是可选请求。

So i have found the Answer 所以我找到了答案

It was simple but i had no knowledge of reading C pointer arrays. 这很简单,但是我不了解读取C指针数组的知识。 All i had to do was: 我要做的就是:

 UInt16 *frameBuffer = buffer.mData;
 for (int j = 0; j < inNumberFrames; j++) {
    frameBuffer[j] = *(frameBuffer + j);
 }

While this UInt16 *frameBuffer = buffer.mData; 虽然这个UInt16 *frameBuffer = buffer.mData; makes frameBuffer point to starting index of buffer.mData , the following 使frameBuffer点开始的索引buffer.mData ,以下

*(frameBuffer + j); is C's way of reading the next pointer. 是C读取下一个指针的方式。

After writing frameBuffer[j] = *(frameBuffer + j); 写入frameBuffer[j] = *(frameBuffer + j); my audio from stream plays like a charm. 我的音频流就像魅力一样。

Will be glad to know if this helped some other too. 我们将很高兴知道这是否对您有所帮助。

Found C pointer arrays info from here 这里找到C指针数组信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM