如何读/分配指向结构C中的数组的指针中的元素++(how to read/assign the el

2019-10-17 06:28发布

在IOS核心音频存在API AudioFileWritePackets具有inPacketDescriptions定义为参数“A指针分组描述用于音频数据的数组。”

它看起来像这样的方法签名:
const AudioStreamPacketDescription *inPacketDescriptions,

现在结构AudioStreamPacketDescription定义如下:

struct  AudioStreamPacketDescription
{
    SInt64  mStartOffset;
    UInt32  mVariableFramesInPacket;
    UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;

我想知道如何创建和填充这样的“指针结构数组”,甚至一度给出的变量,如何阅读它。 使用speakHere从苹果的例子,我把,我收到可变断点并试图把它的所有内容转储到日志..这是一个尝试的例子:

void AQRecorder::printPacketDescriptionContents(const AudioStreamPacketDescription * inPacketDescriptions, UInt32 inNumberPackets)
{
    for (int i = 0; i < inNumberPackets; ++i)
    {
        NSLog(@"\n----------------\n");
        NSLog(@"this is packetDescriptionArray[%d].mStartOffset: %lld", i, (*inPacketDescriptions).mStartOffset);
        NSLog(@"this is packetDescriptionArray[%d].mVariableFramesInPacket: %lu", i, (*inPacketDescriptions).mVariableFramesInPacket);
        NSLog(@"this is packetDescriptionArray[%d].mDataByteSize: %lu", i, (*inPacketDescriptions).mDataByteSize);
        NSLog(@"\n----------------\n");   

    }        
}

有任何想法吗?

更新:这里是我的周围试图惹它的样本数..也许它可以在答案它不断出现空..它没有意义,整个事情就是一个包底帮(公告零,因为它是由适当填充的回调返回的变量,也注意到,它告诉我,我回来的数据包数量..)..另外,如果我运行的代码((const AudioStreamPacketDescription *)(inPacketDescriptions +i))->mDataByteSize)我得到一个EXC_BAD_ACCESS错误

(lldb) po **(inPacketDescriptions)
error: indirection requires pointer operand ('const AudioStreamPacketDescription' invalid)
error: 1 errors parsing expression
(lldb) po *(inPacketDescriptions)
(AudioStreamPacketDescription) $1 = [no Objective-C description available]
(lldb) po *(inPacketDescriptions).mStartOffset
error: member reference type 'const AudioStreamPacketDescription *' is a pointer; maybe you meant to use '->'?
error: indirection requires pointer operand ('SInt64' (aka 'long long') invalid)
error: 2 errors parsing expression
(lldb) po (*inPacketDescriptions).mStartOffset
(SInt64) $2 = 0 <nil>

(lldb) po (const AudioStreamPacketDescription *)(inPacketDescriptions +1)
(const class AudioStreamPacketDescription *) $3 = 0x00000010 [no Objective-C description available]
(lldb) po (const AudioStreamPacketDescription *)(inPacketDescriptions +1)->mStartOffset
error: Execution was interrupted, reason: Attempted to dereference an invalid pointer..
The process has been returned to the state before execution.
(lldb) po ((const AudioStreamPacketDescription *)(inPacketDescriptions +1))->mStartOffset
(SInt64) $5 = 0 <nil>
(lldb) po ((const AudioStreamPacketDescription *)(inPacketDescriptions +1))->mDataByteSize
(UInt32) $6 = 0 <nil>
(lldb) po ((const AudioStreamPacketDescription *)(inPacketDescriptions +100))->mDataByteSize
(UInt32) $7 = 0 <nil>
(lldb) po ((const AudioStreamPacketDescription *)(inPacketDescriptions +500))->mDataByteSize
(UInt32) $8 = 0 <nil>

(lldb) po inPacketDescriptions[0].mStartOffset
error: parent failed to evaluate: parent is NULL
(lldb) 

也是在这里是什么样子在Xcode检查:

Answer 1:

我不记得这个特定的结构是有史以来您居住的情况下,客户端。 你需要为这些结构然后您可以跨多个调用传递,以成功应对读写音频数据创建存储 。 一些非PCM格式,将需要这些信息,这取决于如何音频数据已被存储。

我想知道如何创建和填充这样的“指针结构数组”,甚至一度给出的变量,如何阅读它。

那么,有在的AudioFile I / O的API以及使用这种结构AudioConvertor接口屈指可数。 基本上,你不要自己填写此类型。 基本流程是这样的:

// this is not for PCM audio data
//
// we'll read up to 8 packets at a time:
const size_t MaxPacketsToRead(8);

// allocate MaxPacketsToRead ASPDs on the stack:
AudioStreamPacketDescription aspds[MaxPacketsToRead];

// audio file read function:
AudioFileID inAudioFile = ...;
Boolean inUseCache = ...;
UInt32 outNumBytes = ...;
AudioStreamPacketDescription* outPacketDescriptions(aspds);
SInt64 inStartingPacket = ...;
UInt32 ioNumPackets = MaxPacketsToRead; // << you may not get all the packets
                                        // you request, but this sets the
                                        // upper limit.
void* outBuffer = ...;


OSStatus result(AudioFileReadPackets(inAudioFile,
                                     inUseCache,
                                     &outNumBytes,
                                     outPacketDescriptions,
                                     inStartingPacket,
                                     &ioNumPackets,
                                     outBuffer
));

if (noErr != result) {
  ...uh-oh...
}

// *now* we know that we have ioNumPackets worth of valid ASPDs,
// populated by the reader. and we have the associated audio data
// in other parameters.
// we can now safely pass all this information off to a function which 
// reads the ASPDs, such as AudioFileWritePackets.

(知道OP的问题在一些更详细)在很多情况下,你能避免这一切的复杂性和简单地创建一个ExtAudioFile表示,并指定kExtAudioFileProperty_ClientDataFormat为您的目的地样本格式-然后ExtAudioFile的API将代表您创建一个内部转换器这将任意类型的音频文件的输入转换成指定的一些PCM表示,其可用于回放的样本数据。 如果你想支持多种文件格式实现这一切在这个级别其实是相当复杂的。 ExtAudioFile使得将该样本数据很容易 - 如果这是一个选项,如果你流的情况很好地发挥。

至于日志记录,那么你正在试图打印NULL结构的领域,从它的外观。



Answer 2:

声明的阵列AudioStreamPacketDescription

AudioStreamPacketDescription descriptions[10];

/* Populate 'descriptions' */
descriptions[0].mVariableFramesInPacket = 4; /* For example. */

然后将它传递给函数:

/* 'a' is an instance of AQRecorder. */
a.printPacketDescriptionContents(descriptions, 10);

当一个阵列被传递给函数它衰减到指针(到阵列的第一个元素)。

的例子printPacketDescriptionContents()只访问该阵列的第一个元素inNumberPackets倍:你需要访问的每个元素:

NSLog(@"this is packetDescriptionArray[%d].mStartOffset: %lld",
      i,
      inPacketDescriptions[i].mStartOffset);


文章来源: how to read/assign the elements of a pointer that points to an array of structures in C++