将void数组转换为typedef的最佳做法是什么?
这就是我目前正在做的事情:
typedef struct {
int16_t left,right;
} SampleStereo16;
void *buffer[100000]; // data buffer
SampleStereo16* sample;
// insert something here that writes to the buffer
sample = (SampleStereo16*) buffer;
这似乎工作得很好但不知怎的,我觉得有更好的方法。 我还想知道是否有方法让示例数组和缓冲区共享相同的内存(现在它们各自使用自己的内存)。
以下是我目前正在处理的完整代码:
#include "fmod.h"
#include "fmod.hpp"
#include "fmod_errors.h"
#include "wincompat.h"
#include <stdio.h>
typedef struct {
int16_t left,right;
} SampleStereo16;
void ERRCHECK(FMOD_RESULT result)
{
if (result != FMOD_OK)
{
printf("\nFMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
if (result != FMOD_ERR_FILE_EOF)
exit(-1);
}
}
int main(int argc, char *argv[])
{
FMOD::System *system;
FMOD::Sound *sound;
FMOD_RESULT result;
unsigned int version;
int channels;
int bits;
unsigned int lenbytes; // length in bytes read
void *buffer[1000000]; // data buffer
unsigned int *read; // number of bytes actually read
unsigned int position; // offset in PCM samples
unsigned int samplesread; // number of PCM samples read
unsigned int samplesbuffer; //
unsigned int cueposition;
SampleStereo16* sample;
/*
Create a System object and initialize.
*/
result = FMOD::System_Create(&system);
ERRCHECK(result);
system->getVersion(&version);
result = system->getVersion(&version);
ERRCHECK(result);
if (version < FMOD_VERSION)
{
printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION);
getch();
return 0;
}
result = system->setOutput(FMOD_OUTPUTTYPE_ALSA);
ERRCHECK(result);
result = system->init(32, FMOD_INIT_NORMAL, 0);
ERRCHECK(result);
result = system->createStream("/home/dpk/Dropbox/Music/Will Smith - Miami.mp3", FMOD_SOFTWARE, 0, &sound);
result = sound->getFormat(0, 0, &channels, &bits);
ERRCHECK(result);
printf("channels : %d bits : %d \n", channels, bits);
if (channels!=2 and bits!=16)
{
printf("File must be stereo (2 channels) 16 bits \n");
exit(-1);
}
lenbytes = sizeof(buffer);
samplesbuffer = lenbytes / channels / ( bits / 8 );
position = 0;
cueposition = 0;
do
{
result = sound->seekData(position);
ERRCHECK(result);
printf("Reading block : %u ",position);
result = sound->readData(&buffer, lenbytes, read);
ERRCHECK(result);
samplesread = *read / channels / ( bits / 8 );
sample = (SampleStereo16*) buffer;
printf("number of PCM samples read : %u \n", samplesread);
for(unsigned int i=0; i<samplesread; i++)
{
if (cueposition==0 && ( abs(sample[i].left)>500 || abs(sample[i].right)>500 ) )
{
cueposition = position+i;
printf("cue point : %u \n", cueposition);
}
}
position += lenbytes / channels / ( bits / 8 );
} while(samplesread==samplesbuffer);
printf("\nExit\n");
/*
Shut down
*/
result = sound->release();
ERRCHECK(result);
result = system->close();
ERRCHECK(result);
result = system->release();
ERRCHECK(result);
return 0;
}
在增加缓冲区时,我也遇到了分段错误,但是到目前为止我能够找到它似乎是一个堆栈大小限制。
也可以随意评论我做错的事情,我最近(上周)开始使用C ++,所以我很确定我的代码中有些东西看起来很糟糕。
答案 0 :(得分:5)
您的buffer
是指向void
的指针数组。这很不寻常。通常我们将缓冲区声明为char
或unsigned char
或uint8_t
或其他字节大小类型的数组:
char buffer[100000]; // data buffer
无论如何,“正确的”C ++风格的演员阵容是reinterpret_cast
:
sample = reinterpret_cast<SampleStereo16 *>(buffer);
另一方面,您可以首先将buffer
声明为SampleStereo16
的数组。然后你根本不需要演员:
SampleStereo16 buffer[6250];
SampleStereo16 *sample;
sample = buffer;
答案 1 :(得分:0)
您应该使用sizeof运算符来确定读取的样本数量。即,您的字节数组应该是大小的偶数倍(SampleStereo16)。
然后,您通常会以该大小的块的形式遍历字节数组。你使用malloc(sizeof(SampleStereo16))来获取每个SampleStereo16 *指针,然后从你的字节数组中记忆那些数据并将其添加到你的向量或数组中。
如果你以这种方式打包并解压缩每个结构数组,那么你应该没有问题。
将序列化文件中的前几个字节分配给某种版本号也很常见,以防您决定稍后在结构中添加更多字段,但这似乎不是您的用例,基于您的整个代码示例。